mirror of
http://112.124.100.131/GFRS/ebiz-h5.git
synced 2025-12-09 06:26:44 +08:00
日历修改
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
</div>
|
||||
<div class="flex h50 border-gb ml15 align-items-c fwb">
|
||||
<div>迟到</div>
|
||||
<div class="absolute right30 c-gray-base">{{lateNum}}次</div>
|
||||
<div class="absolute right30 c-gray-base">{{lateNum}}次,共{{lateTime}}分钟</div>
|
||||
</div>
|
||||
<div class="flex h50 border-gb ml15 align-items-c fwb">
|
||||
<div>早退</div>
|
||||
|
||||
775
src/views/ebiz/attendance/Calendar.vue
Normal file
775
src/views/ebiz/attendance/Calendar.vue
Normal file
@@ -0,0 +1,775 @@
|
||||
<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%;
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.calendar_week {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 5px;
|
||||
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 {
|
||||
// color: #E9332E;
|
||||
}
|
||||
|
||||
.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>
|
||||
357
src/views/ebiz/attendance/DatetimePicker.vue
Normal file
357
src/views/ebiz/attendance/DatetimePicker.vue
Normal file
@@ -0,0 +1,357 @@
|
||||
<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">
|
||||
<span v-if="pickerType !== 'time'" class="calendar_title_date_year" :class="{ calendar_title_date_active: isShowCalendar }" @click="showCalendar">
|
||||
{{ formatDate(`${checkedDate.year}/${this.checkedDate.month + 1}/${this.checkedDate.day}`, 'YY年MM月DD日') }}
|
||||
</span>
|
||||
<span v-if="pickerType !== 'time'" class="calendar_title_date_year" :class="{ calendar_title_date_active: isShowCalendar }" @click="showCalendar">
|
||||
{{ lunar(checkedDate.year, this.checkedDate.month, this.checkedDate.day) }}
|
||||
</span>
|
||||
<span v-if="pickerType !== 'date'" class="calendar_title_date_time" :class="{ calendar_title_date_active: !isShowCalendar }" @click="showTime">
|
||||
{{
|
||||
formatDate(
|
||||
`${checkedDate.year}/${this.checkedDate.month + 1}/${this.checkedDate.day} ${fillNumber(checkedDate.hours)}:${fillNumber(checkedDate.minutes)}`,
|
||||
'hh:mm'
|
||||
)
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<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
|
||||
}
|
||||
}
|
||||
},
|
||||
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: 15px 8px;
|
||||
}
|
||||
|
||||
.calendar_title_date_active {
|
||||
color: #4c4c4c;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
</style>
|
||||
@@ -9,26 +9,34 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar">
|
||||
<vue-hash-calendar
|
||||
<DatetimePicker
|
||||
ref="datetimepicker"
|
||||
model="inline"
|
||||
:scroll-change-date="true"
|
||||
:visible.sync="isShowCalendar"
|
||||
@change="change"
|
||||
:markDate="mask"
|
||||
:showTodayButton="showTodayButton"
|
||||
@click="timeDate"
|
||||
:disabledWeekView="disable"
|
||||
:defaultDatetime="date1"
|
||||
@touchend="touchend"
|
||||
class="hashCalendar"
|
||||
style="height:350px;"
|
||||
></vue-hash-calendar>
|
||||
: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"
|
||||
:disabledWeekView='disabledWeekView'
|
||||
></DatetimePicker>
|
||||
</div>
|
||||
<div class="footer" v-if="flagGo!=='4'">
|
||||
<div class="fs12 c-gray-base h30 line-height">班次:正常 09:00-18:00</div>
|
||||
<div class=" h40 flex align-items-c border-gb">
|
||||
<div class="fs12 c-gray-base h30 line-height ml15">班次:正常 09:00-18:00</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">
|
||||
<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>
|
||||
@@ -36,14 +44,14 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="fs14 fw500 ml15">
|
||||
打卡时间 <span v-if="flagGo=='0'">{{goWorkTime}}</span>
|
||||
打卡时间 <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=='0'">{{offWorkTime}}</span>
|
||||
打卡时间 <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>
|
||||
@@ -51,29 +59,41 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="flagGo=='4'">
|
||||
<div v-if="flagGo=='4'" class="ml15">
|
||||
今日休息
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import vueHashCalendar from 'vue-hash-calendar';
|
||||
import DatetimePicker from './DatetimePicker.vue'
|
||||
import { getDayDetail,getMonthDetail } from '@/api/ebiz/attendance/attendance';
|
||||
import utils from '@/assets/js/utils/date-utils'
|
||||
import { formatDate } from './utils/util'
|
||||
export default {
|
||||
name: 'monthly',
|
||||
components: {
|
||||
[vueHashCalendar.name]: vueHashCalendar
|
||||
DatetimePicker
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentDate: new Date(),
|
||||
date1:new Date(),
|
||||
defaultDatetime: new Date(),
|
||||
date: '',
|
||||
show: false,
|
||||
isShowCalendar: true,
|
||||
showTodayButton: false,
|
||||
mask: [],
|
||||
isShowCalendar: true, // 是否显示弹窗
|
||||
disabledWeekView:false,//是否显示周试图
|
||||
markDate: [
|
||||
{
|
||||
color: 'red',
|
||||
date: ['2020/03/25']
|
||||
},
|
||||
{
|
||||
color: '#000000',
|
||||
date: ['2020/03/29']
|
||||
}
|
||||
], // 对象数组形式的标记日期,可以自定义标记颜色
|
||||
// 所有的行事历任务
|
||||
isShowWeek: false,
|
||||
workTime:'',
|
||||
workTimeOff:'',
|
||||
count:'',
|
||||
@@ -95,19 +115,20 @@ export default {
|
||||
},
|
||||
created(){
|
||||
this.isShowCalendar=true
|
||||
console.log(JSON.parse(window.localStorage.getItem('obj1')).time)
|
||||
// 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=utils.formatDate(this.currentDate, 'yyyy-MM-dd')
|
||||
this.time=formatDate(this.currentDate, 'YY-MM-DD')
|
||||
},
|
||||
methods: {
|
||||
onConfirm(date) {
|
||||
this.show = false
|
||||
},
|
||||
change(e) {
|
||||
this.time=utils.formatDate(e, 'yyyy-MM-dd')
|
||||
//点击日期
|
||||
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","六")
|
||||
@@ -143,9 +164,9 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
timeDate(date){
|
||||
this.time = utils.formatDate(date, 'yyyy-MM-dd')
|
||||
this.timeChange= utils.formatDate(date, 'yyyy-MM')
|
||||
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
|
||||
@@ -184,7 +205,7 @@ export default {
|
||||
let date={
|
||||
date:this.time
|
||||
}
|
||||
if(Date.parse(this.time)<=Date.parse(utils.formatDate(new Date(), 'yyyy-MM-dd'))){
|
||||
if(Date.parse(this.time)<=Date.parse(formatDate(new Date(), 'YY-MM-DD'))){
|
||||
getMonthDetail(date).then(res=>{
|
||||
// console.log(res)
|
||||
if(res.result == 0){
|
||||
@@ -195,7 +216,7 @@ export default {
|
||||
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(utils.formatDate(new Date(), 'yyyy-MM-dd'))){
|
||||
if(Date.parse(workTime1)<Date.parse(formatDate(new Date(), 'YY-MM-DD'))){
|
||||
let arr2=res.content.rest.slice(0,i+1)
|
||||
obj1.date=arr2
|
||||
// console.log(arr2)
|
||||
@@ -219,12 +240,17 @@ export default {
|
||||
arr.push(obj)
|
||||
// arr3=arr3.concat(arr1,arr)
|
||||
|
||||
this.mask=arr
|
||||
this.markDate=arr
|
||||
// console.log(this.mask)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
getHeight(val) {
|
||||
this.calendarHeight = val
|
||||
// let taskList = document.getElementsByClassName('task-list')[0].previousElementSibling
|
||||
// taskList.style.height = `${this.calendarHeight + 36}px`
|
||||
},
|
||||
//滑动结束
|
||||
touchend(e){
|
||||
@@ -249,7 +275,7 @@ export default {
|
||||
/* z-index: -1; */
|
||||
width: 100%;
|
||||
height:340px;
|
||||
padding-top:0px !important;
|
||||
padding-top:70px !important;
|
||||
}
|
||||
.calendar_title[data-v-f3b38220] {
|
||||
display: none;
|
||||
@@ -279,4 +305,7 @@ export default {
|
||||
.calendar_title{
|
||||
display:none !important;
|
||||
}
|
||||
.footer-bg{
|
||||
background:#F7F7F7;
|
||||
}
|
||||
</style>
|
||||
289
src/views/ebiz/attendance/TimePicker.vue
Normal file
289
src/views/ebiz/attendance/TimePicker.vue
Normal 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>
|
||||
627
src/views/ebiz/attendance/utils/calendarConvert.js
Normal file
627
src/views/ebiz/attendance/utils/calendarConvert.js
Normal 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
|
||||
48
src/views/ebiz/attendance/utils/util.js
Normal file
48
src/views/ebiz/attendance/utils/util.js
Normal 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
|
||||
}
|
||||
@@ -33,8 +33,9 @@
|
||||
<span class="red">{{Name}}</span>
|
||||
</div>
|
||||
<div class="flex align-items-c h86 content1 bg-white mt10">
|
||||
<div class="absolute h60 ml20 mt20 fs13 white captain">团队长</div>
|
||||
<div
|
||||
class="w40 h60 ml15 text-center relative"
|
||||
class="w40 h60 ml15 text-center relative header-box"
|
||||
v-for="(item, index) in headerList"
|
||||
:key="index"
|
||||
>
|
||||
@@ -377,4 +378,9 @@ export default {
|
||||
border-radius: 20px;
|
||||
position: absolute;
|
||||
}
|
||||
.captain{
|
||||
z-index: 2000;
|
||||
text-align: center;
|
||||
width:26px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user