import { toDate, toDateStr, toTimeStr, toZeroPoint, pickMin, getConflict } from '@/utils/event' import { EventFreq, EventTarget } from '@/constant' export default { data () { return { event: null, dirty: false, conflicts: [] } }, methods: { onRemove (eventProxy) { this.$confirm( `移除 ${eventProxy.origin.target.name} ?`, { type: 'warning' } ).then(() => { this.removeEventProxy(eventProxy) this.correct() }) }, removeEventProxy (eventProxy) { if (eventProxy) { const { key } = eventProxy const index = this.events.findIndex(event => event.key === key) if (~index) { this.events.splice(index, 1) this.dirty = true return index } } return -1 }, onAdd (event) { if (this.editable) { if (event && event.until && toDate(event.until) <= new Date()) { this.calculate() return } this.editEvent(event) } }, onEditProxy (eventProxy) { const event = eventProxy.origin if (this.editable) { this.$eventProxy = eventProxy this.editEvent(event) } else { switch (event.target.type) { case EventTarget.RECUR: this.$refs.scheduleDialog.show(event.target.id) break default: window.open(this.$router.resolve({ name: 'program', params: { id: event.target.id } }).href, '_blank') break } } }, editEvent (event) { if (this.editable) { this.event = event || {} this.$refs.editDialog.show() } }, onSaveEvent (done) { const event = this.$refs.editor.getValue() if (!event) { return } console.log(event) if (this.$eventProxy && this.getEventUnique(this.$eventProxy.origin) === this.getEventUnique(event)) { done() this.dirty = true this.$eventProxy.origin.target = event.target return } this.conflicts = this.getConflicts({ key: this.$eventProxy?.key, origin: event }) if (!this.conflicts.length) { done() this.removeEventProxy(this.$eventProxy) this.saveEvent(event) return } this.$conflictSource = event this.$refs.conflictDialog.show() }, getEventUnique (event) { const { freq, start, until, byDay, startTime, endTime } = event switch (freq) { case EventFreq.ONCE: return `${freq};${start};${until}` case EventFreq.WEEKLY: return `${freq};${start};${until};${byDay};${startTime};${endTime}` default: return Math.random().toString(16).slice(2) } }, onCover (done) { done() this.$refs.editDialog.onCancel() this.conflicts.forEach(this.removeEventProxy) this.saveEvent(this.$conflictSource) this.$conflictSource = null }, saveEvent (event) { this.dirty = true const minDate = toDate(event.start) const insertIndex = this.events.findIndex(eventProxy => toDate(eventProxy.origin.start) > minDate) if (~insertIndex) { this.events.splice(insertIndex, 0, this.createEventProxy(event)) } else { this.events.push(this.createEventProxy(event)) } this.toDay(minDate) }, getConflicts ({ key, origin: event }) { const conflicts = [] if (this.events.length) { this.events.forEach(eventProxy => { if (eventProxy.key !== key) { const date = getConflict(event, eventProxy.origin) if (date) { conflicts.push({ key: eventProxy.key, info: `与 ${eventProxy.origin.target.name} 于 ${toDateStr(date)} ${toTimeStr(date)} 有冲突`, desc: this.getConflectMessage(eventProxy.origin) }) } } }) } return conflicts }, getConflectMessage (event) { const { freq, start, until, byDay, startTime, endTime } = event switch (freq) { case EventFreq.WEEKLY: return `自${start.split(' ')[0]}开始${until ? `至${until.split(' ')[0]}前` : ''} 每周${byDay.split(',').map(val => ['日', '一', '二', '三', '四', '五', '六'][val]).join('、')} ${startTime} - ${endTime}` default: return until ? `${start} - ${until}` : `自${start}开始` } }, onSave () { this.fix().then(this.save).then(() => { this.dirty = false }) }, fix () { let maxDate = Date.now() + 60000 if (this.events.some(({ origin: { until } }) => until && toDate(until) <= maxDate)) { return this.$confirm( '存在过期或将要过期(<=60s)节目,是否移除?', { type: 'warning', distinguishCancelAndClose: true, confirmButtonText: '移除', cancelButtonText: '保留' } ).then(() => { maxDate = Date.now() + 60000 this.scheduleOptions.events = this.events.filter(({ origin: { until } }) => !until || toDate(until) > maxDate) this.correct() }, action => { if (action === 'cancel') { return this.events } return Promise.reject() }) } return Promise.resolve() }, correct () { const today = new Date() const minDate = toZeroPoint(this.events.length ? pickMin(toDate(this.events[0].origin.start), today) : today) if (this.minDate < minDate) { this.minDate = minDate if (this.current < this.minDate) { this.toDay(this.current) return } } this.calculate() } } }