| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- import { EventFrequency } from '@/constant'
- export function isMoreThanOneWeek (timestamp) {
- return timestamp >= 604800000
- }
- export function isOverDay ({ startTime, endTime }) {
- if (startTime === endTime) {
- return startTime !== '00:00:00'
- }
- return startTime > endTime
- }
- export function getNearestHitDate (event, minDate, maxDate) {
- switch (event.freq) {
- case EventFrequency.ONCE:
- return getNearestHitDateForOnce(event, minDate, maxDate)
- case EventFrequency.WEEKLY:
- return getNearestHitDateForWeekly(event, minDate, maxDate)
- default:
- return null
- }
- }
- function getNearestHitDateForOnce (event, minDate, maxDate) {
- minDate = pickMax(toDate(event.start), toDate(minDate))
- maxDate = pickMin(toDate(event.until), toDate(maxDate))
- console.log('getNearestHitDateForOnce', minDate, maxDate)
- return maxDate && maxDate <= minDate ? null : minDate
- }
- function getNearestHitDateForWeekly (event, minDate, maxDate) {
- console.log('getNearestHitDateForWeekly', event)
- minDate = getNearestHitDateForOnce(event, minDate, maxDate)
- if (!minDate) {
- return null
- }
- if (isHitWeeklyByDate(event, minDate)) {
- return minDate
- }
- maxDate = pickMin(toDate(event.until), toDate(maxDate))
- const byDay = event.byDay
- const date = toDate(`${toDateStr(minDate)} ${event.startTime}`)
- if (date < minDate) {
- date.setDate(date.getDate() + 1)
- }
- while (canContinue(date, maxDate)) {
- if (byDay.includes(date.getDay())) {
- return date
- }
- date.setDate(date.getDate() + 1)
- }
- return null
- }
- function offsetWeek (week, offset) {
- return (week + offset + 7) % 7
- }
- export function toDate (val) {
- return val && new Date(typeof val === 'string' ? val.replace(/-/g, '/') : val)
- }
- export function pickMax (a, b) {
- return a >= b ? a : b
- }
- export function pickMin (a, b) {
- return a && b
- ? a >= b
- ? b
- : a
- : a || b
- }
- export function isHit (event, date) {
- console.log('isHit', event, date)
- if (!isIn(toDate(date), toDate(event.start), toDate(event.until))) {
- console.log('miss', 'out of range')
- return false
- }
- switch (event.freq) {
- case EventFrequency.WEEKLY:
- return isHitWeeklyByDate(event, date)
- default:
- return true
- }
- }
- function isHitWeeklyByDate (event, date) {
- date = toDate(date)
- const byDay = event.byDay
- const week = date.getDay()
- if (!isOverDay(event)) {
- return byDay.includes(week) && isIn(toTimeStr(date), event.startTime, correctEndTime(event.endTime))
- }
- if (byDay.includes(week) && isIn(toTimeStr(date), event.startTime, '24:00:00')) {
- return true
- }
- if (byDay.includes(offsetWeek(week, -1)) && isIn(toTimeStr(date), '00:00:00', event.endTime)) {
- return true
- }
- return false
- }
- function canContinue (startDate, endDate) {
- return !endDate || startDate < endDate
- }
- export function isIn (target, start, end) {
- return target >= start && (!end || target < end)
- }
- export function toDateStr (date, offset = 0) {
- date = toDate(date)
- if (offset !== 0) {
- date.setDate(date.getDate() + offset)
- }
- return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`
- }
- export function toTimeStr (date) {
- return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`
- }
- export function toZeroPoint (date) {
- return toDate(`${toDateStr(date)} 00:00:00`)
- }
- export function getStartDate (event, date) {
- switch (event.freq) {
- case EventFrequency.WEEKLY:
- return getWeeklyStartDate(event, date)
- default:
- return toDate(event.start)
- }
- }
- function getWeeklyStartDate (event, date) {
- const time = toTimeStr(date)
- return time < event.startTime
- ? toDate(`${toDateStr(date, -1)} ${event.startTime}`)
- : toDate(`${toDateStr(date)} ${event.startTime}`)
- }
- export function getFinishDate (event, date) {
- switch (event.freq) {
- case EventFrequency.WEEKLY:
- return getWeeklyFinishDate(event, date)
- default:
- return event.until && toDate(event.until)
- }
- }
- function getWeeklyFinishDate (event, date) {
- const time = toTimeStr(date)
- return time < event.startTime
- ? toDate(`${toDateStr(date)} ${event.endTime}`)
- : toDate(`${toDateStr(date, isOverDay(event) ? 1 : 0)} ${correctEndTime(event.endTime)}`)
- }
- export function getConflict (a, b) {
- console.log('compare', a, b)
- if (a.freq !== b.freq) {
- return a.freq === EventFrequency.WEEKLY
- ? getNearestHitDateForWeekly(a, b.start, b.until)
- : getNearestHitDateForWeekly(b, a.start, a.until)
- }
- if (a.freq === EventFrequency.WEEKLY) {
- return getConflictForWeeklyToWeekly(a, b)
- }
- return getNearestHitDateForOnce(a, b.start, b.until)
- }
- function getConflictForWeeklyToWeekly (a, b) {
- const hitDate = getNearestHitDateForOnce(a, b.start, b.until)
- if (hitDate) {
- const untilDate = pickMin(toDate(a.until), toDate(b.until))
- const isMore = !untilDate || isMoreThanOneWeek(untilDate - hitDate)
- const minDate = isMore ? toDate(`${toDateStr(hitDate)} 00:00:00`) : hitDate
- const maxDate = isMore ? toDate(`${toDateStr(hitDate, 7)} 00:00:00`) : untilDate
- console.log('isConflictForWeeklyToWeekly', minDate, maxDate)
- const aTimeSlices = getTimeSlicesInRange(a, minDate, maxDate)
- if (aTimeSlices[0].length) {
- console.log('isConflictForWeeklyToWeekly', a, aTimeSlices)
- const bTimeSlices = getTimeSlicesInRange(b, minDate, maxDate)
- if (bTimeSlices[0].length) {
- console.log('isConflictForWeeklyToWeekly', b, bTimeSlices)
- const fromTimeSlices = [...aTimeSlices[0], ...bTimeSlices[0]].sort(ascSort)
- const toTimeSlices = [...aTimeSlices[1], ...bTimeSlices[1]].sort(ascSort)
- return getConflictTimeSlice(fromTimeSlices, toTimeSlices)
- }
- }
- }
- console.log('miss')
- return null
- }
- function getConflictTimeSlice (fromTimeSlices, toTimeSlices) {
- let i = 0
- let j = 0
- let running = false
- while (i < fromTimeSlices.length && j < toTimeSlices.length) {
- if (fromTimeSlices[i] < toTimeSlices[j]) {
- if (running) {
- return fromTimeSlices[i]
- }
- running = true
- i += 1
- } else {
- running = false
- j += 1
- }
- }
- console.log('time slice miss')
- return null
- }
- function ascSort (a, b) {
- return a - b
- }
- function getTimeSlicesInRange (event, minDate, maxDate) {
- const { byDay, startTime } = event
- const endTime = correctEndTime(event.endTime)
- const minDateStr = toDateStr(minDate)
- const fromTimeSlices = []
- const toTimeSlices = []
- if (isHitOverDayTime(event, minDate)) {
- fromTimeSlices.push(toDate(minDate))
- toTimeSlices.push(pickMin(toDate(`${minDateStr} ${endTime}`), maxDate))
- }
- const referFromDate = toDate(`${minDateStr} ${startTime}`)
- if (referFromDate < maxDate) {
- const referToDate = toDate(`${toDateStr(minDate, isOverDay(event) ? 1 : 0)} ${endTime}`)
- while (canContinue(referFromDate, maxDate)) {
- if (byDay.includes(referFromDate.getDay())) {
- fromTimeSlices.push(toDate(pickMax(referFromDate, minDate)))
- toTimeSlices.push(toDate(pickMin(referToDate, maxDate)))
- }
- referFromDate.setDate(referFromDate.getDate() + 1)
- referToDate.setDate(referToDate.getDate() + 1)
- }
- }
- return [fromTimeSlices, toTimeSlices]
- }
- export function isHitOverDayTime (event, date) {
- if (!isOverDay(event)) {
- return null
- }
- date = toDate(date)
- const { byDay, endTime } = event
- return byDay.includes(offsetWeek(date.getDay(), -1)) && toTimeStr(date) < endTime
- }
- export function correctEndTime (endTime) {
- return endTime === '00:00:00' ? '24:00:00' : endTime
- }
- export function getEventDateDescription (event) {
- const { freq, start, until, endTime } = event
- if (freq === EventFrequency.WEEKLY) {
- return until ? `${toDateStr(start)} - ${toDateStr(until, endTime === '00:00:00' ? -1 : 0)}` : `自${toDateStr(start)}开始`
- }
- return until ? `${start} - ${until}` : `自${start}开始`
- }
- const weekEnum = ['日', '一', '二', '三', '四', '五', '六']
- export function getEventExtraDescription (event) {
- const { freq, start, until, byDay, startTime, endTime, target } = event
- switch (freq) {
- case EventFrequency.WEEKLY:
- if (byDay.split(',').length === 7) {
- return `每天 ${startTime} - ${correctEndTime(endTime)}`
- }
- return `每周${byDay.split(',').sort().map(val => weekEnum[val])
- .join('、')} ${startTime} - ${correctEndTime(endTime)}`
- default:
- return target?.duration
- ? `播放${(toDate(until) - toDate(start)) / target.duration / 1000}次`
- : ''
- }
- }
- export function getEventDescription (event) {
- const extra = getEventExtraDescription(event)
- if (extra) {
- return `${getEventDateDescription(event)} ${extra}`
- }
- return getEventDateDescription(event)
- }
- export function createEmptyEvent () {
- return {
- freq: EventFrequency.ONCE,
- start: `${toDateStr(new Date())} 00:00:00`,
- until: `${toDateStr(new Date(), 1)} 00:00:00`,
- byDay: '',
- startTime: '00:00:00',
- endTime: '00:00:00'
- }
- }
|