Explorar o código

fix: 5/8日云平台优化

lvkun %!s(int64=3) %!d(string=hai) anos
pai
achega
28de864674

+ 1 - 1
src/api/iot/device.ts

@@ -107,7 +107,7 @@ export const delDeviceTag = (id: string) => {
   })
 }
 
-export const getDeviceCount = (params: {modelId: string}) => {
+export const getDeviceCount = (params?: {modelId: string}) => {
   return request<IOT.API.DEVICE.Count>({
     url: '/device/count',
     method: 'GET',

+ 8 - 0
src/api/iot/model.ts

@@ -242,3 +242,11 @@ export const debugModelPlugin = (data: {input: string, pluginBody: string, decod
     data
   })
 }
+
+/** 模型统计 */
+export const getModelCount = () => {
+  return request<string>({
+    url: '/model/count',
+    method: 'GET'
+  })
+}

+ 6 - 6
src/api/iot/rule.ts

@@ -75,7 +75,7 @@ export const delForward = (id: string) => {
  * @returns 函数 getForwardCount 返回解析为数字的
  * Promise。该数字表示具有指定状态的转发规则的计数。通过以指定状态作为参数向“/forwardRule/count”端点发出 GET 请求来获取计数。
  */
-export const getForwardCount = (status: boolean) => {
+export const getForwardCount = (status?: boolean) => {
   return request<number>({
     url: '/forwardRule/count',
     method: 'GET',
@@ -119,8 +119,8 @@ export const getLinkPage = (params: {page: number, pageSize: number, ruleLabel?:
   })
 }
 
-export const getLinkCount = (params: {status: boolean}) => {
-  return request<Number>({
+export const getLinkCount = (params?: {status: boolean}) => {
+  return request<number>({
     url: '/linkRule/count',
     method: 'GET',
     params
@@ -128,7 +128,7 @@ export const getLinkCount = (params: {status: boolean}) => {
 }
 
 export const updateLinkStatus = (data: {status: boolean, id: string}) => {
-  return request<Number>({
+  return request<number>({
     url: '/linkRule/status',
     method: 'PUT',
     data
@@ -136,14 +136,14 @@ export const updateLinkStatus = (data: {status: boolean, id: string}) => {
 }
 
 export const delLink = (id: string) => {
-  return request<Number>({
+  return request<number>({
     url: `/linkRule/${id}`,
     method: 'DELETE'
   })
 }
 
 export const updateLink = (data: IOT.API.RULE.LinkRuleBody) => {
-  return request<Number>({
+  return request<number>({
     url: '/linkRule',
     method: 'PUT',
     data

+ 58 - 0
src/components/CodeMirror/index.tsx

@@ -0,0 +1,58 @@
+import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue'
+
+import { basicSetup } from 'codemirror'
+import { EditorView } from '@codemirror/view'
+import { EditorState, StateEffect } from '@codemirror/state'
+import { javascript } from '@codemirror/lang-javascript'
+import { useId } from '@/hooks'
+// '{"paramName":"page","paramType":"int","paramDesc":"分页页码","require":true}'
+export const CodeMirrorTsx = defineComponent({
+  name: 'code-mirror-tsx',
+  props: {
+    bodyType: {
+      type: String,
+      default: 'javascript' //  javascript json
+    },
+    bodyJson: {
+      type: String,
+      default: ''
+    }
+  },
+  setup (props, ctx) {
+    const id = useId()
+
+    const state = reactive({})
+
+    const editorRef = ref()
+
+    console.log(JSON.stringify(JSON.parse(props.bodyJson)[0]))
+
+    const transDoc = () => {
+      return props.bodyType === 'javascript' ? props.bodyJson : JSON.stringify(JSON.parse(props.bodyJson), null, '\t')
+    }
+
+    const createView = () => {
+      const editorState = EditorState.create({
+        doc: transDoc(),
+        extensions: [basicSetup, javascript()]
+      })
+
+      const view = new EditorView({
+        state: editorState,
+        parent: document.getElementById(`editorRef-${id}`)!
+      })
+    }
+
+    onMounted(() => {
+      nextTick(() => {
+        setTimeout(() => {
+          createView()
+        }, 1000)
+      })
+    })
+
+    return () => (
+      <div ref="editorRef" id={`editorRef-${id}`}></div>
+    )
+  }
+})

+ 11 - 0
src/components/FormPro/index.vue

@@ -176,5 +176,16 @@ onMounted(() => {
 </script>
 
 <style lang="less" scope >
+:deep(.ant-form-inline .ant-form-item ){
+  margin-bottom: 10px !important;
+}
+
+::v-deep .ant-form-inline .ant-form-item  {
+  margin-bottom: 10px !important;
+}
 
+:deep(.ant-form-inline),
+:deep(.ant-form-item) {
+  margin-bottom: 10px !important;
+}
 </style>

+ 8 - 0
src/controller/common/common.ts

@@ -1,6 +1,14 @@
 import { getTransport } from '@/api/common'
 import { TransportEnum } from '@/enum/common'
 export class CommonController {
+  static dataTypeByKeyMap = new Map([
+    ['LONG', 'longValue'],
+    ['STRING', 'stringValue'],
+    ['JSON', 'jsonValue'],
+    ['DOUBLE', 'doubleValue'],
+    ['BOOLEAN', 'booleanValue']
+  ])
+
   static async getTransport () {
     const { data } = await getTransport()
     return Object.keys(data).map(key => {

+ 9 - 9
src/controller/iot/devOps.ts

@@ -2,15 +2,15 @@ import { getNoticePage, getStatsList, getWarnPage } from '@/api/iot/devOps'
 
 export class DevOpsController {
   static statsMap = new Map([
-    ['transportSuccessCounter', { name: '设备上报成功消息数', key: 'transportSuccessCounter' }],
-    ['transportFailCounter', { name: '设备上报失败消息数', key: 'transportFailCounter' }],
-    ['transportTotalCounter', { name: '设备上报总消息数', key: 'transportTotalCounter' }],
-    ['toTransportSuccessCounter', { name: '发送到设备成功消息数', key: 'toTransportSuccessCounter' }],
-    ['toTransportFailCounter', { name: '发送到设备失败消息数', key: 'toTransportFailCounter' }],
-    ['toTransportTotalCounter', { name: '发送到设备总消息数', key: 'toTransportTotalCounter' }],
-    ['transportReqSuccessCounter', { name: '设备请求成功消息数', key: 'transportReqSuccessCounter' }],
-    ['transportReqFailCounter', { name: '设备请求失败消息数', key: 'transportReqFailCounter' }],
-    ['transportReqTotalCounter', { name: '设备请求总消息数', key: 'transportReqTotalCounter' }]
+    ['transportSuccessCounter', { name: '设备上报成功消息数', key: 'transportSuccessCounter', aliasName: '成功消息数' }],
+    ['transportFailCounter', { name: '设备上报失败消息数', key: 'transportFailCounter', aliasName: '失败消息数' }],
+    ['transportTotalCounter', { name: '设备上报总消息数', key: 'transportTotalCounter', aliasName: '总消息数' }],
+    ['toTransportSuccessCounter', { name: '发送到设备成功消息数', key: 'toTransportSuccessCounter', aliasName: '成功消息数' }],
+    ['toTransportFailCounter', { name: '发送到设备失败消息数', key: 'toTransportFailCounter', aliasName: '失败消息数' }],
+    ['toTransportTotalCounter', { name: '发送到设备总消息数', key: 'toTransportTotalCounter', aliasName: '总消息数' }],
+    ['transportReqSuccessCounter', { name: '设备请求成功消息数', key: 'transportReqSuccessCounter', aliasName: '成功消息数' }],
+    ['transportReqFailCounter', { name: '设备请求失败消息数', key: 'transportReqFailCounter', aliasName: '失败消息数' }],
+    ['transportReqTotalCounter', { name: '设备请求总消息数', key: 'transportReqTotalCounter', aliasName: '总消息数' }]
   ])
 
   static async pageWarn (params: {duration: number, page: number, pageSize: number}) {

+ 4 - 0
src/controller/iot/device.ts

@@ -121,6 +121,10 @@ export class DeviceContriller {
     message.success('修改设备名称成功')
   }
 
+  static async count () {
+    return await getDeviceCount()
+  }
+
   /** 设备统计 */
   static async statistics (params: {modelId: string}) {
     const { data } = await getDeviceCount(params)

+ 5 - 1
src/controller/iot/model.ts

@@ -1,4 +1,4 @@
-import { addModel, addModelPlugin, debugModelPlugin, delModel, getModel, getModelById, getModelList, getModelPlugin, updateModelPlugin } from '@/api/iot/model'
+import { addModel, addModelPlugin, debugModelPlugin, delModel, getModel, getModelById, getModelCount, getModelList, getModelPlugin, updateModelPlugin } from '@/api/iot/model'
 import { message } from 'ant-design-vue'
 
 export class ModelController {
@@ -19,6 +19,10 @@ export class ModelController {
     message.success('新增成功')
   }
 
+  static async count () {
+    return await getModelCount()
+  }
+
   static put () {
 
   }

+ 9 - 1
src/controller/iot/rule.ts

@@ -1,4 +1,4 @@
-import { addForwardRule, addLink, delForward, delLink, getForwardById, getForwardRulePage, getLinkPage, getLinkPageById, updateForward, updateForwardStatus, updateLink, updateLinkStatus } from '@/api/iot/rule'
+import { addForwardRule, addLink, delForward, delLink, getForwardById, getForwardCount, getForwardRulePage, getLinkCount, getLinkPage, getLinkPageById, updateForward, updateForwardStatus, updateLink, updateLinkStatus } from '@/api/iot/rule'
 import { SubjectEventEnum, SubjectResourceEnum } from '@/enum/common'
 import { message } from 'ant-design-vue'
 
@@ -44,6 +44,10 @@ export class RuleController {
     message.success('编辑成功')
   }
 
+  static async forwardCount () {
+    return await getForwardCount()
+  }
+
   static async updateForwardStatus (params: { id: string, status: boolean}) {
     await updateForwardStatus(params)
     params.status ? message.success('规则已启动') : message.success('规则已停止')
@@ -77,4 +81,8 @@ export class RuleController {
   static async getLinkById (id: string) {
     return await getLinkPageById(id)
   }
+
+  static async linkCount () {
+    return await getLinkCount()
+  }
 }

+ 7 - 0
src/controller/rts/rts.ts

@@ -1,6 +1,13 @@
 import { getStreams } from '@/api/rts/stream'
 
 export class RtsController {
+  static StateMap = new Map([
+    [0, { name: '等待发布', key: 0 }],
+    [1, { name: '发布中', key: 1 }],
+    [2, { name: '等待关闭', key: 2 }],
+    [3, { name: '已经关闭', key: 3 }]
+  ])
+
   static async getStreams () {
     return getStreams()
   }

+ 12 - 0
src/hooks/effect.ts

@@ -37,3 +37,15 @@ export const useScheduler = (callback: () => void, delay: number) => {
     stop
   }
 }
+
+export const useSchedulerOnce = (callback: () => void, delay: number) => {
+  const timeId = ref()
+  timeId.value = setTimeout(() => {
+    callback()
+    clearTimeout(timeId.value)
+  }, delay)
+
+  onUnmounted(() => {
+    clearTimeout(timeId.value)
+  })
+}

+ 1 - 1
src/hooks/index.ts

@@ -1,3 +1,3 @@
-export { useEmitter, useScheduler } from './effect'
+export { useEmitter, useScheduler, useSchedulerOnce } from './effect'
 
 export { useId } from './state'

+ 55 - 27
src/pages/Iot/dashboard/deviceAccess/index.vue

@@ -2,22 +2,27 @@
     <a-card
       title="功能介绍"
     >
-      <a-row :gutter="[8, 8]" justify="space-between" >
-        <a-col :xs='24' :sm="24" :md='16' :lg="16" :xl="14" >
-          在物联网平台中,某一类具有相同能力或特征的设备的合集被称为一款产品模型(Profile)。
-          如果您希望使用平台查看设备上报的数据信息,并对设备进行管理控制,就需要开发产品模型(Profile)。<br/>
-          定义Profile,使平台理解该款设备支持的属性、命令等信息。根据产品的接入协议、数据格式等可能还需要您定义其他相关的内容。
-        </a-col>
-        <a-col :xs='24' :sm="24" :md='16' :lg="16" :xl="14" >
-          如果你希望对设备上报的数据做一些计算功能,比如将温度除以100并且保留2位小数点,可以采用属性的计算表达式功能,上述案例可以写成表达式 #tem/100.00。当然可以支持更多丰富的功能,具体使用参考SPEL使用手册。
-        </a-col>
-        <a-col :xs='24' :sm="24" :md='16' :lg="16" :xl="14" >
-          对于二进制的负载数据,支持JavaScript脚本开发完成数据解析,同时对于下发的命令也可以通过插件解析完成数据的encode。
-        </a-col>
-        <a-col :xs='24' :sm="24" :md='8' :lg="8" :xl="8" >
-          <img style="width: 100%" :src="staticImg.productIntroduction" alt="">
-        </a-col>
-      </a-row>
+    <a-row justify="space-between" :gutter="[8, 8]" >
+      <a-col :xs='24' :sm="24" :md='24' :lg="14" :xl="14" >
+        <a-row :gutter="[8, 8]" justify="space-between" >
+          <a-col :span="24"  >
+            在物联网平台中,某一类具有相同能力或特征的设备的合集被称为一款产品模型(Profile)。
+            如果您希望使用平台查看设备上报的数据信息,并对设备进行管理控制,就需要开发产品模型(Profile)。<br/>
+            定义Profile,使平台理解该款设备支持的属性、命令等信息。根据产品的接入协议、数据格式等可能还需要您定义其他相关的内容。
+          </a-col>
+          <a-col :span="24"  >
+            如果你希望对设备上报的数据做一些计算功能,比如将温度除以100并且保留2位小数点,可以采用属性的计算表达式功能,上述案例可以写成表达式 #tem/100.00。当然可以支持更多丰富的功能,具体使用参考SPEL使用手册。
+          </a-col>
+          <a-col :span="24"   >
+            对于二进制的负载数据,支持JavaScript脚本开发完成数据解析,同时对于下发的命令也可以通过插件解析完成数据的encode。
+          </a-col>
+        </a-row>
+      </a-col>
+      <a-col :xs='24' :sm="24" :md='24' :lg="8" :xl="8" >
+        <img style="width: 100%" :src="staticImg.productIntroduction" alt="">
+      </a-col>
+    </a-row>
+
     </a-card>
 
     <!-- 协议 -->
@@ -27,7 +32,6 @@
       <table-pro
         :request="CommonController.getTransport"
         :columns="columns"
-
       />
     </a-card>
 
@@ -48,17 +52,13 @@
 </template>
 
 <script setup lang="ts" >
-import { CommonController } from '@/controller/index'
+import { CommonController, DeviceContriller, ModelController, RuleController } from '@/controller/index'
 import { useStaticImg } from '@/utils/static'
+import { onMounted, reactive } from 'vue'
 
 const staticImg = useStaticImg()
 
 const columns = [
-  {
-    title: '接入协议(端口号)',
-    dataIndex: 'port',
-    key: 'port'
-  },
   {
     title: '接入地址',
     dataIndex: 'address',
@@ -77,10 +77,10 @@ const columns = [
   }
 ]
 
-const sourceList = [
+const sourceList = reactive([
   {
     name: '产品数',
-    value: 13
+    value: '13'
   },
   {
     name: '联动规则',
@@ -88,7 +88,7 @@ const sourceList = [
   },
   {
     name: '转发规则',
-    value: 7
+    value: '7'
   },
   {
     name: '设备总数',
@@ -102,7 +102,35 @@ const sourceList = [
     name: '激活设备总数',
     value: 88
   }
-]
+])
+
+const getStatisList = async () => {
+  ModelController.count().then(r => {
+    console.log('ModelController:', r.data)
+    sourceList[0].value = r.data.TOTAL
+  })
+
+  DeviceContriller.count().then(r => {
+    console.log('DeviceContriller', r.data)
+    sourceList[3].value = r.data.TOTAL
+    sourceList[4].value = r.data.CONNECT
+    sourceList[5].value = r.data.INIT
+  })
+
+  RuleController.forwardCount().then(r => {
+    sourceList[1].value = r.data
+    console.log('RuleController:', r.data)
+  })
+
+  RuleController.linkCount().then(r => {
+    sourceList[2].value = r.data
+    console.log('RuleController:', r.data)
+  })
+}
+
+onMounted(() => {
+  getStatisList()
+})
 
 </script>
 

+ 61 - 3
src/pages/Iot/dataServer/openApi.vue

@@ -51,6 +51,9 @@
         <div>{{record.apiResponseDescription}}</div>
       </a-tooltip>
     </template>
+    <template v-if="column.key === 'action'" >
+      <a @click="openDetailModel(record)" >详情</a>
+    </template>
   </template>
   </a-table>
 </a-card>
@@ -61,14 +64,53 @@
   @cancel="state.visible = false"
   @ok="ok"
 >
-  <a-input v-model:value="state.appId" ></a-input>
+  <a-input v-model:value="state.appId"  ></a-input>
 </modal-pro>
 
+<a-drawer
+  style="{width: 600px;}"
+  size="large"
+  title="api详情"
+  v-model:visible="state.detailVisible"
+  destroyOnClose
+  @close="state.spnningLoading = true"
+>
+<a-spin :spinning="state.spnningLoading" >
+
+  <a-card :loading="state.spnningLoading" style="height: 2000px;overflow: hidden;overflow-y: scroll;" >
+    <a-form  style="height: 3000px;">
+      <a-form-item label="api名称" >
+        <span>{{state.openApiDetail.apiLabel}}</span>
+      </a-form-item>
+      <a-form-item label="api地址" >
+        <span>{{state.openApiDetail.apiUrl}}</span>
+      </a-form-item>
+      <a-form-item label="api描述" >
+        <span>{{state.openApiDetail.apiDescription}}</span>
+      </a-form-item>
+      <a-form-item label="请求参数" >
+        <CodeMirrorTsx :body-json="state.openApiDetail.apiParameters" body-type="json" />
+      </a-form-item>
+      <a-form-item label="请求参数描述" >
+        <span>{{state.openApiDetail.apiParametersDescription}}</span>
+      </a-form-item>
+      <a-form-item label="响应参数" >
+        <CodeMirrorTsx :body-json="state.openApiDetail.apiResponse" body-type="json" />
+      </a-form-item>
+      <a-form-item label="响应描述" >
+        <span>{{state.openApiDetail.apiResponseDescription}}</span>
+      </a-form-item>
+    </a-form>
+  </a-card>
+</a-spin>
+  </a-drawer>
 </template>
 <script lang='ts' setup >
 import { DataController } from '@/controller/iot/data'
 import { message } from 'ant-design-vue'
 import { onMounted, reactive } from 'vue'
+import { CodeMirrorTsx } from '@/components/CodeMirror/index'
+import { useSchedulerOnce } from '@/hooks/index'
 
 const columns = [
   {
@@ -99,7 +141,7 @@ const columns = [
     ellipsis: true
   },
   {
-    title: '响应',
+    title: '响应参数',
     dataIndex: 'apiResponse',
     key: 'apiResponse',
     ellipsis: true
@@ -109,6 +151,10 @@ const columns = [
     dataIndex: 'apiResponseDescription',
     key: 'apiResponseDescription',
     ellipsis: true
+  },
+  {
+    title: '操作',
+    key: 'action'
   }
 ]
 
@@ -123,9 +169,21 @@ const state = reactive({
   loading: false,
   appId: '',
   visible: false,
-  dataSource: []
+  detailVisible: false,
+  openApiDetail: {},
+  dataSource: [],
+  spnningLoading: false
 })
 
+const openDetailModel = (record: any) => {
+  state.openApiDetail = record
+  state.detailVisible = true
+  useSchedulerOnce(() => {
+    state.spnningLoading = false
+    console.log('state.spnningLoading:', state.spnningLoading)
+  }, 1000)
+}
+
 const openModal = () => {
   state.visible = true
 }

+ 122 - 11
src/pages/Iot/devOps/statistReport.vue

@@ -1,34 +1,139 @@
 <template>
-<a-card>
-  <a-row :gutter="[8, 8]" justify="space-between" >
+    <!-- <a-row :gutter="[8, 8]" justify="space-between" >
     <a-col :lg="5" :sm="1" :md="3"  v-for="item in state.statsSource" :key="item.key">
       <a-card style="width: 300px" :title="item.name" >
         <div style="font-size: 18px;" >{{item.value}}</div>
       </a-card>
     </a-col>
+  </a-row> -->
+  <a-row :gutter="[8, 8]">
+    <a-col :xl="12" :xs="24" :md="24" >
+      <a-card>
+  <template #title >
+    <upload-outlined /> 数据监控
+  </template>
+  <a-row style="width: 100%;" >
+    <a-col :span="8" >
+      <div class="statis-item" >
+        <div>{{state.statsSource.transportSuccessCounter?.value}}</div>
+        <div><check-circle-two-tone  two-tone-color="#52c41a"  /> {{state.statsSource.transportSuccessCounter?.name}}</div>
+      </div>
+    </a-col>
+    <a-col :span="8" >
+      <div class="statis-item" >
+        <div>{{state.statsSource.transportFailCounter?.value}}</div>
+        <div> <close-circle-two-tone two-tone-color="#eb2f96" /> {{ state.statsSource.transportFailCounter?.name }}</div>
+      </div>
+    </a-col>
+    <a-col :span="8">
+      <div class="statis-item" >
+        <div>{{state.statsSource.transportTotalCounter?.value}}</div>
+        <div><pie-chart-two-tone /> {{state.statsSource.transportTotalCounter?.name}}</div>
+      </div>
+    </a-col>
+  </a-row>
+      </a-card>
+    </a-col>
+    <a-col :xl="12" :xs="24" :md="24" >
+      <a-card>
+  <template #title >
+    <pull-request-outlined  color="#eb2f96" />设备请求
+  </template>
+  <a-row>
+    <a-col :span="8" >
+      <div class="statis-item" >
+        <div>{{state.statsSource.transportReqSuccessCounter?.value}}</div>
+        <div> <check-circle-two-tone  two-tone-color="#52c41a"/> {{ state.statsSource.transportReqSuccessCounter?.name }}</div>
+      </div>
+    </a-col>
+    <a-col :span="8" >
+      <div class="statis-item" >
+        <div>{{state.statsSource.transportReqFailCounter?.value}}</div>
+        <div> <close-circle-two-tone two-tone-color="#eb2f96" /> {{ state.statsSource.transportReqFailCounter?.name }}</div>
+      </div>
+    </a-col>
+    <a-col :span="8" >
+      <div class="statis-item" >
+        <div>{{state.statsSource.transportReqFailCounter?.value}}</div>
+        <div><pie-chart-two-tone /> {{state.statsSource.transportReqFailCounter?.name}}</div>
+      </div>
+    </a-col>
   </a-row>
-</a-card>
+      </a-card>
+    </a-col>
+    <a-col :xl="12" :xs="24" :md="24" >
+      <a-card>
+        <template #title >
+          <video-camera-add-outlined /> 发送到设备
+        </template>
+        <a-row>
+          <a-col :span="8" >
+            <div class="statis-item" >
+              <div>{{ state.statsSource.toTransportSuccessCounter?.value }}</div>
+              <div> <check-circle-two-tone  two-tone-color="#52c41a"/> {{ state.statsSource.toTransportSuccessCounter?.name }}</div>
+            </div>
+          </a-col>
+          <a-col :span="8" >
+            <div class="statis-item" >
+              <div>{{ state.statsSource.toTransportFailCounter?.value }}</div>
+              <div> <close-circle-two-tone two-tone-color="#eb2f96" /> {{ state.statsSource.toTransportFailCounter?.name }}</div>
+            </div>
+          </a-col>
+          <a-col :span="8" >
+            <div class="statis-item" >
+              <div>{{ state.statsSource.toTransportTotalCounter?.value }}</div>
+              <div><pie-chart-two-tone /> {{state.statsSource.toTransportTotalCounter?.name}}</div>
+            </div>
+          </a-col>
+        </a-row>
+      </a-card>
+    </a-col>
+  </a-row>
+<!-- <check-circle-outlined /> -->
+<!-- <close-circle-outlined /> -->
+<!-- <pie-chart-outlined /> -->
+<!-- <check-circle-two-tone /> -->
 </template>
 <script lang='ts' setup >
 import { DevOpsController } from '@/controller/iot/devOps'
 import { onMounted, reactive } from 'vue'
+import {
+  UploadOutlined, PullRequestOutlined, VideoCameraAddOutlined,
+  CheckCircleTwoTone, CloseCircleTwoTone, PieChartTwoTone
+} from '@ant-design/icons-vue'
+// {key: string, name: string, value: string}[]
 
-const state = reactive<{
-  statsSource: {key: string, name: string, value: string}[]
-}>({
-  statsSource: []
+const state = reactive < {
+  statsSource: Partial<Record<IOT.API.DEVOPS.statsType, {
+    key: string,
+    name: string,
+    value: string
+  }>>
+} > ({
+  statsSource: {}
 })
 
 const getStats = async () => {
   const { data } = await DevOpsController.pageStats()
-  state.statsSource = data.map(item => {
-    return {
+  const obj: Record<string, any> = {}
+
+  data.forEach(item => {
+    obj[item.label] = {
       key: item.label,
-      name: DevOpsController.statsMap.get(item.label)?.name,
+      name: DevOpsController.statsMap.get(item.label)?.aliasName,
       value: item.dataValue
     }
   })
-  console.log(state.statsSource)
+
+  state.statsSource = obj
+  // state.statsSource = data.map(item => {
+  //   return {
+  //     key: item.label,
+  //     name: DevOpsController.statsMap.get(item.label)?.name,
+  //     value: item.dataValue
+  //   }
+  // })
+  console.log()
 }
 
 onMounted(() => {
@@ -37,4 +142,10 @@ onMounted(() => {
 
 </script>
 <style lang='less' scoped >
+.statis-item {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+}
 </style>

+ 17 - 8
src/pages/Iot/device/components/deviceShadow.vue

@@ -24,18 +24,30 @@
         :columns="columns"
         :data-source="state.shadowList"
       >
-
+      <template #bodyCell="{column, record}" >
+        <template v-if="column.key === 'value'"  >
+            {{record[CommonController.dataTypeByKeyMap.get(record.dataType)]}}
+        </template>
+      </template>
       </a-table>
   </a-card>
 </template>
 
 <script lang="ts" setup >
+import { CommonController, DeviceContriller } from '@/controller'
 import { ReloadIconTsx } from '@/components/MicroComponents/index'
-import { DeviceContriller } from '@/controller'
 import { onMounted, reactive } from 'vue'
 import { useRoute } from 'vue-router'
 
 const columns = [
+  {
+    title: 'key',
+    dataIndex: 'key'
+  },
+  {
+    title: 'keyLabel',
+    dataIndex: 'keyLabel'
+  },
   {
     title: '数据类型',
     dataIndex: 'dataType'
@@ -45,12 +57,9 @@ const columns = [
     dataIndex: 'dataUnit'
   },
   {
-    title: 'keyLabel',
-    dataIndex: 'keyLabel'
-  },
-  {
-    title: '字符值',
-    dataIndex: 'stringValue'
+    title: '值',
+    dataIndex: 'value',
+    key: 'value'
   }
 ]
 

+ 6 - 5
src/pages/Iot/device/components/overview.vue

@@ -35,23 +35,24 @@
       <!-- <a-col><a-button type="primary" >查看全部属性</a-button></a-col> -->
     </a-row>
 
-    <a-row :gutter="[8, 8]" >
+    <a-row :gutter="[8, 8]" style="width: 100%;" >
       <a-col :span="24" v-if="state.liveDataSource.length === 0" >
         <a-empty></a-empty>
       </a-col>
-      <span v-else >
+      <template v-else >
         <a-col
         :lg="8" :md="8" :sm="24"
         v-for="(item, index) in state.liveDataSource"
         :key="item.ts"
       >
           <div class="data">
+            <div>{{item.key}}</div>
             <div>{{item.keyLabel}}</div>
-            <div> {{`<${item.key}:>`}}</div>
+            <div> <span>{{'<'}} {{item[CommonController.dataTypeByKeyMap.get(item.dataType)]}}</span> <span v-if='item.dataUnit'>{{item.dataUnit}}</span> {{'>'}}</div>
             <div>{{dayjs(item.ts).format('YYYY/MM/DD HH:MM:ss')}}</div>
           </div>
         </a-col>
-      </span>
+      </template>
     </a-row>
 
   <modal-pro
@@ -65,7 +66,7 @@
 </template>
 
 <script lang="ts" setup >
-import { DeviceContriller } from '@/controller'
+import { CommonController, DeviceContriller } from '@/controller'
 import { useScheduler } from '@/hooks'
 import { onMounted, reactive } from 'vue'
 import { useRoute } from 'vue-router'

+ 1 - 1
src/pages/Iot/model/components/plugins.vue

@@ -43,7 +43,7 @@
 <script lang='ts' setup >
 import { basicSetup } from 'codemirror'
 import { EditorView } from '@codemirror/view'
-import { EditorState, StateEffect } from '@codemirror/state'
+import { EditorState } from '@codemirror/state'
 import { javascript } from '@codemirror/lang-javascript'
 import { ref, onMounted, reactive } from 'vue'
 import { ModelCmdController, ModelController } from '@/controller'

+ 5 - 1
src/pages/Iot/rule/linkRules.vue

@@ -1,7 +1,11 @@
 <template>
   <a-card>
     <a-row justify="space-between" >
-      <a-col>
+      <a-col :span="12" >
+        <a-space>
+          <a-input placeholder="请填写规则名称" v-model:value="queryParamsState.ruleLabel" ></a-input>
+          <a-button type="primary" @click="getLinkPage()" >搜索</a-button>
+        </a-space>
       </a-col>
       <a-col>
         <a-space>

+ 21 - 3
src/pages/rts/stream/index.vue

@@ -1,6 +1,22 @@
 <template>
   <a-card>
-
+    <a-row>
+      <a-col></a-col>
+    </a-row>
+    <a-table
+      :loading="state.loading"
+      :columns="columns"
+      :data-source="state.dataSource"
+    >
+      <template #bodyCell="{column, record}" >
+        <template v-if="column.key === 'action'"  >
+          <a-space>
+            <a>编辑</a>
+            <a>关闭视频流</a>
+          </a-space>
+        </template>
+      </template>
+    </a-table>
   </a-card>
 </template>
 
@@ -55,11 +71,13 @@ const queryParamsState = reactive({
 })
 
 const state = reactive({
-  loading: false
+  loading: false,
+  dataSource: []
 })
 
 const getStreamList = async () => {
-  await RtsController.getStreams()
+  const { data } = await RtsController.getStreams()
+  state.dataSource = data
 }
 
 onMounted(() => {

+ 1 - 1
src/router/index.ts

@@ -85,7 +85,7 @@ const routes: Array<ROUTER.RoutesProps> = [
         children: [
           {
             path: '/devOps/report',
-            name: '统计报表',
+            name: '数据监控',
             component: () => import('@/pages/iot/devOps/statistReport.vue')
           },
           {

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

@@ -274,6 +274,11 @@ declare namespace IOT {
     }
 
     namespace DEVOPS {
+
+      type statsType = 'transportSuccessCounter' | 'transportFailCounter'
+      | 'transportTotalCounter' | 'toTransportSuccessCounter' | 'toTransportFailCounter'
+      | 'toTransportTotalCounter'| 'transportReqSuccessCounter'| 'transportReqFailCounter'| 'transportReqTotalCounter'
+
       interface Notice {
         entityId: string,
         id: string