Ver código fonte

feat: 在线调试(ui)

lvkun 3 anos atrás
pai
commit
13f1b007a4

+ 36 - 0
src/api/iot/devOps.ts

@@ -0,0 +1,36 @@
+import request from '@/service/request'
+
+/**
+ * 此函数发送 GET 请求以检索具有指定持续时间、页码和页面大小的警告页面。
+ * @param params - `params` 对象包含三个属性:
+ * @returns `getWarnPage` 函数返回一个解析为 `any` 类型对象数组的 Promise。该数组包含使用指定的 params 对象作为查询参数对 `/warn/page` 端点进行
+ * GET 请求的结果。
+ */
+export const getWarnPage = (params: {duration: number, page: number, pageSize: number}) => {
+  return request<any[]>({
+    url: '/warn/page',
+    method: 'GET',
+    params
+  })
+}
+
+/**
+ * 此函数检索具有指定页码和页面大小的通知页面。
+ * @param params - `params` 参数是一个包含两个属性的对象:`page` 和 `pageSize`。这些属性分别用于指定页码和每页的项目数,用于从服务器检索分页的通知列表。
+ * `page` 属性表示页码
+ * @returns 函数 getNoticePage 返回一个解析为 any 类型对象数组的 Promise。该数组包含所请求页面和页面大小的通知数据。
+ */
+export const getNoticePage = (params: { page: number, pageSize: number}) => {
+  return request<any[]>({
+    url: '/notice/page',
+    method: 'GET',
+    params
+  })
+}
+
+export const getStatsPage = () => {
+  return request<{label: string, value: string}[]>({
+    url: '/stats/page',
+    method: 'GET'
+  })
+}

+ 15 - 0
src/controller/iot/devOps.ts

@@ -0,0 +1,15 @@
+import { getNoticePage, getStatsPage, getWarnPage } from '@/api/iot/devOps'
+
+export class DevOpsController {
+  static async pageWarn (params: {duration: number, page: number, pageSize: number}) {
+    return await getWarnPage(params)
+  }
+
+  static async pageNotice (params: {page: number, pageSize: number}) {
+    return await getNoticePage(params)
+  }
+
+  static async pageStats () {
+    return await getStatsPage()
+  }
+}

+ 1 - 1
src/layout/components/Sidebar/SidebarItem.vue

@@ -9,7 +9,7 @@
       </a-menu-item>
     </template>
 
-      <a-sub-menu v-else>
+      <a-sub-menu v-else :key="item.path" >
         <template #title>
           <user-outlined />
           <span>

+ 3 - 2
src/layout/components/Sidebar/index.vue

@@ -10,7 +10,7 @@
       >
         <a-menu
           :selectedKeys="selectedKeys2"
-          v-model:openKeys="openKeys"
+          :openKeys="openKeys"
           mode="inline"
           :style="{ height: '100%', borderRight: 0 }"
         >
@@ -36,11 +36,12 @@ import { useRouter } from 'vue-router'
 const appRouter = useAppRouter()
 const router = useRouter()
 
-console.log('appRouter.router.sider.route:', appRouter.router.sider.route)
+console.log('appRouter.router.sider.openKeys:', appRouter.router.sider.openKeys)
 
 const collapsed = ref<boolean>(false)
 
 const selectedKeys2 = ref<string[]>([router.currentRoute.value.path])
+// const selectedKeys2 = ref<string[]>(['/dashboard'])
 const openKeys = ref<string[]>(appRouter.router.sider!.openKeys)
 
 console.log(selectedKeys2, openKeys)

+ 9 - 0
src/pages/Iot/devOps/msgTracking.vue

@@ -0,0 +1,9 @@
+<template>
+  <a-card>
+    message
+  </a-card>
+  </template>
+<script lang='ts' setup >
+</script>
+  <style lang='less' scoped >
+  </style>

+ 12 - 0
src/pages/Iot/devOps/nowAlert.vue

@@ -0,0 +1,12 @@
+<template>
+  <a-card>
+    <a-row>
+      <a-col> </a-col>
+    </a-row>
+  </a-card>
+  </template>
+<script lang='ts' setup >
+
+</script>
+<style lang='less' scoped >
+</style>

+ 214 - 0
src/pages/Iot/devOps/onlineTest.vue

@@ -0,0 +1,214 @@
+<template>
+    <a-row>
+        <a-col :span="13">
+            <a-card title="调试输出" style="background-color: #eef0f5;">
+                <a-row>
+                    <a-col :span="6" class="app-imitate" >应用模拟器</a-col>
+                    <a-col :span="3" class="app-to-platform" >
+                        <div class="equipment-platform" >
+                            <div class="border-dot-top">命令下发</div>
+                            <div class="border-dot-bottom">数据上报</div>
+                        </div>
+                    </a-col>
+                    <a-col :span="6" class="IOT" >IOT平台</a-col>
+                    <a-col :span="3" class="app-to-platform" >
+                        <div class="equipment-platform" >
+                            <div class="border-dot-top">命令下发</div>
+                            <div class="border-dot-bottom">数据上报</div>
+                        </div>
+                    </a-col>
+                    <a-col :span="6" class="device-imitate" >设备模拟器</a-col>
+                </a-row>
+                <a-row style="height: 505px;width: 100%" justify="space-between"   >
+                    <a-col :span="11" style="height: 100%;background-color: #fff" ></a-col>
+                    <a-col :span="11" style='background-color: #fff;eight: 100%' ></a-col>
+                </a-row>
+            </a-card>
+        </a-col>
+        <a-col :span="9">
+            <a-row justify='end' >
+                <a-col>
+                    <a-button type="link" >{{state.device.deviceLabel ? state.device.deviceLabel : "尚未选择产品"}}</a-button>
+                    <a-button type="primary" @click="state.drawerVisible = true" >选择设备</a-button>
+                </a-col>
+            </a-row>
+            <a-card
+                style="width: 100%;height: 100%;margin-top: 10px;"
+                :tab-list="tabListNoTitle"
+                :active-tab-key="state.activeKey"
+                @tabChange="onTabChange"
+            >
+                <div></div>
+            </a-card>
+        </a-col>
+    </a-row>
+
+<a-drawer
+    v-model:visible="state.drawerVisible"
+    size="large"
+    class="custom-class"
+    title="选择设备"
+    placement="right"
+  >
+    <SelectDevice ref="selectDeviceRef" />
+    <template #footer >
+        <a-row justify="end" >
+            <a-col>
+                <a-space>
+                    <a-button @click="state.drawerVisible = false">取消</a-button>
+                    <a-button type="primary" @click="handleSelectDevice">确定</a-button>
+                </a-space>
+            </a-col>
+        </a-row>
+    </template>
+  </a-drawer>
+</template>
+<script lang='ts' setup >
+import { reactive, ref } from 'vue'
+import SelectDevice from '@/pages/iot/rule/components/selectDevice.vue'
+import { message } from 'ant-design-vue'
+
+const tabListNoTitle = [
+  {
+    key: 'app',
+    tab: '应用模拟器'
+  },
+  {
+    key: 'device',
+    tab: '设备模拟器'
+  }
+]
+
+const selectDeviceRef = ref()
+
+const state = reactive({
+  activeKey: 'app',
+  drawerVisible: false,
+  device: {
+    deviceLabel: ''
+  }
+})
+
+const handleSelectDevice = () => {
+  const _device = selectDeviceRef.value.getSelectDevice()
+  if (_device) {
+    state.device = _device
+    state.drawerVisible = false
+  } else {
+    message.warn('请选择产品')
+  }
+}
+
+const onTabChange = (key: string) => {
+  state.activeKey = key
+}
+</script>
+<style lang='less' scoped >
+.app-imitate {
+    width: 250px;
+    height: 80px;
+    background-color: #fff;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 20px;
+}
+.IOT {
+    width: 250px;
+    height: 64px;
+    background-color: #fff;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 20px;
+}
+.app-to-platform {
+    height: 100%;
+    // width: 12.5%;
+    // float: left;
+    // height: 100%;
+}
+.device-imitate {
+    width: 250px;
+    height: 80px;
+    background-color: #fff;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 20px;
+}
+.equipment-platform {
+    position: absolute;
+    display: inline-block;
+    vertical-align: middle;
+    width: 100%;
+    line-height: 1;
+    color: #4d4d4d;
+    text-align: center;
+    font-size: 12px;
+    .border-dot-top {
+        position: relative;
+        padding-bottom: 0.6rem;
+        margin-bottom: 1rem;
+        border-bottom: 2px #999 solid;
+    }
+    .border-dot-top::before {
+        left: 0;
+        top: 100%;
+        margin-top: -0.15rem;
+        content: "";
+        display: block;
+        width: 0.4rem;
+        height: 0.4rem;
+        border-radius: 0.2rem;
+        border: 2px #999 solid;
+        background-color: #ebedf0;
+        position: absolute;
+    }
+    .border-dot-top::after {
+        content: "";
+        display: block;
+        border: 4px #999 solid;
+        width: 0;
+        height: 0;
+        transform: rotate(45deg);
+        position: absolute;
+        right: 0;
+        top: 97%;
+        margin-top: -0.15rem;
+        border-color: #999 #999 transparent transparent;
+    }
+    .border-dot-bottom {
+        border-color: #ccc;
+    position: relative;
+    padding-top: 0.6rem;
+    border-top: 2px #999 dashed;
+    }
+    .border-dot-bottom::before {
+        content: "";
+        display: block;
+        border: 4px #999 solid;
+        width: 0;
+        height: 0;
+        transform: rotate(-135deg);
+        position: absolute;
+        top: -11%;
+        margin-top: -0.15rem;
+        border-color: #999 #999 transparent transparent;
+    }
+    .border-dot-bottom::after {
+        right: 0;
+        top: -1px;
+        margin-top: -0.15rem;
+        content: "";
+        display: block;
+        width: 0.4rem;
+        height: 0.4rem;
+        border-radius: 0.2rem;
+        border: 2px #999 solid;
+        background-color: #ebedf0;
+        position: absolute;
+    }
+}
+
+</style>

+ 9 - 0
src/pages/Iot/devOps/statistReport.vue

@@ -0,0 +1,9 @@
+<template>
+<a-card>
+  Statistical report
+</a-card>
+</template>
+<script lang='ts' setup >
+</script>
+<style lang='less' scoped >
+</style>

+ 8 - 8
src/pages/Iot/rule/linkRule.vue

@@ -376,13 +376,13 @@ const sessionEventTypeList = [
 ]
 
 const dayOptions = [
-  { value: '1', label: '周一' },
-  { value: '2', label: '周二' },
-  { value: '3', label: '周三' },
-  { value: '4', label: '周四' },
-  { value: '5', label: '周五' },
-  { value: '6', label: '周六' },
-  { value: '7', label: '周日' }
+  { value: 1, label: '周一' },
+  { value: 2, label: '周二' },
+  { value: 3, label: '周三' },
+  { value: 4, label: '周四' },
+  { value: 5, label: '周五' },
+  { value: 6, label: '周六' },
+  { value: 7, label: '周日' }
 ]
 
 const actionTypeList = [
@@ -449,7 +449,7 @@ const bodyParamsState = reactive<{
 const state = reactive({
   loading: false,
   dataSource: [],
-  visible: true,
+  visible: false,
   deviceModalVisible: false,
   opraState: 'add',
   modelList: [],

+ 28 - 0
src/router/index.ts

@@ -70,6 +70,34 @@ const routes: Array<ROUTER.RoutesProps> = [
             component: () => import('@/pages/iot/rule/linkRule.vue')
           }
         ]
+      },
+      {
+        path: '/devOps',
+        name: ' 监控运维',
+        redirect: '/devOps/report',
+        children: [
+          {
+            path: '/devOps/report',
+            name: '统计报表',
+            component: () => import('@/pages/iot/devOps/statistReport.vue')
+          },
+          {
+            path: '/devOps/onlineTest',
+            name: '在线调试',
+            component: () => import('@/pages/iot/devOps/onlineTest.vue')
+          },
+          {
+            path: '/devOps/mt',
+            name: '消息追踪',
+            component: () => import('@/pages/iot/devOps/msgTracking.vue')
+          },
+          {
+            path: '/devOps/nowAlert',
+            name: '当前告警',
+            component: () => import('@/pages/iot/devOps/nowAlert.vue')
+          }
+
+        ]
       }
 
       // {

+ 1 - 1
src/store/router.ts

@@ -62,7 +62,7 @@ export const useAppRouter = defineStore(ConstantStore.ROUTER, () => {
   watch(
     () => RootRouter.currentRoute.value.path,
     () => {
-      console.log('当前路由改变')
+      console.log('当前路由改变', RootRouter.currentRoute.value.path)
 
       appRouter.sider = {
         route: RootRouter.getRoutes().find(item => item.path === appRouter.navbar!.selectPath)?.children as ROUTER.RoutesProps[],