城阳工作端uniH5前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

478 lines
16 KiB

10 months ago
import baseComponent from '../helpers/baseComponent'
import classNames from '../helpers/classNames'
import locales from './locales/index'
import { props } from './props'
const DATETIME = 'datetime'
const DATE = 'date'
const TIME = 'time'
const MONTH = 'month'
const YEAR = 'year'
const ONE_DAY = 24 * 60 * 60 * 1000
function fomartArray(min, max, step = 1) {
let i = min
let result = []
while (i <= max) {
result.push(i)
i+=step
}
return result
}
function getDaysInMonth(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate()
}
function pad(n) {
return n < 10 ? `0${n}` : n + ''
}
function cloneDate(date) {
return new Date(+date)
}
function setMonth(date, month) {
date.setDate(Math.min(date.getDate(), getDaysInMonth(new Date(date.getFullYear(), month))))
date.setMonth(month)
}
function valueToDate(value, props = {}) {
if (!Array.isArray(value)) {
if (typeof value === 'string') {
value = value.replace(/\-/g, '/')
}
if (!isNaN(Number(value))) {
value = Number(value)
}
return new Date(value)
}
const { mode, use12Hours } = props
const now = new Date()
const year = now.getFullYear()
const month = now.getMonth()
const day = now.getDate()
const newValue = value.map((v) => Number(v))
if (use12Hours && [DATETIME, TIME].includes(mode)) {
const hourIndex = mode === DATETIME ? 3 : 0
const ampmIndex = newValue.length - 1
const ampm = Number(newValue[ampmIndex])
let nhour = Number(newValue[hourIndex])
if (ampm === 1) {
if (nhour <= 12) {
nhour += 12
}
nhour = nhour >= 24 ? 0 : nhour
} else {
if (nhour === 0) {
nhour = 12
}
if (nhour > 12) {
nhour -= 12
}
nhour = nhour >= 12 ? 0 : nhour
}
newValue.splice(hourIndex, 1, nhour)
newValue.splice(ampmIndex, 1)
}
if (mode === TIME) {
newValue.unshift(day)
newValue.unshift(month)
newValue.unshift(year)
} else if (mode === MONTH) {
newValue.push(day)
} else if (mode === YEAR) {
newValue.push(month)
newValue.push(day)
}
while (newValue.length <= 6) {
newValue.push(0)
}
return new Date(...newValue)
}
baseComponent({
properties: props,
data: {
inputValue: [],
options: [],
},
observers: {
inputValue() {
this.updatedCols()
},
value(value) {
this.setValue(value)
},
['mode, minuteStep, use12Hours, minDate, maxDate, minHour, maxHour, minMinute, maxMinute, lang']() {
this.setValue(this.data.inputValue)
},
},
methods: {
getDefaultMinDate() {
if (!this.defaultMinDate) {
this.defaultMinDate = new Date(2000, 1, 1, 0, 0, 0)
}
return this.defaultMinDate
},
getDefaultMaxDate() {
if (!this.defaultMaxDate) {
this.defaultMaxDate = new Date(2030, 1, 1, 23, 59, 59)
}
return this.defaultMaxDate
},
getMinDate() {
return this.data.minDate ? valueToDate(this.data.minDate, this.data) : this.getDefaultMinDate()
},
getMaxDate() {
return this.data.maxDate ? valueToDate(this.data.maxDate, this.data) : this.getDefaultMaxDate()
},
getDateMember(type = 'min', member = 'year') {
const methods = {
min: 'getMinDate',
max: 'getMaxDate',
year: 'getFullYear',
month: 'getMonth',
day: 'getDate',
hour: 'getHours',
minute: 'getMinutes',
}
return this[methods[type]]()[methods[member]]()
},
getDisplayHour(rawHour) {
// 12 hour am (midnight 00:00) -> 12 hour pm (noon 12:00) -> 12 hour am (midnight 00:00)
if (this.data.use12Hours) {
if (rawHour === 0) {
rawHour = 12
}
if (rawHour > 12) {
rawHour -= 12
}
return rawHour
}
return rawHour
},
setHours(date, hour) {
if (this.data.use12Hours) {
const dh = date.getHours()
let nhour = hour
nhour = dh >= 12 ? hour + 12 : hour
nhour = nhour >= 24 ? 0 : nhour // Make sure no more than one day
date.setHours(nhour)
} else {
date.setHours(hour)
}
},
setAmPm(date, index) {
if (index === 0) {
date.setTime(+date - ONE_DAY / 2)
} else {
date.setTime(+date + ONE_DAY / 2)
}
},
getNewDate(values, index) {
const value = parseInt(values[index], 10)
const { mode } = this.data
let newValue = cloneDate(this.getDate())
if (mode === DATETIME || mode === DATE || mode === YEAR || mode === MONTH) {
switch (index) {
case 0:
newValue.setFullYear(value)
break
case 1:
setMonth(newValue, value)
break
case 2:
newValue.setDate(value)
break
case 3:
this.setHours(newValue, value)
break
case 4:
newValue.setMinutes(value)
break
case 5:
this.setAmPm(newValue, value)
break
default:
break
}
} else if (mode === TIME) {
switch (index) {
case 0:
this.setHours(newValue, value)
break
case 1:
newValue.setMinutes(value)
break
case 2:
this.setAmPm(newValue, value)
break
default:
break
}
}
return this.clipDate(newValue)
},
clipDate(date) {
const { mode } = this.data
const minDate = this.getMinDate()
const maxDate = this.getMaxDate()
if (mode === DATETIME) {
if (date < minDate) {
return cloneDate(minDate)
}
if (date > maxDate) {
return cloneDate(maxDate)
}
} else if (mode === DATE || mode === YEAR || mode === MONTH) {
if (+date + ONE_DAY <= minDate) {
return cloneDate(minDate)
}
if (date >= +maxDate + ONE_DAY) {
return cloneDate(maxDate)
}
} else if (mode === TIME) {
const maxHour = maxDate.getHours()
const maxMinutes = maxDate.getMinutes()
const minHour = minDate.getHours()
const minMinutes = minDate.getMinutes()
const hour = date.getHours()
const minutes = date.getMinutes()
if (hour < minHour || hour === minHour && minutes < minMinutes) {
return cloneDate(minDate)
}
if (hour > maxHour || hour === maxHour && minutes > maxMinutes) {
return cloneDate(maxDate)
}
}
return date
},
getDate(d) {
const date = d ? d : this.data.value
return this.clipDate(date ? valueToDate(date, this.data) : this.getMinDate())
},
getDateData(date) {
const { mode, lang } = this.data
const locale = locales[lang]
const selYear = date.getFullYear()
const selMonth = date.getMonth()
const minDateYear = this.getDateMember('min', 'year')
const maxDateYear = this.getDateMember('max', 'year')
const minDateMonth = this.getDateMember('min', 'month')
const maxDateMonth = this.getDateMember('max', 'month')
const minDateDay = this.getDateMember('min', 'day')
const maxDateDay = this.getDateMember('max', 'day')
const years = fomartArray(minDateYear, maxDateYear).map((i) => ({
value: i + '',
label: i + locale.year + '',
}))
if (mode === YEAR) {
return [years]
}
const minMonth = minDateYear === selYear ? minDateMonth : 0
const maxMonth = maxDateYear === selYear ? maxDateMonth : 11
const months = fomartArray(minMonth, maxMonth).map((i) => ({
value: i + '',
label: i + 1 + locale.month + '',
}))
if (mode === MONTH) {
return [years, months]
}
const minDay = minDateYear === selYear && minDateMonth === selMonth ? minDateDay : 1
const maxDay = maxDateYear === selYear && maxDateMonth === selMonth ? maxDateDay : getDaysInMonth(date)
const days = fomartArray(minDay, maxDay).map((i) => ({
value: i + '',
label: i + locale.day + '',
}))
return [years, months, days]
},
getTimeData(date) {
let { minHour, maxHour, minMinute, maxMinute } = this.data
const { mode, minuteStep, use12Hours, lang } = this.data
const locale = locales[lang]
const minDateMinute = this.getDateMember('min', 'minute')
const maxDateMinute = this.getDateMember('max', 'minute')
const minDateHour = this.getDateMember('min', 'hour')
const maxDateHour = this.getDateMember('max', 'hour')
const hour = date.getHours()
if (mode === DATETIME) {
const year = date.getFullYear()
const month = date.getMonth()
const day = date.getDate()
const minDateYear = this.getDateMember('min', 'year')
const maxDateYear = this.getDateMember('max', 'year')
const minDateMonth = this.getDateMember('min', 'month')
const maxDateMonth = this.getDateMember('max', 'month')
const minDateDay = this.getDateMember('min', 'day')
const maxDateDay = this.getDateMember('max', 'day')
if (minDateYear === year && minDateMonth === month && minDateDay === day) {
minHour = minDateHour
if (minDateHour === hour) {
minMinute = minDateMinute
}
}
if (maxDateYear === year && maxDateMonth === month && maxDateDay === day) {
maxHour = maxDateHour
if (maxDateHour === hour) {
maxMinute = maxDateMinute
}
}
} else {
minHour = minDateHour
if (minDateHour === hour) {
minMinute = minDateMinute
}
maxHour = maxDateHour
if (maxDateHour === hour) {
maxMinute = maxDateMinute
}
}
let hours = []
if (minHour === 0 && maxHour === 0 || minHour !== 0 && maxHour !== 0) {
minHour = this.getDisplayHour(minHour)
} else if (minHour === 0 && use12Hours) {
minHour = 1
hours.push({
value: '0',
label: locale.hour ? '12' + locale.hour : '12',
})
}
maxHour = this.getDisplayHour(maxHour)
hours = [...hours, ...fomartArray(minHour, maxHour).map((i) => ({
value: i + '',
label: locale.hour ? i + locale.hour + '' : pad(i),
}))]
const minutes = []
const selMinute = date.getMinutes()
for (let i = minMinute; i <= maxMinute; i += minuteStep) {
minutes.push({
value: i + '',
label: locale.minute ? i + locale.minute + '' : pad(i),
})
if (selMinute > i && selMinute < i + minuteStep) {
minutes.push({
value: selMinute + '',
label: locale.minute ? selMinute + locale.minute + '' : pad(selMinute),
})
}
}
const ampm = [{ value: '0', label: locale.am }, { value: '1', label: locale.pm }]
return [hours, minutes].concat(use12Hours ? [ampm] : [])
},
getValueCols(d) {
const { mode, use12Hours } = this.data
const date = this.getDate(d)
let cols = []
let value = []
if (mode === YEAR) {
return {
cols: this.getDateData(date),
value: [date.getFullYear() + ''],
}
}
if (mode === MONTH) {
return {
cols: this.getDateData(date),
value: [date.getFullYear() + '', date.getMonth() + ''],
}
}
if (mode === DATETIME || mode === DATE) {
cols = this.getDateData(date)
value = [date.getFullYear() + '', date.getMonth() + '', date.getDate() + '']
}
if (mode === DATETIME || mode === TIME) {
cols = cols.concat(this.getTimeData(date))
const hour = date.getHours()
const selMinute = date.getMinutes()
let dtValue = [hour + '', selMinute + '']
let nhour = hour
if (use12Hours) {
nhour = hour === 0 ? 12 : (hour > 12 ? hour - 12 : hour)
dtValue = [nhour + '', selMinute + '', (hour >= 12 ? 1 : 0) + '']
}
value = value.concat(dtValue)
}
return {
value,
cols,
}
},
onValueChange(e) {
const { value, index } = e.detail
const newDate = this.getNewDate(value, index)
const { value: newValue, cols: newCols } = this.getValueCols(newDate)
const values = this.getValue(newValue, newCols)
this.triggerEvent('valueChange', { ...e.detail, ...values, date: +newDate })
},
updatedCols() {
const { cols } = this.getValueCols()
this.setData({ cols })
},
updated(inputValue) {
if (this.data.inputValue !== inputValue) {
this.setData({
inputValue,
})
}
},
setValue(value = this.data.inputValue) {
const { value: inputValue } = this.getValueCols()
this.updated(inputValue)
},
getValue(value = this.data.inputValue, cols = this.data.cols) {
this.picker = this.picker || this.selectComponent('#wux-picker')
return {
...this.picker.getValue(value, cols),
date: +this.getDate(),
}
},
},
attached() {
this.setValue(this.data.value)
},
})