Merge branch 'feature/GFRS-232【待确定】业绩查询' into release/0803

# Conflicts:
#	src/main.js
#	src/router/ebiz/index.js
This commit is contained in:
mengxiaolong
2020-08-04 15:10:59 +08:00
24 changed files with 4094 additions and 33 deletions

8
package-lock.json generated
View File

@@ -14877,6 +14877,14 @@
}
}
},
"vue-hash-calendar": {
"version": "1.2.12",
"resolved": "https://registry.npm.taobao.org/vue-hash-calendar/download/vue-hash-calendar-1.2.12.tgz",
"integrity": "sha1-3TyXG2GpV8ZwavJS9FGVmpsHsoY=",
"requires": {
"vue": "^2.5.17"
}
},
"vue-hot-reload-api": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz",

View File

@@ -3,7 +3,7 @@
<!--实现路由切换动画-->
<transition :name="transitionName">
<keep-alive include="StoreDetail">
<RouterView />
<RouterView v-if="isRouterAlive" />
</keep-alive>
<!-- <keep-alive>
@@ -17,7 +17,21 @@
export default {
data() {
return {
transitionName: ''
transitionName: '',
isRouterAlive: true
}
},
provide() {
return {
reload: this.reload
}
},
methods: {
reload() {
this.isRouterAlive = false
this.$nextTick(() => {
this.isRouterAlive = true
})
}
}
// watch: {

View File

@@ -0,0 +1,27 @@
import request from '@/assets/js/utils/request'
import getUrl from '@/assets/js/utils/get-url'
//打卡情况续期列表查询
export function attendance(data) {
return request({
url: getUrl(`/agent/Performance/attendance`, 1),
method: 'post',
data
})
}
//日期查询
export function getDayDetail(data) {
return request({
url: getUrl(`/agent/Performance/getDayDetail`, 1),
method: 'post',
data
})
}
//月历查询
export function getMonthDetail(data) {
return request({
url: getUrl(`/agent/Performance/getMonthDetail`, 1),
method: 'post',
data
})
}

View File

@@ -0,0 +1,51 @@
import request from '@/assets/js/utils/request'
import getUrl from '@/assets/js/utils/get-url'
//代理人功能获取
export function getBaseAgentInfo(data) {
return request({
url: getUrl(`/agent/agent/getBaseAgentInfo`, 1),
method: 'post',
data
})
}
//代理人关系获取
export function getBranchInfos(data) {
return request({
url: getUrl(`/agent/branch/getBranchInfos`, 1),
method: 'post',
data
})
}
//获取信息
export function getPerformanceDetail(data) {
return request({
url: getUrl(`/agent/Performance/getPerformanceDetail`, 1),
method: 'post',
data
})
}
//获取代理人下级头像
// http://139.199.50.151:7000/api/v1/agent/branch/getAllAgentByAgent
export function getPerformanceHeader(data) {
return request({
url: getUrl(`/agent/branch/getAllAgentByAgent`, 1),
method: 'post',
data
})
}
export function getHeader(data) {
return request({
url: getUrl(`/agent/branch/getAllAgentByGroup`, 1),
method: 'post',
data
})
}
//转code
export function getCode(data) {
return request({
url: getUrl(`/agent/Performance/getGroupCodeByName`, 1),
method: 'post',
data
})
}

BIN
src/assets/images/u1188.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

BIN
src/assets/images/u1203.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
src/assets/images/u1213.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/assets/images/u188.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
src/assets/images/u79.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

View File

@@ -12,40 +12,25 @@ import noMoreClick from '@/directive/noMoreClick'
import vueHashCalendar from 'vue-hash-calendar'
import 'vue-hash-calendar/lib/vue-hash-calendar.css'
import {
Cell, CellGroup,
DatetimePicker ,
Popup ,
Picker,
Col,
Row,
Tab,
Tabs,
NavBar,
Toast,
Button,
Dialog,
Icon,
Lazyload
} from 'vant'
Vue.use(Cell);
import { Cell, CellGroup, DatetimePicker, Popup, Picker, Col, Row, Tab, Tabs, NavBar, Toast, Button, Dialog, Icon, Lazyload } from 'vant'
Vue.use(Cell)
Vue.use(CellGroup)
Vue.use(DatetimePicker);
Vue.use(DatetimePicker)
Vue.use(Popup)
Vue.use(Picker)
Vue.use(Col)
Vue.use(Row);
Vue.use(Row)
Vue.use(Tab)
Vue.use(Tabs);
Vue.use(Tabs)
Vue.use(Icon)
Vue.use(vueHashCalendar)
Vue.use(NavBar);
Vue.use(NavBar)
Vue.use(Toast)
Vue.use(Button)
Vue.use(Dialog)
Vue.use(Lazyload, {
lazyComponent: true,
});
lazyComponent: true
})
Vue.prototype.$assetsUrl = config.assetsUrl
Vue.prototype.$mainUrl = config.mainUrl
@@ -56,7 +41,7 @@ Vue.directive('no-more-click', noMoreClick)
//解决ios移动端input调软键盘问题
let isIphone = navigator.userAgent.indexOf('iPhone') != -1
if (isIphone) {
FastClick.prototype.focus = function (targetElement) {
FastClick.prototype.focus = function(targetElement) {
let length
if (
isIphone &&
@@ -100,14 +85,12 @@ if (process.env.VUE_APP_FLAG != 'prd') {
// Eruda.init()
// 注册过滤器
Object.keys(Filters).forEach(function (k) {
Object.keys(Filters).forEach(function(k) {
Vue.filter(k, Filters[k])
})
//权限控制
import {
permission
} from '@/assets/js/utils/permission'
import { permission } from '@/assets/js/utils/permission'
permission()
//ios点击300毫秒时延
@@ -118,4 +101,4 @@ new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
}).$mount('#app')

View File

@@ -0,0 +1,24 @@
const attendance = () => import('@/views/ebiz/attendance/Attendance')
const monthly = () => import('@/views/ebiz/attendance/Monthly')
export default [
{
path: '/attendance/Attendance',
name: 'Attendance',
component: attendance,
meta: {
title: '考勤统计',
index: 1
}
},
{
path: '/attendance/Monthly',
name: 'Monthly',
component: monthly,
meta: {
title: '考勤统计',
index: 2
}
}
]

View File

@@ -18,6 +18,9 @@ import claims from './claims'
import productStore from './product-store'
// 机构业绩
import institutionalPerform from './institutionalPerform'
import performance from './performance'
import attendance from './attendance'
export default [
...proposal,
...sale,
@@ -36,5 +39,7 @@ export default [
...manpower,
...institutionalPerform,
...claims,
...productStore
] //根据需要进行删减
...productStore,
...performance,
...attendance
] //根据需要进行删减

View File

@@ -0,0 +1,43 @@
const performance = () => import('@/views/ebiz/performance/Performance')
const attendanceInfo = () => import('@/views/ebiz/performance/AttendanceInfo')
const PerformanceList = () => import('@/views/ebiz/performance/PerformanceList')
const PerformanceInfo = () => import('@/views/ebiz/performance/PerformanceInfo')
export default [
{
path: '/performance/Performance',
name: 'Performance',
component: performance,
meta: {
title: '业绩查询',
index: 1
}
},
{
path: '/performance/AttendanceInfo',
name: 'AttendanceInfo',
component: attendanceInfo,
meta: {
title: '业绩查询',
index: 3
}
},
{
path: '/performance/PerformanceList',
name: 'PerformanceList',
component: PerformanceList,
meta: {
title: '业绩查询',
index: 3
}
},
{
path: '/performance/PerformanceInfo',
name: 'PerformanceInfo',
component: PerformanceInfo,
meta: {
title: '业绩查询',
index: 4
}
}
]

View File

@@ -0,0 +1,167 @@
<template>
<div>
<div class="border-gb header mh-auto h50 flex align-items-c bg-white">
<van-button
round
@click="goDetail(order)"
size="small"
class="ml15"
type="danger"
v-no-more-click="1000"
>当月</van-button>
<div @click="timePopup" class="fs12 red ml15">
{{titleTime}}
<img src="@/assets/images/u79.png" alt class="absolute mt2 ml5" />
</div>
<van-popup v-model="dateShow" position="bottom">
<van-datetime-picker
v-model="currentDate"
type="year-month"
title="选择年月日"
:min-date="minDate"
:max-date="maxDate"
@cancel="handleCancel"
@confirm="handleEndDateConfirm"
/>
</van-popup>
</div>
<div class="mt10 bg-white">
<div class="flex h70 align-items-c border-gb">
<img src="@/assets/images/u1203.png" alt class="h40 w40 ml15" />
<span class="ml10 fs14">{{name}}</span>
<div class="absolute right20 flex" @click="month(obj)">
<div class="mt10">
<img src="@/assets/images/u1188.png" alt class />
</div>
<div class="fs14 red mt10">打卡月历</div>
</div>
</div>
<div class="flex h50 border-gb ml15 align-items-c">
<div>应出勤天数</div>
<div class="absolute right30">{{mustWorkDay}}</div>
</div>
<div class="flex h50 border-gb ml15 align-items-c">
<div>实际出勤天数</div>
<div class="absolute right30">{{workDay}}</div>
</div>
<div class="flex h50 border-gb ml15 align-items-c">
<div>实时出勤率</div>
<div class="absolute right30">{{workRate}}%</div>
</div>
<div class="flex h50 border-gb ml15 align-items-c fwb">
<div>迟到</div>
<div class="absolute right30 " :class="Number(lateNum)>0?'red':'c-gray-base'">{{lateNum}},{{lateTime}}分钟</div>
</div>
<div class="flex h50 border-gb ml15 align-items-c fwb">
<div>早退</div>
<div class="absolute right30" :class="Number(earllyNum)>0?'red':'c-gray-base'">{{earllyNum}}{{earllyTime}}分钟</div>
</div>
<div class="flex h50 border-gb ml15 align-items-c fwb">
<div>缺卡</div>
<div class="absolute right30 " :class="Number(forgetNum)>0?'red':'c-gray-base'">{{forgetNum}}</div>
</div>
<div class="flex h50 ml15 align-items-c fwb">
<div>旷工</div>
<div class="absolute right30 " :class="Number(dontWork)>0?'red':'c-gray-base'">{{dontWork}}</div>
</div>
</div>
<div class="fs13 red mt10 ml15">最终参训数据以次月公司下发的参训系统数据为准</div>
</div>
</template>
<script>
import { Popup, DatetimePicker } from 'vant'
import { attendance } from '@/api/ebiz/attendance/attendance'
import utils from '@/assets/js/utils/date-utils'
export default {
name: 'attendance',
components: {
[Popup.name]: Popup,
[DatetimePicker.name]: DatetimePicker
},
data() {
return {
currentDate: new Date(),
dateShow: false,
minDate: new Date(2020, 0, 1),
maxDate: new Date(),
mustWorkDay: '',
workDay: 1,
workRate: '0.0',
lateNum: 0,
lateTime: 0,
earllyNum: 0,
earllyTime: 0,
forgetNum: 0,
dontWork: 0,
titleTime: '',
timeCode:'',
name:'',
obj:{}
}
},
created() {
this.formatDate1()
this.attendance1()
},
methods: {
timePopup() {
this.dateShow = true
},
handleCancel() {
this.dateShow = false
},
//开始时间
handleEndDateConfirm(e) {
this.dateShow = false
console.log(e)
this.titleTime = utils.formatDate(e, 'yyyy-MM')
this.timeCode=utils.formatDate(e, 'yyyy-MM-dd')
this.obj.time=this.timeCode
this.attendance1()
},
month(obj) {
localStorage.obj1 = JSON.stringify(this.obj)
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/attendance/Monthly`
},
routerInfo: {
path: `/attendance/Monthly`
}
})
},
attendance1() {
let date1 = {
date: this.timeCode
}
attendance(date1).then(res => {
console.log(res)
if (res.result == 0) {
;(this.mustWorkDay = res.content.mustWorkDay),
(this.workDay = res.content.workDay),
(this.workRate = res.content.workRate),
(this.lateNum = res.content.lateNum),
(this.lateTime = res.content.lateTime),
(this.earllyNum = res.content.earllyNum),
(this.earllyTime = res.content.earllyTime),
(this.forgetNum = res.content.forgetNum),
(this.dontWork = res.content.dontWork),
this.name=res.content.name,
this.obj.name=this.name
}
})
},
formatDate1() {
// console.log(utils.formatDate("2020-1-1"))
this.titleTime = utils.formatDate(this.currentDate, 'yyyy-MM')
this.timeCode = utils.formatDate(this.currentDate, 'yyyy-MM-dd')
this.obj.time=this.timeCode
console.log(this.titleTime)
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,774 @@
<template>
<div class="calendar_body" v-show="show">
<div class="calendar_week" ref="weekTitle">
<div class="calendar_item" v-for="item in calendarWeek" :key="item">
<p class="calendar_day">{{ item }}</p>
</div>
</div>
<div
class="calendar_group"
:style="{ height: `${calendarGroupHeight}px` }"
ref="calendar"
@touchstart="touchStart"
@touchmove.stop.prevent="touchMove"
@touchend="touchEnd"
>
<ul :style="{ transform: `translate3d(${-translateIndex * 100}%, 0, 0)` }">
<li
class="calendar_group_li"
v-for="(item, i) in calendarOfMonthShow"
:key="i"
:style="{
transform: `translate3d(${(i - 1 + translateIndex + (isTouching ? touch.x : 0)) * 100}%, ${calendarY}px, 0)`,
transitionDuration: `${isTouching ? 0 : transitionDuration}s`
}"
>
<div
class="calendar_item"
ref="calendarItem"
v-for="(date, j) in item"
:key="i + j"
:class="{ calendar_item_disable: formatDisabledDate(date) }"
@click="clickCalendarDay(date)"
>
<div class="calendar_day_nochecked" :class="{ calendar_day_checked: isCheckedDay(date) }">
<p
v-if="date.day === 1 && !isNotCurrentMonthDay(date, i)"
:class="{ checked_color: isCheckedDay(date) }"
class="calendar_day calendar_first_today"
ref="calendarDay"
>
{{ calendarMonth[date.month] }}
</p>
<p
v-else
class="calendar_day"
ref="calendarDay"
:style="{ 'border-color': markDateColor(date, 'circle') }"
:class="{
checked_color: isCheckedDay(date),
calendar_day_today: isToday(date),
calendar_day_not: isNotCurrentMonthDay(date, i),
calendar_mark_circle: markDateColor(date, 'circle')
}"
>
{{ date.day }}
</p>
<p
class="fs10 text-center calendar_day_not"
:class="{
checked_color: isCheckedDay(date),
calendar_day_today: isToday(date),
calendar_mark_circle: markDateColor(date, 'circle')
}"
>
{{ lunar(date) }}
</p>
</div>
<div :style="{ background: markDateColor(date, 'dot') }" class="calendar_dot"></div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
import { formatDate } from './utils/util'
import sloarToLunar from './utils/calendarConvert'
export default {
name: 'Calendar',
props: {
// 滑动的时候,是否触发改变日期
scrollChangeDate: {
type: Boolean,
default: true
},
// 禁用周视图
disabledWeekView: {
type: Boolean,
default: false
},
defaultDate: {
type: Date,
default() {
return new Date()
}
},
show: {
type: Boolean,
default: false
},
weekStart: {
type: String,
default: 'Sunday'
},
// 是否展示周视图
isShowWeekView: {
type: Boolean,
default: false
},
// 日期下面的标记
markDate: {
type: Array,
default: () => []
},
// 日期标记类型
markType: {
type: String,
default: 'dot'
},
// 禁用的日期
disabledDate: {
type: Function,
default: () => {
return false
}
},
// 使用的语言包
lang: {
type: String,
default: 'CN'
}
},
data() {
return {
currentChangeIsScroll: false, // 改变当前日期的方式是否为滑动事件
yearOfCurrentShow: new Date().getFullYear(), // 当前日历展示的年份
monthOfCurrentShow: new Date().getMonth(), // 当前日历展示的月份
yearOfToday: new Date().getFullYear(), // 今天所在的年份
monthOfToday: new Date().getMonth(), // 今天所在的月份
dayOfToday: new Date().getDate(), // 今天所在的日期
weekArray: ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'], // 星期数组
calendarWeek: ['日', '一', '二', '三', '四', '五', '六'], // 日历对应的星期
calendarMonth: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
calendarOfMonth: [], // 月份对应的日历表
calendarOfMonthShow: [], // 月份对应的日历表
calendarDaysTotalLength: 42, // 日历表展示的总天数 6行7列
lastMonthYear: null, // 上个月的年份
lastMonth: null, // 上个月的月份
nextMonthYear: null, // 下个月的年份
nextMonth: null, // 下个月的月份
checkedDate: {}, // 被选中的日期
weekStartIndex: 0, // 日历第一天星期名称的index
translateIndex: 0, // 用于计算上下偏移的距离
transitionDuration: 0.3, // 动画持续时间
touch: {
x: 0,
y: 0
}, // 本次touch事件横向纵向滑动的距离
isTouching: false, // 是否正在滑动
calendarGroupHeight: 0,
calendarWeekTitleHeight: 0,
calendarItemHeight: 0,
touchStartPositionX: null, // 开始滑动x轴的值
touchStartPositionY: null, // 开始滑动时y轴的值
isShowWeek: false, // 当前日历是否以星期方式展示
calendarY: 0, // 日历相对于Y轴的位置
selectedDayIndex: 0, // 当前选中的日期,在这一周的第几天
lastWeek: [], // 上一周的数据
nextWeek: [], // 下一周的数据
isLastWeekInCurrentMonth: false, // 上一周的数据是否在本月
isNextWeekInCurrentMonth: false, // 下一周的数据是否在本月
markDateColorObj: [] // 所有被标记的日期所对应的颜色
}
},
mounted() {
this.weekStartIndex = this.weekArray.indexOf(this.weekStart.toLowerCase())
this.calendarWeek = [...this.calendarWeek.slice(this.weekStartIndex, this.calendarWeek.length), ...this.calendarWeek.slice(0, this.weekStartIndex)]
},
watch: {
markDate: {
handler(val) {
val.forEach((item, index) => {
if (item.color === undefined) {
let obj = {}
obj.color = '#E9332E'
if (typeof item === 'string' || typeof item === 'number') {
item = [item]
}
obj.date = item || []
val[index] = obj
}
/* val[index].forEach(dateObj => {
this.$set(this.markDateColorObj, this.formatDate(dateObj.date), dateObj.color)
}) 待简化 */
val[index].date = this.dateFormat(val[index].date)
})
this.markDateColorObj = []
val.forEach(item => {
item.date.forEach(date => {
this.$set(this.markDateColorObj, date, item.color)
})
})
},
deep: true,
immediate: true
},
weekStartIndex() {
this.calculateCalendarOfThreeMonth(this.checkedDate.year, this.checkedDate.month)
},
defaultDate: {
handler(val) {
if (!(val instanceof Date)) {
throw new Error(`The calendar component's defaultDate must be date type!`)
}
this.$set(this.checkedDate, 'day', val.getDate())
this.calculateCalendarOfThreeMonth(val.getFullYear(), val.getMonth())
},
immediate: true
},
checkedDate: {
handler(val) {
this.$emit('change', val)
},
deep: true,
immediate: true
},
show: {
handler(val) {
if (val) {
this.calculateCalendarOfThreeMonth(this.checkedDate.year, this.checkedDate.month)
this.initDom()
}
},
immediate: true
},
isShowWeekView: {
handler(val) {
if (val) {
this.$nextTick(() => {
this.showWeek()
})
} else {
this.$nextTick(() => {
this.showMonth()
})
}
},
immediate: true
},
calendarGroupHeight(val) {
this.$emit('height', val + this.calendarWeekTitleHeight)
}
},
computed: {},
methods: {
lunar(date) {
let lunar = sloarToLunar.solarToLunar(new Date(date.year, date.month, date.day), 'MD')
return lunar.slice(lunar.indexOf('月') + 1)
},
initDom() {
// 初始化日历dom
this.$nextTick(() => {
this.calendarItemHeight = this.$refs.calendarDay[0].offsetHeight + 35
this.calendarWeekTitleHeight = this.$refs.weekTitle.offsetHeight
let calendarItemGroup = this.$refs.calendarItem
calendarItemGroup.forEach(item => {
item.style.height = `${this.calendarItemHeight}px`
})
this.showMonth()
this.calendarGroupHeight = this.calendarItemHeight * 6
})
},
today() {
// 今天
this.$set(this.checkedDate, 'day', new Date().getDate())
this.yearOfCurrentShow = new Date().getFullYear() // 当前日历展示的年份
this.monthOfCurrentShow = new Date().getMonth() // 当前日历展示的月份
this.calculateCalendarOfThreeMonth()
if (this.isShowWeek) {
setTimeout(() => {
this.isTouching = true
this.showWeek()
}, this.transitionDuration * 1000)
}
},
// 计算当前展示月份的前后月份日历信息 flag -1:获取上个月日历信息 0:当月信息或者跨月展示日历信息 1:获取下个月日历信息
calculateCalendarOfThreeMonth(year = new Date().getFullYear(), month = new Date().getMonth()) {
this.lastMonthYear = month === 0 ? year - 1 : year // 上个月的年份
this.lastMonth = month === 0 ? 11 : month - 1 // 上个月的月份
this.nextMonthYear = month === 11 ? year + 1 : year // 下个月的年份
this.nextMonth = month === 11 ? 0 : month + 1 // 下个月的月份
let firstMonth = this.calculateCalendarOfMonth(this.lastMonthYear, this.lastMonth)
let secondMonth = this.calculateCalendarOfMonth(year, month)
let thirdMonth = this.calculateCalendarOfMonth(this.nextMonthYear, this.nextMonth)
this.calendarOfMonth = []
this.calendarOfMonth.push(firstMonth, secondMonth, thirdMonth)
this.calendarOfMonthShow = JSON.parse(JSON.stringify(this.calendarOfMonth))
if (!this.scrollChangeDate && this.currentChangeIsScroll) {
this.currentChangeIsScroll = false
return
}
// 改变日期选择的日期
let tempDate = {}
let day = this.checkedDate.day
if (day > 30 || (day > 28 && month === 1)) {
day = this.daysOfMonth(year)[month]
}
tempDate = { day: day, year: year, month: month }
if (this.formatDisabledDate(tempDate)) return
this.$set(this.checkedDate, 'day', tempDate.day)
this.$set(this.checkedDate, 'year', year)
this.$set(this.checkedDate, 'month', month)
},
calculateCalendarOfMonth(year = new Date().getFullYear(), month = new Date().getMonth()) {
// 计算每个月的日历
let calendarOfCurrentMonth = []
let lastMonthYear = month === 0 ? year - 1 : year // 上个月的年份
let lastMonth = month === 0 ? 11 : month - 1 // 上个月的月份
let nextMonthYear = month === 11 ? year + 1 : year // 下个月的年份
let nextMonth = month === 11 ? 0 : month + 1 // 下个月的月份
// 如果当月第一天不是指定的开始星期名称,则在前面补齐上个月的日期
let dayOfWeek = this.getDayOfWeek(year, month)
let lastMonthDays = this.daysOfMonth(year)[lastMonth] // 上个月的总天数
if (dayOfWeek < this.weekStartIndex) {
dayOfWeek = 7 - this.weekStartIndex + dayOfWeek
} else {
dayOfWeek -= this.weekStartIndex
}
for (let i = 0; i < dayOfWeek; i++) {
calendarOfCurrentMonth.push({
year: lastMonthYear,
month: lastMonth,
day: lastMonthDays - (dayOfWeek - 1 - i)
})
}
// 当月日期
for (let i = 0; i < this.daysOfMonth(year)[month]; i++) {
calendarOfCurrentMonth.push({
year: year,
month: month,
day: i + 1
})
}
// 在日历后面填充下个月的日期补齐6行7列
let fillDays = this.calendarDaysTotalLength - calendarOfCurrentMonth.length
for (let i = 0; i < fillDays; i++) {
calendarOfCurrentMonth.push({
year: nextMonthYear,
month: nextMonth,
day: i + 1
})
}
return calendarOfCurrentMonth
},
daysOfMonth(year) {
return [31, 28 + this.isLeap(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
},
isLeap(year) {
// 判断是否为闰年
return year % 4 === 0 ? (year % 100 !== 0 ? 1 : year % 400 === 0 ? 1 : 0) : 0
},
getDayOfWeek(year = new Date().getFullYear(), month = new Date().getMonth(), day = 1) {
// 获取月份某一天是星期几
let dayOfMonth = new Date(year, month, day) // 获取当月的第day天
let dayOfWeek = dayOfMonth.getDay() // 判断第day天是星期几(返回[0-6]中的一个0代表星期天1代表星期一)
return dayOfWeek
},
clickCalendarDay(date) {
// 点击日历上的日期
if (!date) return
if (this.formatDisabledDate(date)) return
this.$set(this.checkedDate, 'year', date.year)
this.$set(this.checkedDate, 'month', date.month)
this.$set(this.checkedDate, 'day', date.day)
if (date.month === this.lastMonth && date.year === this.lastMonthYear) {
this.getLastMonth()
}
if (date.month === this.nextMonth && date.year === this.nextMonthYear) {
this.getNextMonth()
}
if (this.isShowWeek) {
this.showWeek()
}
this.$emit('click', this.checkedDate)
},
isToday(date) {
// 该日期是否为今天
return this.yearOfToday === date.year && this.monthOfToday === date.month && this.dayOfToday === date.day
},
isCheckedDay(date) {
// 该日期是否为选中的日期
if (this.formatDisabledDate(date)) return false
return this.checkedDate.year === date.year && this.checkedDate.month === date.month && this.checkedDate.day === date.day
},
isNotCurrentMonthDay(date, index) {
// 非本月日期
let dateOfCurrentShow = this.calendarOfMonth[index][15] // 本月中间的日期一定为本月
return date.year !== dateOfCurrentShow.year || date.month !== dateOfCurrentShow.month
},
touchStart(event) {
// 监听手指开始滑动事件
this.$emit('touchstart', event)
this.touchStartPositionX = event.touches[0].clientX
this.touchStartPositionY = event.touches[0].clientY
this.touch = {
x: 0
}
this.isTouching = true
},
touchMove(event) {
// 监听手指移动事件
this.$emit('touchmove', event)
let moveX = event.touches[0].clientX - this.touchStartPositionX
let moveY = event.touches[0].clientY - this.touchStartPositionY
if (Math.abs(moveX) > Math.abs(moveY)) {
this.touch = {
x: moveX / this.$refs.calendar.offsetWidth,
y: 0
}
} else {
// 禁用周视图(禁止上下滑动)
if (this.disabledWeekView) return
this.touch = {
x: 0,
y: moveY / this.$refs.calendar.offsetHeight
}
}
},
touchEnd(e) {
// 监听touch结束事件
this.$emit('touchend', e)
this.isTouching = false
if (Math.abs(this.touch.x) > Math.abs(this.touch.y) && Math.abs(this.touch.x) > 0.2) {
this.currentChangeIsScroll = true
if (this.touch.x > 0) {
this.$emit('slidechange', 'right')
this.getLastMonth()
if (this.isShowWeek) {
setTimeout(() => {
this.isTouching = true
this.currentChangeIsScroll = true
this.getLastWeek()
}, this.transitionDuration * 1000)
}
} else if (this.touch.x < 0) {
this.$emit('slidechange', 'left')
this.getNextMonth()
if (this.isShowWeek) {
setTimeout(() => {
this.isTouching = true
this.currentChangeIsScroll = true
this.getNextWeek()
}, this.transitionDuration * 1000)
}
}
}
if (Math.abs(this.touch.y) > Math.abs(this.touch.x) && Math.abs(this.touch.y * this.$refs.calendar.offsetHeight) > 50) {
if (this.touch.y > 0 && this.isShowWeek) {
this.$emit('slidechange', 'down')
this.showMonth()
} else if (this.touch.y < 0 && !this.isShowWeek) {
this.$emit('slidechange', 'up')
this.showWeek()
}
} else {
this.touch = {
x: 0,
y: 0
}
}
},
showMonth() {
// 日历以月份方式展示
this.calendarY = 0
this.isShowWeek = false
this.calendarGroupHeight = this.calendarItemHeight * 6
this.isLastWeekInCurrentMonth = false
this.isNextWeekInCurrentMonth = false
this.calculateCalendarOfThreeMonth(this.checkedDate.year, this.checkedDate.month)
},
showWeek(checkedDate = this.checkedDate) {
// 日历以星期方式展示
let daysArr = []
this.calendarOfMonth[1].forEach(item => {
daysArr.push(item.day)
})
let dayIndexOfMonth = daysArr.indexOf(checkedDate.day)
// 当day为月底的天数时有可能在daysArr的前面也存在上一个月对应的日期所以需要取lastIndexOf
if (checkedDate.day > 15) {
dayIndexOfMonth = daysArr.lastIndexOf(checkedDate.day)
}
// 计算当前日期在第几行
let indexOfLine = Math.ceil((dayIndexOfMonth + 1) / 7)
let lastLine = indexOfLine - 1
this.calendarY = -(this.calendarItemHeight * lastLine)
this.isShowWeek = true
this.calendarGroupHeight = this.calendarItemHeight
let currentWeek = []
let sliceStart = lastLine * 7
let sliceEnd = sliceStart + 7
this.isLastWeekInCurrentMonth = false
currentWeek = this.calendarOfMonth[1].slice(sliceStart, sliceEnd)
for (let i in currentWeek) {
if (currentWeek[i].day === checkedDate.day) {
this.selectedDayIndex = i
}
}
let firstDayOfCurrentWeek = currentWeek[0]
let lastDayOfCurrentWeek = currentWeek[6]
if (lastDayOfCurrentWeek.day < firstDayOfCurrentWeek.day && lastDayOfCurrentWeek.month === checkedDate.month) {
this.lastWeek = this.calendarOfMonth[0].slice(21, 28)
} else {
if (firstDayOfCurrentWeek.day === 1) {
this.lastWeek = this.calendarOfMonth[0].slice(28, 35)
} else {
this.lastWeek = this.calendarOfMonth[1].slice(sliceStart - 7, sliceEnd - 7)
if (this.lastWeek[this.selectedDayIndex].month === checkedDate.month) {
this.isLastWeekInCurrentMonth = true
}
}
}
this.isNextWeekInCurrentMonth = false
if (lastDayOfCurrentWeek.day < firstDayOfCurrentWeek.day && lastDayOfCurrentWeek.month !== checkedDate.month) {
this.nextWeek = this.calendarOfMonth[2].slice(7, 14)
} else {
if (lastDayOfCurrentWeek.day === this.daysOfMonth(lastDayOfCurrentWeek.year)[lastDayOfCurrentWeek.month]) {
this.nextWeek = this.calendarOfMonth[2].slice(0, 7)
} else {
this.nextWeek = this.calendarOfMonth[1].slice(sliceStart + 7, sliceEnd + 7)
if (this.nextWeek[this.selectedDayIndex].month === checkedDate.month) {
this.isNextWeekInCurrentMonth = true
}
}
}
this.calendarOfMonthShow[0].splice(sliceStart, 7, ...this.lastWeek)
this.calendarOfMonthShow[2].splice(sliceStart, 7, ...this.nextWeek)
},
getLastWeek() {
// 显示上一周
let checkedDate = this.lastWeek[this.selectedDayIndex]
this.showWeek(checkedDate)
if (this.formatDisabledDate(checkedDate)) return
if (!this.scrollChangeDate && this.currentChangeIsScroll) {
this.currentChangeIsScroll = false
return
}
this.checkedDate = checkedDate
},
getNextWeek() {
// 显示下一周
let checkedDate = this.nextWeek[this.selectedDayIndex]
this.showWeek(checkedDate)
if (this.formatDisabledDate(checkedDate)) return
if (!this.scrollChangeDate && this.currentChangeIsScroll) {
this.currentChangeIsScroll = false
return
}
this.checkedDate = checkedDate
},
getLastMonth() {
// 获取上个月日历
this.translateIndex += 1
if (!this.isLastWeekInCurrentMonth) {
this.yearOfCurrentShow = this.lastMonthYear
this.monthOfCurrentShow = this.lastMonth
}
this.calculateCalendarOfThreeMonth(this.yearOfCurrentShow, this.monthOfCurrentShow)
},
getNextMonth() {
// 获取下个月日历
this.translateIndex -= 1
if (!this.isNextWeekInCurrentMonth) {
this.yearOfCurrentShow = this.nextMonthYear
this.monthOfCurrentShow = this.nextMonth
}
this.calculateCalendarOfThreeMonth(this.yearOfCurrentShow, this.monthOfCurrentShow)
},
markDateColor(date, type) {
// 当前日期是否需要标记
if (this.markType.indexOf(type) === -1) return
let dateString = `${date.year}/${this.fillNumber(date.month + 1)}/${this.fillNumber(date.day)}`
return this.markDateColorObj[dateString]
},
formatDisabledDate(date) {
let fDate = new Date(`${date.year}/${date.month + 1}/${date.day}`)
return this.disabledDate(fDate)
},
fillNumber(val) {
// 小于10在前面补0
return val > 9 ? val : '0' + val
},
dateFormat(dateArr) {
// 日期格式转换
dateArr.forEach((date, index) => {
dateArr[index] = formatDate(date, 'YY/MM/DD')
})
return dateArr
}
}
}
</script>
<style lang="scss" scoped>
.calendar_body {
position: relative;
width: 100%;
margin-top: 50px;
background: #F7F7F7;
}
.calendar_week {
position: absolute;
width: 100%;
left: 0;
top: 12px;
display: flex;
align-items: center;
color: #898989;
z-index: 2;
}
.calendar_group {
position: absolute;
// top: 35px;
left: 0;
bottom: 12px;
right: 0;
overflow: hidden;
}
.calendar_group ul {
height: 100%;
}
.calendar_group_li {
position: absolute;
top: 0;
left: 2px;
bottom: 0;
right: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
flex-wrap: wrap;
will-change: transform;
}
.calendar_item {
width: 14.13333335%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
border-radius: 50%;
}
.calendar_item_disable {
background-color: #f5f7fa;
opacity: 1;
cursor: not-allowed;
color: #c0c4cc;
}
.calendar_day {
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 1px;
font-weight: bold;
color: #333333;
}
.calendar_first_today span {
font-size: 10px;
margin-top: 1px;
}
.calendar_day_today {
// background: #f4f4f4;
}
.calendar_mark_circle {
border: 1px solid #E9332E;
}
.calendar_day_not {
color: #c0c4cc;
}
.calendar_day_checked {
width: 40px;
height: 40px;
border-radius: 50%;
background: #00BFFF;
color: white;
}
.calendar_day_nochecked {
width: 40px;
height: 40px;
}
.checked_color {
color: white;
}
.calendar_dot {
width: 5px;
height: 5px;
border-radius: 50%;
margin-top: 4px;
}
.fs10 {
transform: scale(0.7);
}
</style>

View File

@@ -0,0 +1,355 @@
<template>
<!-- :class="{ calendar_inline: model === 'inline' }" class="hash-calendar" -->
<div
:class="model === 'inline' ? 'calendar_inline' : 'hash-calendar'"
v-show="isShowDatetimePicker"
:style="{ height: `${model === 'inline' ? calendarContentHeight : undefined}px` }"
@click="close"
>
<div class="calendar_content" :style="{ height: `${calendarContentHeight}px` }" @click.stop>
<div class="calendar_title" ref="calendarTitle">
<div class="calendar_title_date flex">
<img src="@/assets/images/u1203.png" alt class="h40 w40 ml15" />
<div class="ml10 fs14 mt12">{{name}}</div>
</div>
<div class="flex mr20">
<span v-if="pickerType !== 'time'" class="calendar_title_date_year fs13" :class="{ calendar_title_date_active: isShowCalendar }" @click="showCalendar">
{{ formatDate(`${checkedDate.year}/${this.checkedDate.month + 1}/${this.checkedDate.day}`, 'YY-MM-DD') }}
</span>
<span class="fs13 ml10 span_week">星期{{ String(new Date(formatDate(`${checkedDate.year}/${this.checkedDate.month + 1}/${this.checkedDate.day}`, 'YY-MM-DD')).getDay()).replace("0","日").replace("1","一").replace("2","二").replace("3","三").replace("4","四").replace("5","五").replace("6","六")}}</span>
<!-- <div v-if="showTodayButton" class="calendar_confirm fs17 text-center" :class="{ today_disable: disabledDate(new Date()) }" @click="today"></div>
<div class="calendar_confirm fs17 text-center" @click="confirm">+</div> -->
</div>
</div>
<calendar
ref="calendar"
v-if="pickerType !== 'time'"
:show="isShowCalendar"
v-bind="{ ...$props, ...$attrs }"
@height="heightChange"
:default-date="defaultDatetime"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
@slidechange="slideChange"
@change="dateChange"
@click="dateClick"
></calendar>
<time-picker
v-if="pickerType !== 'date'"
:show="!isShowCalendar"
:default-time="defaultDatetime"
v-bind="{ ...$props, ...$attrs }"
@change="timeChange"
></time-picker>
</div>
</div>
</template>
<script>
import Calendar from './Calendar.vue'
import TimePicker from './TimePicker.vue'
import { formatDate } from './utils/util'
import sloarToLunar from './utils/calendarConvert'
export default {
props: {
visible: {
// 是否显示日历组件
type: Boolean,
default: false
},
pickerType: {
// 选择器类型 datetime日期+时间 date日期 time时间
type: String,
default: 'datetime'
},
showTodayButton: {
// 是否显示返回今日按钮
type: Boolean,
default: true
},
defaultDatetime: {
// 默认时间
type: Date,
default() {
return new Date()
}
},
format: null, // 确认选择之后,返回的日期格式
model: {
type: String,
default: 'inline'
},
// 日期下面的标记
markDate: {
type: Array,
default: () => []
},
// 禁用的日期
disabledDate: {
type: Function,
default: () => {
return false
}
},
//name
name:{
type:String,
default:'name'
}
},
components: {
TimePicker,
Calendar
},
name: 'VueHashCalendar',
data() {
return {
checkedDate: {
year: new Date().getFullYear(),
month: new Date().getMonth(),
day: new Date().getDate(),
hours: new Date().getHours(),
minutes: new Date().getMinutes()
}, // 被选中的日期
isShowCalendar: false, // 是否显示日历选择控件
calendarContentHeight: 0, // 日历组件高度
calendarTitleHeight: 0, // 日历组件标题高度
firstTimes: true // 第一次触发
}
},
inject: ['reload'],
created() {
window.onresize = () => {
console.log('重置页面')
this.reload()
}
},
mounted() {
if (this.model === 'inline') {
this.isShowDatetimePicker = true
}
},
destroyed() {
window.onresize = () => {}
},
watch: {
defaultDatetime(val) {
if (!(val instanceof Date)) {
throw new Error(`The calendar component's defaultDate must be date type!`)
}
},
pickerType: {
handler(val) {
if (val === 'time') {
this.showTime()
}
},
immediate: true
},
checkedDate: {
handler() {
let date = new Date(
`${this.checkedDate.year}/${this.checkedDate.month + 1}/${this.checkedDate.day} ${this.checkedDate.hours}:${this.checkedDate.minutes}`
)
if (this.format) {
date = formatDate(date, this.format)
}
this.$emit('change', date)
},
deep: true
},
visible: {
handler(val) {
this.isShowCalendar = val
this.$nextTick(() => {
this.calendarTitleHeight = this.$refs.calendarTitle.offsetHeight
})
},
immediate: true
}
},
computed: {
isShowDatetimePicker: {
// 是否显示日期控件
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
}
},
methods: {
lunar(year, month, day) {
let lunar = sloarToLunar.solarToLunar(new Date(year, month, day), 'MD')
return lunar.split('').reverse()[0] === '月' ? `${lunar.slice(lunar.indexOf('月') + 1)}初一` : lunar
},
today() {
if (this.disabledDate(new Date())) return
this.$refs.calendar.today()
},
dateChange(date) {
date.hours = this.checkedDate.hours
date.minutes = this.checkedDate.minutes
this.checkedDate = date
},
dateClick(date) {
date.hours = this.checkedDate.hours
date.minutes = this.checkedDate.minutes
this.checkedDate = date
let fDate = new Date(
`${this.checkedDate.year}/${this.checkedDate.month + 1}/${this.checkedDate.day} ${this.checkedDate.hours}:${this.checkedDate.minutes}`
)
if (this.format) {
fDate = formatDate(fDate, this.format)
}
this.$emit('click', fDate)
},
timeChange(date) {
date.year = this.checkedDate.year
date.month = this.checkedDate.month
date.day = this.checkedDate.day
this.checkedDate = date
},
confirm() {
// 确认选择时间
let date = new Date(
`${this.checkedDate.year}/${this.checkedDate.month + 1}/${this.checkedDate.day} ${this.checkedDate.hours}:${this.checkedDate.minutes}`
)
if (this.format) {
date = formatDate(date, this.format)
}
this.$emit('confirm', date)
if (this.model === 'dialog') {
this.close()
}
},
show() {
this.isShowDatetimePicker = true
},
close() {
this.isShowDatetimePicker = false
},
fillNumber(val) {
// 小于10在前面补0
return val > 9 ? val : '0' + val
},
formatDate(time, format) {
return formatDate(time, format)
},
showCalendar() {
// 显示日历控件
this.isShowCalendar = true
},
showTime() {
// 显示时间选择控件
this.isShowCalendar = false
},
heightChange(height) {
// 高度变化
if (!this.firstTimes && this.model === 'dialog') return
this.calendarContentHeight = height + this.calendarTitleHeight + 30
this.$emit('get-height', this.calendarContentHeight)
this.firstTimes = false
},
touchStart(event) {
// 监听手指开始滑动事件
this.$emit('touchstart', event)
},
touchMove(event) {
// 监听手指开始滑动事件
this.$emit('touchmove', event)
},
touchEnd(event) {
// 监听手指开始滑动事件
this.$emit('touchend', event)
},
slideChange(direction) {
// 滑动方向改变
this.$emit('slidechange', direction)
}
}
}
</script>
<style lang="scss" scoped>
.hash-calendar {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 999;
}
.calendar_inline {
position: relative;
width: 100vw;
background: none;
height: 355px;
z-index: 1;
}
.calendar_content {
position: absolute;
width: 100%;
left: 0;
bottom: 0;
display: flex;
flex-wrap: wrap;
background: white;
height: 355px;
overflow: hidden;
box-sizing: border-box;
}
.calendar_title {
position: absolute;
width: 100%;
left: 0;
top: 0;
background: white;
border-bottom: 1px solid color;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 1;
}
.calendar_title_date {
color: #898989;
padding: 8px 3px;
}
.calendar_title_date_time {
margin-left: 10px;
}
.calendar_confirm {
width: 35px;
height: 35px;
line-height: 35px;
border-radius: 50%;
color: #ffffff;
background: #E9332E;
margin-right: 17px;
box-shadow: 0px 3px 7px 0px rgba(233,51,46, 0.53);
}
.today_disable {
color: #c0c4cc;
}
.span_week{
margin-top:-2px;
}
</style>

View File

@@ -0,0 +1,352 @@
<template>
<div>
<van-sticky>
<DatetimePicker
ref="datetimepicker"
model="inline"
:scroll-change-date="true"
:visible.sync="isShowCalendar"
:default-datetime="defaultDatetime"
:is-show-week-view="isShowWeek"
:minute-step="1"
:mark-date="markDate"
mark-type="dot"
week-start="sunday"
picker-type="date"
:show-today-button="true"
:disabled-week-view="false"
format="YY/MM/DD hh:mm"
@get-height="getHeight"
@confirm="dateConfirm"
@change="dateChange"
:name="name"
></DatetimePicker>
</van-sticky>
<div class="footer" v-if="flagGo!=='4'">
<div class="fs12 c-gray-base h30 line-height ml15">班次正常 {{workTime}}-{{workTimeOff}}</div>
<div class="h40 flex align-items-c border-gb footer-bg">
<img class="h15 w15 ml15" src="@/assets/images/u20046.png" alt />
<div class="fs14 ml5">今日打卡{{count}}工时共计{{Number(amount).toFixed(2)}}小时</div>
</div>
<div class="flex pt10 footer-bg">
<div class="text-center ml10 white">
<div class="w18 h18 fs12 bg-gray radius50"></div>
<div class="lin"></div>
<div class="w18 h18 fs12 bg-gray radius50"></div>
</div>
<div>
<div class="fs14 fw500 ml15">
打卡时间
<span v-if="flagGo!=='4'">{{goWorkTime}}</span>
<span class="c-gray-base">(上班 时间 {{workTime}})</span>
</div>
<!-- <img class="w30 h20 ml15" src="@/assets/images/u1213.png" alt /> -->
<div
class="w41 h18 ml15 bg-blue-dark white fs13 text-center text1"
v-if="flagGo=='0'"
>{{text}}</div>
<div
class="w41 h18 ml15 white fs13 text-center text"
v-if="flagGo=='1'||flagGo=='2'"
>{{text1}}</div>
<div class="fs14 fw500 ml15 mt50">
打卡时间
<span v-if="flagOff!=='4'">{{offWorkTime}}</span>
<span class="c-gray-base">(下班 时间 {{workTimeOff}})</span>
</div>
<div
class="w41 h18 ml15 bg-blue-dark white fs13 text-center text1"
v-if="flagOff=='0'"
>{{text}}</div>
<div
class="w41 h18 ml15 fs13 text-center text"
v-if="flagOff=='1'||flagOff=='3'"
>{{text1}}</div>
</div>
</div>
</div>
<div v-if="flagGo=='4'" class="ml15">{{text2}}</div>
</div>
</template>
<script>
import DatetimePicker from './DatetimePicker.vue'
import { Sticky } from 'vant'
import { getDayDetail, getMonthDetail } from '@/api/ebiz/attendance/attendance'
import { formatDate } from './utils/util'
export default {
name: 'monthly',
components: {
DatetimePicker,
[Sticky.name]: Sticky,
},
data() {
return {
currentDate: new Date(),
date1: new Date(),
defaultDatetime: new Date(),
date: '',
show: false,
isShowCalendar: true, // 是否显示弹窗
disabledWeekView: false, //是否显示周试图
markDate: [
{
color: 'red',
date: ['2020/03/25'],
},
{
color: '#000000',
date: ['2020/03/29'],
},
], // 对象数组形式的标记日期,可以自定义标记颜色
// 所有的行事历任务
isShowWeek: false,
workTime: '',
workTimeOff: '',
count: '',
amount: '',
time: '',
week: '',
nomal: [],
name: '',
rest: [],
flagGo: '',
flagOff: '',
text: '',
text1: '',
goWorkTime: '',
offWorkTime: '',
}
},
created() {
// console.log(JSON.parse(window.localStorage.getItem('obj1')).time)
this.date1 = new Date(JSON.parse(window.localStorage.getItem('obj1')).time)
this.time = JSON.parse(window.localStorage.getItem('obj1')).time
this.name = JSON.parse(window.localStorage.getItem('obj1')).name
this.getMonthDetail1()
this.time = formatDate(this.currentDate, 'YY-MM-DD')
},
methods: {
onConfirm(date) {
this.show = false
},
//点击日期
dateChange(e) {
this.time = formatDate(e, 'YY-MM-DD')
console.log(this.time)
this.getMonthDetail1()
this.week = String(new Date(e).getDay())
.replace('0', '日')
.replace('1', '一')
.replace('2', '二')
.replace('3', '三')
.replace('4', '四')
.replace('5', '五')
.replace('6', '六')
let date = {
date: String(this.time),
}
//日上班
if (Date.parse(this.time) <= Date.parse(formatDate(new Date(), 'YY-MM-DD'))) {
getDayDetail(date).then((res) => {
console.log(res)
if (res.result == 0) {
;(this.workTime = res.content.workTime),
(this.workTimeOff = res.content.workTimeoff),
(this.count = res.content.count),
(this.amount = res.content.amount),
(this.flagGo = res.content.flagGo),
(this.flagOff = res.content.flagOff),
(this.goWorkTime = res.content.goWorkTime),
(this.offWorkTime = res.content.offWorkTime)
if (this.flagGo == '0' || this.flagOff == '0') {
this.goWorkTime = this.goWorkTime.split(' ')[1]
this.offWorkTime = this.offWorkTime.split(' ')[1]
this.text = '正常'
}
if (this.flagGo == '1') {
if(this.goWorkTime!==null){
this.goWorkTime = this.goWorkTime.split(' ')[1]
}
if(this.offWorkTime!==null){
this.offWorkTime = this.offWorkTime.split(' ')[1]
}
this.text1 = '缺勤'
}
if (this.flagGo == '2') {
console.log(this.goWorkTime)
// this.goWorkTime = this.goWorkTime.split(' ')[1]
this.text1 = '迟到'
}
if (this.flagOff == '3') {
this.offWorkTime = this.offWorkTime.split(' ')[1]
this.text1 = '早退'
}
if(this.flagGo=="4"){
this.text2='今日休息'
}
}
})
}else{
this.flagGo="4"
this.flagOff="4"
this.text2='无打卡记录'
this.count='0'
this.amount='0'
this.offWorkTime=''
this.goWorkTime=''
}
},
dateConfirm(date) {
this.time = utils.formatDate(date, 'YY-MM-DD')
this.timeChange = formatDate(date, 'YY-MM')
this.week = String(new Date(date).getDay())
.replace('0', '日')
.replace('1', '一')
.replace('2', '二')
.replace('3', '三')
.replace('4', '四')
.replace('5', '五')
.replace('6', '六')
let date1 = {
date: this.time,
}
if (Date.parse(this.time) <= Date.parse(formatDate(new Date(), 'YY-MM-DD'))) {
getDayDetail(date1).then((res) => {
console.log(res)
if (res.result == 0) {
;(this.workTime = res.content.workTime),
(this.workTimeOff = res.content.workTimeoff),
(this.count = res.content.count),
(this.amount = res.content.amount),
(this.flagGo = res.content.flagGo),
(this.flagOff = res.content.flagOff),
(this.goWorkTime = res.content.goWorkTime),
(this.offWorkTime = res.content.offWorkTime)
if (this.flagGo == '0' || this.flagOff == '0') {
this.goWorkTime = this.goWorkTime.split(' ')[1]
this.offWorkTime = this.offWorkTime.split(' ')[1]
this.text = '正常'
}
if (this.flagGo == '1' ||this.flagOff=="1") {
this.text1 = '缺勤'
}
if (this.flagGo == '2') {
this.goWorkTime = this.goWorkTime.split(' ')[1]
this.text1 = '迟到'
}
if (this.flagOff == '3') {
this.offWorkTime = this.offWorkTime.split(' ')[1]
this.text1 = '早退'
}
if(this.flagGo=="4"){
this.text2='今日休息'
}
}
})
}else{
this.flagGo="4"
this.flagOff="4"
this.text2='无打卡记录'
this.count='0'
this.amount='0'
this.offWorkTime=''
this.goWorkTime=''
}
},
//月历
getMonthDetail1() {
// console.log('================' + this.time)
let date = {
date: this.time,
}
if (Date.parse(this.time) <= Date.parse(formatDate(new Date(), 'YY-MM-DD'))) {
getMonthDetail(date).then((res) => {
// console.log(res)
if (res.result == 0) {
let arr1 = []
let obj1 = {}
let date1 = []
obj1.color = '#FFA500'
for (let i = 0; i < res.content.rest.length; i++) {
let workTime = res.content.rest[i].split(' ')
let workTime1 = workTime[0]
if (Date.parse(workTime1) < Date.parse(formatDate(new Date(), 'YY-MM-DD'))) {
date1.push(workTime1)
}
}
obj1.date = date1
arr1.push(obj1)
console.log(obj1)
// this.mask=arr1
let arr = arr1
let obj = {}
let date = []
let arr3 = []
if(res.content.normal.length>0){
obj.color = '#00BFFF'
for (let t = 0; t < res.content.normal.length; t++) {
let workTime = res.content.normal[t].split(' ')
let workTime1 = workTime[0]
date.push(workTime1)
// console.log(date)
obj.date = date
}
arr.push(obj)
}
console.log(obj)
this.markDate = arr
// console.log(this.markDate)
}
})
}
},
getHeight(val) {
this.calendarHeight = val
let taskList = document.getElementsByClassName('footer')[0].previousElementSibling
taskList.style.height = `${this.calendarHeight + 36}px`
},
//滑动结束
touchend(e) {
// console.log(e)
// console.log(this.time)
// this.getMonthDetail1()
},
},
destroyed: function () {
// console.log("我已经离开了!");
// localStorage.removeItem('obj1')
},
}
</script>
<style>
.header {
width: 100%;
z-index: 100;
height: 70px;
}
.calendar {
/* z-index: -1; */
width: 100%;
}
.lin {
width: 1px;
height: 75px;
border-right: 1px solid #ccc;
margin-left: 7px;
}
.text {
line-height: 18px;
border-radius: 10px;
background: #ffa500;
color: white;
}
.text1 {
line-height: 18px;
border-radius: 10px;
background: #00bfff;
color: white;
}
.footer-bg {
background: #f7f7f7;
}
</style>

View File

@@ -0,0 +1,289 @@
<template>
<div class="time_body" v-show="show">
<div class="time_group">
<div
class="time_content"
:id="hashID[index]"
v-for="(item, index) in timeArray"
:key="index"
@touchstart="timeTouchStart"
@touchmove="timeTouchMove($event, index)"
@touchend="timeTouchEnd($event, index)"
>
<div class="time_item" :class="[{ time_item_show: isBeSelectedTime(time, index) }, hashClass]" v-for="(time, j) in item" :key="index + j">
>{{ time | fillNumber }}
</div>
</div>
</div>
</div>
</template>
<script>
import { checkPlatform } from './utils/util'
export default {
name: 'TimePicker',
props: {
defaultTime: null,
show: false,
minuteStep: {
type: Number,
default: 1
},
selectableRange: {
type: String | Array,
default: ''
}
},
data() {
return {
hashID: [], // 用于生成随机ID
hashClass: '', // 用于生成随机class
timeRange: [], // 时间范围
timeOptions: {
minHours: 24,
minMinutes: 59,
maxHours: 0,
maxMinutes: 0
},
checkedDate: {
hours: new Date().getHours(),
minutes: new Date().getMinutes()
}, // 被选中的日期
timeHeight: 0, // 单个时间项的高度
timeArray: [], // 时间选择器数据
timeStartY: 0, // touchstart,Y轴坐标
timeStartUp: 0 // 滑动开始前时间控件dom与顶部的偏移量
}
},
created() {
this.hashID = [`time${parseInt(Math.random() * 1000000)}`, `time${parseInt(Math.random() * 1000000)}`]
this.hashClass = `time_item_${parseInt(Math.random() * 1000000)}`
},
computed: {},
watch: {
defaultTime: {
handler(val) {
if (!(val instanceof Date)) {
throw new Error(`The calendar component's defaultTime must be date type!`)
}
this.$set(this.checkedDate, 'hours', val.getHours())
this.$set(this.checkedDate, 'minutes', val.getMinutes())
},
immediate: true
},
checkedDate: {
handler(val) {
this.$emit('change', val)
},
deep: true,
immediate: true
},
show: {
handler(val) {
if (val) {
this.initTimeArray()
}
},
immediate: true
},
minuteStep: {
handler(val) {
if (val <= 0 || val >= 60) {
throw new Error(`The minutes-step can't be: ${val}!`)
}
if (60 % val !== 0) {
throw new Error(`The minutes-step must be divided by 60!`)
}
},
immediate: true
},
selectableRange: {
handler(val) {
if (!val) return
this.timeRange = []
let formatPass = false
if (typeof val === 'string') {
formatPass = this.checkTimeRange(val)
} else if (val instanceof Array) {
formatPass = val.every(item => this.checkTimeRange(item))
}
if (!formatPass) throw new Error('The format of selectableRange is error!')
},
immediate: true
}
},
filters: {
fillNumber(val) {
// 小于10在前面补0
return val > 9 ? val : '0' + val
}
},
methods: {
initTimeArray() {
// 初始化时间选择器数据
let hours = []
this.timeArray = []
for (let i = 0; i < 24; i++) {
hours.push(i)
}
let minutes = []
for (let i = 0; i < 60; i++) {
if (i % this.minuteStep === 0) {
minutes.push(i)
}
}
this.timeArray.push(hours, minutes)
this.$nextTick(() => {
let checkHours = this.checkedDate.hours
let checkMinutes = this.checkedDate.minutes
this.timeHeight = getComputedStyle(document.querySelector(`.${this.hashClass}`)).height || ''
this.timeHeight = parseFloat(this.timeHeight.split('px')[0])
let hoursUp = (2 - parseFloat(checkHours)) * this.timeHeight
let minutesUp = (2 - parseFloat(checkMinutes) / this.minuteStep) * this.timeHeight
document.querySelector(`#${this.hashID[0]}`).style.webkitTransform = 'translate3d(0px,' + hoursUp + 'px,0px)'
document.querySelector(`#${this.hashID[1]}`).style.webkitTransform = 'translate3d(0px,' + minutesUp + 'px,0px)'
})
},
timeTouchStart(e) {
e.preventDefault()
this.timeStartY = e.changedTouches[0].pageY
let transform = e.currentTarget.style.webkitTransform
if (transform) {
this.timeStartUp = parseFloat(transform.split(' ')[1].split('px')[0])
}
},
timeTouchMove(e, index) {
let moveEndY = e.changedTouches[0].pageY
let Y = moveEndY - this.timeStartY
e.currentTarget.style.webkitTransform = 'translate3d(0px,' + (Y + this.timeStartUp) + 'px,0px)'
if (checkPlatform() === '2') {
this.timeTouchEnd(e, index)
return false
}
},
timeTouchEnd(e, index) {
let transform = e.currentTarget.style.webkitTransform
let endUp = this.timeStartUp
if (transform) {
endUp = parseFloat(e.currentTarget.style.webkitTransform.split(' ')[1].split('px')[0])
}
let distance = Math.abs(endUp - this.timeStartUp)
let upCount = Math.floor(distance / this.timeHeight) || 1
let halfWinWith = this.timeHeight / 2
let up = this.timeStartUp
if (endUp <= this.timeStartUp) {
// 向上滑动 未过临界值
if (distance <= halfWinWith) {
up = this.timeStartUp
} else {
up = this.timeStartUp - this.timeHeight * upCount
if (up < -(this.timeArray[index].length - 3) * this.timeHeight) {
up = -(this.timeArray[index].length - 3) * this.timeHeight
}
}
} else {
// 向下滑动 未过临界值
if (distance <= halfWinWith) {
up = this.timeStartUp
} else {
up = this.timeStartUp + this.timeHeight * upCount
if (up > this.timeHeight * 2) {
up = this.timeHeight * 2
}
}
}
if (index === 0) {
let hour = 2 - Math.round(parseFloat(up) / parseFloat(this.timeHeight))
this.$set(this.checkedDate, 'hours', hour)
} else {
let minute = 2 - Math.round(parseFloat(up) / parseFloat(this.timeHeight))
this.$set(this.checkedDate, 'minutes', minute * this.minuteStep)
}
e.currentTarget.style.webkitTransition = 'transform 300ms'
e.currentTarget.style.webkitTransform = 'translate3d(0px,' + up + 'px,0px)'
},
isBeSelectedTime(time, index) {
// 是否为当前选中的时间
return (index === 0 && time === this.checkedDate.hours) || (index === 1 && time === this.checkedDate.minutes)
},
isDisableTime(time, index) {
// 是否禁用当前时间
// console.log(this.timeRange, 'timeRange')
for (let i in this.timeRange) {
for (let j in this.timeRange[i]) {
if (index === 0) {
let currentHours = this.timeRange[i][j].split(':')[0]
if (currentHours > time) {
this.timeOptions.minHours = currentHours
return true
}
}
}
}
return false
},
checkTimeRange(timeRange) {
// 校验时间范围
if (!timeRange) return
let timeArr = timeRange.split('-')
if (timeArr.length === 0 || timeArr.length > 2) return false
this.timeRange.push(timeRange)
return timeArr.every(time => {
let mhArr = time.split(':')
if (mhArr.length === 0 || mhArr.length > 2) return false
// 校验单个时间是否符合规范 00:00 - 24:00
if (parseInt(mhArr[0]) < 0 || parseInt(mhArr[0]) > 24) return false
if (parseInt(mhArr[1]) < 0 || parseInt(mhArr[1]) > 59) return false
if (parseInt(mhArr[0]) === 24 && parseInt(mhArr[1]) > 0) return false
return true
})
}
}
}
</script>
<style lang="scss" scoped>
.time_body {
width: 100%;
margin-top: 50px;
}
.time_group {
width: 100%;
display: flex;
align-items: flex-start;
justify-content: center;
height: 180px;
margin-top: 50px;
-webkit-overflow-scrolling: touch;
overflow: hidden;
}
.time_content {
touch-action: none;
padding: 0 20px;
-webkit-overflow-scrolling: touch;
}
.time_item {
padding: 10px 0;
color: #898989;
}
.time_item_show {
color: #4c4c4c;
}
.time_disabled {
color: red;
}
</style>

View File

@@ -0,0 +1,627 @@
/*
农历每一年,对应公历的数据
此数据来源于互联网,原作者不详细,在此感谢
MAPPING[0][0]每年闰月的月份0表示不闰
MAPPING[0][1, 13]:表示每月初一对应的阳历时间,前两个字符表示月,后两个字符表示月
*/
var MAPPING = [
[8, '0131', '0301', '0331', '0429', '0528', '0627', '0726', '0825', '0924', '1023', '1122', '1222', '1320'], //1900
[0, '0219', '0320', '0419', '0518', '0616', '0716', '0814', '0913', '1012', '1111', '1211', '1310'], //1901
[0, '0208', '0310', '0408', '0508', '0606', '0705', '0804', '0902', '1002', '1031', '1130', '1230'], //1902
[5, '0129', '0227', '0329', '0427', '0527', '0625', '0724', '0823', '0921', '1020', '1119', '1219', '1317'], //1903
[0, '0216', '0317', '0416', '0515', '0614', '0713', '0811', '0910', '1009', '1107', '1207', '1306'], //1904
[0, '0204', '0306', '0405', '0504', '0603', '0703', '0801', '0830', '0929', '1028', '1127', '1226'], //1905
[4, '0125', '0223', '0325', '0424', '0523', '0622', '0721', '0820', '0918', '1018', '1116', '1216', '1314'], //1906
[0, '0213', '0314', '0413', '0512', '0611', '0710', '0809', '0908', '1007', '1106', '1205', '1304'], //1907
[0, '0202', '0303', '0401', '0430', '0530', '0629', '0728', '0827', '0925', '1025', '1124', '1223'], //1908
[2, '0122', '0220', '0322', '0420', '0519', '0618', '0717', '0816', '0914', '1014', '1113', '1213', '1311'], //1909
[0, '0210', '0311', '0410', '0509', '0607', '0707', '0805', '0904', '1003', '1102', '1202', '1301'], //1910
[6, '0130', '0301', '0330', '0429', '0528', '0626', '0726', '0824', '0922', '1022', '1121', '1220', '1319'], //1911
[0, '0218', '0319', '0417', '0517', '0615', '0714', '0813', '0911', '1010', '1109', '1209', '1307'], //1912
[0, '0206', '0308', '0407', '0506', '0605', '0704', '0802', '0901', '0930', '1029', '1128', '1227'], //1913
[5, '0126', '0225', '0327', '0425', '0525', '0623', '0723', '0821', '0920', '1019', '1117', '1217', '1315'], //1914
[0, '0214', '0316', '0414', '0514', '0613', '0712', '0811', '0909', '1009', '1107', '1207', '1305'], //1915
[0, '0203', '0304', '0403', '0502', '0601', '0630', '0730', '0829', '0927', '1027', '1125', '1225'], //1916
[2, '0123', '0222', '0323', '0421', '0521', '0619', '0719', '0818', '0916', '1016', '1115', '1214', '1313'], //1917
[0, '0211', '0313', '0411', '0510', '0609', '0708', '0807', '0905', '1005', '1104', '1203', '1302'], //1918
[7, '0201', '0302', '0401', '0430', '0529', '0628', '0727', '0825', '0924', '1024', '1122', '1222', '1321'], //1919
[0, '0220', '0320', '0419', '0518', '0616', '0716', '0814', '0912', '1012', '1110', '1210', '1309'], //1920
[0, '0208', '0310', '0408', '0508', '0606', '0705', '0804', '0902', '1001', '1031', '1129', '1229'], //1921
[5, '0128', '0227', '0328', '0427', '0527', '0625', '0724', '0823', '0921', '1020', '1119', '1218', '1317'], //1922
[0, '0216', '0317', '0416', '0516', '0614', '0714', '0812', '0911', '1010', '1108', '1208', '1306'], //1923
[0, '0205', '0305', '0404', '0504', '0602', '0702', '0801', '0830', '0929', '1028', '1127', '1226'], //1924
[4, '0124', '0223', '0324', '0423', '0522', '0621', '0721', '0819', '0918', '1018', '1116', '1216', '1314'], //1925
[0, '0213', '0314', '0412', '0512', '0610', '0710', '0808', '0907', '1007', '1105', '1205', '1304'], //1926
[0, '0202', '0304', '0402', '0501', '0531', '0629', '0729', '0827', '0926', '1025', '1124', '1224'], //1927
[2, '0123', '0221', '0322', '0420', '0519', '0618', '0717', '0815', '0914', '1013', '1112', '1212', '1311'], //1928
[0, '0210', '0311', '0410', '0509', '0607', '0707', '0805', '0903', '1003', '1101', '1201', '1231'], //1929
[6, '0130', '0228', '0330', '0429', '0528', '0626', '0726', '0824', '0922', '1022', '1120', '1220', '1319'], //1930
[0, '0217', '0319', '0418', '0517', '0616', '0715', '0814', '0912', '1011', '1110', '1209', '1308'], //1931
[0, '0206', '0307', '0406', '0506', '0604', '0704', '0802', '0901', '0930', '1029', '1128', '1227'], //1932
[5, '0126', '0224', '0326', '0425', '0524', '0623', '0722', '0821', '0920', '1019', '1118', '1217', '1315'], //1933
[0, '0214', '0315', '0414', '0513', '0612', '0712', '0810', '0909', '1008', '1107', '1207', '1305'], //1934
[0, '0204', '0305', '0403', '0503', '0601', '0701', '0730', '0829', '0928', '1027', '1126', '1226'], //1935
[3, '0124', '0223', '0323', '0421', '0521', '0619', '0718', '0817', '0916', '1015', '1114', '1214', '1313'], //1936
[0, '0211', '0313', '0411', '0510', '0609', '0708', '0806', '0905', '1004', '1103', '1203', '1302'], //1937
[7, '0131', '0302', '0401', '0430', '0529', '0628', '0727', '0825', '0924', '1023', '1122', '1222', '1320'], //1938
[0, '0219', '0321', '0420', '0519', '0617', '0717', '0815', '0913', '1013', '1111', '1211', '1309'], //1939
[0, '0208', '0309', '0408', '0507', '0606', '0705', '0804', '0902', '1001', '1031', '1129', '1229'], //1940
[6, '0127', '0226', '0328', '0426', '0526', '0625', '0724', '0823', '0921', '1020', '1119', '1218', '1317'], //1941
[0, '0215', '0317', '0415', '0515', '0614', '0713', '0812', '0910', '1010', '1108', '1208', '1306'], //1942
[0, '0205', '0306', '0405', '0504', '0603', '0702', '0801', '0831', '0929', '1029', '1127', '1227'], //1943
[4, '0125', '0224', '0324', '0423', '0522', '0621', '0720', '0819', '0917', '1017', '1116', '1215', '1314'], //1944
[0, '0213', '0314', '0412', '0512', '0610', '0709', '0808', '0906', '1006', '1105', '1205', '1303'], //1945
[0, '0202', '0304', '0402', '0501', '0531', '0629', '0728', '0827', '0925', '1025', '1124', '1223'], //1946
[2, '0122', '0221', '0323', '0421', '0520', '0619', '0718', '0816', '0915', '1014', '1113', '1212', '1311'], //1947
[0, '0210', '0311', '0409', '0509', '0607', '0707', '0805', '0903', '1003', '1101', '1201', '1230'], //1948
[7, '0129', '0228', '0329', '0428', '0528', '0626', '0726', '0824', '0922', '1022', '1120', '1220', '1318'], //1949
[0, '0217', '0318', '0417', '0517', '0615', '0715', '0814', '0912', '1011', '1110', '1209', '1308'], //1950
[0, '0206', '0308', '0406', '0506', '0605', '0704', '0803', '0901', '1001', '1030', '1129', '1228'], //1951
[5, '0127', '0225', '0326', '0424', '0524', '0622', '0722', '0820', '0919', '1019', '1117', '1217', '1315'], //1952
[0, '0214', '0315', '0414', '0513', '0611', '0711', '0810', '0908', '1008', '1107', '1206', '1305'], //1953
[0, '0203', '0305', '0403', '0503', '0601', '0630', '0730', '0828', '0927', '1027', '1126', '1225'], //1954
[3, '0124', '0222', '0324', '0422', '0522', '0620', '0719', '0818', '0916', '1016', '1114', '1214', '1313'], //1955
[0, '0212', '0312', '0411', '0510', '0609', '0708', '0806', '0905', '1004', '1103', '1203', '1301'], //1956
[8, '0131', '0302', '0331', '0430', '0529', '0628', '0727', '0825', '0924', '1023', '1122', '1221', '1320'], //1957
[0, '0218', '0320', '0419', '0519', '0617', '0717', '0815', '0913', '1013', '1111', '1211', '1309'], //1958
[0, '0208', '0309', '0408', '0508', '0606', '0706', '0804', '0903', '1002', '1101', '1130', '1230'], //1959
[6, '0128', '0227', '0327', '0426', '0525', '0624', '0724', '0822', '0921', '1020', '1119', '1218', '1317'], //1960
[0, '0215', '0317', '0415', '0515', '0613', '0713', '0811', '0910', '1010', '1108', '1208', '1306'], //1961
[0, '0205', '0306', '0405', '0504', '0602', '0702', '0731', '0830', '0929', '1028', '1127', '1227'], //1962
[4, '0125', '0224', '0325', '0424', '0523', '0621', '0721', '0819', '0918', '1017', '1116', '1216', '1315'], //1963
[0, '0213', '0314', '0412', '0512', '0610', '0709', '0808', '0906', '1006', '1104', '1204', '1303'], //1964
[0, '0202', '0303', '0402', '0501', '0531', '0629', '0728', '0827', '0925', '1024', '1123', '1223'], //1965
[3, '0121', '0220', '0322', '0421', '0520', '0619', '0718', '0816', '0915', '1014', '1112', '1212', '1311'], //1966
[0, '0209', '0311', '0410', '0509', '0608', '0708', '0806', '0904', '1004', '1102', '1202', '1231'], //1967
[7, '0130', '0228', '0329', '0427', '0527', '0626', '0725', '0824', '0922', '1022', '1120', '1220', '1318'], //1968
[0, '0217', '0318', '0417', '0516', '0615', '0714', '0813', '0912', '1011', '1110', '1209', '1308'], //1969
[0, '0206', '0308', '0406', '0505', '0604', '0703', '0802', '0901', '0930', '1030', '1129', '1228'], //1970
[5, '0127', '0225', '0327', '0425', '0524', '0623', '0722', '0821', '0919', '1019', '1118', '1218', '1316'], //1971
[0, '0215', '0315', '0414', '0513', '0611', '0711', '0809', '0908', '1007', '1106', '1206', '1304'], //1972
[0, '0203', '0305', '0403', '0503', '0601', '0630', '0730', '0828', '0926', '1026', '1125', '1224'], //1973
[4, '0123', '0222', '0324', '0422', '0522', '0620', '0719', '0818', '0916', '1015', '1114', '1214', '1312'], //1974
[0, '0211', '0313', '0412', '0511', '0610', '0709', '0807', '0906', '1005', '1103', '1203', '1301'], //1975
[8, '0131', '0301', '0331', '0429', '0529', '0627', '0727', '0825', '0924', '1023', '1121', '1221', '1319'], //1976
[0, '0218', '0320', '0418', '0518', '0617', '0716', '0815', '0913', '1013', '1111', '1211', '1309'], //1977
[0, '0207', '0309', '0407', '0507', '0606', '0705', '0804', '0902', '1002', '1101', '1130', '1230'], //1978
[6, '0128', '0227', '0328', '0426', '0526', '0624', '0724', '0823', '0921', '1021', '1120', '1219', '1318'], //1979
[0, '0216', '0317', '0415', '0514', '0613', '0712', '0811', '0909', '1009', '1108', '1207', '1306'], //1980
[0, '0205', '0306', '0405', '0504', '0602', '0702', '0731', '0829', '0928', '1028', '1126', '1226'], //1981
[4, '0125', '0224', '0325', '0424', '0523', '0621', '0721', '0819', '0917', '1017', '1115', '1215', '1314'], //1982
[0, '0213', '0315', '0413', '0513', '0611', '0710', '0809', '0907', '1006', '1105', '1204', '1303'], //1983
[10, '0202', '0303', '0401', '0501', '0531', '0629', '0728', '0827', '0925', '1024', '1123', '1222', '1321'], //1984
[0, '0220', '0321', '0420', '0520', '0618', '0718', '0816', '0915', '1014', '1112', '1212', '1310'], //1985
[0, '0209', '0310', '0409', '0509', '0607', '0707', '0806', '0904', '1004', '1102', '1202', '1231'], //1986
[6, '0129', '0228', '0329', '0428', '0527', '0626', '0726', '0824', '0923', '1023', '1121', '1221', '1319'], //1987
[0, '0217', '0318', '0416', '0516', '0614', '0714', '0812', '0911', '1011', '1109', '1209', '1308'], //1988
[0, '0206', '0308', '0406', '0505', '0604', '0703', '0802', '0831', '0930', '1029', '1128', '1228'], //1989
[5, '0127', '0225', '0327', '0425', '0524', '0623', '0722', '0820', '0919', '1018', '1117', '1217', '1316'], //1990
[0, '0215', '0316', '0415', '0514', '0612', '0712', '0810', '0908', '1008', '1106', '1206', '1305'], //1991
[0, '0204', '0304', '0403', '0503', '0601', '0630', '0730', '0828', '0926', '1026', '1124', '1224'], //1992
[3, '0123', '0221', '0323', '0422', '0521', '0620', '0719', '0818', '0916', '1015', '1114', '1213', '1312'], //1993
[0, '0210', '0312', '0411', '0511', '0609', '0709', '0807', '0906', '1005', '1103', '1203', '1301'], //1994
[8, '0131', '0301', '0331', '0430', '0529', '0628', '0727', '0826', '0925', '1024', '1122', '1222', '1320'], //1995
[0, '0219', '0319', '0418', '0517', '0616', '0715', '0814', '0912', '1012', '1111', '1211', '1309'], //1996
[0, '0207', '0309', '0407', '0507', '0605', '0705', '0803', '0902', '1002', '1031', '1130', '1230'], //1997
[5, '0128', '0227', '0328', '0426', '0526', '0624', '0723', '0822', '0921', '1020', '1119', '1219', '1317'], //1998
[0, '0216', '0318', '0416', '0515', '0614', '0713', '0811', '0910', '1009', '1108', '1208', '1307'], //1999
[0, '0205', '0306', '0405', '0504', '0602', '0702', '0731', '0829', '0928', '1027', '1126', '1226'], //2000
[4, '0124', '0223', '0325', '0423', '0523', '0621', '0721', '0819', '0917', '1017', '1115', '1215', '1313'], //2001
[0, '0212', '0314', '0413', '0512', '0611', '0710', '0809', '0907', '1006', '1105', '1204', '1303'], //2002
[0, '0201', '0303', '0402', '0501', '0531', '0630', '0729', '0828', '0926', '1025', '1124', '1223'], //2003
[2, '0122', '0220', '0321', '0419', '0519', '0618', '0717', '0816', '0914', '1014', '1112', '1212', '1310'], //2004
[0, '0209', '0310', '0409', '0508', '0607', '0706', '0805', '0904', '1003', '1102', '1201', '1231'], //2005
[7, '0129', '0228', '0329', '0428', '0527', '0626', '0725', '0824', '0922', '1022', '1121', '1220', '1319'], //2006
[0, '0218', '0319', '0417', '0517', '0615', '0714', '0813', '0911', '1011', '1110', '1210', '1308'], //2007
[0, '0207', '0308', '0406', '0505', '0604', '0703', '0801', '0831', '0929', '1029', '1128', '1227'], //2008
[5, '0126', '0225', '0327', '0425', '0524', '0623', '0722', '0820', '0919', '1018', '1117', '1216', '1315'], //2009
[0, '0214', '0316', '0414', '0514', '0612', '0712', '0810', '0908', '1008', '1106', '1206', '1304'], //2010
[0, '0203', '0305', '0403', '0503', '0602', '0701', '0731', '0829', '0927', '1027', '1125', '1225'], //2011
[4, '0123', '0222', '0322', '0421', '0521', '0619', '0719', '0817', '0916', '1015', '1114', '1213', '1312'], //2012
[0, '0210', '0312', '0410', '0510', '0608', '0708', '0807', '0905', '1005', '1103', '1203', '1301'], //2013
[9, '0131', '0301', '0331', '0429', '0529', '0627', '0727', '0825', '0924', '1024', '1122', '1222', '1320'], //2014
[0, '0219', '0320', '0419', '0518', '0616', '0716', '0814', '0913', '1013', '1112', '1211', '1310'], //2015
[0, '0208', '0309', '0407', '0507', '0605', '0704', '0803', '0901', '1001', '1031', '1129', '1229'], //2016
[6, '0128', '0226', '0328', '0426', '0526', '0624', '0723', '0822', '0920', '1020', '1118', '1218', '1317'], //2017
[0, '0216', '0317', '0416', '0515', '0614', '0713', '0811', '0910', '1009', '1108', '1207', '1306'], //2018
[0, '0205', '0307', '0405', '0505', '0603', '0703', '0801', '0830', '0929', '1028', '1126', '1226'], //2019
[4, '0125', '0223', '0324', '0423', '0523', '0621', '0721', '0819', '0917', '1017', '1115', '1215', '1313'], //2020
[0, '0212', '0313', '0412', '0512', '0610', '0710', '0808', '0907', '1006', '1105', '1204', '1303'], //2021
[0, '0201', '0303', '0401', '0501', '0530', '0629', '0729', '0827', '0926', '1025', '1124', '1223'], //2022
[2, '0122', '0220', '0322', '0420', '0519', '0618', '0718', '0816', '0915', '1015', '1113', '1213', '1311'], //2023
[0, '0210', '0310', '0409', '0508', '0606', '0706', '0804', '0903', '1003', '1101', '1201', '1231'], //2024
[6, '0129', '0228', '0329', '0428', '0527', '0625', '0725', '0823', '0922', '1021', '1120', '1220', '1319'], //2025
[0, '0217', '0319', '0417', '0517', '0615', '0714', '0813', '0911', '1010', '1109', '1209', '1308'], //2026
[0, '0206', '0308', '0407', '0506', '0605', '0704', '0802', '0901', '0930', '1029', '1128', '1228'], //2027
[5, '0126', '0225', '0326', '0425', '0524', '0623', '0722', '0820', '0919', '1018', '1116', '1216', '1315'], //2028
[0, '0213', '0315', '0414', '0513', '0612', '0711', '0810', '0908', '1008', '1106', '1205', '1304'], //2029
[0, '0203', '0304', '0403', '0502', '0601', '0701', '0730', '0829', '0927', '1027', '1125', '1225'], //2030
[3, '0123', '0221', '0323', '0422', '0521', '0620', '0719', '0818', '0917', '1016', '1115', '1214', '1313'], //2031
[0, '0211', '0312', '0410', '0509', '0608', '0707', '0806', '0905', '1004', '1103', '1203', '1301'], //2032
[7, '0131', '0301', '0331', '0429', '0528', '0627', '0726', '0825', '0923', '1023', '1122', '1222', '1320'], //2033
[0, '0219', '0320', '0419', '0518', '0616', '0716', '0814', '0913', '1012', '1111', '1211', '1309'], //2034
[0, '0208', '0310', '0408', '0508', '0606', '0705', '0804', '0902', '1001', '1031', '1130', '1229'], //2035
[6, '0128', '0227', '0328', '0426', '0526', '0624', '0723', '0822', '0920', '1019', '1118', '1217', '1316'], //2036
[0, '0215', '0317', '0416', '0515', '0614', '0713', '0811', '0910', '1009', '1107', '1207', '1305'], //2037
[0, '0204', '0306', '0405', '0504', '0603', '0702', '0801', '0830', '0929', '1028', '1126', '1226'], //2038
[5, '0124', '0223', '0325', '0423', '0523', '0622', '0721', '0820', '0918', '1018', '1116', '1216', '1314'], //2039
[0, '0212', '0313', '0411', '0511', '0610', '0709', '0808', '0906', '1006', '1105', '1204', '1303'], //2040
[0, '0201', '0302', '0401', '0430', '0530', '0628', '0728', '0827', '0925', '1025', '1124', '1223'], //2041
[2, '0122', '0220', '0322', '0420', '0519', '0618', '0717', '0816', '0914', '1014', '1113', '1212', '1311'], //2042
[0, '0210', '0311', '0410', '0509', '0607', '0707', '0805', '0903', '1003', '1102', '1201', '1231'], //2043
[7, '0130', '0229', '0329', '0428', '0527', '0625', '0725', '0823', '0921', '1021', '1119', '1219', '1318'], //2044
[0, '0217', '0319', '0417', '0517', '0615', '0714', '0813', '0911', '1010', '1109', '1208', '1307'], //2045
[0, '0206', '0308', '0406', '0506', '0604', '0704', '0802', '0901', '0930', '1029', '1128', '1227'], //2046
[5, '0126', '0225', '0326', '0425', '0525', '0623', '0723', '0821', '0920', '1019', '1117', '1217', '1315'], //2047
[0, '0214', '0314', '0413', '0513', '0611', '0711', '0810', '0908', '1008', '1106', '1205', '1304'], //2048
[0, '0202', '0304', '0402', '0502', '0531', '0630', '0730', '0828', '0927', '1027', '1125', '1225'], //2049
[3, '0123', '0221', '0323', '0421', '0521', '0619', '0719', '0817', '0916', '1016', '1114', '1214', '1313'], //2050
[0, '0211', '0313', '0411', '0510', '0609', '0708', '0806', '0905', '1005', '1103', '1203', '1302'], //2051
[8, '0201', '0301', '0331', '0429', '0528', '0627', '0726', '0824', '0923', '1022', '1121', '1221', '1320'], //2052
[0, '0219', '0320', '0419', '0518', '0616', '0716', '0814', '0912', '1012', '1110', '1210', '1309'], //2053
[0, '0208', '0309', '0408', '0508', '0606', '0705', '0804', '0902', '1001', '1031', '1129', '1229'], //2054
[6, '0128', '0226', '0328', '0427', '0526', '0625', '0724', '0823', '0921', '1020', '1119', '1218', '1317'], //2055
[0, '0215', '0316', '0415', '0515', '0613', '0713', '0811', '0910', '1009', '1107', '1207', '1305'], //2056
[0, '0204', '0305', '0404', '0504', '0602', '0702', '0731', '0830', '0929', '1028', '1126', '1226'], //2057
[4, '0124', '0223', '0324', '0423', '0522', '0621', '0720', '0819', '0918', '1017', '1116', '1216', '1314'], //2058
[0, '0212', '0314', '0412', '0512', '0610', '0710', '0808', '0907', '1006', '1105', '1205', '1304'], //2059
[0, '0202', '0303', '0401', '0501', '0530', '0628', '0727', '0826', '0924', '1024', '1123', '1223'], //2060
[3, '0121', '0220', '0322', '0420', '0519', '0618', '0717', '0815', '0914', '1013', '1112', '1212', '1311'], //2061
[0, '0209', '0311', '0410', '0509', '0607', '0707', '0805', '0903', '1003', '1101', '1201', '1231'], //2062
[7, '0129', '0228', '0330', '0428', '0528', '0626', '0726', '0824', '0922', '1022', '1120', '1220', '1318'], //2063
[0, '0217', '0318', '0417', '0516', '0615', '0714', '0813', '0911', '1010', '1109', '1208', '1307'], //2064
[0, '0205', '0307', '0406', '0505', '0604', '0704', '0802', '0901', '0930', '1029', '1128', '1227'], //2065
[5, '0126', '0224', '0326', '0424', '0524', '0623', '0722', '0821', '0919', '1019', '1117', '1217', '1315'], //2066
[0, '0214', '0315', '0414', '0513', '0612', '0711', '0810', '0909', '1008', '1107', '1206', '1305'], //2067
[0, '0203', '0304', '0402', '0502', '0531', '0629', '0729', '0828', '0926', '1026', '1125', '1224'], //2068
[4, '0123', '0221', '0323', '0421', '0521', '0619', '0718', '0817', '0915', '1015', '1114', '1214', '1312'], //2069
[0, '0211', '0312', '0411', '0510', '0609', '0708', '0806', '0905', '1004', '1103', '1203', '1301'], // 2070
[8, '0131', '0302', '0331', '0430', '0529', '0628', '0727', '0825', '0924', '1023', '1122', '1221', '1320'], // 2071
[0, '0219', '0320', '0418', '0518', '0616', '0716', '0814', '0912', '1012', '1110', '1210', '1308'], // 2072
[0, '0207', '0309', '0407', '0507', '0606', '0705', '0804', '0902', '1001', '1031', '1129', '1229'], // 2073
[6, '0127', '0226', '0327', '0426', '0526', '0624', '0724', '0822', '0921', '1020', '1119', '1218', '1317'], // 2074
[0, '0215', '0317', '0415', '0515', '0613', '0713', '0812', '0910', '1010', '1108', '1208', '1306'], // 2075
[0, '0205', '0305', '0404', '0503', '0602', '0701', '0731', '0829', '0928', '1028', '1126', '1226'], // 2076
[4, '0124', '0223', '0324', '0423', '0522', '0620', '0720', '0818', '0917', '1017', '1116', '1215', '1314'], // 2077
[0, '0212', '0314', '0412', '0512', '0610', '0709', '0808', '0906', '1006', '1105', '1204', '1303'], // 2078
[0, '0202', '0303', '0402', '0501', '0531', '0629', '0728', '0827', '0925', '1025', '1123', '1223'], // 2079
[3, '0122', '0221', '0321', '0420', '0519', '0618', '0717', '0815', '0914', '1013', '1111', '1211', '1310'], // 2080
[0, '0209', '0310', '0409', '0509', '0607', '0707', '0805', '0903', '1003', '1101', '1130', '1230'], // 2081
[7, '0129', '0227', '0329', '0428', '0528', '0626', '0725', '0824', '0922', '1022', '1120', '1219', '1318'], // 2082
[0, '0217', '0318', '0417', '0517', '0615', '0715', '0813', '0912', '1011', '1110', '1209', '1308'], // 2083
[0, '0206', '0307', '0405', '0505', '0603', '0703', '0802', '0831', '0930', '1029', '1128', '1227'], // 2084
[5, '0126', '0224', '0326', '0424', '0523', '0622', '0722', '0820', '0919', '1019', '1117', '1217', '1315'], // 2085
[0, '0214', '0315', '0414', '0513', '0611', '0711', '0809', '0908', '1008', '1106', '1206', '1305'], // 2086
[0, '0203', '0305', '0403', '0503', '0601', '0630', '0730', '0828', '0927', '1026', '1125', '1225'], // 2087
[4, '0124', '0222', '0323', '0421', '0521', '0619', '0718', '0817', '0915', '1014', '1113', '1213', '1312'], // 2088
[0, '0210', '0312', '0411', '0510', '0609', '0708', '0806', '0904', '1004', '1102', '1202', '1301'], // 2089
[8, '0130', '0301', '0331', '0430', '0529', '0628', '0727', '0825', '0924', '1023', '1121', '1221', '1320'], // 2090
[0, '0218', '0320', '0419', '0518', '0617', '0716', '0815', '0913', '1013', '1111', '1210', '1309'], // 2091
[0, '0207', '0308', '0407', '0506', '0605', '0705', '0803', '0902', '1001', '1031', '1129', '1229'], // 2092
[6, '0127', '0225', '0327', '0426', '0525', '0624', '0723', '0822', '0921', '1020', '1119', '1218', '1317'], // 2093
[0, '0215', '0316', '0415', '0514', '0613', '0712', '0811', '0910', '1009', '1108', '1208', '1306'], // 2094
[0, '0205', '0306', '0405', '0504', '0602', '0702', '0731', '0830', '0928', '1028', '1127', '1227'], // 2095
[4, '0125', '0224', '0324', '0423', '0522', '0620', '0720', '0818', '0916', '1016', '1115', '1215', '1313'], // 2096
[0, '0212', '0314', '0412', '0512', '0610', '0709', '0808', '0906', '1005', '1104', '1204', '1302'], // 2097
[0, '0201', '0303', '0402', '0501', '0531', '0629', '0728', '0826', '0925', '1024', '1123', '1222'], // 2098
[2, '0121', '0220', '0322', '0420', '0520', '0619', '0718', '0816', '0915', '1014', '1112', '1212', '1310'] // 2099
]
var MINYEAR = 1900
var _chineseLunar = {}
/*
* 分析日期表达式,并提取其中的单位和数值
*/
var _expression = function(expr) {
var list = expr.match(/[+-]?\d+((ms)|[yMdhmsw])/g)
var result = []
for (var i = 0; i < list.length; i++) {
//提取单位和数值
if (/([+-])(\d+)(.+)/.test(list[i])) {
var val = parseInt(RegExp.$2)
if (RegExp.$1 === '-') val = -val
result.push({
value: val,
unit: RegExp.$3
})
}
return result
}
}
//计算公历两个日期之差
var _solarDiff = function(left, right, interval) {
var span = left.getTime() - right.getTime() //相差毫秒
switch (interval) {
case 'y':
return parseInt(left.getFullYear() - right.getFullYear())
case 'M':
return parseInt((left.getFullYear() - right.getFullYear()) * 12 + (left.getMonth() - right.getMonth()))
case 'd':
return Math.ceil(span / 1000 / 60 / 60 / 24)
case 'w':
return Math.floor(span / 1000 / 60 / 60 / 24 / 7)
case 'h':
return Math.floor(span / 1000 / 60 / 60)
case 'm':
return Math.floor(span / 1000 / 60)
case 's':
return Math.floor(span / 1000)
case 'ms':
return parseInt(span)
}
}
/*
找到农历
isPerYear是否为农历前一年的对应数据
*/
var _findLunar = function(solar, index, minMonth, maxMonth, isPreYear) {
//取得映射的数据
var mapping = MAPPING[index]
if (!mapping) return false
var year = solar.getFullYear(),
month = solar.getMonth() + 1,
date = solar.getDate()
var lunarYear = year
var lunarMonth, find, solarMonth
//查找农历
for (var i = mapping.length - 1; i > 0; i--) {
lunarMonth = i
//取对应的农历月与天
var segMonth = Number(mapping[i].substring(0, 2))
var segDay = Number(mapping[i].substring(2, 4))
solarMonth = isPreYear && segMonth > 12 ? segMonth - 12 : segMonth
find = solarMonth < month || (solarMonth == month && segDay <= date) || ((segMonth <= minMonth || segMonth >= maxMonth) && isPreYear)
if (solarMonth == 12 && solarMonth > month && i == 1) {
find = true
year--
}
if (find) break
}
//如果找到,则赋值
if (!find) return false
//取前一年
if (isPreYear && segMonth == 12) year = year - 1
lunarYear = isPreYear ? lunarYear - 1 : lunarYear
return {
year: year,
month: solarMonth,
day: segDay,
lunarYear: lunarYear,
lunarMonth: lunarMonth,
leapMonth: mapping[0] //闰月
}
}
//日期累加
var _dateAdd = function(lunar, value, unit) {
if (unit == 'M') {
return _chineseLunar.monthAdd(lunar, value)
} else {
//转换为阳历,计算完再转为农历
var solar = _chineseLunar.lunarToSolar(lunar)
return _chineseLunar.solarToLunar(solar)
}
}
/*
农历相加
*/
_chineseLunar.dateAdd = function(lunar, expr) {
//分析表达式
var list = _expression(expr)
for (var i = 0; i < list.length; i++) {
lunar = _dateAdd(lunar, list[i])
}
return lunar
}
/*
计算两个农历时间的差值,主要计算月份之间的差,其它和公历是一样的
*/
_chineseLunar.dateDiff = function(lunar1, lunar2, expr) {
//计算农历月份差值
if (expr == 'M') {
return _chineseLunar.monthDiff(lunar1, lunar2)
}
//先转成公历,除了月份,其它的都可以按公历计算
var solar1 = _chineseLunar.lunarToSolar(lunar1)
var solar2 = _chineseLunar.lunarToSolar(lunar2)
//再把农历转到公历
return _solarDiff(solar2, solar1, expr)
}
/*
农历月份相加
*/
_chineseLunar.monthAdd = function(lunar, inc) {
//如果是Date则转换为农历
if (lunar instanceof Date) lunar = _chineseLunar.solarToLunar(lunar)
if (inc == 0) return lunar
var year = lunar.year,
count
var month = lunar.month
if (lunar.leap || (lunar.leapMonth > 0 && lunar.month > lunar.leapMonth)) month++
var run = true
do {
//计算当前年有多少个月
count = _chineseLunar.monthsOfYear(year)
inc = inc + month - count
if (inc <= 0) {
run = false
month = year == lunar.year ? count + inc : count + inc - month
} else {
year++
month = 1
}
} while (run)
//获取最后的结果年的闰月是哪一个月
var leapMonth = _chineseLunar.leapMonthOfYear(year)
var leap = false
//如果闰月大于农历月则月份减1
if (leapMonth > 0 && month > leapMonth) {
month--
//如果减完后月份和闰月相等,表示是闰月
leap = month == leapMonth
}
return {
year: year,
month: month,
leap: leap,
leapMonth: leapMonth
}
}
/*
* 返回两段日期的农历差了多少个月,因为有闰月,所以和公历不一样
* date1和date2允许为公历
*/
_chineseLunar.monthDiff = function(lunar1, lunar2) {
//如果是公历的日期格式,则转换为农历
var count = 0
//如果数据类型是日期,则转换为农历
if (lunar1 instanceof Date) lunar1 = _chineseLunar.solarToLunar(lunar1)
if (lunar2 instanceof Date) lunar2 = _chineseLunar.solarToLunar(lunar2)
//两个日期是同一年
if (lunar1.year == lunar2.year) {
count = lunar2.month - lunar1.month
//中间有闰月的存在,计数器加一
if (lunar1.leapMonth >= lunar1.month && lunar1.leapMonth <= lunar2.month) count++
} else {
//计算首年,如果当前的闰月大于当前月,或者当前年有闰月且当前月等于闰月,但当前月又不是闰月,则要多添加一个月
count = 12
if (lunar1.leapMonth > lunar1.month || (lunar1.leapMonth == lunar1.month && !lunar1.isLeaMonth)) count += 1
count -= lunar1.month
//计算两年之间中间的年月份
var year = lunar1.year + 1
for (var i = year; i < lunar2.year; i++) {
count += _chineseLunar.monthsOfYear(year++)
}
//计算最后一年
count += lunar2.month
if (lunar2.isLeapMonth || lunar2.month < lunar2.leapMonth) count++
}
return count
}
/*
* 计算某年某月一个有多少天
* daysOfMonth({}) 或者 daysOfMonth(year, month, leap)
*/
_chineseLunar.daysOfMonth = function(year, month, leap) {
if (typeof year == 'object') {
month = year.month
leap = year.leap
year = year.year
}
var date1 = _chineseLunar.lunarToSolar(year, month, 1, leap)
var leapMonth = _chineseLunar.leapMonthOfYear(year)
if (leapMonth == month && !leap) {
//如果是闰月和当前一月一至且当前月不是闰月说明下一个月是闰月例如2009年5月这一年闰5月如果传过来的不是闰月那么下一个月就是闰月
leap = true
} else if (month == 12) {
//农历的最后一个月
year++
month = 1
} else {
leap = false
month++
}
var date2 = _chineseLunar.lunarToSolar(year, month, 1, leap)
return _chineseLunar.dateDiff(date2, date1, 'd')
}
//获取农历某一年有多少个月
_chineseLunar.monthsOfYear = function(year) {
return MAPPING[year - MINYEAR].length - 1
}
//获取农历某年的闰月是几月,
_chineseLunar.leapMonthOfYear = function(year) {
var info = MAPPING[year - MINYEAR]
return info ? info[0] : 0
}
/*
农历转阳历
lunarToSolar({})或者lunarToSolar(year, month, day, leap)
*/
_chineseLunar.lunarToSolar = function(year, month, day, leap) {
var arg0 = arguments[0]
//第一个参数是对象
if (typeof arg0 == 'object' && arguments.length == 1) {
year = arg0.year
month = arg0.month
day = arg0.day
leap = arg0.leap
}
//根据偏移量取得映射数据
var offset = year - MINYEAR
//所查询的日期超出范围
if (offset < 0 || offset > MAPPING.length) {
throw new Error('Specified date range is invalid.')
}
//取得润月是哪一个月
var leapMonth = MAPPING[offset][0]
//如果isLeap=true并且当前月份就是闰月或者本月有闰月且当前月份大于闰月则月份需要加1
if ((leap && month == leapMonth) || (leapMonth > 0 && month > leapMonth)) {
month += 1
}
//取出对应到某个月的片断
var segment = MAPPING[offset][month] //农历第一天对应公历的具体天
var mapMonth = Number(segment.substring(0, 2))
var mapDate = Number(segment.substring(2, 4))
if (mapMonth > 12) {
year += 1
mapMonth -= 12
}
var solar = new Date(year, mapMonth - 1, mapDate)
var time = solar.getTime() + (day - 1) * 24 * 60 * 60 * 1000
return new Date(time)
}
/*
公历转农历
1.查找对应农历初一是哪一天
2.将农历初一转换为公历
3.计入偏移量
*/
_chineseLunar.solarToLunar = function(solar, format) {
var offset = solar.getFullYear() - MINYEAR
//超出范围
if (offset <= 0 || offset >= MAPPING.length) {
throw new Error('Specified date range is invalid.')
}
//查找范围内的农历数据
var data = _findLunar(solar, offset, 0, 13, false)
//如果没有找到,则找前一年的,因为农历在公历之前,并且不会超过一年,查一年就可以了
data = data || _findLunar(solar, offset - 1, 12, 99, true)
//还是没有找到,表示超出范围
if (!data) return false
//农历初一对应公历的哪一天
var firstDay = new Date(data.year, data.month - 1, data.day)
var day = _solarDiff(solar, firstDay, 'd') + 1
//返回的农历结果
var result = {
leap: data.leapMonth > 0 && data.leapMonth + 1 == data.lunarMonth,
year: data.lunarYear,
month: data.leapMonth > 0 && data.lunarMonth > data.leapMonth ? data.lunarMonth - 1 : data.lunarMonth,
day: day,
leapMonth: data.leapMonth
}
//判断是否要格式化结果
return format && result ? _chineseLunar.format(result, format) : result
}
//获取中国传统干支的名称
_chineseLunar.traditionalYearName = function(year) {
var Gan = '甲乙丙丁戊己庚辛壬癸'.split('')
var Zhi = '子丑寅卯辰巳午未申酉戌亥'.split('')
year = year - MINYEAR + 36
return Gan[year % 10] + Zhi[year % 12] + '年'
}
//获取中文的年
_chineseLunar.yearName = function(year) {
var cnStr = ',一,二,三,四,五,六,七,八,九'.split(',')
var cYear = year.toString()
var result = ''
for (var i = 0; i < cYear.length; i++) {
result += cnStr[parseInt(cYear.charAt(i))]
}
return result + '年'
}
//获取中国的生肖
_chineseLunar.animalName = function(year) {
return '鼠牛虎兔龙蛇马羊猴鸡狗猪'.split('')[(year - 4) % 12]
}
//获取农历月的名称
_chineseLunar.monthName = function(month, traditional, leap) {
var monthName = '正,二,三,四,五,六,七,八,九,十,十一,十二'.split(',')
if (traditional) {
monthName[11] = '腊'
}
return (leap ? '闰' : '') + monthName[month - 1] + '月'
}
//获取农历传统天的名称
_chineseLunar.dayName = function(lunar) {
switch (lunar) {
case 10:
return '初十'
case 20:
return '二十'
case 30:
return '三十'
default:
return '初十廿卅'.split('')[Math.floor(lunar / 10)] + '一二三四五六七八九十'.split('')[(lunar - 1) % 10] || lunar
}
}
//格式化农历日期date是农历的日期
_chineseLunar.format = function(lunar, expr) {
return expr.replace(/[TAYyMmdD]/g, function(m, i) {
switch (m) {
//获取传统的年
case 'T':
return _chineseLunar.traditionalYearName(lunar.year)
//获取生肖
case 'A':
return _chineseLunar.animalName(lunar.year)
//获取中文的年
case 'Y':
return _chineseLunar.yearName(lunar.year)
//获取数字年
case 'y':
return lunar.year
//获取月份
case 'm':
return _chineseLunar.monthName(lunar.month, false, lunar.leap)
//获取传统的月
case 'M':
return _chineseLunar.monthName(lunar.month, true, lunar.leap)
//获取天
case 'd':
return _chineseLunar.dayName(lunar.day)
//如果是初一,则显示月,而不是显示
case 'D':
if (lunar.day == 1) {
return _chineseLunar.monthName(lunar.month, false, lunar.leap)
} else {
return _chineseLunar.dayName(lunar.day)
}
}
})
}
export default _chineseLunar

View File

@@ -0,0 +1,48 @@
/**
* @Description: 各种工具类
* @Author: TSY
* @CreateDate: 2018/6/9 13:28
*/
/**
* 判断安卓与IOS平台
* @returns {string}
*/
export const checkPlatform = function() {
if (/android/i.test(navigator.userAgent)) {
return '1'
}
if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
return '2'
}
}
/**
* 日期格式化
* @param time
* @param format
* @returns {string}
*/
export let formatDate = function(time, format) {
format = format || 'YY年MM月DD日 hh:mm'
let date = time ? new Date(time) : new Date()
let year = date.getFullYear()
let month = date.getMonth() + 1 // 月份是从0开始的
let day = date.getDate()
let hour = date.getHours()
let min = date.getMinutes()
let sec = date.getSeconds()
let preArr = Array.apply(null, Array(10)).map(function(elem, index) {
return '0' + index
}) // /开个长度为10的数组 格式为 00 01 02 03
let newTime = format
.replace(/YY/g, year)
.replace(/F/g, hour >= 12 ? 'pm' : 'am')
.replace(/ss/g, preArr[sec] || sec)
.replace(/mm/g, preArr[min] || min)
.replace(/hh/g, hour > 12 && format.includes('F') ? hour - 12 : format.includes('F') ? hour : preArr[hour] || hour)
.replace(/DD/g, preArr[day] || day)
.replace(/MM/g, preArr[month] || month)
return newTime
}

View File

@@ -0,0 +1,299 @@
<template>
<div class="page">
<div class="border-gb header mh-auto h50 flex align-items-c header">
<van-button
round
@click="goDetail(order)"
size="small"
class="ml15"
type="danger"
v-no-more-click="1000"
>当月</van-button>
<div @click="timePopup" class="fs12 red ml15">
{{titleTime}}
<img src="@/assets/images/u79.png" alt class="absolute mt2 ml5" />
</div>
<van-popup v-model="dateShow" position="bottom">
<van-datetime-picker
v-model="currentDate"
type="year-month"
title="选择年月日"
:min-date="minDate"
:max-date="maxDate"
@cancel="handleCancel"
@confirm="handleEndDateConfirm"
/>
</van-popup>
</div>
<div class="c-gray-base fs16 pl25 footer" :class="dateShow?'footer':'footer1'">
所在机构
<span class="red">{{unitName}}</span>
</div>
<div class="flex">
<div class="crew-list-container ml15 " :class="dateShow?'crew-list-container':'crew-list-container1'">
<van-sticky flex>
<table class="top-table fw500 bg-white">
<tr>
<td>
<div class="name">直辖组</div>
</td>
<td>
<div class="name">承保标保</div>
</td>
<td>
<div class="date">寿险承保件数</div>
</td>
<!-- <td>
<div class="date">承保FYC</div>
</td>
<td>
<div class="date">合格人力</div>
</td>
<td>
<div class="date">综合开拓承保保费</div>
</td>-->
<td>
<div class="date">本月预收标保</div>
</td>
<td>
<div class="date">本月预收件数</div>
</td>
<!-- <td>
<div class="date">本月预收FYC</div>
</td>-->
<td>
<div class="date">操作</div>
</td>
</tr>
</table>
</van-sticky>
<div>
<div class="directly fs14">
</div>
<table class="main-table bg-white">
<tr v-for="(item1,index1) in list" :key="index1">
<td>
<div class="text-center" >{{item1.name}}</div>
</td>
<td>
<div class="name">{{item1.cbbb}}</div>
</td>
<td>
<div class="date">{{item1.cbjs}}</div>
</td>
<td>
<div class="date">{{item1.ysbb}}</div>
</td>
<td>
<div class="date">{{item1.ysjs}}</div>
</td>
<td>
<div class="date red" @click="details(index1)">查看</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</template>
<script>
import { Popup, DatetimePicker, Sticky } from 'vant'
import { getBranchInfos, getPerformanceDetail } from '@/api/ebiz/performance/performance'
import utils from '@/assets/js/utils/date-utils'
export default {
components: {
[Popup.name]: Popup,
[DatetimePicker.name]: DatetimePicker,
[Sticky.name]: Sticky,
},
data() {
return {
currentDate: new Date(),
dateShow: false,
minDate: new Date(2019, 1),
maxDate: new Date(),
data1: [],
titleTime: '',
code: '',
dateTime: '',
list: [],
cbbb: '',
cbjs: '',
ysbb: '',
ysjs: '',
parmas: {},
unitName:''
}
},
created() {
console.log('=======' + this.$route.params.parmas)
console.log(JSON.parse(window.localStorage.getItem('parmas1')).time)
this.unitName = JSON.parse(window.localStorage.getItem('parmas1')).unitName
this.titleTime = JSON.parse(window.localStorage.getItem('parmas1')).date.slice(0, 7)
;(this.dateTime = JSON.parse(window.localStorage.getItem('parmas1')).date), (this.code = JSON.parse(window.localStorage.getItem('parmas1')).code)
this.getBranchInfos1()
},
mounted(){
},
methods: {
timePopup() {
this.dateShow = true
},
handleCancel() {
this.dateShow = false
},
//开始时间
handleEndDateConfirm(e) {
this.dateShow = false
this.titleTime = utils.formatDate(e, 'yyyy-MM')
this.dateTime = utils.formatDate(e, 'yyyy-MM-dd')
console.log(e)
// this.titleTime = dateFormat(this.currentDate, 'yyyy-MM')
},
//跳转查看
details(e) {
console.log(e)
let i=Number(e)
let parmas={}
parmas.code = this.list[i].code,
parmas.date = this.dateTime
parmas.mask = '1'
parmas.agentCode=this.list[i].code
parmas.Name = this.list[i].name.split("部")[1]
parmas.buName=this.unitName
localStorage.parmas2 = JSON.stringify(parmas)
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/performance/PerformanceInfo`,
},
routerInfo: {
path: `/performance/PerformanceInfo`,
},
})
},
getBranchInfos1() {
let date = {
code: this.code,
}
getBranchInfos(date).then((res) => {
console.log(res)
if (res.result == 0) {
this.data1 = res.content
let arr = []
for (let i = 0; i < res.content.length; i++) {
let code = res.content[i].code
arr.push(code)
// console.log(arr)
}
this.arr1 = arr
// console.log(this.arr)
this.getPerformanceDetailC()
}
})
},
//获取代理人相关信息
getPerformanceDetailC() {
// console.log(this.agentCode)
let code = {
date: this.dateTime,
groupList: [1,2,3],
}
// console.log(code)
getPerformanceDetail(code).then((res) => {
console.log(res)
if (res.result == 0) {
this.list = res.content.list
console.log(this.list)
}
})
},
},
destroyed: function () {
console.log("我已经离开了!");
console.log(JSON.parse(window.localStorage.getItem('parmas1')).mask)
// localStorage.removeItem('parmas1');
},
}
</script>
<style lang="scss" scoped>
.crew-list-container {
// overflow: hidden;
padding-top: 10px;
}
.crew-list-container1 {
// overflow: hidden;
padding-top: 10px;
margin-top:90px;
}
.top-table,
.main-table {
margin: 0 auto;
margin-left: 10px;
border-collapse: collapse;
td {
border: 1px solid #ccc;
}
.status,
.name,
.date {
height: 27px;
font-size: 14px;
text-align: center;
line-height: 27px;
}
.status,
.name {
width: 99px;
}
.date {
width: 154px;
}
}
.header {
position: fixed;
top: 10px;
width: 100%;
}
.footer {
width: 100%;
// position: fixed;
margin-top: 70px;
}
.footer1 {
width: 100%;
position: fixed;
margin-top: 70px;
}
.directly {
width: 99px;
position: fixed;
}
.directly1 {
width: 99px;
height: 27px;
border: 0.5px solid #ccc;
text-align: center;
line-height: 27px;
}
.directly2 {
width: 99px;
position: fixed;
height: 27px;
border: 0.5px solid #ccc;
text-align: center;
line-height: 27px;
background: white;
}
.kong{
// position: fixed;
height:100vh;
background:rgb(247, 246, 246);
}
</style>

View File

@@ -0,0 +1,352 @@
<template>
<div v-cloak>
<div
class="border-gb mt20 header mh-auto van-cell:not(:last-child)::after h50 flex align-items-c"
>
<van-button
round
@click="goDetail(order)"
size="small"
class="ml15"
type="danger"
v-no-more-click="1000"
>当月</van-button>
<div @click="timePopup" class="fs12 red ml15">
{{titleTime}}
<img src="@/assets/images/u79.png" alt class="absolute mt2 ml5" />
</div>
<van-popup v-model="dateShow" position="bottom">
<van-datetime-picker
v-model="currentDate"
type="year-month"
title="选择年月日"
:min-date="minDate"
:max-date="maxDate"
@cancel="handleCancel"
@confirm="handleEndDateConfirm"
/>
</van-popup>
</div>
<!-- <div class="c-gray-base fs13 ml25 mt10" v-if="mask=='1'">
所在机构
<span v-if="buName!==undefined">{{buName}}></span>
<span class="red">{{Name}}</span>
</div> -->
<!-- <div class="flex align-items-c h86 content1 bg-white mt10" v-if="mask=='1'">
<div
class="w40 h60 ml15 text-center relative"
v-for="(item, index) in headerList"
:key="index"
>
<div @click="(InfoDetails(index))">
<img class="h40 w40" src="@/assets/images/u188.png" alt />
<div :class="[item.isShowImg?'active':'']"></div>
<div class="fs13">{{item.agentName}}</div>
</div>
</div>
</div> -->
<div class="mt20">
<div class="h50 bg-white content mh-auto fs13 fw500">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>个人承保标保</div>
<div class="red">{{cbbb}}</div>
</div>
</div>
<div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>寿险承保件数</div>
<div class="red">{{cbjs}}</div>
</div>
</div>
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>承保FYC</div>
<div class="red">{{cfyc}}</div>
</div>
</div>-->
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>综合开拓承保保费</div>
<div class="red">{{zcbf}}</div>
</div>
</div>-->
<div v-if="isShow">
<div class="h50 bg-white content mh-auto fs13 fw500 mt5" >
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收标保</div>
<div class="red">{{ysbb}}</div>
</div>
</div>
<div class="h50 bg-white content mh-auto fs13 fw500 mt5" >
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收件数</div>
<div class="red">{{ysjs}}</div>
</div>
</div>
</div>
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5" v-if="isShow">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收FYC</div>
<div class="red">{{yfyc}}</div>
</div>
</div>-->
</div>
<div >
<div class="h40 bg-red absolute bottom0 footer text-center fs13 fw500 white" v-if="mask1" @click="checkTeam(obj)">
{{footerText}}
</div>
</div>
</div>
</template>
<script>
import { getBaseAgentInfo, getPerformanceHeader, getPerformanceDetail, getHeader } from '@/api/ebiz/performance/performance'
import utils from '@/assets/js/utils/date-utils'
import { Popup, DatetimePicker,Button } from 'vant'
export default {
name: 'performance',
components: {
[Popup.name]: Popup,
[DatetimePicker.name]: DatetimePicker,
},
data() {
return {
currentDate: new Date(),
dateShow: false,
minDate: new Date(2020, 0, 1),
maxDate: new Date(),
titleTime: '',
date1: {
date: '2020-07-01',
},
agentGrade: '',
isShow: true,
obj: {},
agentCode: '',
cbbb: '',
cbjs: '',
ysjs: '',
cfyc: '0.00',
zcbf: '0.00',
ysbb: '',
yfyc: '0.00',
timeCode: '',
mask: '',
headerList: [],
unitName: '',
Name: '',
code: '',
isShowImg: true,
buName:'',
mask1:false,
footerText:''
}
},
created() {
if(this.mask=="1"){
this.getPerformanceDetailC()
}
this.formatDate1()
this.getBaseAgentInfo1()
if (this.code !== '') {
this.getHeader1()
}
setTimeout(() => {
// eslint-disable-next-line no-undef
EWebBridge.webCallAppInJs('webview_right_button', {
btns: [
{
title: '考勤记录',
title_color: 'FF0000',
},
],
})
}, 1000)
},
mounted() {
window.appCallBack = this.appCallBack
},
methods: {
appCallBack(data) {
if (data.trigger == 'right_button_click') {
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/attendance/Attendance`,
},
routerInfo: {
path: `/attendance/Attendance`,
},
})
}
if (data.trigger == 'left_button_click') {
this.$jump({
flag: 'home',
})
}
},
timePopup() {
this.dateShow = true
},
handleCancel() {
this.dateShow = false
},
//开始时间
handleEndDateConfirm(e) {
this.dateShow = false
this.titleTime = utils.formatDate(e, 'yyyy-MM')
this.timeCode = utils.formatDate(e, 'yyyy-MM-dd')
this.obj.date = this.timeCode
this.getPerformanceDetailC()
if (String(this.titleTime) === String(utils.formatDate(new Date(), 'yyyy-MM'))) {
this.isShow = true
} else {
this.isShow = false
}
},
formatDate1() {
// console.log(utils.formatDate("2020-1-1"))
if (this.$route.params.parmas !== undefined) {
;(this.titleTime = JSON.parse(this.$route.params.parmas).date.slice(0, 7)), (this.timeCode = JSON.parse(this.$route.params.parmas).date)
} else {
this.titleTime = utils.formatDate(this.currentDate, 'yyyy-MM')
this.timeCode = utils.formatDate(this.currentDate, 'yyyy-MM-dd')
}
this.obj.date = this.timeCode
// console.log(this.titleTime)
},
checkTeam(obj) {
console.log(obj)
localStorage.obj = JSON.stringify(this.obj)
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/performance/PerformanceList`,
},
routerInfo: {
path: `/performance/PerformanceList`,
},
})
},
//获取代理人关系
getBaseAgentInfo1() {
let date = {}
getBaseAgentInfo(date).then((res) => {
console.log(res)
if (res.result == 0) {
;(this.agentGrade = res.agentGrade),
(this.unitName = res.unitName),
(this.saleArea = res.saleArea)
if(window.localStorage.getItem('parmas2') == null){
(this.agentCode = res.jobNo)
}else{
this.agentCode=JSON.parse(window.localStorage.getItem('parmas2')).agentCode
}
(this.obj.agentGrade = this.agentGrade),
(this.obj.agentCode = this.agentCode),
(this.branchCode = res.branchCode),
(this.deptCode = res.deptCode),
(this.areaCode = res.areaCode)
if (this.agentGrade.slice(0, 2) == 'A1') {
this.mask1 = false
this.footerText=''
}else if (this.agentGrade.slice(0, 2) == 'A2') {
this.mask1 = true
this.footerText='查看团队业绩'
;(this.obj.unitName = this.unitName), (this.obj.code = this.branchCode)
} else if (this.agentGrade.slice(0, 2) == 'A3') {
this.mask1 = true
this.footerText='查看团队业绩'
;(this.obj.unitName = this.saleArea), (this.obj.code = this.deptCode)
} else if (this.agentGrade.slice(0, 2) == 'A4') {
}
this.getPerformanceDetailC()
}
})
},
// //获取代理人下级头像
// getPerformanceHeader1() {
// let date = {}
// getPerformanceHeader(date).then((res) => {
// console.log(res)
// if (res.result == 0) {
// for (let i = 0; i < res.content.length; i++) {
// res.content[i].isShowImg = true
// }
// this.headerList = res.content
// }
// })
// },
getHeader1() {
console.log(1111)
let code = {
agentgroup: this.code,
}
getHeader(code).then((res) => {
console.log(res)
if (res.result == 0) {
for (let i = 0; i < res.content.length; i++) {
res.content[i].isShowImg = true
res.content[0].isShowImg = false
}
this.headerList = res.content
}
})
},
//获取代理人相关信息
getPerformanceDetailC() {
// console.log(this.agentCode)
let code = {
date: this.timeCode,
agentCode: this.agentCode,
}
getPerformanceDetail(code).then((res) => {
console.log(res)
if (res.result == 0) {
;(this.cbbb = res.content.list[0].cbbb),
(this.cbjs = res.content.list[0].cbjs),
(this.ysjs = res.content.list[0].ysjs),
(this.ysbb = res.content.list[0].ysbb),(this.agentCode = res.content.list[0].code)
}
})
}
},
destroyed: function () {
console.log("我已经离开了!");
window.localStorage.removeItem('parmas1');
window.localStorage.removeItem('parmas2');
window.localStorage.removeItem('obj1')
},
}
</script>
<style scoped>
.header {
width: 92%;
}
.content {
width: 86%;
}
.footer {
width: 100%;
line-height: 40px;
}
:footer([v-cloak]) {
display:none !important;
}
.content1 {
width: 100%;
overflow-x: scroll;
}
.active {
width: 40px;
height: 40px;
z-index: 100;
background: #ccc;
opacity: 0.5;
top: 0px;
border-radius: 20px;
position: absolute;
}
</style>

View File

@@ -0,0 +1,397 @@
<template>
<div>
<div
class="border-gb mt20 header mh-auto van-cell:not(:last-child)::after h50 flex align-items-c"
>
<van-button
round
@click="goDetail(order)"
size="small"
class="ml15"
type="danger"
v-no-more-click="1000"
>当月</van-button>
<div @click="timePopup" class="fs12 red ml15">
{{titleTime}}
<img src="@/assets/images/u79.png" alt class="absolute mt2 ml5" />
</div>
<van-popup v-model="dateShow" position="bottom">
<van-datetime-picker
v-model="currentDate"
type="year-month"
title="选择年月日"
:min-date="minDate"
:max-date="maxDate"
@cancel="handleCancel"
@confirm="handleEndDateConfirm"
/>
</van-popup>
</div>
<div class="c-gray-base fs13 ml25 mt10" v-if="mask=='1'">
所在机构
<span v-if="buName!==undefined">{{buName}}></span>
<span class="red">{{Name}}</span>
</div>
<div class="flex align-items-c h86 content1 bg-white mt10">
<div
class="w40 h60 ml15 text-center relative header-box"
v-for="(item, index) in headerList"
:key="index"
>
<div @click="(InfoDetails(index))" class="w40 h60">
<div style="width:40px; height:42px;border-radius: 20px; margin-top: 2px;margin-left: 2px;" v-if="item.agentHeadUrl!==null">
<img style="width:40px; height:40px;border-radius: 20px" :src="item.agentHeadUrl | urlFormat" alt />
</div>
<div class="h40 w40" v-else>
<img class="h40 w40" src="@/assets/images/u188.png" alt />
</div>
<div class="absolute fs12 white captain" v-if="String(item.agentName)==String(Name).split('组')[0] ||String(item.agentName)==String(unitName).split('组')[0]">团队长</div>
<div :class="[item.isShowImg?'active':'']"></div>
<div class="fs13">{{item.agentName}}</div>
</div>
</div>
</div>
<div class="mt20">
<div class="h50 bg-white content mh-auto fs13 fw500">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>个人承保标保</div>
<div class="red">{{cbbb}}</div>
</div>
</div>
<div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>寿险承保件数</div>
<div class="red">{{cbjs}}</div>
</div>
</div>
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>承保FYC</div>
<div class="red">{{cfyc}}</div>
</div>
</div>-->
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>综合开拓承保保费</div>
<div class="red">{{zcbf}}</div>
</div>
</div>-->
<div class="h50 bg-white content mh-auto fs13 fw500 mt5" v-if="isShow">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收标保</div>
<div class="red">{{ysbb}}</div>
</div>
</div>
<div class="h50 bg-white content mh-auto fs13 fw500 mt5" v-if="isShow">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收件数</div>
<div class="red">{{ysjs}}</div>
</div>
</div>
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5" v-if="isShow">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收FYC</div>
<div class="red">{{yfyc}}</div>
</div>
</div>-->
</div>
</div>
</template>
<script>
import { getBaseAgentInfo, getPerformanceHeader, getPerformanceDetail, getHeader,getCode } from '@/api/ebiz/performance/performance'
import utils from '@/assets/js/utils/date-utils'
import { Popup, DatetimePicker } from 'vant'
import config from '@/config'
export default {
name: 'performance',
components: {
[Popup.name]: Popup,
[DatetimePicker.name]: DatetimePicker,
},
data() {
return {
currentDate: new Date(),
dateShow: false,
minDate: new Date(2020, 0, 1),
maxDate: new Date(),
titleTime: '',
date1: {
date: '2020-07-01',
},
agentGrade: '',
isShow: true,
obj: {},
agentCode: '',
cbbb: '',
cbjs: '',
ysjs: '',
cfyc: '0.00',
zcbf: '0.00',
ysbb: '0.00',
yfyc: '0.00',
timeCode: '',
mask: '',
headerList: [],
unitName: '',
Name: '',
code: '',
isShowImg: true,
buName:''
}
},
created() {
// console.log('=======' + this.$route.params.parmas)
console.log(JSON.parse(window.localStorage.getItem('parmas2')))
if (window.localStorage.getItem('parmas') !== null) {
this.mask = JSON.parse(window.localStorage.getItem('parmas')).mask
;(this.titleTime = JSON.parse(window.localStorage.getItem('parmas')).date.slice(0, 7)),
(this.dateTime = JSON.parse(window.localStorage.getItem('parmas')).date),
(this.unitName = JSON.parse(window.localStorage.getItem('parmas')).unitName),
(this.Name = JSON.parse(window.localStorage.getItem('parmas')).Name),
(this.code = JSON.parse(window.localStorage.getItem('parmas')).code),
this.buName=JSON.parse(window.localStorage.getItem('parmas')).buName
}else if (window.localStorage.getItem('parmas2') !== null) {
this.mask = JSON.parse(window.localStorage.getItem('parmas2')).mask
;(this.titleTime = JSON.parse(window.localStorage.getItem('parmas2')).date.slice(0, 7)),
(this.dateTime = JSON.parse(window.localStorage.getItem('parmas2')).date),
(this.unitName = JSON.parse(window.localStorage.getItem('parmas2')).unitName),
(this.Name = JSON.parse(window.localStorage.getItem('parmas2')).Name),
(this.code = JSON.parse(window.localStorage.getItem('parmas2')).code),
this.buName=JSON.parse(window.localStorage.getItem('parmas2')).buName,
this.agentCode=JSON.parse(window.localStorage.getItem('parmas2')).agentCode
}else if (window.localStorage.getItem('parmas1') !== null) {
this.mask = JSON.parse(window.localStorage.getItem('parmas1')).mask
;(this.titleTime = JSON.parse(window.localStorage.getItem('parmas1')).date.slice(0, 7)),
(this.dateTime = JSON.parse(window.localStorage.getItem('parmas1')).date),
(this.unitName = JSON.parse(window.localStorage.getItem('parmas1')).unitName),
(this.code = JSON.parse(window.localStorage.getItem('parmas1')).code),
this.buName=JSON.parse(window.localStorage.getItem('parmas1')).buName
// window.localStorage.removeItem('parmas1');
}
// this.performanceData()
if (JSON.parse(window.localStorage.getItem('obj')).agentGrade.slice(0, 2) == 'A2') {
this.getPerformanceHeader1()
}else{
this.getCode1()
}
if(this.mask=="1"){
// this.getPerformanceDetailC()
}
this.formatDate1()
this.getBaseAgentInfo1()
if (this.code !== '') {
// this.getHeader1()
}
},
mounted() {
},
methods: {
timePopup() {
this.dateShow = true
},
handleCancel() {
this.dateShow = false
},
//开始时间
handleEndDateConfirm(e) {
this.dateShow = false
this.titleTime = utils.formatDate(e, 'yyyy-MM')
this.timeCode = utils.formatDate(e, 'yyyy-MM-dd')
this.obj.date = this.timeCode
this.getPerformanceDetailC()
if (String(this.titleTime) === String(utils.formatDate(new Date(), 'yyyy-MM'))) {
this.isShow = true
} else {
this.isShow = false
}
},
formatDate1() {
// console.log(utils.formatDate("2020-1-1"))
if (window.localStorage.getItem('parmas2') !== null) {
this.titleTime = JSON.parse(window.localStorage.getItem('parmas2')).date.slice(0, 7),
this.timeCode = JSON.parse(window.localStorage.getItem('parmas2')).date
}
if(window.localStorage.getItem('parmas1') !== null){
this.titleTime = JSON.parse(window.localStorage.getItem('parmas1')).date.slice(0, 7),
this.timeCode = JSON.parse(window.localStorage.getItem('parmas1')).date
}
this.obj.date = this.timeCode
// console.log(this.titleTime)
},
//获取代理人关系
getBaseAgentInfo1() {
let date = {}
getBaseAgentInfo(date).then((res) => {
// console.log(res)
if (res.result == 0) {
;(this.agentGrade = res.agentGrade),
(this.unitName = res.unitName),
(this.saleArea = res.saleArea)
if(window.localStorage.getItem('parmas2') == null){
(this.agentCode = res.jobNo)
}else{
this.agentCode=JSON.parse(window.localStorage.getItem('parmas2')).agentCode
}
(this.obj.agentGrade = this.agentGrade),
(this.obj.agentCode = this.agentCode),
(this.branchCode = res.branchCode),
(this.deptCode = res.deptCode),
(this.areaCode = res.areaCode)
if (this.agentGrade.slice(0, 2) == 'A2') {
;(this.obj.unitName = this.unitName), (this.obj.code = this.branchCode)
} else if (this.agentGrade.slice(0, 2) == 'A3') {
;(this.obj.unitName = this.saleArea), (this.obj.code = this.deptCode)
} else if (this.agentGrade.slice(0, 2) == 'A4') {
}
if (this.agentGrade == 'A101') {
this.mask = 1
}
this.getPerformanceDetailC()
}
})
},
//获取代理人下级头像
getPerformanceHeader1() {
let date = {}
getPerformanceHeader(date).then((res) => {
// console.log( res)
if (res.result == 0) {
for (let i = 0; i < res.content.length; i++) {
res.content[i].isShowImg = true
// res.content[i].agentHeadUrl=encodeURIComponent(config.imgDomain + '/returnDirectStream?imgPath=' +res.content[i].imgUrl)
}
this.headerList = res.content
console.log(this.headerList)
}
})
},
getHeader1() {
console.log(this.code)
let code = {
agentgroup: this.code,
}
getHeader(code).then((res) => {
console.log(res)
if (res.result == 0) {
for (let i = 0; i < res.content.length; i++) {
res.content[i].isShowImg = true
res.content[0].isShowImg = false
}
this.headerList = res.content
}
})
},
//获取代理人相关信息
getPerformanceDetailC() {
// console.log(this.agentCode)
let code = {
date: this.timeCode,
agentCode: this.agentCode,
}
getPerformanceDetail(code).then((res) => {
console.log(res)
if (res.result == 0) {
;(this.cbbb = res.content.list[0].cbbb),
(this.cbjs = res.content.list[0].cbjs),
(this.ysjs = res.content.list[0].ysjs),
(this.ysbb = res.content.list[0].ysbb),(this.agentCode = res.content.list[0].code)
}
})
},
getCode1(){
console.log("=========="+this.Name)
let code={
groupCode:this.Name
}
getCode(code).then(res=>{
console.log(res)
if (res.result == 0) {
this.code=res.content.groupCode
}
console.log(this.code)
this.getHeader1()
})
},
//点击头像
InfoDetails(item) {
console.log(item)
for (let i = 0; i < this.headerList.length; i++) {
this.headerList[i].isShowImg = true
}
this.headerList[item].isShowImg = false
let code = {
date: this.timeCode,
agentCode: this.headerList[item].agentCode,
}
getPerformanceDetail(code).then((res) => {
console.log(res)
if (res.result == 0) {
;(this.cbbb = res.content.list[0].cbbb),
(this.cbjs = res.content.list[0].cbjs),
(this.ysjs = res.content.list[0].ysjs),
(this.ysbb = res.content.list[0].ysbb),
(this.agentCode = res.content.list[0].code)
}
})
},
},
filters: {
urlFormat(url) {
return (config.imgDomain + `/returnImageStream?a=b.jpg&imgPath=${url}`).replace(/\+/g, '%2B')
}
},
destroyed: function () {
console.log("我已经离开了!");
let parmas1={}
parmas1.date=this.dateTime
parmas1.unitName=this.unitName
parmas1.Name=this.Name
parmas1.code=this.code
if(this.mask=="1"){
// localStorage.parmas1 = JSON.stringify(parmas1)
}else{
window.localStorage.removeItem('parmas1');
}
window.localStorage.removeItem('parmas2');
},
}
</script>
<style scoped>
.header {
width: 92%;
}
.content {
width: 86%;
}
.footer {
width: 100%;
line-height: 40px;
}
.content1 {
width: 100%;
overflow-x: scroll;
}
.active {
width: 40px !important;
height: 40px !important;
z-index: 100;
background: #ccc;
opacity: 0.5;
top: 0px;
border-radius: 20px;
position: absolute;
}
.captain{
z-index: 2000;
text-align: center;
width:40px;
margin-top:-14px;
margin-left:2px;
background:red;
}
</style>

View File

@@ -0,0 +1,246 @@
<template>
<div>
<div
class="border-gb mt20 header mh-auto van-cell:not(:last-child)::after h50 flex align-items-c"
>
<van-button
round
@click="goDetail(order)"
size="small"
class="ml15"
type="danger"
v-no-more-click="1000"
>当月</van-button>
<div @click="timePopup" class="fs12 red ml15">
{{titleTime}}
<img src="@/assets/images/u79.png" alt class="absolute mt2 ml5" />
</div>
<van-popup v-model="dateShow" position="bottom">
<van-datetime-picker
v-model="currentDate"
type="year-month"
title="选择年月日"
:min-date="minDate"
:max-date="maxDate"
@cancel="handleCancel"
@confirm="handleEndDateConfirm"
/>
</van-popup>
<div class="absolute right30 fs13 red" @click="checkDetails(parmas)">查看明细>></div>
</div>
<div class="c-gray-base fs13 ml25 mt10">所在机构{{unitName}}</div>
<div class="mt20">
<div class="h50 bg-white content mh-auto fs13 fw500">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>{{teamName}}承保标保</div>
<div class="red">{{cbbb}}</div>
</div>
</div>
<div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>{{teamName}}寿险承保件数</div>
<div class="red">{{cbjs}}</div>
</div>
</div>
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>{{teamName}}承保FYC</div>
<div class="red">{{cfyc}}</div>
</div>
</div>-->
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>{{teamName}}综合开拓承保保费</div>
<div class="red">{{zcbf}}</div>
</div>
</div>-->
<div class="h50 bg-white content mh-auto fs13 fw500 mt5" v-if="isShow">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收标保</div>
<div class="red">{{ysbb}}</div>
</div>
</div>
<div class="h50 bg-white content mh-auto fs13 fw500 mt5" v-if="isShow">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收件数</div>
<div class="red">{{ysjs}}</div>
</div>
</div>
<!-- <div class="h50 bg-white content mh-auto fs13 fw500 mt5" v-if="isShow">
<div class="pl10 pr10 pt15 flex justify-content-s align-items-c">
<div>本月预收FYC</div>
<div class="red">{{yfyc}}</div>
</div>
</div>-->
</div>
</div>
</template>
<script>
import { getBaseAgentInfo, getBranchInfos, getPerformanceDetail } from '@/api/ebiz/performance/performance'
import utils from '@/assets/js/utils/date-utils'
import common from '@/assets/js/common'
import { Popup, DatetimePicker } from 'vant'
export default {
name: 'performance',
components: {
[Popup.name]: Popup,
[DatetimePicker.name]: DatetimePicker,
},
data() {
return {
currentDate: new Date(),
dateShow: false,
minDate: new Date(2020, 0, 1),
maxDate: new Date(),
titleTime: '',
isShow: true,
mask: '1',
cbbb: '',
cbjs: '',
ysjs: '',
cfyc: '0.00',
zcbf: '0.00',
ysbb: '0.00',
yfyc: '0.00',
teamName: '',
parmas: {},
unitName: '',
code: '',
agentGrade: '',
agentCode: '',
dateTime: '',
codeValue:{}
}
},
created() {
// console.log(JSON.parse(this.$route.params.obj))
// console.log(JSON.parse(window.localStorage.getItem('obj')).time)
//代理人编码
;(this.agentGrade = JSON.parse(window.localStorage.getItem('obj')).agentGrade),
(this.agentCode = JSON.parse(window.localStorage.getItem('obj')).agentCode),
(this.titleTime = JSON.parse(window.localStorage.getItem('obj')).date.slice(0, 7)),
(this.dateTime = JSON.parse(window.localStorage.getItem('obj')).date)
this.parmas.date = JSON.parse(window.localStorage.getItem('obj')).date
this.unitName = JSON.parse(window.localStorage.getItem('obj')).unitName
this.code = JSON.parse(window.localStorage.getItem('obj')).code
this.parmas.unitName = JSON.parse(window.localStorage.getItem('obj')).unitName
// console.log(typeof(this.titleTime))
// console.log(this.agentGrade.slice(0,2))
if (this.agentGrade.slice(0, 2) == 'A2') {
this.teamName = '直辖组'
} else if (this.agentGrade.slice(0, 2) == 'A3') {
this.teamName = '直辖部'
} else if (this.agentGrade.slice(0, 2) == 'A4') {
this.teamName = '大直辖'
}
if (this.titleTime !== String(utils.formatDate(this.currentDate, 'yyyy-MM'))) {
this.isShow = false
} else {
this.isShow = true
}
// this.performanceData()
this.formatDate1()
// this.getBranchInfos1()
this.getPerformanceDetail1()
},
mounted() {
window.appCallBack = this.appCallBack
},
methods: {
timePopup() {
this.dateShow = true
},
handleCancel() {
this.dateShow = false
},
//开始时间
handleEndDateConfirm(e) {
this.dateShow = false
console.log(e)
this.titleTime = utils.formatDate(e, 'yyyy-MM')
console.log(this.titleTime)
this.dateTime = utils.formatDate(e, 'yyyy-MM-dd')
this.parmas.date = this.dateTime
this.getPerformanceDetail1()
// console.log(this.titleTime)
if (this.titleTime !== String(utils.formatDate(new Date(), 'yyyy-MM'))) {
this.isShow = false
} else {
this.isShow = true
}
},
formatDate1() {
// console.log(utils.formatDate("2020-1-1"))
// this.titleTime = utils.formatDate(this.currentDate, 'yyyy-MM')
// this.dateTime=utils.formatDate(this.currentDate, 'yyyy-MM-dd')
console.log(this.dateTime)
},
checkDetails(parmas) {
if (this.agentGrade.slice(0, 2) == 'A2') {
this.parmas.mask = this.mask
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/performance/PerformanceInfo`,
},
routerInfo: {
path: `/performance/PerformanceInfo`,
},
})
localStorage.parmas1 = JSON.stringify(parmas)
} else if (this.agentGrade.slice(0, 2) == 'A3') {
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/performance/AttendanceInfo`,
},
routerInfo: {
path: `/performance/AttendanceInfo`,
},
})
localStorage.parmas1 = JSON.stringify(parmas)
}
},
// getBranchInfos1(code) {
// getBranchInfos(code).then((res) => {
// // console.log(res)
// })
// },
getPerformanceDetail1() {
if (this.agentGrade.slice(0, 2) == 'A2') {
let code = {
date: this.dateTime,
groupCode: this.code,
}
this.codeValue=code
} else if (this.agentGrade.slice(0, 2) == 'A3') {
let code = {
date: this.dateTime,
deptCode: this.code,
}
this.codeValue=code
}
let code=this.codeValue
getPerformanceDetail(code).then((res) => {
console.log(res)
if (res.result == 0) {
;(this.cbbb = res.content.list[0].cbbb),
(this.cbjs = res.content.list[0].cbjs),
(this.ysjs = res.content.list[0].ysjs),
(this.ysbb = res.content.list[0].ysbb),
(this.agentCode = res.content.list[0].code),
(this.parmas.code = this.agentCode)
}
})
},
},
}
</script>
<style scoped>
.header {
width: 92%;
}
.content {
width: 86%;
}
</style>