Bladeren bron

Merge branch 'master' of https://e.coding.net/jiaolongcloud/cloudlink/cloudlink-ui

lvkun996 1 jaar geleden
bovenliggende
commit
1bd52378c1

+ 16 - 1
src/api/iot/data.ts

@@ -29,10 +29,25 @@ export const getAppId = () => {
   })
 }
 
-export const postAppId = (data: {appId: string}) => {
+export const delAppIdById = (id: string) => {
+  return request<string>({
+    url: '/dataApi/appId/' + id,
+    method: 'DELETE'
+  })
+}
+
+export const postAppId = (data: any) => {
   return request<string>({
     url: '/dataApi/appId',
     method: 'POST',
     data
   })
 }
+
+export const updateAppId = (data: any) => {
+  return request<string>({
+    url: '/dataApi/appId',
+    method: 'PUT',
+    data
+  })
+}

+ 11 - 1
src/controller/iot/data.ts

@@ -1,4 +1,4 @@
-import { getAppId, getDataApiPage, getHistoryDataPage, postAppId } from '@/api/iot/data'
+import { getAppId, getDataApiPage, getHistoryDataPage, postAppId, delAppIdById, updateAppId } from '@/api/iot/data'
 import { message } from 'ant-design-vue'
 
 export class DataController {
@@ -14,8 +14,18 @@ export class DataController {
     return await getAppId()
   }
 
+  static async delAppIdById (id: string) {
+    const { code, msg } = await delAppIdById(id)
+    code === 200 ? message.success('删除成功') : message.error(msg)
+  }
+
   static async postAppId (data: {appId: string}) {
     await postAppId(data)
     message.success('创建Appid成功')
   }
+
+  static async updateAppId (data: {appId: string}) {
+    await updateAppId(data)
+    message.success('编辑Appid成功')
+  }
 }

+ 151 - 0
src/pages/Iot/dataServer/apis.vue

@@ -0,0 +1,151 @@
+<template>
+  <a-card>
+    <a-row justify="space-between" >
+      <a-col>
+        <a-space>
+
+        </a-space>
+      </a-col>
+      <a-col>
+        <a-tag color="blue" v-if="state.appId" style="scale: 1.2;" >appid: {{state.appId}}</a-tag>
+        <a-button v-else type="primary" @click="openModal('add', {})" >创建Appid</a-button>
+      </a-col>
+    </a-row>
+    <a-table
+      :columns="columns"
+      :loading="state.loading"
+      :data-source="state.dataSource"
+      style="margin-top: 20px;"
+      :pagination="false"
+    >
+    <template #bodyCell="{column, record}" >
+      <template v-if="column.key === 'createAt'" >
+        <div>{{ dayjs(record.createAt).format('YYYY/MM/DD HH:mm:ss')}}</div>
+      </template>
+      <template v-if="column.key === 'action'" >
+        <a-space>
+          <!-- <a @click="openModal('update', record)" >编辑</a> -->
+          <a @click="delApiId(record)" >删除</a>
+        </a-space>
+
+      </template>
+    </template>
+    </a-table>
+  </a-card>
+
+  <modal-pro
+    title="创建Appid"
+    :open="state.visible"
+    @cancel="state.visible = false"
+    @ok="ok"
+  >
+    <a-form  :labelCol="{span: 6}" :wrapperCol="{span: 14}" >
+      <a-form-item label="appid" v-bind="validateInfos.appId"  >
+        <a-input allowClear v-model:value="appidState.appId" />
+      </a-form-item>
+      <a-form-item label="appid名称" v-bind="validateInfos.appIdLabel"  >
+        <a-input allowClear v-model:value="appidState.appIdLabel" />
+      </a-form-item>
+    </a-form>
+  </modal-pro>
+
+  </template>
+<script lang='ts' setup >
+import { DataController } from '@/controller/iot/data'
+import { Form } from 'ant-design-vue'
+import { onMounted, reactive, ref } from 'vue'
+import { useSchedulerOnce } from '@/hooks/index'
+import dayjs from 'dayjs'
+
+const useForm = Form.useForm
+
+const columns = [
+  {
+    title: 'appId名称',
+    dataIndex: 'appIdLabel'
+  },
+  {
+    title: 'appId',
+    dataIndex: 'appId'
+  },
+  {
+    title: '创建时间',
+    dataIndex: 'createAt',
+    key: 'createAt'
+  },
+  {
+    title: '操作',
+    key: 'action'
+  }
+]
+
+const queryParams = reactive({
+  page: 1,
+  pageSize: 10,
+  total: 0,
+  apiLabel: ''
+})
+
+const state = reactive({
+  loading: false,
+  appId: '',
+  visible: false,
+  detailVisible: false,
+  openApiDetail: {},
+  dataSource: [],
+  spnningLoading: false
+})
+
+const appidState = reactive({
+  id: '',
+  appId: '',
+  appIdLabel: ''
+})
+
+const { resetFields, validate, validateInfos } = useForm(appidState, {
+  appId: [{ required: true, message: '请填写appid' }],
+  appIdLabel: [{ required: true, message: '请填写id名称' }]
+})
+
+const delApiId = async (record: any) => {
+  await DataController.delAppIdById(record.id)
+  getAppid()
+}
+
+const openDetailModel = (record: any) => {
+  state.openApiDetail = record
+  state.detailVisible = true
+  useSchedulerOnce(() => {
+    state.spnningLoading = false
+    console.log('state.spnningLoading:', state.spnningLoading)
+  }, 1000)
+}
+
+const opraState = ref<'add' | 'update'>('add')
+
+const openModal = (type: 'add' | 'update', record: any) => {
+  state.visible = true
+  opraState.value = type
+  resetFields(record)
+}
+
+const ok = async () => {
+  validate().then(async () => {
+    opraState.value === 'add' ? await DataController.postAppId(appidState) : await DataController.updateAppId(appidState)
+    state.visible = false
+    getAppid()
+  })
+}
+
+const getAppid = async () => {
+  const { data } = await DataController.getAppId()
+  state.dataSource = data
+}
+
+onMounted(() => {
+  getAppid()
+})
+
+</script>
+  <style lang='less' scoped >
+  </style>

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

@@ -8,8 +8,8 @@
       </a-space>
     </a-col>
     <a-col>
-      <a-tag color="blue" v-if="state.appId" style="scale: 1.2;" >appid: {{state.appId}}</a-tag>
-      <a-button v-else type="primary" @click="openModal" >创建Appid</a-button>
+      <!-- <a-tag color="blue" v-if="state.appId" style="scale: 1.2;" >appid: {{state.appId}}</a-tag> -->
+      <!-- <a-button v-else type="primary" @click="openModal" >创建Appid</a-button> -->
     </a-col>
   </a-row>
   <a-table
@@ -205,7 +205,7 @@ const changePage = ({ current }) => {
 
 const getAppid = async () => {
   const { data } = await DataController.getAppId()
-  state.appId = data
+  state.appId = data.length === 0 ? '' : data
 }
 
 const getOpenApiPage = async () => {

+ 2 - 1
src/pages/Iot/devOps/onlineTest.vue

@@ -174,7 +174,6 @@
                     title="设备模拟器"
                     style="width: 100%;height: 316px;margin-top: 10px;position: relative;"
                  >
-
                     <a-textarea
                         v-model:input="simulatorState.input"
                         :placeholder="placeholder"
@@ -336,6 +335,8 @@ const handleSelectDevice = () => {
   if (_device) {
     state.device = _device
     state.drawerVisible = false
+    simulatorState.searchDeviceLabel = _device.deviceLabel
+    simulatorState.deviceId = _device.id
   } else {
     message.warn('请选择产品')
   }

+ 52 - 15
src/pages/Iot/device/analysis.vue

@@ -1,8 +1,4 @@
 <template>
-  <!-- <statistics-template
-    title="上下线统计"
-    :list="[{value: 20, color: 'green', label: '上线次数'}, {value: 20, color: 'red', label: '下线次数'}]"
-  /> -->
   <a-card
     style="margin-top: 20px;"
     title="设备分析"
@@ -28,6 +24,7 @@
                 :options="state.deviceLit"
                 @search="getDeviceLabel"
                 @change="selectDevice"
+                allowClear
               >
                 <template v-if="state.fetching" #notFoundContent>
                   <a-spin size="small" />
@@ -71,13 +68,25 @@
           <a-spin :spinning="state.loading" >
           <a-empty style="margin: 0 auto;" v-if="emptyCondition" :description="emptyDesc" ></a-empty>
           <span v-else>
-            <a-col :span="24" v-if="activeTabKey === 'session'">
-              <a-row>
-                <a-col :xs="24" :md="24" :xl="12" >
-                  <div id="device-session" style="width: 600px;height: 400px;" ></div>
+
+            <a-col :span="24" v-if="activeTabKey === 'session'" style="margin-top: 20px">
+              <a-row  >
+                <a-col :xs="24" :md="24" :xl="12"  style="position: relative;width: 100%;height: 400px;" >
+                  <!-- <div style="position: absolute;right: 0;top: 0;z-index: 99;width: 40px;height: 60px" >
+                    <a-space>
+                      <a-button :type="lineChartZindex.line > lineChartZindex.bar ? 'primary' : ''"  :icon="h(LineChartOutlined)"  @click="changeChart('line')"/>
+                      <a-button :type="lineChartZindex.line <= lineChartZindex.bar ? 'primary' : ''"  :icon="h(BarChartOutlined)"  @click="changeChart('bar')"/>
+                    </a-space>
+                  </div> -->
+                  <div id="device-session" :style="{backgroundColor: '#fff', width: '600px',height: '400px',position: 'absolute',top: '0',left: 0,zIndex: lineChartZindex.line}" ></div>
+                  <div id="device-session-scatter" :style="{backgroundColor: '#fff',width: '600px',height: '400px',position: 'absolute',top: '0',left: 0,zIndex: lineChartZindex.bar}" ></div>
                 </a-col>
-                <a-col :xs="24" :md="24" :xl="12">
-                  <div id="device-session-scatter" style="width: 600px;height: 400px;" ></div>
+                <a-col :xs="24" :md="24" :xl="12" >
+                  <a-table
+                    :dataSource="state.dataSource"
+                    :columns="lineCloumns"
+                  >
+                  </a-table>
                 </a-col>
               </a-row>
             </a-col>
@@ -105,13 +114,14 @@
 </template>
 <script lang='ts' setup >
 import { DeviceContriller } from '@/controller'
-import { reactive, watch, computed, ref, onMounted, watchEffect, nextTick } from 'vue'
+import { reactive, watch, computed, ref, onMounted, watchEffect, nextTick, h } from 'vue'
 import * as echarts from 'echarts'
 import { useRoute } from 'vue-router'
 import { sessionEchartsJson, attrEchartsJson, scatterOption, barOption, calculateAverage } from './json/echartsJson'
 import dayjs from 'dayjs'
 import StatisticsTemplate from '@/components/StatisticsTemplate'
 import { message } from 'ant-design-vue'
+import { LineChartOutlined, BarChartOutlined } from '@ant-design/icons-vue'
 import { useThrottle } from 'flicker-vue-hooks'
 
 const columns = [
@@ -175,6 +185,30 @@ const aggregationFunc = [
   }
 ]
 
+const lineCloumns = [
+  {
+    title: '创建时间',
+    dataIndex: 'createAt',
+    key: 'createAt'
+  },
+  {
+    title: '连接状态',
+    dataIndex: 'sessionType',
+    key: 'sessionType'
+  }
+]
+
+const lineChartZindex = ref({
+  line: 1,
+  bar: 0
+})
+
+const changeChart = (chart: 'line' | 'bar') => {
+  if (lineChartZindex.value.line > lineChartZindex.value.bar && chart === 'line') return
+  if (lineChartZindex.value.line <= lineChartZindex.value.bar && chart === 'bar') return
+  chart === 'line' ? lineChartZindex.value.line++ : lineChartZindex.value.bar++
+}
+
 const route = useRoute()
 
 const activeTabKey = ref<'session' | 'attr' | 'poly'>('session')
@@ -304,7 +338,6 @@ watch(
 // 选择属性
 const selectAttr = (value: string) => {
   state.attributeKey = value
-  // getDeviceAttr()
 }
 
 const search = () => {
@@ -317,9 +350,13 @@ const search = () => {
 
 // 选择设备
 const selectDevice = async (value: string) => {
-  const device = await DeviceContriller.byId(value)
-  state.deviceId = device.id
-  getDeviceAttribute()
+  console.log('value:', value)
+
+  // const device = await DeviceContriller.byId(value)
+  state.deviceId = value
+  console.log('选择了设备')
+
+  // getDeviceAttribute()
 }
 
 // 获取设备列表

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

@@ -19,7 +19,7 @@
     <SubDevice @goDetail="goDetail" v-else-if="state.tabsActive === '5'" />
     <DeviceTag @goDetail="goDetail" v-else-if="state.tabsActive === '6'" />
     <Ota v-else-if="state.tabsActive === '7'" />
-    <Live v-else-if="state.tabsActive === '8'" />
+    <!-- <Live v-else-if="state.tabsActive === '8'" /> -->
   </a-card>
 </template>
 

+ 5 - 1
src/pages/Iot/device/index.vue

@@ -112,6 +112,9 @@
       <a-form-item label="设备名称" >
         <a-input allowClear v-model:value="deviceState.deviceLabel" />
       </a-form-item>
+      <a-form-item label="设备地址" >
+        <a-input allowClear v-model:value="deviceState.deviceAddress" />
+      </a-form-item>
       <a-form-item label="设备认证类型" >
         <a-radio-group v-model:value="deviceState.deviceAuthType">
           <a-radio value="SECRET">密钥认证</a-radio>
@@ -251,7 +254,8 @@ const deviceState = reactive({
   deviceAuthType: DeviceAuthTypeEnum.SECRET,
   modelLabel: '',
   deviceSecret: '',
-  confirmSecret: ''
+  confirmSecret: '',
+  deviceAddress: ''
 })
 
 const { resetFields, validate, validateInfos } = useForm(searchState, {})

+ 16 - 3
src/pages/Iot/model/components/modelDefine.vue

@@ -192,9 +192,12 @@
     cancel-text="取消"
   >
   <a-form :label-col="{span: 4}" :wrapper-col="{span: 18}" >
-      <a-form-item label="参数名称" v-bind="validateInfosCmdP.paramLabel" >
+      <a-form-item label="参数名称"  >
         <a-input placeholder="请填写参数名称" v-model:value="cmdParamsRef.paramLabel"  />
       </a-form-item>
+      <a-form-item label="参数code" v-bind="validateInfosCmdP.paramCode" >
+        <a-input placeholder="请填写参数名称" v-model:value="cmdParamsRef.paramCode"  />
+      </a-form-item>
       <a-form-item label="数据类型" v-bind="validateInfosCmdP.dataType" >
         <a-select allowClear v-model:value="cmdParamsRef.dataType" >
           <a-select-option :value="item.value" v-for="item in dataTypes" :key="item.value" >
@@ -216,7 +219,6 @@ import { nextTick, onMounted, reactive } from 'vue'
 import { Form } from 'ant-design-vue'
 import { useRoute } from 'vue-router'
 import { useId } from '@/hooks'
-import { Item } from 'ant-design-vue/es/menu'
 
 const columns = [
   {
@@ -261,6 +263,11 @@ const columnsCmd = [
     key: 'cmdLabel',
     dataIndex: 'cmdLabel'
   },
+  {
+    title: '命令code',
+    key: 'cmdCode',
+    dataIndex: 'cmdCode'
+  },
   {
     title: '下发参数',
     key: 'cmdParams',
@@ -283,6 +290,11 @@ const columnsCmdParams = [
     key: 'paramLabel',
     dataIndex: 'paramLabel'
   },
+  {
+    title: '参数code',
+    key: 'paramCode',
+    dataIndex: 'paramCode'
+  },
   {
     title: '数据类型',
     key: 'dataType',
@@ -389,6 +401,7 @@ const cmdRef = reactive({
 
 const cmdParamsRef = reactive({
   id: '',
+  paramCode: '',
   paramLabel: '',
   description: '',
   dataType: ''
@@ -406,7 +419,7 @@ const { resetFields: resetFieldsCmd, validate: validateCmd, validateInfos: valid
 })
 
 const { resetFields: resetFieldsCmdP, validate: validateCmdP, validateInfos: validateInfosCmdP } = useForm(cmdParamsRef, {
-  paramLabel: [{ require: true, message: '请填写参数名称' }],
+  paramCode: [{ require: true, message: '请填写参数名称' }],
   dataType: [{ require: true, message: '请选择数据类型' }]
 })
 

+ 4 - 4
src/pages/Iot/model/index.vue

@@ -111,9 +111,9 @@
     <a-form-item label="厂商描述">
       <a-textarea  :disabled="formOptions.disabled" v-model:value="modelRef.modelDescription" />
     </a-form-item>
-    <a-form-item label="支持视频流">
+    <!-- <a-form-item label="支持视频流">
       <a-switch v-model:checked="modelRef.rts" checked-children="支持" un-checked-children="不支持" />
-    </a-form-item>
+    </a-form-item> -->
    </a-form>
   </a-modal>
 </template>
@@ -212,8 +212,8 @@ const modelRef = reactive({
   transportType: null,
   payloadType: null,
   deviceType: '',
-  modelDescription: '',
-  rts: false
+  modelDescription: ''
+  // rts: false
 })
 
 const rulesRef = reactive({

+ 9 - 4
src/pages/Iot/rule/components/selectDevice.vue

@@ -1,4 +1,3 @@
-
 <template>
 <a-card :bordered="false"   style="height: 600px;overflow: hidden;overflow-y: scroll;">
   <a-row>
@@ -19,7 +18,6 @@
     :columns="columns"
     :data-source="state.dataSource"
     :pagination="state.queryParams"
-
     :rowSelection="{
       type: 'radio',
       selectedRowKeys: state.selectedRowKeys,
@@ -57,6 +55,12 @@ const columns = [
   }
 ]
 
+interface IProps {
+  modelId?: string
+}
+
+const props = defineProps<IProps>()
+
 const state = reactive({
   loading: false,
   dataSource: [],
@@ -68,7 +72,8 @@ const state = reactive({
     size: 'small',
     searchKey: 'deviceLabel',
     searchValue: '',
-    showSizeChanger: false
+    showSizeChanger: false,
+    modelId: ''
   }
 })
 
@@ -86,7 +91,6 @@ const getDevicePage = async () => {
   const { data, sum } = await DeviceContriller.page(state.queryParams)
   state.dataSource = data
   state.queryParams.total = sum
-  console.log('sum:', sum)
 }
 
 defineExpose({
@@ -94,6 +98,7 @@ defineExpose({
 })
 
 onMounted(() => {
+  if (props.modelId) state.queryParams.modelId = props.modelId
   getDevicePage()
 })
 

+ 11 - 2
src/pages/Iot/rule/linkRules.vue

@@ -678,17 +678,18 @@
   </modal-pro>
 
   <a-drawer
-    title="选择设备"
+    :title="initActionsData.modelId ? '当前产品:' +  initActionsData.modelLabel : '选择设备'"
     v-model:open="state.deviceModalVisible"
     placement="right"
     zIndex="1003"
     size="large"
+    destroyOnClose
   >
     <template #extra>
       <a-button style="margin-right: 8px" @click="state.deviceModalVisible = false">取消</a-button>
       <a-button type="primary" @click="selectDevice">确定</a-button>
     </template>
-    <SelectDevice ref="selectDeviceRef" />
+    <SelectDevice ref="selectDeviceRef" :modelId="initActionsData.modelId"/>
   </a-drawer>
 
   <modal-pro
@@ -890,6 +891,7 @@ const initConditionsData = reactive({ ..._initConditionsData })
 const _initActionsData = {
   actionType: '',
   modelId: '',
+  modelLabel: '',
   deviceId: '',
   deviceLabel: '',
   deviceType: '',
@@ -939,6 +941,13 @@ const state = reactive({
   linkCount: []
 })
 
+watch(
+  () => initActionsData.modelId,
+  () => {
+    initActionsData.modelLabel = state.modelList.find(model => model.id === initActionsData.modelId).modelLabel
+  }
+)
+
 watch(
   () => initConditionsData.conditionType,
   () => {

+ 5 - 0
src/router/index.ts

@@ -145,6 +145,11 @@ const iot = {
           path: '/dataServer/openApi',
           name: '开放接口',
           component: () => import('@/pages/iot/dataServer/openApi.vue')
+        },
+        {
+          path: '/dataServer/apis',
+          name: 'api列表',
+          component: () => import('@/pages/iot/dataServer/apis.vue')
         }
       ]
     },