event.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import {
  2. toDate,
  3. toDateStr,
  4. toTimeStr,
  5. toZeroPoint,
  6. pickMin,
  7. getConflict
  8. } from '@/utils/event'
  9. import {
  10. EventFreq,
  11. EventTarget
  12. } from '@/constant'
  13. export default {
  14. data () {
  15. return {
  16. event: null,
  17. dirty: false,
  18. conflicts: []
  19. }
  20. },
  21. methods: {
  22. onRemove (eventProxy) {
  23. this.$confirm(
  24. `移除 ${eventProxy.origin.target.name} ?`,
  25. { type: 'warning' }
  26. ).then(() => {
  27. this.removeEventProxy(eventProxy)
  28. this.correct()
  29. })
  30. },
  31. removeEventProxy (eventProxy) {
  32. if (eventProxy) {
  33. const { key } = eventProxy
  34. const index = this.events.findIndex(event => event.key === key)
  35. if (~index) {
  36. this.events.splice(index, 1)
  37. this.dirty = true
  38. return index
  39. }
  40. }
  41. return -1
  42. },
  43. onAdd (event) {
  44. if (this.editable) {
  45. if (event && event.until && toDate(event.until) <= new Date()) {
  46. this.calculate()
  47. return
  48. }
  49. this.editEvent(event)
  50. }
  51. },
  52. onEditProxy (eventProxy) {
  53. const event = eventProxy.origin
  54. if (this.editable) {
  55. this.$eventProxy = eventProxy
  56. this.editEvent(event)
  57. } else {
  58. switch (event.target.type) {
  59. case EventTarget.RECUR:
  60. this.$refs.scheduleDialog.show(event.target.id)
  61. break
  62. default:
  63. window.open(this.$router.resolve({
  64. name: 'program',
  65. params: { id: event.target.id }
  66. }).href, '_blank')
  67. break
  68. }
  69. }
  70. },
  71. editEvent (event) {
  72. if (this.editable) {
  73. this.event = event || {}
  74. this.$refs.editDialog.show()
  75. }
  76. },
  77. onSaveEvent (done) {
  78. const event = this.$refs.editor.getValue()
  79. if (!event) {
  80. return
  81. }
  82. console.log(event)
  83. if (this.$eventProxy && this.getEventUnique(this.$eventProxy.origin) === this.getEventUnique(event)) {
  84. done()
  85. this.dirty = true
  86. this.$eventProxy.origin.target = event.target
  87. return
  88. }
  89. this.conflicts = this.getConflicts({
  90. key: this.$eventProxy?.key,
  91. origin: event
  92. })
  93. if (!this.conflicts.length) {
  94. done()
  95. this.removeEventProxy(this.$eventProxy)
  96. this.saveEvent(event)
  97. return
  98. }
  99. this.$conflictSource = event
  100. this.$refs.conflictDialog.show()
  101. },
  102. getEventUnique (event) {
  103. const { freq, start, until, byDay, startTime, endTime } = event
  104. switch (freq) {
  105. case EventFreq.ONCE:
  106. return `${freq};${start};${until}`
  107. case EventFreq.WEEKLY:
  108. return `${freq};${start};${until};${byDay};${startTime};${endTime}`
  109. default:
  110. return Math.random().toString(16).slice(2)
  111. }
  112. },
  113. onCover (done) {
  114. done()
  115. this.$refs.editDialog.onCancel()
  116. this.conflicts.forEach(this.removeEventProxy)
  117. this.saveEvent(this.$conflictSource)
  118. this.$conflictSource = null
  119. },
  120. saveEvent (event) {
  121. this.dirty = true
  122. const minDate = toDate(event.start)
  123. const insertIndex = this.events.findIndex(eventProxy => toDate(eventProxy.origin.start) > minDate)
  124. if (~insertIndex) {
  125. this.events.splice(insertIndex, 0, this.createEventProxy(event))
  126. } else {
  127. this.events.push(this.createEventProxy(event))
  128. }
  129. this.toDay(minDate)
  130. },
  131. getConflicts ({ key, origin: event }) {
  132. const conflicts = []
  133. if (this.events.length) {
  134. this.events.forEach(eventProxy => {
  135. if (eventProxy.key !== key) {
  136. const date = getConflict(event, eventProxy.origin)
  137. if (date) {
  138. conflicts.push({
  139. key: eventProxy.key,
  140. info: `与 ${eventProxy.origin.target.name} 于 ${toDateStr(date)} ${toTimeStr(date)} 有冲突`,
  141. desc: this.getConflectMessage(eventProxy.origin)
  142. })
  143. }
  144. }
  145. })
  146. }
  147. return conflicts
  148. },
  149. getConflectMessage (event) {
  150. const { freq, start, until, byDay, startTime, endTime } = event
  151. switch (freq) {
  152. case EventFreq.WEEKLY:
  153. return `自${start.split(' ')[0]}开始${until ? `至${until.split(' ')[0]}前` : ''} 每周${byDay.split(',').map(val => ['日', '一', '二', '三', '四', '五', '六'][val]).join('、')} ${startTime} - ${endTime}`
  154. default:
  155. return until ? `${start} - ${until}` : `自${start}开始`
  156. }
  157. },
  158. onSave () {
  159. this.fix().then(this.save).then(() => { this.dirty = false })
  160. },
  161. fix () {
  162. let maxDate = Date.now() + 60000
  163. if (this.events.some(({ origin: { until } }) => until && toDate(until) <= maxDate)) {
  164. return this.$confirm(
  165. '存在过期或将要过期(<=60s)节目,是否移除?',
  166. {
  167. type: 'warning',
  168. distinguishCancelAndClose: true,
  169. confirmButtonText: '移除',
  170. cancelButtonText: '保留'
  171. }
  172. ).then(() => {
  173. maxDate = Date.now() + 60000
  174. this.scheduleOptions.events = this.events.filter(({ origin: { until } }) => !until || toDate(until) > maxDate)
  175. this.correct()
  176. }, action => {
  177. if (action === 'cancel') {
  178. return this.events
  179. }
  180. return Promise.reject()
  181. })
  182. }
  183. return Promise.resolve()
  184. },
  185. correct () {
  186. const today = new Date()
  187. const minDate = toZeroPoint(this.events.length ? pickMin(toDate(this.events[0].origin.start), today) : today)
  188. if (this.minDate < minDate) {
  189. this.minDate = minDate
  190. if (this.current < this.minDate) {
  191. this.toDay(this.current)
  192. return
  193. }
  194. }
  195. this.calculate()
  196. }
  197. }
  198. }