cloudview.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <a-card
  3. style="width: 100%"
  4. :tab-list="tabListNoTitle"
  5. :active-tab-key="state.tasActive"
  6. @tabChange="onTabChange"
  7. >
  8. <template v-if="state.tasActive == 'msg'" >
  9. <a-alert :message="tipMessage" type="info" show-icon />
  10. <div class="subtitle" >注意:平台为每个设备默认最多保存20条消息,超过20条后,后续的消息会替换下发最早的消息。</div>
  11. <a-row>
  12. <a-col> <a-button type="primary" @click="state.visible = true">下发消息</a-button> </a-col>
  13. </a-row>
  14. <a-table
  15. style="margin-top: 20px;"
  16. :columns="columns"
  17. :dataSource="state.msgDataSource"
  18. :loading="state.loading"
  19. >
  20. <template #bodyCell="{ column, record }">
  21. <template v-if="column.key === 'status'">
  22. <span>{{ DeviceContriller.deviceMag.get(record.status)?.name }}</span>
  23. </template>
  24. <template v-if="column.key === 'action'">
  25. <a @click="openDetailModal(record)" >详情</a>
  26. </template>
  27. </template>
  28. </a-table>
  29. </template>
  30. <template v-if="state.tasActive == 'cmd'" >
  31. </template>
  32. </a-card>
  33. <modal-pro
  34. :title="modalTitle"
  35. :visible="state.visible"
  36. @cancel="state.visible = false"
  37. @ok="ok"
  38. >
  39. <a-form
  40. :labelCol="{span: 4}"
  41. :wrapperCol="{span: 14}"
  42. >
  43. <a-form-item
  44. label="消息名称"
  45. v-bind="validateInfos.msgLabel"
  46. >
  47. <a-input v-model:value="msgState.msgLabel" > </a-input>
  48. </a-form-item>
  49. <a-form-item
  50. label="Topic"
  51. >
  52. <a-input v-model:value="msgState.topic" > </a-input>
  53. </a-form-item>
  54. <a-form-item
  55. label="消息内容"
  56. v-bind="validateInfos.msgPayload"
  57. >
  58. <a-textarea v-model:value="msgState.msgPayload" > </a-textarea>
  59. </a-form-item>
  60. </a-form>
  61. </modal-pro>
  62. </template>
  63. <script lang="ts" setup >
  64. import { DeviceContriller } from '@/controller'
  65. import { computed, onMounted, reactive, ref } from 'vue'
  66. import { useRoute } from 'vue-router'
  67. import { Form } from 'ant-design-vue'
  68. const msg = '消息下发不依赖产品模型,平台会以异步方式(消息下发后无需等待设备侧回复响应)下发消息给设备。当前仅MQTT设备支持消息下发。'
  69. const cmdMsg = '如果设备所属产品定义了命令功能,则您可以通过应用调用平台接口或者操作下面的“下发命令”按钮下发命令。当前MQTT设备仅支持同步命令下发,NB设备仅支持异步命令下发 。'
  70. const modalTitle = '新增下发消息'
  71. const tabListNoTitle = [
  72. {
  73. key: 'msg',
  74. tab: '消息下发'
  75. },
  76. {
  77. key: 'cmd',
  78. tab: '命令下发'
  79. }
  80. ]
  81. const columns = [
  82. {
  83. title: '状态',
  84. dataIndex: 'status',
  85. key: 'status'
  86. },
  87. {
  88. title: '消息名称',
  89. dataIndex: 'msgLabel'
  90. },
  91. {
  92. title: '消息id',
  93. dataIndex: 'msgId'
  94. },
  95. {
  96. title: '消息内容',
  97. dataIndex: 'msgPayload'
  98. },
  99. {
  100. title: '消息创建时间',
  101. dataIndex: 'createAt'
  102. },
  103. {
  104. title: '操纵',
  105. key: 'action'
  106. }
  107. ]
  108. const useForm = Form.useForm
  109. const route = useRoute()
  110. const deviceId = route.query.id as string
  111. const tipMessage = computed(() => state.tasActive === 'msg' ? msg : cmdMsg)
  112. const state = reactive<{
  113. tasActive: 'msg' | 'cmd',
  114. msgDataSource: IOT.API.DEVICE.Msg[],
  115. visible: boolean,
  116. loading: boolean,
  117. detailVisible: boolean,
  118. msgDetail: IOT.API.DEVICE.Msg | {}
  119. }>({
  120. tasActive: 'msg',
  121. msgDataSource: [],
  122. visible: false,
  123. loading: false,
  124. detailVisible: false,
  125. msgDetail: {}
  126. })
  127. const msgState = reactive({
  128. deviceId: deviceId,
  129. msgPayload: '',
  130. msgLabel: '',
  131. topic: ''
  132. })
  133. const { resetFields, validate, validateInfos } = useForm(msgState, reactive({
  134. msgPayload: [{ required: true, message: '请填写消息内容' }],
  135. msgLabel: [{ required: true, message: '请填写消息标题' }]
  136. }))
  137. const ok = () => {
  138. validate().then(async () => {
  139. await DeviceContriller.addDeviceMsg(msgState)
  140. state.visible = false
  141. getDeviceMsgList()
  142. })
  143. }
  144. const openDetailModal = (record: IOT.API.DEVICE.Msg) => {
  145. state.detailVisible = true
  146. state.msgDetail = record
  147. }
  148. const getDeviceMsgList = async () => {
  149. state.loading = true
  150. state.msgDataSource = await DeviceContriller.listDeviceMsg({ deviceId })
  151. state.loading = false
  152. }
  153. const onTabChange = (value: 'msg' | 'cmd') => state.tasActive = value
  154. onMounted(() => {
  155. getDeviceMsgList()
  156. })
  157. </script>
  158. <style lang="less" scoped >
  159. @import '~@/styles/theme.less';
  160. .subtitle {
  161. color: @sublabel-color;
  162. margin: 20px 0px;
  163. }
  164. </style>