ソースを参照

feat: step-modal组件

lvkun996 2 年 前
コミット
78857a6569

+ 10 - 2
README.md

@@ -66,7 +66,6 @@ npm run build:package  该指令全是将目前已有的模块分别打包
 ## 待做
 
 1. 支持对浏览器标签的信息设置
-2. 打包mac程序
 5. 区域纯净模式
 6. 登录逻辑封装npm包
 7. 当前项目对状态码的错误处理
@@ -84,4 +83,13 @@ npm run build:package  该指令全是将目前已有的模块分别打包
 
 ### cli
 
-​	只保留后台公共功能的逻辑与基本的路由菜单功能
+​	只保留后台公共功能的逻辑与基本的路由菜单功能
+
+## 模块说明
+
+### cvs蛟龙云视
+
+参考地址: https://console.bce.baidu.com/
+
+
+

+ 5 - 0
config/proxy.ts

@@ -19,6 +19,11 @@ module.exports = {
       target: 'http://124.222.113.37:8888',
       changeOrigin: true,
       pathRewrite: { '^/iot': '' }
+    },
+    '/dataSource': {
+      target: 'http://bynt9d.natappfree.cc',
+      changeOrigin: true,
+      pathRewrite: { '^/dataSource': '' }
     }
   }
 }

ファイルの差分が大きいため隠しています
+ 15454 - 1
package-lock.json


+ 0 - 0
src/api/cvs/readme.md


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

@@ -249,7 +249,7 @@ export const getDeviceByGroup = (params: IOT.API.DEVICE.GroupQueryParams) => {
   })
 }
 
-/** 实时数据 */
+/** 获取设备属性 */
 export const getDeviceAttribute = (deviceId: string) => {
   return request<IOT.API.DEVICE.Device[]>({
     url: `/deviceAttribute/latest?deviceId=${deviceId}`,

+ 68 - 0
src/api/schedule/dataSource.ts

@@ -0,0 +1,68 @@
+import request from '@/service/request'
+
+/**
+ * 查询数据源
+ * */
+export function getDataSourcePage (params) {
+  return request<SCHEDULE.SOURCE.Detail[]>({
+    url: '/dataSource/page',
+    method: 'GET',
+    params
+  })
+}
+
+/**
+ * 新增数据源
+ * */
+export function addDataSource (data: SCHEDULE.SOURCE.Detail) {
+  return request({
+    url: '/dataSource',
+    method: 'POST',
+    data
+  })
+}
+
+/**
+ * 修改数据源
+ * */
+export function updateDataSource (data: SCHEDULE.SOURCE.Detail) {
+  return request({
+    url: '/dataSource',
+    method: 'POST',
+    data
+  })
+}
+
+export function getDataSourceById (id: string) {
+  return request<SCHEDULE.SOURCE.Detail>({
+    method: 'GET'
+  })
+}
+
+/**
+ * 数据源连接参数 -连接测试 【用在新建还未保存】
+ * */
+export function dataSourceConnect (data: SCHEDULE.SOURCE.Detail) {
+  return request<Boolean>({
+    url: '/dataSource/connect',
+    method: 'POST',
+    data
+  })
+}
+
+/**
+ * 数据源连接参数 -连接测试 【用在新建还未保存】
+ * */
+export function dataSourceConnectTest (id: string) {
+  return request<Boolean>({
+    url: `/dataSource/${id}/connectTest`,
+    method: 'GET'
+  })
+}
+
+export function delDataSource (id: string) {
+  return request<Boolean>({
+    url: `/dataSource/${id}`,
+    method: 'DELETE'
+  })
+}

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

@@ -1,5 +1,4 @@
 import { defineComponent, nextTick, onMounted, reactive, ref, defineExpose } from 'vue'
-
 import { basicSetup } from 'codemirror'
 import { EditorView } from '@codemirror/view'
 import { EditorState, StateEffect } from '@codemirror/state'

+ 1 - 1
src/components/StatisticsTemplate/index.vue

@@ -16,11 +16,11 @@
           {{item.label}}
         </div>
       </a-col>
+      <!-- <vueCountTo :startVal='2' :endVal='2023' :duration='3000'  /> -->
     </a-row>
 </a-card>
 </template>
 <script lang='ts' setup >
-
 import CountUp from 'vue-countup-v3'
 interface IProps {
   title: string,

+ 21 - 0
src/components/StepModal/index.less

@@ -0,0 +1,21 @@
+
+
+.step-modal {
+  width: 100vw;
+  height: 100vh;
+  background-color: #fff;
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 20;
+  .footer {
+    width: 100vw;
+    height: 80px;
+    box-shadow: 0px 1px 1px #000;
+    border-top: 1px solid #ccc;
+    position: absolute;
+    left: 0;
+    bottom: 0;
+  }
+  
+}

+ 54 - 0
src/components/StepModal/index.tsx

@@ -0,0 +1,54 @@
+import { Button, Col, Row, Space } from 'ant-design-vue'
+import { defineComponent, PropType, computed, ref, createApp } from 'vue'
+import './index.less'
+
+interface Steps {
+  name: string
+}
+
+export const StepModal = defineComponent({
+  name: 'step-modal',
+  props: {
+    steps: {
+      type: Array as PropType<Steps[]>,
+      default: () => []
+    },
+    step: {
+      type: Number,
+      default: 0
+    }
+  },
+  emits: ['next', 'pre', 'ok'],
+  setup (props, ctx) {
+    const isLastStep = computed(() => props.step === props.steps.length)
+
+    // 已经填写过的step的下标
+    const writeSteped = ref([0])
+
+    // 是否允许当前进行下一步
+
+    const nextStep = () => {
+      writeSteped.value.push(writeSteped.value.length)
+    }
+
+    return () => (
+      <div class='step-modal' >
+        <Row></Row>
+        <Row class='footer' >
+          <Col>
+            <Space>
+              <Button>上一步</Button>
+              {/* <Button disabled={} onClick={nextStep} >{isLastStep.value ? '提交' : '下一步'}</Button> */}
+            </Space>
+          </Col>
+        </Row>
+      </div>
+    )
+  }
+})
+
+// const stepModalNode = document.createElement('div')
+// const app = createApp(StepModal)
+
+// app.mount(stepModalNode)
+// document.body.appendChild(stepModalNode)

+ 7 - 2
src/controller/iot/device.ts

@@ -239,6 +239,11 @@ export class DeviceContriller {
     return await getDeviceAttribute(deviceId)
   }
 
+  /** 获取设备属性 */
+  static async getDeviceAttribute (deviceId: string) {
+    return await getDeviceAttribute(deviceId)
+  }
+
   static async getDevicShadow (deviceId: string) {
     return await getDevicShadow(deviceId)
   }
@@ -255,7 +260,7 @@ export class DeviceContriller {
         sessionEntities: data.sessionEntities.map(item => {
           return {
             ...item,
-            createAt: dayjs(item.createAt).format('YYYY/MM/DD')
+            createAt: dayjs(item.createAt).format('YYYY/MM/DD HH:mm:ss')
           }
         }),
         offlineNum: data.offlineNum,
@@ -265,7 +270,7 @@ export class DeviceContriller {
     }
   }
 
-  static async getAttr (params: {deviceId: string, start: number, end: number}) {
+  static async getAttr (params: {deviceId: string, start: number, end: number, attributeKey: string}) {
     return await getDeviceAttributes(params)
   }
 

+ 23 - 8
src/controller/schedule/dataSource.ts

@@ -1,22 +1,37 @@
+import { addDataSource, dataSourceConnect, dataSourceConnectTest, delDataSource, getDataSourceById, getDataSourcePage, updateDataSource } from '@/api/schedule/dataSource'
+import { message } from 'ant-design-vue'
 
 export class DataSourceController {
-  static async dataSource () {
-
+  static async page (params: COMMON.API.QueryParams & {label: string, dataSourceType: SCHEDULE.SOURCE.DataSourceType}) {
+    return await getDataSourcePage(params)
   }
 
-  static async addDataSource () {
-
+  static async add (data: SCHEDULE.SOURCE.Detail) {
+    await addDataSource(data)
+    message.success('新增成功')
   }
 
-  static async updateDataSource () {
-
+  static async update (data: SCHEDULE.SOURCE.Detail) {
+    await updateDataSource(data)
+    message.success('修改成功')
   }
 
-  static async delDataSource (id: string) {
+  static async del (id: string) {
+    await delDataSource(id)
+    message.success('删除成功')
+  }
 
+  static async byId (id: string) {
+    return getDataSourceById(id)
   }
 
-  static async dataSourceById () {
+  static async connect (data: SCHEDULE.SOURCE.Detail) {
+    await dataSourceConnect(data)
+    message.success('连接成功')
+  }
 
+  static async connectTest (id: string) {
+    await dataSourceConnectTest(id)
+    message.success('测试连接成功')
   }
 }

+ 15 - 0
src/enum/common.ts

@@ -66,3 +66,18 @@ export enum OtaStatusEnum {
   'TIMEOUT' = 'TIMEOUT',
   'FAILED' = 'FAILED',
 }
+
+// 数据源类型
+export enum DataSourceTypeEnum {
+  'MYSQL' = 'MYSQL',
+  'PGSQL' = 'PGSQL',
+  'DM' = 'DM',
+  'ORACLE' = 'ORACLE',
+  'DORIS' = 'DORIS'
+}
+
+// 数据源连接类型
+export enum DataSourceTConnectTypeEnum {
+  'ORACLE_SERVICE_NAME' = 'ORACLE_SERVICE_NAME',
+  'ORACLE_SID' = 'ORACLE_SID'
+}

+ 3 - 0
src/layout/navbar.vue

@@ -91,6 +91,9 @@ const changeRouter = (route: ROUTER.RoutesProps) => {
   //   selectedKeys.value = [route.path]
   //   router.push(route.path)
   // }
+  selectedKeys.value = [route.path]
+  console.log('route:', route, selectedKeys)
+
   appRouter.changeNavbarRoute(route)
 }
 

+ 1 - 3
src/layout/user.vue

@@ -22,15 +22,13 @@
 </template>
 
 <script lang="ts" setup >
+
 import { useUserStore } from '@/store'
-import { storeToRefs } from 'pinia'
 
 const ava = require('@/assets/logo/logo-blue.png')
 
 const userStore = useUserStore()
 
-console.log('userStore.userInfo:', userStore)
-
 </script>
 
 <style lang="less" scoped >

+ 74 - 48
src/pages/Iot/device/analysis.vue

@@ -10,7 +10,7 @@
     :active-tab-key="activeTabKey"
     @tabChange="key => onTabChange(key)"
   >
-    <a-row :gutter="[8, 8]" style="margin-top: 20px;" >
+    <a-row :gutter="[8, 8]" style="margin: 0 20px;" >
 
         <a-col :span="24" >
           <a-space>
@@ -35,12 +35,26 @@
                 </template>
               </a-select>
             </a-spin>
-            <a-range-picker  v-model:value="times" @change="changeRangePicker"  />
+            <a-select
+                v-if="activeTabKey === 'attr'"
+                v-model:value="state.attributeKey"
+                placeholder="请选择属性"
+                style="width: 170px"
+                :show-arrow="false"
+                @change="selectAttr"
+              >
+                <a-select-option
+                  v-for="item in deviceState.attrList"
+                  :key="item.key"
+                  :value="item.key"
+                >{{item.keyLabel}}</a-select-option>
+              </a-select>
+            <a-range-picker :show-time="{ format: 'HH:mm' }" v-model:value="times" @change="changeRangePicker"  />
           </a-space>
         </a-col>
         <a-col :span="24">
           <a-spin :spinning="state.loading" >
-          <a-empty style="margin: 0 auto;" v-if="!state.deviceId" description="请选择设备" ></a-empty>
+          <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>
@@ -54,10 +68,8 @@
             </a-col>
             <a-col :span="24" v-else>
               <div
-                :id="`device-attr-` + key"
+                id="device-attr"
                 style="width: 1000px; height: 400px;"
-                v-for="key in attrKeys"
-                :key="key"
               >
               </div>
             </a-col>
@@ -90,12 +102,16 @@ const route = useRoute()
 
 const activeTabKey = ref<'session' | 'attr'>('session')
 
-const attrKeys = computed(() => Object.keys(state.attrSource))
+const emptyCondition = computed(() => activeTabKey.value === 'session' ? state.dataSource.length === 0 : state.attrSource.length === 0)
+
+const emptyDesc = computed(() => !state.deviceId ? '请选择设备' : '该设备下暂无数据')
 
 const deviceState = reactive<{
   dataSource: IOT.API.DEVICE.Device[]
+  attrList: IOT.API.DEVICE.Attr[]
 }>({
-  dataSource: []
+  dataSource: [],
+  attrList: []
 })
 
 const state = reactive<{
@@ -112,18 +128,24 @@ const state = reactive<{
   analysisType: '',
   spinning: false,
   onlineNum: 0,
-  offlineNum: 0
+  offlineNum: 0,
+  attributeKey: null
 })
 
-const times = ref([dayjs(), dayjs()])
+const times = ref([dayjs().subtract(30, 'minute'), dayjs()])
 
 state.deviceId = route.query.id as string
 
 const onTabChange = (key: 'session' | 'attr') => activeTabKey.value = key
 
+// 切换上下线分析
 watch(
   () => activeTabKey.value,
-  () => activeTabKey.value === 'session' ? getDeviceSession() : getDeviceAttr()
+  () => {
+    state.deviceId = null
+    state.searchDeviceLabel = null
+    state.attributeKey = null
+  }
 )
 
 // 获取设备属性分析数据
@@ -131,20 +153,22 @@ watch(
   () => state.attrSource,
   () => {
     nextTick(() => {
-      Object.keys(state.attrSource).forEach(key => {
-        const chartDom = document.getElementById('device-attr-' + key)
+      if (state.attrSource.length === 0) {
+        state.loading = false
+        return
+      }
+      const chartDom = document.getElementById('device-attr')
 
-        const myChart = echarts.init(chartDom!)
-        const attrItem = state.attrSource[key]
+      const myChart = echarts.init(chartDom!)
+
+      attrEchartsJson.xAxis.data = (state.attrSource.map(item => dayjs(item.ts).format('HH:MM:ss')) || []) as never[]
 
-        attrEchartsJson.xAxis.data = (attrItem.map(item => dayjs(item.ts).format('HH:MM:ss')) || []) as never[]
+      attrEchartsJson.series[0].data = state.attrSource.map(item => item.value)
 
-        attrEchartsJson.series[0].data = attrItem.map(item => item.longValue)
+      attrEchartsJson.title.text = state.attrSource[0].keyLabel
 
-        attrEchartsJson.title.text = key
+      myChart.setOption(attrEchartsJson)
 
-        myChart.setOption(attrEchartsJson)
-      })
       state.loading = false
     })
   }
@@ -153,9 +177,13 @@ watch(
 // 获取上下线分析图表数据
 // state.dataSource
 watch(
-  () => state.deviceId,
+  () => state.dataSource,
   () => {
     setTimeout(() => {
+      if (state.dataSource.length === 0) {
+        state.loading = false
+        return
+      }
       if (activeTabKey.value === 'session') {
         const chartDom = document.getElementById('device-session')
         const chartDomScatter = document.getElementById('device-session-scatter')
@@ -165,6 +193,7 @@ watch(
         const chartDomScatterChart = echarts.init(chartDomScatter!)
         sessionEchartsJson.xAxis.data = state.dataSource.map(item => item.createAt) as never[]
         sessionEchartsJson.series[0].data = state.dataSource.map(item => item.sessionType === 'CONNECT' ? '上线' : '下线')
+        sessionEchartsJson.series[1].data = state.dataSource.map(item => item.sessionType !== 'CONNECT' ? '上线' : '下线')
 
         const connectCount = state.dataSource.filter(item => item.sessionType === 'CONNECT').length
         const disconnectCount = state.dataSource.length - connectCount
@@ -180,20 +209,10 @@ watch(
           }
         ]
 
-        sessionEchartsJson.legend.data = [`上线数量 ${state.onlineNum}`, `下线数量 ${state.offlineNum}`]
-
-        scatterOption.series[0].data = state.dataSource.filter(item => item.sessionType === 'CONNECT').map(item => [0, connectCount])
-
-        scatterOption.series[1].data = state.dataSource.filter(item => item.sessionType !== 'CONNECT').map(item => [1, disconnectCount])
-
-        let currentOption = scatterOption
+        sessionEchartsJson.series[0].name = `上线数量 ${state.onlineNum}`
+        sessionEchartsJson.series[1].name = `下线数量 ${state.offlineNum}`
 
-        setInterval(function () {
-          currentOption = currentOption === scatterOption ? barOption : scatterOption
-          chartDomScatterChart.setOption(currentOption, true)
-        }, 2000)
-
-        chartDomScatterChart.setOption(currentOption)
+        chartDomScatterChart.setOption(barOption)
         myChart.setOption(sessionEchartsJson)
 
         state.loading = false
@@ -202,19 +221,24 @@ watch(
   }
 )
 
-watch(
-  () => state.deviceId,
-  () => activeTabKey.value === 'session' ? getDeviceSession() : getDeviceAttr()
-)
+const selectAttr = (value: string) => {
+  state.attributeKey = value
+  getDeviceAttr()
+}
 
 const changeRangePicker = (time) => {
   activeTabKey.value === 'session' ? getDeviceSession() : getDeviceAttr()
 }
 
-const selectDevice = async (value: records) => {
+const selectDevice = async (value: string) => {
   const device = await DeviceContriller.byId(value)
   state.deviceId = device.id
   console.log('device:', state.deviceId)
+  if (activeTabKey.value === 'attr') {
+    getDeviceAttribute()
+  } else {
+    getDeviceSession()
+  }
 }
 
 const getDeviceLabel = async (val: string) => {
@@ -229,7 +253,7 @@ const getDeviceLabel = async (val: string) => {
 const getDeviceSession = async () => {
   if (!state.deviceId) return
   state.loading = true
-  const { data } = await DeviceContriller.getSession({ deviceId: state.deviceId, start: state.start, end: state.end })
+  const { data } = await DeviceContriller.getSession({ deviceId: state.deviceId, start: dayjs(times.value[0]).unix() * 1000, end: dayjs(times.value[1]).unix() * 1000 })
   state.dataSource = data.sessionEntities
   state.offlineNum = data.offlineNum
   state.onlineNum = data.onlineNum
@@ -238,20 +262,22 @@ const getDeviceSession = async () => {
 const getDeviceAttr = async () => {
   if (!state.deviceId) return
   state.loading = true
-
-  const { data } = await DeviceContriller.getAttr({ deviceId: state.deviceId, start: 1, end: state.end })
+  // .format('YYYY/MM/DD HH:mm:ss')
+  const { data } = await DeviceContriller.getAttr({
+    deviceId: state.deviceId,
+    start: 1,
+    end: new Date().getTime(),
+    attributeKey: state.attributeKey
+  })
   state.attrSource = data
 }
 
-const getDeviceList = async () => {
-  state.spinning = true
-  const { data } = await DeviceContriller.list()
-  state.spinning = false
-  deviceState.dataSource = data
+const getDeviceAttribute = async () => {
+  const { data } = await DeviceContriller.getDeviceAttribute(state.deviceId)
+  deviceState.attrList = data
 }
 
 onMounted(() => {
-  // getDeviceList()
   if (state.deviceId) {
     getDeviceSession()
   }

+ 16 - 3
src/pages/Iot/device/json/echartsJson.ts

@@ -3,10 +3,15 @@ export const sessionEchartsJson = {
     text: ''
   },
   tooltip: {
-    trigger: 'axis'
+    trigger: 'axis',
+    formatter: function (params, ticket, callback) {
+      console.log('params:', params)
+
+      // return params.name.split(' ')[1]
+      return ''
+    }
   },
   legend: {
-    data: ['上线数量', '下线数量']
   },
   grid: {
     left: '3%',
@@ -33,7 +38,15 @@ export const sessionEchartsJson = {
       name: 'offlineNum',
       type: 'line',
       stack: 'Total',
-      data: ['上线', '下线', '下线', '上线']
+      data: [],
+      timeStamp: 7788
+    },
+    {
+      name: 'onlineNum',
+      type: 'line',
+      stack: 'Total',
+      data: [],
+      timeStamp: 7788
     }
   ]
 }

+ 2 - 4
src/pages/Iot/rule/forwardRule.vue

@@ -368,13 +368,13 @@
 </modal-pro>
 
 <modal-pro
-  style="width: 1000px"
+  style="width: 1000px;"
   label="详情"
   :open="state.detailVisible"
   @cancel="state.detailVisible = false"
   @ok="state.detailVisible  = false"
 >
-  <a-form  :label-col="{span: 2}" style="height: 600px;overflow: hidden;overflow-y: scroll;">
+  <a-form  :label-col="{span: 2}" style="height: 400px;overflow: hidden;overflow-y: scroll;">
     <a-form-item label="规则名称"> {{detailForwardRef.ruleLabel}} </a-form-item>
     <a-form-item label="数据来源"> {{RuleController.SubjectResourceMap.get(detailForwardRef.subjectResource)?.name}} </a-form-item>
     <a-form-item label="触发事件"> {{RuleController.SubjectEventMap.get(detailForwardRef.subjectEvent)?.name}} </a-form-item>
@@ -402,7 +402,6 @@
         :data-source="detailMQTTList"
         :pagination="false"
       >
-
       </a-table>
     </a-form-item>
     <a-form-item label="RabbitMQ" v-if="detailRABBITList.length">
@@ -411,7 +410,6 @@
         :data-source="detailRABBITList"
         :pagination="false"
       >
-
       </a-table>
     </a-form-item>
   </a-form>

+ 9 - 0
src/pages/cvs/csys/index.vue

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

+ 9 - 0
src/pages/cvs/dataServer/car.vue

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

+ 9 - 0
src/pages/cvs/dataServer/face.vue

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

+ 9 - 0
src/pages/cvs/dataServer/frock.vue

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

+ 9 - 0
src/pages/cvs/edge/task.vue

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

+ 9 - 0
src/pages/cvs/edge/video.vue

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

+ 9 - 0
src/pages/cvs/operator/manage.vue

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

+ 9 - 0
src/pages/cvs/video/device.vue

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

+ 11 - 0
src/pages/cvs/video/space.vue

@@ -0,0 +1,11 @@
+<template>
+<a-card>
+  <StepModal />
+</a-card>
+</template>
+<script lang='ts' setup >
+
+import { StepModal } from '@/components/StepModal'
+</script>
+<style lang='less' scoped >
+</style>

+ 2 - 1
src/pages/schedule/dataSource/manage/index.vue

@@ -23,6 +23,7 @@
 <script lang='ts' setup >
 import { DataSourceController } from '@/controller'
 import { reactive, onMounted } from 'vue'
+
 const columns = [
   {
     title: '名称',
@@ -61,7 +62,7 @@ const changePage = ({ current }) => {
 
 const getDataSource = async () => {
   state.loading = true
-  const { data } = await DataSourceController.dataSource()
+  const { data } = await DataSourceController.page(queryState)
   state.loading = false
   state.dataSource = data
 }

+ 118 - 16
src/router/index.ts

@@ -11,13 +11,13 @@ const iot = {
   children: [
     {
       path: '/dashboard',
-      name: '首页',
+      name: '系统概览',
       icon: 'DashboardOutlined',
       component: () => import('@/pages/iot/dashboard/deviceAccess/index.vue')
     },
     {
       path: '/product',
-      name: '产品',
+      name: '产品模型',
       redirect: '/product/index',
       icon: 'AppstoreOutlined',
       children: [
@@ -41,7 +41,7 @@ const iot = {
     },
     {
       path: '/device',
-      name: '设备',
+      name: '设备管理',
       redirect: '/device/index',
       icon: 'RobotOutlined',
       children: [
@@ -75,7 +75,7 @@ const iot = {
     },
     {
       path: '/rule',
-      name: '规则',
+      name: '数据规则',
       redirect: '/rule/forward',
       icon: 'AimOutlined',
       children: [
@@ -185,16 +185,24 @@ const iot = {
       ]
     },
     {
-      path: '/deviceDoc',
-      name: '设备接入文档',
-      component: () => import('@/pages/iot/doc/deviceDoc.vue'),
-      icon: 'BookOutlined'
-    },
-    {
-      path: '/dataDoc',
-      name: '数据服务文档',
-      component: () => import('@/pages/iot/doc/dataDoc.vue'),
-      icon: 'CoffeeOutlined'
+      path: '/doc',
+      name: '使用文档',
+      redirect: '',
+      icon: 'SnippetsOutlined',
+      children: [
+        {
+          path: '/deviceDoc',
+          name: '设备接入文档',
+          component: () => import('@/pages/iot/doc/deviceDoc.vue'),
+          icon: 'BookOutlined'
+        },
+        {
+          path: '/dataDoc',
+          name: '数据服务文档',
+          component: () => import('@/pages/iot/doc/dataDoc.vue'),
+          icon: 'CoffeeOutlined'
+        }
+      ]
     }
   ]
 }
@@ -371,6 +379,101 @@ const login = {
   component: () => import('@/pages/login/index.vue')
 }
 
+const cvs = {
+  path: '/cvs',
+  name: 'cvs',
+  meta: {
+    title: 'cvs'
+  },
+  component: () => import('@/layout/layout.vue'),
+  redirect: '/cvs/video/space',
+  children: [
+    {
+      path: '/cvs/video',
+      name: '视频接入',
+      icon: '',
+      children: [
+        {
+          path: '/cvs/video/space',
+          name: '空间',
+          icon: '',
+          component: () => import('@/pages/cvs/video/space.vue')
+        },
+        {
+          path: '/cvs/video/device',
+          name: '设备',
+          icon: '',
+          component: () => import('@/pages/cvs/video/device.vue')
+        }
+      ]
+    },
+    {
+      path: '/cvs/operator',
+      name: '算子仓库',
+      icon: '',
+      children: [
+        {
+          path: '/cvs/operator/manage',
+          name: '算子管理',
+          icon: '',
+          component: () => import('@/pages/cvs/operator/manage.vue')
+        }
+      ]
+    },
+    {
+      path: '/cvs/dataSever',
+      name: '数据服务',
+      icon: '',
+      children: [
+        {
+          path: '/cvs/dataSever/car',
+          name: '车辆库',
+          icon: '',
+          component: () => import('@/pages/cvs/dataServer/car.vue')
+        },
+        {
+          path: '/cvs/dataSever/face',
+          name: '人脸库',
+          icon: '',
+          component: () => import('@/pages/cvs/dataServer/face.vue')
+        },
+        {
+          path: '/cvs/dataSever/frock',
+          name: '工装库',
+          icon: '',
+          component: () => import('@/pages/cvs/dataServer/frock.vue')
+        }
+      ]
+    },
+    {
+      path: '/cvs/edge',
+      name: '边缘设备',
+      icon: '',
+      children: [
+        {
+          path: '/cvs/edge/task',
+          name: '任务管理',
+          icon: '',
+          component: () => import('@/pages/cvs/edge/task.vue')
+        },
+        {
+          path: '/cvs/dataSever/video',
+          name: '视频管理',
+          icon: '',
+          component: () => import('@/pages/cvs/edge/video.vue')
+        }
+      ]
+    },
+    {
+      path: '/cvs/csys',
+      name: '系统概览 ',
+      icon: '',
+      component: () => import('@/pages/cvs/csys/index.vue')
+    }
+  ]
+}
+// }HQDZKE6BBJCJB0412
+
 const demo = {
   path: '/demo',
   name: 'demo',
@@ -378,8 +481,7 @@ const demo = {
   component: () => import('@/pages/demo/index.vue')
 }
 
-const _routes = [iot, rts, schedule, view, lowcode, user] as any
-// const _routes = [iot] as any
+const _routes = [iot, rts, schedule, view, lowcode, user, cvs] as any
 
 if (_routes[0].link) {
   window.open(_routes[0].path)

+ 2 - 0
src/store/modules/commonStore/routerTravelStore.ts

@@ -43,6 +43,8 @@ export const useRouterTravelStore = defineStore('routerTravelStore', () => {
       currenRouteIndex.value = history.value.length - 1
     }
     currentRoute.value = route
+
+    // console.log('寻找顶级节点:')
   }
 
   const setCurrentRoute = (route: RouteRecordRaw) => {

+ 1 - 0
src/store/modules/user/index.ts

@@ -17,6 +17,7 @@ const initState: USER.Tenant.Detail = {
 
 export const useUserStore = defineStore('userStore', () => {
   const router = useRouter()
+
   const route = useRoute()
 
   let userInfo = reactive<USER.Tenant.Detail>(JSON.parse(window.localStorage.getItem('userInfo') as string) || initState)

+ 28 - 33
src/store/router.ts

@@ -49,41 +49,36 @@ export const useAppRouter = defineStore(ConstantStore.ROUTER, () => {
   function findRootRoute (data, path: string) {
     const routes = RootRouter.options.routes as RouteRecordRaw[]
 
-    // const fn = (routes: RouteRecordRaw[]) => {
-    //   for (let index = 0; index < routes.length; index++) {
-    //     if (routes[index].path === path) {
-    //       return routes[index]
-    //     } else {
-    //       fn(routes[index].children)
-    //     }
-    //   }
-    //   if (route.path === path) return true
-    //   else if (route.children && route.children.length > 0) {
-    //     fn(route.children)
-    //   } else return false
-    // }
+    const getParentRouteByPath = (routes: RouteRecordRaw, path: string) => {
+      if (routes.children && routes.children.length > 0) {
+        const index = routes.children.findIndex(route => route.path === path)
+        return index >= 0
+      } else {
+        return false
+      }
+    }
 
-    // for (let index = 0; index < routes.length; index++) {
-    //   if (routes[index].path === path) {
-    //     return routes[index]
-    //   } else {
-    //     fn(routes[index].children)
-    //   }
-    // }
+    const count = 0
 
-    // for (const node of data) {
-    //   if (node.path === path) {
-    //     // 如果找到匹配的 path,表示当前节点就是根节点
-    //     return node
-    //   } else if (node.children) {
-    //     // 如果当前节点有子节点,递归搜索子节点
-    //     const result = findRootRoute(node.children, path)
-    //     if (result) {
-    //       // 如果在子节点中找到匹配的 path,返回子节点的结果
-    //       return result
-    //     }
-    //   }
-    // }
+    const fn = (route: RouteRecordRaw) => {
+      const chidlren = route.children
+      if (!chidlren) {
+        console.log(route.path === path)
+        if (route.path === path) return true
+      } else {
+        for (let i = 0; i < chidlren.length; i++) {
+          fn(chidlren[i])
+        }
+      }
+    }
+
+    routes.forEach(route => {
+      console.log('fn(route):', fn(route))
+
+      if (fn(route)) {
+        console.log('寻找顶级及诶点:', route.path)
+      }
+    })
   }
 
   return {

+ 32 - 0
src/type/schedule.d.ts

@@ -43,4 +43,36 @@ declare namespace SCHEDULE {
       respParam: [],
     }
   }
+
+  namespace SOURCE {
+
+    type DataSourceType = 'MYSQL' | 'PGSQL' | 'DM' | 'ORACLE' | 'DORIS'
+
+    // 区别
+    // ORACLE 数据库增加一些参数
+    // connectType:”“ //连接类型 值有 ORACLE_SERVICE_NAME,ORACLE_SID
+
+    interface DataSourceConnectParam {
+      dataSourceType: DataSourceType // 数据源类型
+      username: string // 用户名
+      password: string // 密码
+      address: string // 连接地址
+      port: number // 端口int
+      database: string // 数据库
+      driverClassName: string // 驱动class 名称
+      validateQuery: string // 校验sql
+      minimumIdle: nunber
+      'maximumPoolSize': number,
+      'otherParameters': Record<string, string>[]
+      'connectType'?: 'ORACLE_SERVICE_NAM' | 'ORACLE_SID'
+    }
+
+    interface Detail {
+      'id'?: string // id
+      'label': string // 数据源名称,字符串,必须填写
+      'description': string // 描述, 字符串,必须填写
+      'dataSourceConnectParam': DataSourceConnectParam // 数据源连接参数,根据不同的数据源 连接参数可能不同
+      }
+
+  }
 }

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません