index.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <template>
  2. <wrapper
  3. class="c-step"
  4. fill
  5. margin
  6. padding
  7. background
  8. >
  9. <div class="l-flex__none l-flex--row c-step__header">
  10. <button
  11. class="l-flex__none c-sibling-item o-button"
  12. :class="{ hidden: active === 0 }"
  13. @click="onPresent"
  14. >
  15. 上一步
  16. </button>
  17. <el-steps
  18. :active="active"
  19. class="l-flex__fill"
  20. finish-status="success"
  21. align-center
  22. >
  23. <el-step title="选择模板" />
  24. <el-step title="选择设备" />
  25. <el-step title="信息确认" />
  26. </el-steps>
  27. <button
  28. class="l-flex__none c-sibling-item o-button"
  29. :class="{ hidden: hideNext }"
  30. @click="onNext"
  31. >
  32. {{ btnMsg }}
  33. </button>
  34. </div>
  35. <div class="l-flex__auto l-flex--col">
  36. <div
  37. v-show="active === 0"
  38. class="c-grid-form u-align-self--center"
  39. >
  40. <span class="c-grid-form__label required">位置</span>
  41. <el-select v-model="position">
  42. <el-option
  43. v-for="option in positionOptions"
  44. :key="option.value"
  45. :label="option.label"
  46. :value="option.value"
  47. />
  48. </el-select>
  49. <span class="c-grid-form__label required">模板</span>
  50. <schema-select
  51. v-model="templateId"
  52. :schema="templateSelectSchema"
  53. placeholder="请选择"
  54. @change="onTemplateChange"
  55. />
  56. <span class="c-grid-form__label">失效时间</span>
  57. <el-date-picker
  58. v-model="endDateTime"
  59. type="datetime"
  60. placeholder="请选择失效时间"
  61. value-format="yyyy-MM-dd HH:mm:ss"
  62. :picker-options="endDatePickerOptions"
  63. @change="onEndDateTimeChange"
  64. />
  65. <div
  66. v-if="templateId && !templateContent"
  67. class="c-grid-form__row u-text-center"
  68. >
  69. <i class="el-icon-loading" />
  70. </div>
  71. <template v-if="templateContent">
  72. <span class="c-grid-form__label">内容</span>
  73. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ templateContent }}</div>
  74. <div
  75. v-for="(value, key) in keywordMap"
  76. :key="key"
  77. class="c-grid-form__row"
  78. >
  79. <span class="c-grid-form__label required c-grid-form__text">{{ value.keywordName }}</span>
  80. <el-input
  81. v-model.trim="value.content"
  82. clearable
  83. />
  84. </div>
  85. </template>
  86. </div>
  87. <device-group-tree
  88. v-show="active === 1"
  89. ref="tree"
  90. class="l-flex__fill"
  91. @change="onChange"
  92. />
  93. <div
  94. v-if="active === 2"
  95. class="c-grid-form u-align-self--center"
  96. >
  97. <span class="c-grid-form__label">位置:</span>
  98. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ positionDesc }}</div>
  99. <span class="c-grid-form__label">内容:</span>
  100. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ targetContent }}</div>
  101. <span class="c-grid-form__label">目标设备:</span>
  102. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ selectedDeviceName }}</div>
  103. <span class="c-grid-form__label">失效时间:</span>
  104. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ endDateTime || '不限定' }}</div>
  105. </div>
  106. </div>
  107. </wrapper>
  108. </template>
  109. <script>
  110. import { parseTime } from '@/utils'
  111. import {
  112. getBroadcastTemplates,
  113. getBroadcastTemplate,
  114. publishBroadcast
  115. } from '../api'
  116. export default {
  117. name: 'BrodcastDeployPanel',
  118. data () {
  119. return {
  120. active: 0,
  121. position: 1,
  122. positionOptions: [
  123. { label: '屏幕顶部', value: 0 },
  124. { label: '屏幕底部', value: 1 }
  125. ],
  126. templateSelectSchema: {
  127. remote: getBroadcastTemplates,
  128. pagination: true,
  129. value: 'templateId',
  130. label: 'templateName'
  131. },
  132. templateId: '',
  133. templateContent: '',
  134. targetContent: '',
  135. endDateTime: '',
  136. keywordMap: [],
  137. selectedDevices: []
  138. }
  139. },
  140. computed: {
  141. minDate () {
  142. const now = new Date()
  143. return new Date(now.getFullYear(), now.getMonth(), now.getDate())
  144. },
  145. endDatePickerOptions () {
  146. return {
  147. disabledDate: this.isDisableDate
  148. }
  149. },
  150. hideNext () {
  151. switch (this.active) {
  152. case 0:
  153. return !this.templateContent || this.keywordMap.some(({ content }) => !content)
  154. case 1:
  155. return this.selectedDevices.length === 0
  156. default:
  157. return false
  158. }
  159. },
  160. btnMsg () {
  161. return this.active < 2 ? '下一步' : '发布'
  162. },
  163. positionDesc () {
  164. return this.positionOptions[this.position].label
  165. },
  166. selectedDeviceName () {
  167. return this.selectedDevices.map(device => device.name).join(', ')
  168. }
  169. },
  170. methods: {
  171. onEndDateTimeChange () {
  172. if (this.endDateTime && new Date(this.endDateTime).getTime() < Date.now()) {
  173. this.endDateTime = parseTime(Date.now(), '{y}-{m}-{d} {h}:{i}:{s}')
  174. }
  175. },
  176. isDisableDate (date) {
  177. return date < this.minDate
  178. },
  179. onTemplateChange (templateId) {
  180. this.templateContent = ''
  181. this.keywordMap = []
  182. getBroadcastTemplate(templateId).then(({ data }) => {
  183. const { templateName, templateContent, keywordMap, optionalNumbers } = data
  184. const arr = []
  185. let content = templateContent
  186. for (let i = 0; i < optionalNumbers; i++) {
  187. content = content.replace(new RegExp(`\\{${i}\\}`, 'g'), `{${keywordMap[i].keywordName}}`)
  188. arr.push({
  189. ...keywordMap[i],
  190. content: ''
  191. })
  192. }
  193. this.templateContent = content
  194. this.$templateData = {
  195. templateName,
  196. templateContent,
  197. optionalNumbers
  198. }
  199. this.keywordMap = arr
  200. })
  201. },
  202. onPresent () {
  203. if (this.active > 0) {
  204. this.active -= 1
  205. }
  206. },
  207. onNext () {
  208. switch (this.active) {
  209. case 0:
  210. this.active += 1
  211. break
  212. case 1:
  213. this.collectInfo()
  214. this.active += 1
  215. break
  216. case 2:
  217. this.publish().then(() => {
  218. this.active = 0
  219. this.position = 1
  220. this.templateId = ''
  221. this.templateContent = ''
  222. this.keywordMap = []
  223. this.endDateTime = ''
  224. this.$refs.tree.reset()
  225. })
  226. break
  227. default:
  228. break
  229. }
  230. },
  231. onChange (devices) {
  232. this.selectedDevices = devices
  233. },
  234. collectInfo () {
  235. const { templateContent, optionalNumbers } = this.$templateData
  236. let content = templateContent
  237. for (let i = 0; i < optionalNumbers; i++) {
  238. content = content.replace(new RegExp(`\\{${i}\\}`, 'g'), this.keywordMap[i].content)
  239. }
  240. this.targetContent = content
  241. },
  242. publish () {
  243. if (this.endDateTime && new Date(this.endDateTime).getTime() < Date.now()) {
  244. this.$message({
  245. type: 'warning',
  246. message: '失效时间已过期'
  247. })
  248. return Promise.reject()
  249. }
  250. return this.$confirm(
  251. `立即发布?`,
  252. { type: 'warning' }
  253. ).then(() => {
  254. const keywordMap = {}
  255. this.keywordMap.forEach(({ content }, key) => {
  256. keywordMap[key] = { content }
  257. })
  258. return publishBroadcast({
  259. position: this.position,
  260. name: this.$templateData.templateName,
  261. templateId: this.templateId,
  262. keywordMap,
  263. startTime: parseTime(Date.now(), '{y}-{m}-{d} {h}:{i}:{s}'),
  264. endTime: this.endDateTime,
  265. deviceIds: this.selectedDevices.map(device => device.id)
  266. })
  267. })
  268. }
  269. }
  270. }
  271. </script>