DevicePowerTask.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <script>
  2. import { ThirdPartyDevice } from '@/constant'
  3. import { publish } from '@/utils/mqtt'
  4. import {
  5. Status,
  6. RELAY_KEY,
  7. GET_MULTI_POWER_TIMING,
  8. SET_MULTI_POWER_TIMING,
  9. addListener,
  10. removeListener,
  11. addInjectListener,
  12. removeInjectListener
  13. } from '@/utils/adapter'
  14. import { savePowerLogger } from '@/api/platform'
  15. export default {
  16. name: 'DevicePowerTask',
  17. props: {
  18. device: {
  19. type: Object,
  20. required: true
  21. },
  22. tasks: {
  23. type: Array,
  24. required: true
  25. }
  26. },
  27. data () {
  28. return {
  29. status: 0,
  30. retryCount: 0,
  31. cardInfo: null
  32. }
  33. },
  34. mounted () {
  35. this.$timer = -1
  36. addListener(this.device.id, this.onMessage)
  37. addInjectListener(this.device.id, this.onInjectMessage)
  38. },
  39. beforeDestroy () {
  40. clearTimeout(this.$timer)
  41. removeListener(this.device.id, this.onMessage)
  42. removeInjectListener(this.device.id, this.onInjectMessage)
  43. },
  44. methods: {
  45. onMessage (value) {
  46. const multiCard = value[ThirdPartyDevice.MULTI_FUNCTION_CARD]
  47. if (multiCard.status === Status.OK) {
  48. if (!this.cardInfo) {
  49. const { connectIndex, portIndex } = multiCard.powers[0]
  50. const type = multiCard.powers.find(({ type }) => type === '屏体电源' || type === '默认')?.type || multiCard.powers.find(({ type }) => !!type)?.type
  51. this.cardInfo = { type, connectIndex, portIndex }
  52. if (type) {
  53. this.onSync()
  54. } else {
  55. this.status = 4
  56. }
  57. }
  58. }
  59. },
  60. onInjectMessage (message) {
  61. if (message.messageId === this.$messageId) {
  62. this.$messageId = null
  63. if (message.code !== 0) {
  64. this.status = 3
  65. return
  66. }
  67. const data = message.data ? JSON.parse(message.data.replaceAll("'", '"')) : {}
  68. if (data.logined === false) {
  69. this.status = 3
  70. return
  71. }
  72. switch (message.function) {
  73. case GET_MULTI_POWER_TIMING:
  74. clearTimeout(this.$timer)
  75. if (this.retryCount > 0) {
  76. this.checkTasks(data.data.filter(({ connectIndex, portIndex }) => connectIndex !== RELAY_KEY && portIndex !== RELAY_KEY))
  77. } else {
  78. this.sendTasks(data.data.filter(({ connectIndex, portIndex }) => connectIndex !== RELAY_KEY && portIndex !== RELAY_KEY))
  79. }
  80. break
  81. case SET_MULTI_POWER_TIMING:
  82. clearTimeout(this.$timer)
  83. this.status = 2
  84. break
  85. default:
  86. break
  87. }
  88. }
  89. },
  90. onSync () {
  91. this.$timer = setTimeout(this.retry, 5000)
  92. this.sendTopic(GET_MULTI_POWER_TIMING, { sn: this.device.serialNumber }).then(messageId => {
  93. this.$messageId = messageId
  94. }, () => {
  95. clearTimeout(this.$timer)
  96. })
  97. },
  98. createTasks () {
  99. const type = this.cardInfo.type
  100. return this.tasks.map(task => {
  101. return {
  102. ...task,
  103. type
  104. }
  105. })
  106. },
  107. sendTasks (tasks) {
  108. this.status = 1
  109. const { connectIndex, portIndex } = this.cardInfo
  110. const newTasks = this.createTasks()
  111. this.$timer = setTimeout(this.retry, 5000)
  112. this.sendTopic(SET_MULTI_POWER_TIMING, {
  113. sn: this.device.serialNumber,
  114. taskInfo: tasks.length
  115. ? tasks.map(({ enable, conditions, ...options }) => {
  116. return {
  117. ...options,
  118. enable: true,
  119. conditions: [
  120. ...newTasks,
  121. ...conditions.map(({ status, ...task }) => task)
  122. ]
  123. }
  124. })
  125. : [{
  126. connectIndex,
  127. portIndex,
  128. enable: true,
  129. conditions: newTasks
  130. }]
  131. }).then(messageId => {
  132. this.$messageId = messageId
  133. savePowerLogger({
  134. description: `设备【${this.device.name}】 新增电源定时任务 ${this.cardInfo.type}`,
  135. method: '电源定时任务设置',
  136. params: JSON.stringify({
  137. id: this.device.id,
  138. name: this.device.name,
  139. tasks: this.tasks
  140. })
  141. })
  142. }, () => {
  143. clearTimeout(this.$timer)
  144. })
  145. },
  146. retry () {
  147. this.retryCount += 1
  148. this.status = 1
  149. this.onSync()
  150. },
  151. checkTasks (tasks) {
  152. const map = {}
  153. this.tasks.forEach(({ flag }) => {
  154. map[flag] = true
  155. })
  156. for (let i = 0; i < tasks.length; i++) {
  157. if (tasks[i].conditions.some(({ flag }) => map[flag])) {
  158. this.status = 2
  159. return
  160. }
  161. }
  162. this.sendTasks(tasks)
  163. },
  164. sendTopic (invoke, inputs) {
  165. const timestamp = `${Date.now()}`
  166. const messageId = `${invoke}_${timestamp}`
  167. return publish(
  168. `${this.device.productId}/${this.device.id}/multifunctionCard/invoke`,
  169. JSON.stringify({
  170. messageId,
  171. timestamp,
  172. 'function': invoke,
  173. inputs: JSON.stringify(inputs || [])
  174. }),
  175. true
  176. ).then(() => messageId)
  177. }
  178. },
  179. render (h) {
  180. if (this.status === 3 || this.status === 4) {
  181. return h('el-tooltip', {
  182. props: {
  183. content: this.status === 3 ? '连接失败,请联系管理员' : '无可用端口,请联系管理员',
  184. placement: 'left',
  185. enterable: false
  186. }
  187. }, [
  188. h('el-tag', {
  189. staticClass: 'o-tag u-readonly',
  190. props: {
  191. size: 'medium',
  192. 'disable-transitions': true,
  193. type: 'danger'
  194. }
  195. }, '失败')
  196. ])
  197. }
  198. return h('el-tag', {
  199. staticClass: 'o-tag u-readonly',
  200. props: {
  201. size: 'medium',
  202. 'disable-transitions': true,
  203. type: ['primary', 'warning', 'success'][this.status]
  204. }
  205. }, ['等待', this.retryCount === 0 ? '同步中' : `重试(${this.retryCount})`, '成功'][this.status])
  206. }
  207. }
  208. </script>