lvkun пре 3 година
родитељ
комит
01323e2716

+ 28 - 0
src/api/iot/device.ts

@@ -131,3 +131,31 @@ export const addDeviceMsg = (data: {deviceId: string, msgPayload: string, msgLab
     data
   })
 }
+
+/**
+ * 此函数检索特定设备的命令列表。
+ * @param params - `params` 参数是一个包含单个属性 `deviceId` 的对象,该属性是表示设备 ID 的字符串。此参数用于向“/toTransport/cmd”端点发出
+ * GET 请求以检索消息列表(类型为“IOT.API.DEVICE.Msg”
+ * @returns 函数 getDeviceCmdList 返回一个解析为 IOT.API.DEVICE.Msg 对象数组的 Promise。
+ */
+export const getDeviceCmdList = (params: {deviceId: string}) => {
+  return request<IOT.API.DEVICE.Msg[]>({
+    url: '/toTransport/cmd',
+    method: 'GET',
+    params
+  })
+}
+
+/**
+ * 函数“addDeviceCmd”向“/toTransport/cmd”发送一个 POST 请求,其中包含设备 ID、命令标签和命令参数作为数据。
+ * @param data - 包含以下属性的对象:
+ * @returns `addDeviceCmd` 函数返回一个解析为字符串的 Promise。 Promise
+ * 由“request”函数返回,该函数使用提供的“data”对象作为请求主体向“/toTransport/cmd”端点发送 POST 请求。
+ */
+export const addDeviceCmd = (data: { deviceId: string, cmdLabel: string, cmdParameters: any}) => {
+  return request<string>({
+    url: '/toTransport/cmd',
+    method: 'POST',
+    data
+  })
+}

+ 13 - 1
src/controller/iot/device.ts

@@ -1,6 +1,6 @@
 import {
   addDevice, addSubDevice, delDevice, delDeviceMul, delDeviceTag,
-  getDeviceById, getDeviceCount, getDeviceList, getDeviceMsgList, addDeviceMsg, getDeviceTag, getSubDeviceList, updateDeviceLabel
+  getDeviceById, getDeviceCount, getDeviceList, getDeviceMsgList, addDeviceMsg, getDeviceTag, getSubDeviceList, updateDeviceLabel, addDeviceCmd, getDeviceCmdList
 } from '@/api/iot/device'
 import { DeviceMsgEnum } from '@/enum/common'
 import { message } from 'ant-design-vue'
@@ -118,4 +118,16 @@ export class DeviceContriller {
     await addDeviceMsg(data)
     message.success('新增下发消息成功')
   }
+
+  /** 命令下发 获取列表 */
+  static async listDeviceCmd (params: {deviceId: string}) {
+    const { data } = await getDeviceCmdList(params)
+    return data
+  }
+
+  /** 命令下发 新增命令 */
+  static async addDeviceCmd (data: { deviceId: string, cmdLabel: string, cmdParameters: any}) {
+    await addDeviceCmd(data)
+    message.success('新增命令成功')
+  }
 }

+ 85 - 21
src/pages/Iot/device/components/cloudview.vue

@@ -8,10 +8,23 @@
     <template v-if="state.tasActive == 'msg'" >
       <a-alert :message="tipMessage" type="info" show-icon />
       <div class="subtitle" >注意:平台为每个设备默认最多保存20条消息,超过20条后,后续的消息会替换下发最早的消息。</div>
-      <a-row>
+      <a-row justify="space-between" >
+        <a-col></a-col>
         <a-col> <a-button type="primary" @click="state.visible = true">下发消息</a-button>  </a-col>
       </a-row>
-      <a-table
+    </template>
+    <template v-else >
+      <a-alert :message="tipMessage" type="info" show-icon style="margin-bottom: 20px;" />
+      <a-row justify="space-between" >
+        <a-col class="msg-title" >
+          <div class="title" >同步命令下发</div>
+          <div class="subtitle" >同步命令暂不支持历史记录查看。</div>
+        </a-col>
+        <a-col> <a-button type="primary" @click="state.visible = true">命令下发</a-button> </a-col>
+      </a-row>
+    </template>
+
+    <a-table
         style="margin-top: 20px;"
         :columns="columns"
         :dataSource="state.msgDataSource"
@@ -26,19 +39,18 @@
           </template>
         </template>
       </a-table>
-    </template>
-    <template v-if="state.tasActive == 'cmd'" >
 
-    </template>
   </a-card>
 
   <modal-pro
+    style="width: 700px;"
     :title="modalTitle"
     :visible="state.visible"
     @cancel="state.visible = false"
     @ok="ok"
   >
   <a-form
+    v-if="state.tasActive === 'msg'"
     :labelCol="{span: 4}"
     :wrapperCol="{span: 14}"
   >
@@ -60,6 +72,23 @@
       <a-textarea v-model:value="msgState.msgPayload" > </a-textarea>
     </a-form-item>
   </a-form>
+  <template v-else >
+    <a-alert message="同步命令成功下发后,设备需要在20秒内向平台回复响应,否则会认为命令请求超时。" type="info" show-icon style="margin-bottom: 20px;" />
+    <a-form
+    :labelCol="{span: 4}"
+    :wrapperCol="{span: 14}"
+  >
+    <a-form-item
+      label="选择命令"
+      v-bind="validateInfos.msgLabel"
+    >
+      <a-input v-model:value="msgState.msgLabel" > </a-input>
+    </a-form-item>
+    <a-form-item  label="设置命令参数" >
+      产品尚未配置命令,请先去 <a @click="pushProductDetail" >产品详情</a> 定义命令。
+    </a-form-item>
+    </a-form>
+  </template>
   </modal-pro>
 
   <modal-pro
@@ -82,6 +111,7 @@
       </a-descriptions-item>
     </a-descriptions>
   </modal-pro>
+
 </template>
 
 <script lang="ts" setup >
@@ -141,19 +171,19 @@ const tipMessage = computed(() => state.tasActive === 'msg' ? msg : cmdMsg)
 
 const state = reactive<{
   tasActive: 'msg' | 'cmd',
-  msgDataSource: IOT.API.DEVICE.Msg[],
+  msgDataSource: (IOT.API.DEVICE.Msg | IOT.API.DEVICE.Cmd)[],
   visible: boolean,
   loading: boolean,
   detailVisible: boolean,
   msgDetail: Partial<IOT.API.DEVICE.Msg >
-}>({
-  tasActive: 'msg',
-  msgDataSource: [],
-  visible: false,
-  loading: false,
-  detailVisible: false,
-  msgDetail: {}
-})
+    }>({
+      tasActive: 'msg',
+      msgDataSource: [],
+      visible: false,
+      loading: false,
+      detailVisible: false,
+      msgDetail: {}
+    })
 
 const msgState = reactive({
   deviceId: deviceId,
@@ -162,17 +192,38 @@ const msgState = reactive({
   topic: ''
 })
 
+const cmdState = reactive({
+  deviceId: deviceId,
+  cmdLabel: '',
+  cmdParameters: {}
+})
+
 const { resetFields, validate, validateInfos } = useForm(msgState, reactive({
   msgPayload: [{ required: true, message: '请填写消息内容' }],
   msgLabel: [{ required: true, message: '请填写消息标题' }]
 }))
 
+const { resetFields: resetFieldsCmd, validate: validateCmd, validateInfos: validateInfosCmd } = useForm(cmdState, reactive({
+}))
+
+const pushProductDetail = () => {
+  console.log('pushProductDetail')
+}
+
 const ok = () => {
-  validate().then(async () => {
-    await DeviceContriller.addDeviceMsg(msgState)
-    state.visible = false
-    getDeviceMsgList()
-  })
+  if (state.tasActive === 'msg') {
+    validate().then(async () => {
+      await DeviceContriller.addDeviceMsg(msgState)
+      state.visible = false
+      getDeviceMsgList()
+    })
+  } else {
+    validateCmd().then(async () => {
+      await DeviceContriller.addDeviceCmd(cmdState)
+      state.visible = false
+      getDeviceMsgList()
+    })
+  }
 }
 
 const openDetailModal = (record: IOT.API.DEVICE.Msg) => {
@@ -182,11 +233,14 @@ const openDetailModal = (record: IOT.API.DEVICE.Msg) => {
 
 const getDeviceMsgList = async () => {
   state.loading = true
-  state.msgDataSource = await DeviceContriller.listDeviceMsg({ deviceId })
+  state.msgDataSource = state.tasActive === 'msg' ? await DeviceContriller.listDeviceMsg({ deviceId }) : await DeviceContriller.listDeviceCmd({ deviceId })
   state.loading = false
 }
 
-const onTabChange = (value: 'msg' | 'cmd') => state.tasActive = value
+const onTabChange = (value: 'msg' | 'cmd') => {
+  state.tasActive = value
+  getDeviceMsgList()
+}
 
 onMounted(() => {
   getDeviceMsgList()
@@ -199,4 +253,14 @@ onMounted(() => {
   color: @sublabel-color;
   margin: 20px 0px;
 }
+
+.msg-title {
+  .title {
+    font-size: 20px;
+  }
+  .subtitle {
+    color: @sublabel-color;
+    font-size: 14px;
+  }
+}
 </style>

+ 21 - 0
src/pages/Iot/device/components/deviceShadow.vue

@@ -0,0 +1,21 @@
+<template>
+  <a-card>
+    <div class="subtitle" >
+      设备接入服务为每个设备添加“设备影子”,用于访问和控制设备的属性值。它通过可靠的数据存储能力,无论设备在线或者离线,您都能查询和更改设备的属性。
+
+      当设备离线时,“设备影子”将显示设备最近一次上报的属性值;通过下发“期望值”,“设备影子”将存储对设备属性的预期控制,当设备重新连接时,服务将“期望值”更新至设备
+    </div>
+  </a-card>
+</template>
+
+<script lang="ts" setup >
+
+</script>
+
+<style lang="less" scoped >
+@import '~@/styles/theme.less';
+.subtitle {
+  color: @sublabel-color;
+  font-size: 14px;
+}
+</style>

+ 1 - 1
src/pages/Iot/model/detail.vue

@@ -31,7 +31,7 @@
 
 <script lang="ts" setup >
 import { ModelController } from '@/controller'
-import { onMounted, reactive, ref } from 'vue'
+import { onMounted, reactive } from 'vue'
 import { useRoute } from 'vue-router'
 import ModelDefine from './components/modelDefine.vue'
 import OnlineTest from './components/onlineTest.vue'

+ 9 - 0
src/type/iot.d.ts

@@ -126,6 +126,15 @@ declare namespace IOT {
         'topic': string,
         'msgId': number
       }
+
+      interface Cmd {
+        id: string
+        'status': DeviceMsgEnum,
+        'msgId': number,
+        'cmdLabel': string,
+        'cmdPayload': any // '{"method":null,"params":null}',
+        'deviceId': string
+      }
     }
 
     namespace EVENT {