BroadcasDeployPanel.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <template>
  2. <div class="l-flex__auto l-flex--col">
  3. <div class="l-flex__none l-flex--row c-step has-padding">
  4. <button
  5. class="l-flex__none c-sibling-item o-button"
  6. :class="{ hidden: active === 0 }"
  7. @click="onPresent"
  8. >
  9. 上一步
  10. </button>
  11. <el-steps
  12. :active="active"
  13. class="l-flex__fill"
  14. finish-status="success"
  15. align-center
  16. >
  17. <el-step title="选择模板" />
  18. <el-step title="选择设备" />
  19. <el-step title="信息确认" />
  20. </el-steps>
  21. <button
  22. class="l-flex__none c-sibling-item o-button"
  23. :class="{ hidden: hideNext }"
  24. @click="onNext"
  25. >
  26. {{ btnMsg }}
  27. </button>
  28. </div>
  29. <div class="l-flex__auto l-flex--col has-padding">
  30. <div
  31. v-show="active === 0"
  32. class="c-grid-form u-align-self--center"
  33. >
  34. <span class="c-grid-form__label required">位置</span>
  35. <el-select v-model="position">
  36. <el-option
  37. v-for="option in positionOptions"
  38. :key="option.value"
  39. :label="option.label"
  40. :value="option.value"
  41. />
  42. </el-select>
  43. <span class="c-grid-form__label required">模板</span>
  44. <schema-select
  45. v-model="templateId"
  46. :schema="templateSelectSchema"
  47. placeholder="请选择"
  48. @change="onTemplateChange"
  49. />
  50. <span class="c-grid-form__label">失效时间</span>
  51. <el-date-picker
  52. v-model="endDateTime"
  53. type="datetime"
  54. placeholder="请选择失效时间"
  55. value-format="yyyy-MM-dd HH:mm:ss"
  56. :picker-options="endDatePickerOptions"
  57. @change="onEndDateTimeChange"
  58. />
  59. <div
  60. v-if="templateId && !templateContent"
  61. class="c-grid-form__row u-text-center"
  62. >
  63. <i class="el-icon-loading" />
  64. </div>
  65. <template v-if="templateContent">
  66. <span class="c-grid-form__label">内容</span>
  67. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ templateContent }}</div>
  68. <div
  69. v-for="(value, key) in keywordMap"
  70. :key="key"
  71. class="c-grid-form__row"
  72. >
  73. <span class="c-grid-form__label required c-grid-form__text">{{ value.keywordName }}</span>
  74. <el-input
  75. v-model.trim="value.content"
  76. clearable
  77. />
  78. </div>
  79. </template>
  80. </div>
  81. <device-group-tree
  82. v-show="active === 1"
  83. ref="tree"
  84. class="l-flex__fill has-padding"
  85. @change="onChange"
  86. />
  87. <div
  88. v-if="active === 2"
  89. class="c-grid-form u-align-self--center"
  90. >
  91. <span class="c-grid-form__label">位置:</span>
  92. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ positionDesc }}</div>
  93. <span class="c-grid-form__label">内容:</span>
  94. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ targetContent }}</div>
  95. <span class="c-grid-form__label">目标设备:</span>
  96. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ selectedDeviceName }}</div>
  97. <span class="c-grid-form__label">失效时间:</span>
  98. <div class="l-flex--row c-grid-form__option c-grid-form__text">{{ endDateTime || '不限定' }}</div>
  99. </div>
  100. </div>
  101. </div>
  102. </template>
  103. <script>
  104. import { parseTime } from '@/utils'
  105. import {
  106. getBroadcastTemplates,
  107. getBroadcastTemplate,
  108. publishBroadcast
  109. } from '@/api/broadcast'
  110. export default {
  111. name: 'BrodcastDeployPanel',
  112. props: {
  113. tenant: {
  114. type: String,
  115. default: ''
  116. }
  117. },
  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. tenant: this.tenant,
  260. position: this.position,
  261. name: this.$templateData.templateName,
  262. templateId: this.templateId,
  263. keywordMap,
  264. startTime: parseTime(Date.now(), '{y}-{m}-{d} {h}:{i}:{s}'),
  265. endTime: this.endDateTime,
  266. deviceIds: this.selectedDevices.map(device => device.id)
  267. })
  268. })
  269. }
  270. }
  271. }
  272. </script>
  273. <style lang="scss" scoped>
  274. .c-step {
  275. border-bottom: 1px solid $gray--light;
  276. .hidden {
  277. visibility: hidden;
  278. }
  279. }
  280. </style>