event.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. done()
  81. return
  82. }
  83. console.log(event)
  84. if (this.$eventProxy && this.getEventUnique(this.$eventProxy.origin) === this.getEventUnique(event)) {
  85. done()
  86. this.dirty = true
  87. this.$eventProxy.origin.target = event.target
  88. return
  89. }
  90. this.conflicts = this.getConflicts({
  91. key: this.$eventProxy?.key,
  92. origin: event
  93. })
  94. if (!this.conflicts.length) {
  95. done()
  96. this.removeEventProxy(this.$eventProxy)
  97. this.saveEvent(event)
  98. return
  99. }
  100. this.$conflictSource = event
  101. this.$refs.conflictDialog.show()
  102. },
  103. getEventUnique (event) {
  104. const { freq, start, until, byDay, startTime, endTime } = event
  105. switch (freq) {
  106. case EventFreq.ONCE:
  107. return `${freq};${start};${until}`
  108. case EventFreq.WEEKLY:
  109. return `${freq};${start};${until};${byDay};${startTime};${endTime}`
  110. default:
  111. return Math.random().toString(16).slice(2)
  112. }
  113. },
  114. onCover (done) {
  115. done()
  116. this.$refs.editDialog.onCancel()
  117. this.conflicts.forEach(this.removeEventProxy)
  118. this.saveEvent(this.$conflictSource)
  119. this.$conflictSource = null
  120. },
  121. saveEvent (event) {
  122. this.dirty = true
  123. const minDate = toDate(event.start)
  124. const insertIndex = this.events.findIndex(eventProxy => toDate(eventProxy.origin.start) > minDate)
  125. if (~insertIndex) {
  126. this.events.splice(insertIndex, 0, this.createEventProxy(event))
  127. } else {
  128. this.events.push(this.createEventProxy(event))
  129. }
  130. this.toDay(minDate)
  131. },
  132. getConflicts ({ key, origin: event }) {
  133. const conflicts = []
  134. if (this.events.length) {
  135. this.events.forEach(eventProxy => {
  136. if (eventProxy.key !== key) {
  137. const date = getConflict(event, eventProxy.origin)
  138. if (date) {
  139. conflicts.push({
  140. key: eventProxy.key,
  141. info: `与 ${eventProxy.origin.target.name} 于 ${toDateStr(date)} ${toTimeStr(date)} 有冲突`,
  142. desc: this.getConflectMessage(eventProxy.origin)
  143. })
  144. }
  145. }
  146. })
  147. }
  148. return conflicts
  149. },
  150. getConflectMessage (event) {
  151. const { freq, start, until, byDay, startTime, endTime } = event
  152. switch (freq) {
  153. case EventFreq.WEEKLY:
  154. return `自${start.split(' ')[0]}开始${until ? `至${until.split(' ')[0]}前` : ''} 每周${byDay.split(',').map(val => ['日', '一', '二', '三', '四', '五', '六'][val]).join('、')} ${startTime} - ${endTime}`
  155. default:
  156. return until ? `${start} - ${until}` : `自${start}开始`
  157. }
  158. },
  159. onSave () {
  160. this.fix().then(this.save).then(() => { this.dirty = false })
  161. },
  162. fix () {
  163. let maxDate = Date.now() + 60000
  164. if (this.events.some(({ origin: { until } }) => until && toDate(until) <= maxDate)) {
  165. return this.$confirm(
  166. '存在过期或将要过期(<=60s)节目,是否移除?',
  167. {
  168. type: 'warning',
  169. distinguishCancelAndClose: true,
  170. confirmButtonText: '移除',
  171. cancelButtonText: '保留'
  172. }
  173. ).then(() => {
  174. maxDate = Date.now() + 60000
  175. this.scheduleOptions.events = this.events.filter(({ origin: { until } }) => !until || toDate(until) > maxDate)
  176. this.correct()
  177. }, action => {
  178. if (action === 'cancel') {
  179. return this.events
  180. }
  181. return Promise.reject()
  182. })
  183. }
  184. return Promise.resolve()
  185. },
  186. correct () {
  187. const today = new Date()
  188. const minDate = toZeroPoint(this.events.length ? pickMin(toDate(this.events[0].origin.start), today) : today)
  189. if (this.minDate < minDate) {
  190. this.minDate = minDate
  191. if (this.current < this.minDate) {
  192. this.toDay(this.current)
  193. return
  194. }
  195. }
  196. this.calculate()
  197. }
  198. }
  199. }