event.js 5.2 KB

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