Browse Source

项目重构

李富豪 1 year ago
parent
commit
f39f9f7b7b
57 changed files with 720 additions and 517 deletions
  1. 21 7
      Web/.gitignore
  2. 0 2
      Web/env/.env
  3. 0 2
      Web/env/.env.production
  4. 0 2
      Web/env/.env.stag
  5. 22 22
      Web/package-lock.json
  6. 9 8
      Web/package.json
  7. 2 2
      Web/src/App.vue
  8. 4 0
      Web/src/api/http/request.ts
  9. 37 23
      Web/src/components/LayersTree.vue
  10. 1 0
      Web/src/components/MediaPanel.vue
  11. 20 20
      Web/src/components/common/topbar.vue
  12. 52 30
      Web/src/components/devices/device-hms/DeviceHmsDrawer.vue
  13. 39 31
      Web/src/components/devices/device-log/DeviceLogDetailModal.vue
  14. 38 26
      Web/src/components/devices/device-log/DeviceLogUploadModal.vue
  15. 52 43
      Web/src/components/devices/device-log/DeviceLogUploadRecordDrawer.vue
  16. 3 3
      Web/src/components/devices/device-log/use-device-log-upload-detail.ts
  17. 3 2
      Web/src/components/devices/device-log/use-device-log-upload-progress-event.ts
  18. 3 2
      Web/src/components/devices/device-upgrade/use-device-upgrade-event.ts
  19. 7 6
      Web/src/components/flight-area/use-flight-area.ts
  20. 7 4
      Web/src/components/g-map/use-drone-control-ws-event.ts
  21. 72 21
      Web/src/components/livestream-agora.vue
  22. 1 1
      Web/src/components/livestream-others.vue
  23. 1 0
      Web/src/components/task/use-task-ws-event.ts
  24. 1 1
      Web/src/constants/index.ts
  25. 8 10
      Web/src/constants/map.ts
  26. 1 1
      Web/src/constants/mock-layers.ts
  27. 2 2
      Web/src/directives/drag-window.ts
  28. 2 2
      Web/src/directives/index.ts
  29. 0 9
      Web/src/env.d.ts
  30. 1 1
      Web/src/event-bus/index.ts
  31. 1 1
      Web/src/hooks/use-connect-websocket.ts
  32. 20 20
      Web/src/hooks/use-g-map-cover.ts
  33. 18 8
      Web/src/hooks/use-g-map-tsa.ts
  34. 3 3
      Web/src/hooks/use-g-map.ts
  35. 3 3
      Web/src/hooks/use-map-tool.ts
  36. 8 8
      Web/src/hooks/use-mouse-tool.ts
  37. 1 1
      Web/src/main.ts
  38. 1 1
      Web/src/mqtt/config.ts
  39. 1 1
      Web/src/mqtt/index.ts
  40. 15 17
      Web/src/pages/page-pilot/pilot-bind.vue
  41. 26 33
      Web/src/pages/page-pilot/pilot-home.vue
  42. 29 15
      Web/src/pages/page-pilot/pilot-index.vue
  43. 62 45
      Web/src/pages/page-pilot/pilot-liveshare.vue
  44. 64 34
      Web/src/pages/page-pilot/pilot-media.vue
  45. 1 0
      Web/src/pages/page-web/projects/flight-area.vue
  46. 1 0
      Web/src/pages/page-web/projects/tsa.vue
  47. 7 5
      Web/src/root.ts
  48. 1 0
      Web/src/router/index.ts
  49. 0 0
      Web/src/typings/shims-mqtt.d.ts
  50. 0 0
      Web/src/typings/shims-vue.d.ts
  51. 0 0
      Web/src/typings/vite-env.d.ts
  52. 2 2
      Web/src/use-common-components.ts
  53. 1 1
      Web/src/utils/logger.ts
  54. 11 0
      Web/src/vendors/srs.sdk.js
  55. 11 11
      Web/src/websocket/index.ts
  56. 5 3
      Web/tsconfig.json
  57. 19 22
      Web/vite.config.ts

+ 21 - 7
Web/.gitignore

@@ -1,11 +1,25 @@
+node_modules
 .DS_Store
+dist
+dist-ssr
+*.local
+node_modules/
 
-# 编辑器配置
-.vscode/
-.idea/
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
 
-# 项目依赖
-node_modules
+# Editor directories and files
+.idea
+# .vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
 
-# 打包文件
-/build
+.history
+/coverage
+/backup
+node_modules

+ 0 - 2
Web/env/.env

@@ -1,2 +0,0 @@
-VITE_APP_ENVIRONMENT=DEV
-VITE_APP_APIGATEWAY_BACKEND_HOST=''

+ 0 - 2
Web/env/.env.production

@@ -1,2 +0,0 @@
-VITE_APP_ENVIRONMENT=production
-VITE_APP_APIGATEWAY_BACKEND_HOST=''

+ 0 - 2
Web/env/.env.stag

@@ -1,2 +0,0 @@
-VITE_APP_ENVIRONMENT=STAG
-VITE_APP_APIGATEWAY_BACKEND_HOST=''

+ 22 - 22
Web/package-lock.json

@@ -1,12 +1,12 @@
 {
-  "name": "demo-web",
-  "version": "0.0.1",
+  "name": "uav-manage-web",
+  "version": "1.0.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
-      "name": "demo-web",
-      "version": "0.0.1",
+      "name": "uav-manage-web",
+      "version": "1.0.0",
       "license": "ISC",
       "dependencies": {
         "@amap/amap-jsapi-loader": "^1.0.1",
@@ -14,7 +14,7 @@
         "@vitejs/plugin-legacy": "^1.6.2",
         "agora-rtc-sdk-ng": "^4.12.1",
         "ant-design-vue": "^2.2.8",
-        "axios": "^0.21.4",
+        "axios": "^0.21.1",
         "eventemitter3": "^5.0.0",
         "mitt": "^3.0.0",
         "mqtt": "^4.3.7",
@@ -28,8 +28,8 @@
         "vue": "^3.2.26",
         "vue-cookies": "^1.7.4",
         "vue-i18n": "^9.1.6",
-        "vue-router": "4.3.0",
-        "vuex": "^4.1.0"
+        "vue-router": "4",
+        "vuex": "^4.0.2"
       },
       "devDependencies": {
         "@types/node": "^18.15.0",
@@ -37,8 +37,8 @@
         "@vitejs/plugin-vue": "^1.2.4",
         "@vue/compiler-sfc": "^3.0.5",
         "rollup-plugin-external-globals": "^0.6.1",
-        "sass": "^1.77.0",
-        "typescript": "^5.4.0",
+        "sass": "^1.35.1",
+        "typescript": "^4.5.4",
         "vite": "^2.4.0",
         "vite-plugin-style-import": "^1.0.1",
         "vite-plugin-svg-icons": "^1.0.5",
@@ -653,9 +653,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "18.19.36",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.36.tgz",
-      "integrity": "sha512-tX1BNmYSWEvViftB26VLNxT6mEr37M7+ldUtq7rlKnv4/2fKYsJIOmqJAjT6h1DNuwQjIKgw3VJ/Dtw3yiTIQw==",
+      "version": "18.19.37",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.37.tgz",
+      "integrity": "sha512-Pi53fdVMk7Ig5IfAMltQQMgtY7xLzHaEous8IQasYsdQbYK3v90FkxI3XYQCe/Qme58pqp14lXJIsFmGP8VoZQ==",
       "dev": true,
       "dependencies": {
         "undici-types": "~5.26.4"
@@ -1907,9 +1907,9 @@
       }
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.805",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.805.tgz",
-      "integrity": "sha512-8W4UJwX/w9T0QSzINJckTKG6CYpAUTqsaWcWIsdud3I1FYJcMgW9QqT1/4CBff/pP/TihWh13OmiyY8neto6vw=="
+      "version": "1.4.807",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.807.tgz",
+      "integrity": "sha512-kSmJl2ZwhNf/bcIuCH/imtNOKlpkLDn2jqT5FJ+/0CXjhnFaOa9cOe9gHKKy71eM49izwuQjZhKk+lWQ1JxB7A=="
     },
     "node_modules/emojis-list": {
       "version": "3.0.0",
@@ -5748,16 +5748,16 @@
       }
     },
     "node_modules/typescript": {
-      "version": "5.4.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
-      "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
       "devOptional": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
       },
       "engines": {
-        "node": ">=14.17"
+        "node": ">=4.2.0"
       }
     },
     "node_modules/ua-parser-js": {
@@ -6182,9 +6182,9 @@
       }
     },
     "node_modules/vue-router": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz",
-      "integrity": "sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==",
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.3.tgz",
+      "integrity": "sha512-8Q+u+WP4N2SXY38FDcF2H1dUEbYVHVPtPCPZj/GTZx8RCbiB8AtJP9+YIxn4Vs0svMTNQcLIzka4GH7Utkx9xQ==",
       "dependencies": {
         "@vue/devtools-api": "^6.5.1"
       },

+ 9 - 8
Web/package.json

@@ -1,6 +1,8 @@
 {
-  "name": "demo-web",
-  "version": "0.0.1",
+  "name": "uav-manage-web",
+  "version": "1.0.0",
+  "description": "无人机管理系统",
+  "license": "ISC",
   "scripts": {
     "start": "vite",
     "build": "vite build"
@@ -11,7 +13,7 @@
     "@vitejs/plugin-legacy": "^1.6.2",
     "agora-rtc-sdk-ng": "^4.12.1",
     "ant-design-vue": "^2.2.8",
-    "axios": "^0.21.4",
+    "axios": "^0.21.1",
     "eventemitter3": "^5.0.0",
     "mitt": "^3.0.0",
     "mqtt": "^4.3.7",
@@ -25,8 +27,8 @@
     "vue": "^3.2.26",
     "vue-cookies": "^1.7.4",
     "vue-i18n": "^9.1.6",
-    "vue-router": "4.3.0",
-    "vuex": "^4.1.0"
+    "vue-router": "4",
+    "vuex": "^4.0.2"
   },
   "devDependencies": {
     "@types/node": "^18.15.0",
@@ -34,14 +36,13 @@
     "@vitejs/plugin-vue": "^1.2.4",
     "@vue/compiler-sfc": "^3.0.5",
     "rollup-plugin-external-globals": "^0.6.1",
-    "sass": "^1.77.0",
-    "typescript": "^5.4.0",
+    "sass": "^1.35.1",
+    "typescript": "^4.5.4",
     "vite": "^2.4.0",
     "vite-plugin-style-import": "^1.0.1",
     "vite-plugin-svg-icons": "^1.0.5",
     "vite-plugin-vconsole": "^1.1.0"
   },
-  "license": "ISC",
   "vite": {
     "optimizeDeps": {
       "include": [

+ 2 - 2
Web/src/App.vue

@@ -16,7 +16,7 @@ export default defineComponent({
   name: 'App',
   components: { GMap },
 
-  setup() {
+  setup () {
     const store = useMyStore()
     return {}
   }
@@ -39,4 +39,4 @@ export default defineComponent({
   width: 100%;
   height: 100%
 }
-</style>
+</style>

+ 4 - 0
Web/src/api/http/request.ts

@@ -33,6 +33,7 @@ instance.interceptors.request.use(
 
 instance.interceptors.response.use(
   response => {
+    console.info('URL: ' + response.config.baseURL + response.config.url, '\nData: ', response.data, '\nResponse:', response)
     if (response.data.code && response.data.code !== 0) {
       message.error(response.data.message)
     }
@@ -41,7 +42,10 @@ instance.interceptors.response.use(
   err => {
     const requestId = err?.config?.headers && err?.config?.headers[REQUEST_ID]
     if (requestId) {
+      console.info(REQUEST_ID, ':', requestId)
     }
+    console.info('url: ', err?.config?.url, `【${err?.config?.method}】 \n>>>> err: `, err)
+
     let description = '-'
     if (err.response?.data && err.response.data.message) {
       description = err.response.data.message

+ 37 - 23
Web/src/components/LayersTree.vue

@@ -1,13 +1,27 @@
 <template>
   <span>
-    <a-tree draggable :defaultExpandAll="true" class="device-map-layers" @drop="onDrop" v-bind="$attrs">
-      <a-tree-node :title="layer.name" :id="layer.id" v-for="layer in getTreeData" :key="layer.id">
+    <a-tree
+      draggable
+      :defaultExpandAll="true"
+      class="device-map-layers"
+      @drop="onDrop"
+      v-bind="$attrs"
+    >
+      <a-tree-node
+        :title="layer.name"
+        :id="layer.id"
+        v-for="layer in getTreeData"
+        :key="layer.id"
+      >
         <!-- <template #title>
                 {{layer.name}}
               </template> -->
         <template v-if="layer.elements">
-          <a-tree-node v-for="resource in layer.elements" :id="getLayerTreeKey('resource', resource.id)"
-            :key="getLayerTreeKey('resource', resource.id)">
+          <a-tree-node
+            v-for="resource in layer.elements"
+            :id="getLayerTreeKey('resource', resource.id)"
+            :key="getLayerTreeKey('resource', resource.id)"
+          >
             <template #title>
               {{ resource.name }}
             </template>
@@ -32,6 +46,7 @@ const state = reactive({
   expandedKeys: [] as string[]
 })
 const getTreeData = computed(() => {
+  // console.log('props.treeData', JSON.parse(JSON.stringify(props.layerData)))
   return JSON.parse(JSON.stringify(props.layerData))
 })
 const shareId = computed(() => {
@@ -40,14 +55,14 @@ const shareId = computed(() => {
 const defaultId = computed(() => {
   return store.state.layerBaseInfo.default
 })
-async function onDrop({ node, dragNode, dropPosition, dropToGap }: DropEvent) {
+async function onDrop ({ node, dragNode, dropPosition, dropToGap }: DropEvent) {
   let _treeData = props.layerData || []
   let dragKey = dragNode.eventKey
   dragKey = dragKey.replaceAll('resource__', '')
   const dropPos = node.pos.split('-')
   let dropKey =
     node.eventKey.includes(shareId.value) ||
-      node.eventKey.includes(defaultId.value)
+    node.eventKey.includes(defaultId.value)
       ? node.eventKey
       : node.$parent.eventKey
   if (!dragKey || !dropKey) return
@@ -79,15 +94,16 @@ async function onDrop({ node, dragNode, dropPosition, dropToGap }: DropEvent) {
     })
   }
   _treeData = data
+  // console.log('_treeData', _treeData)
 }
 </script>
 <style lang="scss">
 $antPrefix: 'ant';
-
 .device-map-layers.#{$antPrefix}-tree {
   color: #fff;
 
-  .#{$antPrefix}-tree-checkbox:not(.#{$antPrefix}-tree-checkbox-checked) .#{$antPrefix}-tree-checkbox-inner {
+  .#{$antPrefix}-tree-checkbox:not(.#{$antPrefix}-tree-checkbox-checked)
+    .#{$antPrefix}-tree-checkbox-inner {
     background-color: unset;
   }
 
@@ -96,7 +112,7 @@ $antPrefix: 'ant';
   }
 
   // 第一个层级的 li,有左边距 16px
-  >li {
+  > li {
     padding-left: 16px;
     padding-right: 16px;
   }
@@ -112,15 +128,14 @@ $antPrefix: 'ant';
       padding-top: 4px;
     }
 
-    &.#{$antPrefix}-tree-treenode-disabled>.#{$antPrefix}-tree-node-content-wrapper {
+    &.#{$antPrefix}-tree-treenode-disabled
+      > .#{$antPrefix}-tree-node-content-wrapper {
       height: 20px;
-
       span {
         color: #fff;
       }
     }
-
-    >ul {
+    > ul {
       width: 100%;
     }
 
@@ -134,9 +149,9 @@ $antPrefix: 'ant';
     .#{$antPrefix}-tree-checkbox {
       z-index: 1;
     }
-
     .#{$antPrefix}-tree-checkbox:hover::after,
-    .#{$antPrefix}-tree-checkbox-wrapper:hover .#{$antPrefix}-tree-checkbox::after {
+    .#{$antPrefix}-tree-checkbox-wrapper:hover
+      .#{$antPrefix}-tree-checkbox::after {
       visibility: collapse;
     }
 
@@ -162,7 +177,7 @@ $antPrefix: 'ant';
         background-color: transparent;
       }
 
-      >span {
+      > span {
         &::before {
           // position: absolute;
           // right: 0;
@@ -173,7 +188,7 @@ $antPrefix: 'ant';
         }
 
         // 进度条组件需要相对最外层定位,进度条组件的position不能设置为relative
-        >*:not(.progress-wrapper) {
+        > *:not(.progress-wrapper) {
           position: relative;
           z-index: 1;
         }
@@ -182,8 +197,7 @@ $antPrefix: 'ant';
       &.#{$antPrefix}-tree-node-selected {
         background-color: transparent;
         color: #2d8cf0;
-
-        >span {
+        > span {
           &::before {
             background-color: #4f4f4f;
           }
@@ -191,12 +205,12 @@ $antPrefix: 'ant';
       }
     }
   }
-
-  span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_open .#{$antPrefix}-tree-switcher-icon {
+  span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_open
+    .#{$antPrefix}-tree-switcher-icon {
     transform: rotate(0deg) !important;
   }
-
-  span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_close .#{$antPrefix}-tree-switcher-icon {
+  span.#{$antPrefix}-tree-switcher.#{$antPrefix}-tree-switcher_close
+    .#{$antPrefix}-tree-switcher-icon {
     transform: rotate(0deg) !important;
   }
 }

+ 1 - 0
Web/src/components/MediaPanel.vue

@@ -117,6 +117,7 @@ function getFiles () {
     mediaData.data = res.data.list
     paginationProp.total = res.data.pagination.total
     paginationProp.current = res.data.pagination.page
+    console.info(mediaData.data[0])
   })
 }
 

+ 20 - 20
Web/src/components/common/topbar.vue

@@ -6,28 +6,29 @@
     </div>
 
     <a-space class="fz16 height-100" size="large">
-        <router-link
-        v-for="item in options"
-        :key="item.key"
-        :to="item.path"
-        :class="{
-            'menu-item': true,
-        }">
-          <span @click="selectedRoute(item.path)" :style="selected === item.path ? 'color: #2d8cf0;' : 'color: white'">{{ item.label }}</span>
-        </router-link>
+      <router-link v-for="item in options" :key="item.key" :to="item.path" :class="{
+        'menu-item': true,
+      }">
+        <span @click="selectedRoute(item.path)" :style="selected === item.path ? 'color: #2d8cf0;' : 'color: white'">{{
+          item.label }}</span>
+      </router-link>
     </a-space>
 
     <div class="height-100 fz16 flex-row flex-justify-between flex-align-center">
       <a-dropdown>
         <div class="height-100">
-          <span class="fz20 mt20" style="border: 2px solid white; border-radius: 50%; display: inline-flex;"><UserOutlined /></span>
+          <span class="fz20 mt20" style="border: 2px solid white; border-radius: 50%; display: inline-flex;">
+            <UserOutlined />
+          </span>
           <span class="ml10 mr10" style="float: right;">{{ username }}</span>
         </div>
         <template #overlay>
           <a-menu theme="dark" class="flex-column flex-justify-between flex-align-center">
             <a-menu-item>
-              <span class="mr10" style="font-size: 16px;"><ExportOutlined /></span>
-              <span @click="logout">Log Out</span>
+              <span class="mr10" style="font-size: 16px;">
+                <PoweroffOutlined />
+              </span>
+              <span @click="logout">退出登录</span>
             </a-menu-item>
           </a-menu>
         </template>
@@ -42,7 +43,7 @@ import { defineComponent, onMounted, ref } from 'vue'
 import { getRoot } from '/@/root'
 import { getPlatformInfo } from '/@/api/manage'
 import { ELocalStorageKey, ERouterName } from '/@/types'
-import { UserOutlined, ExportOutlined } from '@ant-design/icons-vue'
+import { UserOutlined, PoweroffOutlined } from '@ant-design/icons-vue'
 import cloudapi from '/@/assets/icons/cloudapi.png'
 
 const root = getRoot()
@@ -51,11 +52,11 @@ interface IOptions {
   key: number
   label: string
   path:
-    | string
-    | {
-        path: string
-        query?: any
-      }
+  | string
+  | {
+    path: string
+    query?: any
+  }
   icon: string
 }
 const username = ref(localStorage.getItem(ELocalStorageKey.Username))
@@ -75,7 +76,7 @@ onMounted(() => {
   })
 })
 
-function selectedRoute (path: string) {
+function selectedRoute(path: string) {
   selected.value = path
 }
 
@@ -92,5 +93,4 @@ const logout = () => {
   font-weight: 500;
   font-size: 18px;
 }
-
 </style>

+ 52 - 30
Web/src/components/devices/device-hms/DeviceHmsDrawer.vue

@@ -1,56 +1,78 @@
 <template>
-  <a-drawer title="Hms Info" placement="right" v-model:visible="sVisible" @update:visible="onVisibleChange"
-    :destroyOnClose="true" :width="800">
+  <a-drawer
+    title="Hms Info"
+    placement="right"
+    v-model:visible="sVisible"
+    @update:visible="onVisibleChange"
+    :destroyOnClose="true"
+    :width="800">
     <div class="flex-row flex-align-center">
       <div style="width: 240px;">
-        <a-range-picker v-model:value="time" format="YYYY-MM-DD" :placeholder="['Start Time', 'End Time']"
-          @change="onTimeChange" />
+        <a-range-picker
+          v-model:value="time"
+          format="YYYY-MM-DD"
+          :placeholder="['Start Time', 'End Time']"
+          @change="onTimeChange"/>
       </div>
       <div class="ml5">
-        <a-select style="width: 150px" v-model:value="param.level" @select="onLevelSelect">
-          <a-select-option v-for="item in levels" :key="item.label" :value="item.value">
+        <a-select
+          style="width: 150px"
+          v-model:value="param.level"
+          @select="onLevelSelect">
+          <a-select-option
+            v-for="item in levels"
+            :key="item.label"
+            :value="item.value"
+          >
             {{ item.label }}
           </a-select-option>
         </a-select>
       </div>
       <div class="ml5">
-        <a-select v-model:value="param.domain" :disabled="!param.children_sn || !param.device_sn" style="width: 150px"
+        <a-select
+          v-model:value="param.domain"
+          :disabled="!param.children_sn || !param.device_sn"
+          style="width: 150px"
           @select="onDeviceTypeSelect">
-          <a-select-option v-for="item in deviceTypes" :key="item.label" :value="item.value">
+          <a-select-option
+            v-for="item in deviceTypes"
+            :key="item.label"
+            :value="item.value"
+          >
             {{ item.label }}
           </a-select-option>
         </a-select>
       </div>
       <div class="ml5">
-        <a-input-search v-model:value="param.message" placeholder="input search message" style="width: 200px"
-          @search="getHms" />
+        <a-input-search
+          v-model:value="param.message"
+          placeholder="input search message"
+          style="width: 200px"
+          @search="getHms"/>
       </div>
     </div>
     <div>
-      <a-table :columns="hmsColumns" :scroll="{ x: '100%', y: 600 }" :data-source="hmsData.data"
-        :pagination="hmsPaginationProp" @change="refreshHmsData" row-key="hms_id" :rowClassName="rowClassName"
-        :loading="loading">
+      <a-table :columns="hmsColumns"  :scroll="{ x: '100%', y: 600 }" :data-source="hmsData.data" :pagination="hmsPaginationProp" @change="refreshHmsData" row-key="hms_id"
+        :rowClassName="rowClassName" :loading="loading">
         <template #time="{ record }">
           <div>{{ record.create_time }}</div>
           <div :style="record.update_time ? '' : record.level === EHmsLevel.CAUTION ? 'color: orange;' :
-            record.level === EHmsLevel.WARN ? 'color: red;' : 'color: #28d445;'">{{ record.update_time ?? 'It is
-            happening...' }}</div>
+            record.level === EHmsLevel.WARN ? 'color: red;' : 'color: #28d445;'">{{ record.update_time ?? 'It is happening...' }}</div>
         </template>
         <template #level="{ text }">
           <div class="flex-row flex-align-center">
-            <div :class="text === EHmsLevel.CAUTION ? 'caution' : text === EHmsLevel.WARN ? 'warn' : 'notice'"
-              style="width: 10px; height: 10px; border-radius: 50%;"></div>
+            <div :class="text === EHmsLevel.CAUTION ? 'caution' : text === EHmsLevel.WARN ? 'warn' : 'notice'" style="width: 10px; height: 10px; border-radius: 50%;"></div>
             <div style="margin-left: 3px;">{{ EHmsLevel[text] }}</div>
           </div>
         </template>
         <template v-for="col in ['code', 'message']" #[col]="{ text }" :key="col">
           <a-tooltip :title="text">
-            <div>{{ text }}</div>
+              <div >{{ text }}</div>
           </a-tooltip>
         </template>
-        <template #domain="{ text }">
+        <template #domain="{text}">
           <a-tooltip :title="EDeviceTypeName[text]">
-            <div>{{ EDeviceTypeName[text] }}</div>
+              <div >{{ EDeviceTypeName[text] }}</div>
           </a-tooltip>
         </template>
       </a-table>
@@ -86,11 +108,11 @@ watch(props, () => {
   }
 })
 
-function onVisibleChange(sVisible: boolean) {
+function onVisibleChange (sVisible: boolean) {
   setVisible(sVisible)
 }
 
-function setVisible(v: boolean, e?: Event) {
+function setVisible (v: boolean, e?: Event) {
   sVisible.value = v
   emit('update:visible', v, e)
 }
@@ -126,14 +148,14 @@ const hmsPaginationProp = reactive({
 })
 
 // 获取分页信息
-function getPaginationBody() {
+function getPaginationBody () {
   return {
     page: hmsPaginationProp.current,
     page_size: hmsPaginationProp.pageSize
   } as IPage
 }
 
-function showHms() {
+function showHms () {
   const dock = props.device
   if (!dock) return
   if (dock.domain === EDeviceTypeName.Dock) {
@@ -145,7 +167,7 @@ function showHms() {
   }
 }
 
-function refreshHmsData(page: Pagination) {
+function refreshHmsData (page: Pagination) {
   hmsPaginationProp.current = page?.current!
   hmsPaginationProp.pageSize = page?.pageSize!
   getHms()
@@ -205,7 +227,7 @@ const rowClassName = (record: any, index: number) => {
 
 const time = ref([moment(param.begin_time), moment(param.end_time)])
 
-function getHms() {
+function getHms () {
   loading.value = true
   getDeviceHms(param, workspaceId, getPaginationBody())
     .then(res => {
@@ -221,20 +243,20 @@ function getHms() {
     })
 }
 
-function getDeviceHmsBySn(sn: string, childSn: string) {
+function getDeviceHmsBySn (sn: string, childSn: string) {
   param.device_sn = sn
   param.children_sn = childSn
   param.sns = [param.device_sn, param.children_sn]
   getHms()
 }
 
-function onTimeChange(newTime: [Moment, Moment]) {
+function onTimeChange (newTime: [Moment, Moment]) {
   param.begin_time = newTime[0].valueOf()
   param.end_time = newTime[1].valueOf()
   getHms()
 }
 
-function onDeviceTypeSelect(val: number) {
+function onDeviceTypeSelect (val: number) {
   param.sns = [param.device_sn, param.children_sn]
   if (val === EDeviceTypeName.Dock) {
     param.sns = [param.device_sn, '']
@@ -245,7 +267,7 @@ function onDeviceTypeSelect(val: number) {
   getHms()
 }
 
-function onLevelSelect(val: number) {
+function onLevelSelect (val: number) {
   param.level = val
   getHms()
 }

+ 39 - 31
Web/src/components/devices/device-log/DeviceLogDetailModal.vue

@@ -1,36 +1,45 @@
 <template>
-  <a-modal title="日志上传详情" v-model:visible="sVisible" width="900px" :footer="null" @update:visible="onVisibleChange">
+  <a-modal
+    title="日志上传详情"
+    v-model:visible="sVisible"
+    width="900px"
+    :footer="null"
+    @update:visible="onVisibleChange">
     <div class="device-log-detail-wrap">
       <div class="device-log-list">
         <div class="log-list-item">
-          <a-button type="primary" class="download-btn"
-            :disabled="!airportTableLogState.logList?.file_id || !airportTableLogState.logList?.object_key" size="small"
-            @click="onDownloadLog(airportTableLogState.logList.file_id)">
-            下载机场日志
+          <a-button type="primary" class="download-btn" :disabled="!airportTableLogState.logList?.file_id || !airportTableLogState.logList?.object_key"  size="small" @click="onDownloadLog(airportTableLogState.logList.file_id)">
+             下载机场日志
           </a-button>
-          <a-table :columns="airportLogColumns" :scroll="{ x: '100%', y: 600 }"
-            :data-source="airportTableLogState.logList?.list" rowKey="boot_index" :pagination="false">
-            <template #log_time="{ record }">
-              <div>{{ getLogTime(record) }}</div>
+          <a-table  :columns="airportLogColumns"
+                    :scroll="{ x: '100%', y: 600 }"
+                    :data-source="airportTableLogState.logList?.list"
+                    rowKey="boot_index"
+                    :pagination = "false"
+                    >
+            <template #log_time="{record}">
+              <div>{{getLogTime(record)}}</div>
             </template>
-            <template #size="{ record }">
-              <div>{{ getLogSize(record.size) }}</div>
+            <template #size="{record}">
+              <div>{{getLogSize(record.size)}}</div>
             </template>
           </a-table>
         </div>
         <div class="log-list-item">
-          <a-button type="primary" class="download-btn"
-            :disabled="!droneTableLogState.logList?.file_id || !droneTableLogState.logList?.object_key" size="small"
-            @click="onDownloadLog(droneTableLogState.logList.file_id)">
-            下载飞行器日志
+          <a-button type="primary"  class="download-btn" :disabled="!droneTableLogState.logList?.file_id || !droneTableLogState.logList?.object_key" size="small" @click="onDownloadLog(droneTableLogState.logList.file_id)">
+             下载飞行器日志
           </a-button>
-          <a-table :columns="droneLogColumns" :scroll="{ x: '100%', y: 600 }"
-            :data-source="droneTableLogState.logList?.list" rowKey="boot_index" :pagination="false">
-            <template #log_time="{ record }">
-              <div>{{ getLogTime(record) }}</div>
+          <a-table  :columns="droneLogColumns"
+                    :scroll="{ x: '100%', y: 600 }"
+                    :data-source="droneTableLogState.logList?.list"
+                    rowKey="boot_index"
+                    :pagination = "false"
+          >
+            <template #log_time="{record}">
+              <div>{{getLogTime(record)}}</div>
             </template>
-            <template #size="{ record }">
-              <div>{{ getLogSize(record.size) }}</div>
+            <template #size="{record}">
+              <div>{{getLogSize(record.size)}}</div>
             </template>
           </a-table>
         </div>
@@ -63,11 +72,11 @@ watchEffect(() => {
   }
 })
 
-function onVisibleChange(sVisible: boolean) {
+function onVisibleChange (sVisible: boolean) {
   setVisible(sVisible)
 }
 
-function setVisible(v: boolean, e?: Event) {
+function setVisible (v: boolean, e?: Event) {
   sVisible.value = v
   emit('update:visible', v, e)
 }
@@ -91,7 +100,7 @@ const droneTableLogState = reactive({
   logList: {} as DeviceLogFileInfo,
 })
 
-function classifyDeviceLog() {
+function classifyDeviceLog () {
   if (!props.deviceLog) return
   const { device_logs } = props.deviceLog
   const { files } = device_logs || {}
@@ -108,31 +117,30 @@ function classifyDeviceLog() {
 
 const { getLogTime, getLogSize } = useDeviceLogUploadDetail()
 
-async function onDownloadLog(fileId: string) {
+async function onDownloadLog (fileId: string) {
   const { data } = await getUploadDeviceLogUrl({
     file_id: fileId,
     logs_id: props.deviceLog?.logs_id || ''
   })
   if (data) {
     download(data)
-    // download('https:/github.com/dji-sdk/Mobile-SDK-Android-V5/archive/refs/heads/dev-sdk-main.zip')
+  // download('https:/github.com/dji-sdk/Mobile-SDK-Android-V5/archive/refs/heads/dev-sdk-main.zip')
   }
 }
 
 </script>
 
 <style lang="scss" scoped>
-.device-log-detail-wrap {
+.device-log-detail-wrap{
 
-  .device-log-list {
+  .device-log-list{
     display: flex;
     justify-content: space-between;
     padding: 8px 0;
-
-    .log-list-item {
+    .log-list-item{
       width: 420px;
 
-      .download-btn {
+      .download-btn{
         margin-bottom: 10px;
       }
     }

+ 38 - 26
Web/src/components/devices/device-log/DeviceLogUploadModal.vue

@@ -1,31 +1,44 @@
 <template>
-  <a-modal title="设备日志上传" v-model:visible="sVisible" width="900px" :footer="null" @update:visible="onVisibleChange">
+  <a-modal
+    title="设备日志上传"
+    v-model:visible="sVisible"
+    width="900px"
+    :footer="null"
+    @update:visible="onVisibleChange">
     <div class="device-log-upload-wrap">
       <div class="page-action-row">
         <a-button type="primary" :disabled="deviceLogUploadBtnDisabled" @click="uploadDeviceLog">上传日志</a-button>
       </div>
       <div class="device-log-list">
         <div class="log-list-item">
-          <a-table :columns="airportLogColumns" :scroll="{ x: '100%', y: 600 }"
-            :data-source="airportTableLogState.logList?.list" :loading="airportTableLogState.tableLoading"
-            :row-selection="airportTableLogState.rowSelection" rowKey="boot_index" :pagination="false">
-            <template #log_time="{ record }">
-              <div>{{ getLogTime(record) }}</div>
+          <a-table  :columns="airportLogColumns"
+                    :scroll="{ x: '100%', y: 600 }"
+                    :data-source="airportTableLogState.logList?.list"
+                    :loading="airportTableLogState.tableLoading"
+                    :row-selection="airportTableLogState.rowSelection"
+                    rowKey="boot_index"
+                    :pagination = "false">
+            <template #log_time="{record}">
+              <div>{{getLogTime(record)}}</div>
             </template>
-            <template #size="{ record }">
-              <div>{{ getLogSize(record.size) }}</div>
+            <template #size="{record}">
+              <div>{{getLogSize(record.size)}}</div>
             </template>
           </a-table>
         </div>
         <div class="log-list-item">
-          <a-table :columns="droneLogColumns" :scroll="{ x: '100%', y: 600 }"
-            :data-source="droneTableLogState.logList?.list" :loading="droneTableLogState.tableLoading"
-            :row-selection="droneTableLogState.rowSelection" rowKey="boot_index" :pagination="false">
-            <template #log_time="{ record }">
-              <div>{{ getLogTime(record) }}</div>
+          <a-table  :columns="droneLogColumns"
+                    :scroll="{ x: '100%', y: 600 }"
+                    :data-source="droneTableLogState.logList?.list"
+                    :loading="droneTableLogState.tableLoading"
+                    :row-selection="droneTableLogState.rowSelection"
+                    rowKey="boot_index"
+                    :pagination = "false">
+            <template #log_time="{record}">
+              <div>{{getLogTime(record)}}</div>
             </template>
-            <template #size="{ record }">
-              <div>{{ getLogSize(record.size) }}</div>
+            <template #size="{record}">
+              <div>{{getLogSize(record.size)}}</div>
             </template>
           </a-table>
         </div>
@@ -59,14 +72,14 @@ watchEffect(() => {
   }
 })
 
-function onVisibleChange(sVisible: boolean) {
+function onVisibleChange (sVisible: boolean) {
   setVisible(sVisible)
   if (!sVisible) {
     resetTableLogState()
   }
 }
 
-function setVisible(v: boolean, e?: Event) {
+function setVisible (v: boolean, e?: Event) {
   sVisible.value = v
   emit('update:visible', v, e)
 }
@@ -89,7 +102,7 @@ const airportTableLogState = reactive({
   rowSelection: {
     columnWidth: 15,
     selectedRowKeys: [] as number[],
-    onChange: (selectedRowKeys: number[], selectedRows: []) => {
+    onChange: (selectedRowKeys:number[], selectedRows: []) => {
       airportTableLogState.rowSelection.selectedRowKeys = selectedRowKeys
       airportTableLogState.selectRow = selectedRows
       console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
@@ -97,7 +110,7 @@ const airportTableLogState = reactive({
   }
 })
 
-function resetTableLogState() {
+function resetTableLogState () {
   airportTableLogState.logList = {} as DeviceLogFileInfo
   airportTableLogState.selectRow = []
   airportTableLogState.tableLoading = false
@@ -120,11 +133,11 @@ const droneTableLogState = reactive({
 
 const deviceLogUploadBtnDisabled = computed(() => {
   return (airportTableLogState.rowSelection.selectedRowKeys && airportTableLogState.rowSelection.selectedRowKeys.length <= 0) &&
-    (droneTableLogState.rowSelection.selectedRowKeys && droneTableLogState.rowSelection.selectedRowKeys.length <= 0)
+  (droneTableLogState.rowSelection.selectedRowKeys && droneTableLogState.rowSelection.selectedRowKeys.length <= 0)
 })
 
 // 获取设备内日志
-async function getDeviceLogInfo() {
+async function getDeviceLogInfo () {
   airportTableLogState.tableLoading = true
   droneTableLogState.tableLoading = true
   try {
@@ -151,7 +164,7 @@ async function getDeviceLogInfo() {
 }
 
 // 日志上传
-async function uploadDeviceLog() {
+async function uploadDeviceLog () {
   const body = {
     device_sn: props.device?.device_sn || '',
     files: [] as any
@@ -183,14 +196,13 @@ const { getLogTime, getLogSize } = useDeviceLogUploadDetail()
 </script>
 
 <style lang="scss" scoped>
-.device-log-upload-wrap {
+.device-log-upload-wrap{
 
-  .device-log-list {
+  .device-log-list{
     display: flex;
     justify-content: space-between;
     padding: 8px 0;
-
-    .log-list-item {
+    .log-list-item{
       width: 420px;
     }
   }

+ 52 - 43
Web/src/components/devices/device-log/DeviceLogUploadRecordDrawer.vue

@@ -1,5 +1,9 @@
 <template>
-  <a-drawer title="设备日志上传记录" placement="right" v-model:visible="sVisible" @update:visible="onVisibleChange"
+  <a-drawer
+    title="设备日志上传记录"
+    placement="right"
+    v-model:visible="sVisible"
+    @update:visible="onVisibleChange"
     :width="800">
     <!-- 设备日志上传记录 -->
     <div class="device-log-upload-record-wrap">
@@ -7,32 +11,32 @@
         <a-button type="primary" @click="onUploadDeviceLog">上传日志</a-button>
       </div>
       <div class="device-log-upload-list">
-        <a-table :columns="deviceLogUploadListColumns" :scroll="{ x: '100%', y: 600 }"
-          :data-source="deviceUploadLogState.uploadLogList" :loading="deviceUploadLogState.loading"
-          :pagination="deviceUploadLogState.paginationProp" @change="onDeviceUploadLogTableChange" rowKey="logs_id">
-          <!-- 设备类型 -->
+        <a-table :columns="deviceLogUploadListColumns"
+                  :scroll="{ x: '100%', y: 600 }"
+                  :data-source="deviceUploadLogState.uploadLogList"
+                  :loading="deviceUploadLogState.loading"
+                  :pagination="deviceUploadLogState.paginationProp"
+                  @change="onDeviceUploadLogTableChange"
+                  rowKey="logs_id">
+         <!-- 设备类型 -->
           <template #device_type="{ record }">
             <div>
-              <div v-if="getDeviceInfo(record).parents && getDeviceInfo(record).parents.length > 0">{{
-                DEVICE_NAME[getDeviceInfo(record).parents[0].device_model.device_model_key]}}</div>
-              <div v-if="getDeviceInfo(record).hosts && getDeviceInfo(record).hosts.length > 0">{{
-                DEVICE_NAME[getDeviceInfo(record).hosts[0].device_model.device_model_key]}}</div>
+              <div v-if="getDeviceInfo(record).parents && getDeviceInfo(record).parents.length > 0">{{ DEVICE_NAME[getDeviceInfo(record).parents[0].device_model.device_model_key]}}</div>
+              <div v-if="getDeviceInfo(record).hosts && getDeviceInfo(record).hosts.length > 0">{{ DEVICE_NAME[getDeviceInfo(record).hosts[0].device_model.device_model_key]}}</div>
             </div>
           </template>
           <!-- 设备sn -->
           <template #device_sn="{ record }">
             <div>
-              <div v-if="getDeviceInfo(record).parents && getDeviceInfo(record).parents.length > 0">{{
-                getDeviceInfo(record).parents[0].sn }}</div>
-              <div v-if="getDeviceInfo(record).hosts && getDeviceInfo(record).hosts.length > 0">{{
-                getDeviceInfo(record).hosts[0].sn }}</div>
+              <div v-if="getDeviceInfo(record).parents && getDeviceInfo(record).parents.length > 0">{{ getDeviceInfo(record).parents[0].sn }}</div>
+              <div v-if="getDeviceInfo(record).hosts && getDeviceInfo(record).hosts.length > 0">{{ getDeviceInfo(record).hosts[0].sn }}</div>
             </div>
           </template>
           <!-- 上传状态 -->
           <template #status="{ record }">
             <div>
               <div>
-                <span class="circle-icon" :style="{ backgroundColor: getDeviceLogUploadStatus(record).color }"></span>
+                <span class="circle-icon" :style="{backgroundColor: getDeviceLogUploadStatus(record).color}"></span>
                 {{ getDeviceLogUploadStatus(record).text }}
               </div>
               <div v-if="record.status === DeviceLogUploadStatusEnum.Uploading">
@@ -44,16 +48,16 @@
           <template #action="{ record }">
             <div class="row-action">
               <a-tooltip title="查看详情">
-                <FileTextOutlined @click="showDeviceLogDetail(record)" />
+                  <FileTextOutlined  @click="showDeviceLogDetail(record)"/>
               </a-tooltip>
               <span v-if="record.status === DeviceLogUploadStatusEnum.Uploading">
                 <a-tooltip title="取消">
-                  <StopOutlined @click="onCancelUploadDeviceLog(record)" />
+                  <StopOutlined @click="onCancelUploadDeviceLog(record)"/>
                 </a-tooltip>
               </span>
               <span v-else>
                 <a-tooltip title="删除">
-                  <DeleteOutlined @click="onDeleteUploadDeviceLog(record)" />
+                  <DeleteOutlined @click="onDeleteUploadDeviceLog(record)"/>
                 </a-tooltip>
               </span>
             </div>
@@ -63,12 +67,17 @@
     </div>
   </a-drawer>
   <!-- 设备日志上传弹框 -->
-  <DeviceLogUploadModal v-model:visible="deviceLogUploadModalVisible" :device="props.device"
-    @upload-log-ok="onUploadLogOk"></DeviceLogUploadModal>
+  <DeviceLogUploadModal
+     v-model:visible="deviceLogUploadModalVisible"
+     :device="props.device"
+     @upload-log-ok="onUploadLogOk"
+  ></DeviceLogUploadModal>
 
   <!-- 设备日志上传详情弹框 -->
-  <DeviceLogDetailModal v-model:visible="deviceLogDetailModalVisible" :deviceLog="currentDeviceLog">
-  </DeviceLogDetailModal>
+  <DeviceLogDetailModal
+     v-model:visible="deviceLogDetailModalVisible"
+     :deviceLog="currentDeviceLog"
+  ></DeviceLogDetailModal>
 </template>
 
 <script lang="ts" setup>
@@ -100,11 +109,11 @@ watchEffect(() => {
   }
 })
 
-function onVisibleChange(sVisible: boolean) {
+function onVisibleChange (sVisible: boolean) {
   setVisible(sVisible)
 }
 
-function setVisible(v: boolean, e?: Event) {
+function setVisible (v: boolean, e?: Event) {
   sVisible.value = v
   emit('update:visible', v, e)
 }
@@ -132,7 +141,7 @@ const deviceUploadLogState = reactive({
 })
 
 // 获取上传的设备日志
-async function getDeviceUploadLogInfo() {
+async function getDeviceUploadLogInfo () {
   deviceUploadLogState.loading = true
   try {
     const { code, data } = await getDeviceUploadLogList({
@@ -154,13 +163,13 @@ async function getDeviceUploadLogInfo() {
 type Pagination = TableState['pagination']
 
 // 获取设备信息
-function getDeviceInfo(deviceLogItem: GetDeviceUploadLogListRsp) {
+function getDeviceInfo (deviceLogItem: GetDeviceUploadLogListRsp) {
   const { device_topo: deviceTopo } = deviceLogItem
   return deviceTopo
 }
 
 // 获取上传状态
-function getDeviceLogUploadStatus(deviceLogItem: GetDeviceUploadLogListRsp) {
+function getDeviceLogUploadStatus (deviceLogItem: GetDeviceUploadLogListRsp) {
   const statusObj = {
     color: '',
     text: ''
@@ -172,7 +181,7 @@ function getDeviceLogUploadStatus(deviceLogItem: GetDeviceUploadLogListRsp) {
 }
 
 // 获取上传进度
-function getLogProgress(deviceLogItem: GetDeviceUploadLogListRsp) {
+function getLogProgress (deviceLogItem: GetDeviceUploadLogListRsp) {
   let percent = 0
   const { logs_progress } = deviceLogItem
   if (logs_progress && logs_progress.length > 0) {
@@ -185,7 +194,7 @@ function getLogProgress(deviceLogItem: GetDeviceUploadLogListRsp) {
 }
 
 // 设备日志上传进度更新
-function onDeviceLogUploadWs(data: DeviceLogUploadInfo) {
+function onDeviceLogUploadWs (data: DeviceLogUploadInfo) {
   const { sn, output } = data
   if (output) {
     const { files, status, logs_id: logId } = output || {}
@@ -210,7 +219,7 @@ function onDeviceLogUploadWs(data: DeviceLogUploadInfo) {
 useDeviceLogUploadProgressEvent(onDeviceLogUploadWs)
 
 // 搜索
-async function onDeviceUploadLogTableChange(page: Pagination) {
+async function onDeviceUploadLogTableChange (page: Pagination) {
   deviceUploadLogState.paginationProp.current = page?.current || 1
   deviceUploadLogState.paginationProp.pageSize = page?.pageSize || 20
   await getDeviceUploadLogInfo()
@@ -220,25 +229,25 @@ async function onDeviceUploadLogTableChange(page: Pagination) {
 const deviceLogDetailModalVisible = ref(false)
 const currentDeviceLog = ref({} as GetDeviceUploadLogListRsp)
 
-function showDeviceLogDetail(deviceLogItem: GetDeviceUploadLogListRsp) {
+function showDeviceLogDetail (deviceLogItem: GetDeviceUploadLogListRsp) {
   if (!deviceLogItem) return
   currentDeviceLog.value = deviceLogItem
   deviceLogDetailModalVisible.value = true
 }
 
 // 取消上传设备日志
-async function onCancelUploadDeviceLog(deviceLogItem: GetDeviceUploadLogListRsp) {
+async function onCancelUploadDeviceLog (deviceLogItem: GetDeviceUploadLogListRsp) {
   Modal.confirm({
     title: '取消日志上传',
     content: '您确认取消设备日志上传吗?',
     okType: 'danger',
-    onOk() {
+    onOk () {
       cancelDeviceLogUploadOk()
     },
   })
 }
 
-async function cancelDeviceLogUploadOk() {
+async function cancelDeviceLogUploadOk () {
   const { code } = await cancelDeviceLogUpload({
     device_sn: props.device?.device_sn || '',
     module_list: [DOMAIN.DOCK, DOMAIN.DRONE],
@@ -250,18 +259,18 @@ async function cancelDeviceLogUploadOk() {
 }
 
 // 删除上传的设备日志
-function onDeleteUploadDeviceLog(deviceLogItem: GetDeviceUploadLogListRsp) {
+function onDeleteUploadDeviceLog (deviceLogItem: GetDeviceUploadLogListRsp) {
   Modal.confirm({
     title: '删除上传日志',
     content: '您确认删除该条已上传设备日志吗?',
     okType: 'danger',
-    onOk() {
+    onOk () {
       deleteUploadDeviceLogOk(deviceLogItem)
     },
   })
 }
 
-async function deleteUploadDeviceLogOk(deviceLogItem: GetDeviceUploadLogListRsp) {
+async function deleteUploadDeviceLogOk (deviceLogItem: GetDeviceUploadLogListRsp) {
   const { code } = await deleteDeviceLogUpload({
     device_sn: props.device?.device_sn || '',
     logs_id: deviceLogItem.logs_id
@@ -274,25 +283,25 @@ async function deleteUploadDeviceLogOk(deviceLogItem: GetDeviceUploadLogListRsp)
 // 上传日志
 const deviceLogUploadModalVisible = ref(false)
 
-function onUploadDeviceLog() {
+function onUploadDeviceLog () {
   deviceLogUploadModalVisible.value = true
 }
 
-function onUploadLogOk() {
+function onUploadLogOk () {
   // 刷新列表
   getDeviceUploadLogInfo()
 }
 </script>
 
 <style lang="scss" scoped>
-.device-log-upload-record-wrap {
-  .page-action-row {
+.device-log-upload-record-wrap{
+  .page-action-row{
     display: flex;
     justify-content: space-between;
     width: 100%;
   }
 
-  .device-log-upload-list {
+  .device-log-upload-list{
     padding: 20px 0 10px;
   }
 
@@ -306,10 +315,10 @@ function onUploadLogOk() {
     flex-shrink: 0;
   }
 
-  .row-action {
+  .row-action{
     color: #2d8cf0;
 
-    &>span {
+    & > span{
       margin-right: 10px;
     }
   }

+ 3 - 3
Web/src/components/devices/device-log/use-device-log-upload-detail.ts

@@ -5,14 +5,14 @@ import {
   DATE_FORMAT_MINUTE
 } from '/@/utils/constants'
 
-export function useDeviceLogUploadDetail() {
-  function getLogTime(deviceLog: DeviceLogItem): string {
+export function useDeviceLogUploadDetail () {
+  function getLogTime (deviceLog: DeviceLogItem): string {
     const startTime = formatUnixTime(deviceLog.start_time, DATE_FORMAT_MINUTE)
     const endTime = formatUnixTime(deviceLog.end_time, DATE_FORMAT_MINUTE)
     return `${startTime} — ${endTime}`
   }
 
-  function getLogSize(size: number) {
+  function getLogSize (size: number) {
     return bytesToSize(size)
   }
 

+ 3 - 2
Web/src/components/devices/device-log/use-device-log-upload-progress-event.ts

@@ -2,9 +2,10 @@ import EventBus from '/@/event-bus/'
 import { onMounted, onBeforeUnmount } from 'vue'
 import { DeviceLogUploadInfo } from '/@/types/device-log'
 
-export function useDeviceLogUploadProgressEvent(onDeviceLogUploadWs: (data: DeviceLogUploadInfo) => void): void {
-  function handleDeviceLogUploadProgress(payload: any) {
+export function useDeviceLogUploadProgressEvent (onDeviceLogUploadWs: (data: DeviceLogUploadInfo) => void): void {
+  function handleDeviceLogUploadProgress (payload: any) {
     onDeviceLogUploadWs(payload.data)
+    // console.log('payload', payload.data)
   }
 
   onMounted(() => {

+ 3 - 2
Web/src/components/devices/device-upgrade/use-device-upgrade-event.ts

@@ -2,9 +2,10 @@ import EventBus from '/@/event-bus/'
 import { onMounted, onBeforeUnmount } from 'vue'
 import { DeviceCmdExecuteInfo, DeviceCmdExecuteStatus } from '/@/types/device-cmd'
 
-export function useDeviceUpgradeEvent(onDeviceUpgradeWs: (payload: DeviceCmdExecuteInfo) => void): void {
-  function handleDeviceUpgrade(payload: any) {
+export function useDeviceUpgradeEvent (onDeviceUpgradeWs: (payload: DeviceCmdExecuteInfo) => void): void {
+  function handleDeviceUpgrade (payload: any) {
     onDeviceUpgradeWs(payload.data)
+    // console.log('payload', payload.data)
   }
 
   onMounted(() => {

+ 7 - 6
Web/src/components/flight-area/use-flight-area.ts

@@ -14,7 +14,7 @@ import { useGMapCover } from '/@/hooks/use-g-map-cover'
 import moment from 'moment'
 import { DATE_FORMAT } from '/@/utils/constants'
 
-export function useFlightArea() {
+export function useFlightArea () {
   const root = getRoot()
   const store = rootStore
   const coverMap = store.state.coverMap
@@ -22,7 +22,7 @@ export function useFlightArea() {
   let useGMapCoverHook = useGMapCover()
 
   const MIN_RADIUS = 10
-  function checkCircle(obj: any): boolean {
+  function checkCircle (obj: any): boolean {
     if (obj.getRadius() < MIN_RADIUS) {
       message.error(`The radius must be greater than ${MIN_RADIUS}m.`)
       root.$map.remove(obj)
@@ -31,17 +31,18 @@ export function useFlightArea() {
     return true
   }
 
-  function checkPolygon(obj: any): boolean {
+  function checkPolygon (obj: any): boolean {
     const path: any[][] = obj.getPath()
     if (path.length < 3) {
       message.error('The path of the polygon cannot be crossed.')
       root.$map.remove(obj)
       return false
     }
+    // root.$aMap.GeometryUtil.doesLineLineIntersect()
     return true
   }
 
-  function setExtData(obj: any) {
+  function setExtData (obj: any) {
     let ext = obj.getExtData()
     const id = uuidv4()
     const name = `${ext.type}-${moment().format(DATE_FORMAT)}`
@@ -49,7 +50,7 @@ export function useFlightArea() {
     obj.setExtData(ext)
     return ext
   }
-  function createFlightArea(obj: any) {
+  function createFlightArea (obj: any) {
     const ext = obj.getExtData()
     const data = {
       id: ext.id,
@@ -81,7 +82,7 @@ export function useFlightArea() {
     }).finally(() => root.$map.remove(obj))
   }
 
-  function getDrawFlightAreaCallback(obj: any) {
+  function getDrawFlightAreaCallback (obj: any) {
     useGMapCoverHook = useGMapCover()
     const ext = setExtData(obj)
     switch (ext.mapType) {

+ 7 - 4
Web/src/components/g-map/use-drone-control-ws-event.ts

@@ -8,10 +8,10 @@ import { ControlSourceChangeType, ControlSourceChangeInfo, FlyToPointMessage, Ta
 export interface UseDroneControlWsEventParams {
 }
 
-export function useDroneControlWsEvent(sn: string, payloadSn: string, funcs?: UseDroneControlWsEventParams) {
+export function useDroneControlWsEvent (sn: string, payloadSn: string, funcs?: UseDroneControlWsEventParams) {
   const droneControlSource = ref(ControlSource.A)
   const payloadControlSource = ref(ControlSource.B)
-  function onControlSourceChange(data: ControlSourceChangeInfo) {
+  function onControlSourceChange (data: ControlSourceChangeInfo) {
     if (data.type === ControlSourceChangeType.Flight && data.sn === sn) {
       droneControlSource.value = data.control_source
       message.info(`Flight control is changed to ${droneControlSource.value}`)
@@ -23,7 +23,7 @@ export function useDroneControlWsEvent(sn: string, payloadSn: string, funcs?: Us
     }
   }
 
-  function handleProgress(key: string, message: string, error: number) {
+  function handleProgress (key: string, message: string, error: number) {
     if (error !== 0) {
       notification.error({
         key: key,
@@ -41,7 +41,7 @@ export function useDroneControlWsEvent(sn: string, payloadSn: string, funcs?: Us
     }
   }
 
-  function handleDroneControlWsEvent(payload: any) {
+  function handleDroneControlWsEvent (payload: any) {
     if (!payload) {
       return
     }
@@ -71,9 +71,12 @@ export function useDroneControlWsEvent(sn: string, payloadSn: string, funcs?: Us
       }
       case EBizCode.DrcStatusNotify: {
         const { sn: deviceSn, result, message: msg } = payload.data as DrcStatusNotifyMessage
+        // handleProgress(EBizCode.DrcStatusNotify, `device(sn: ${deviceSn}) ${msg}`, result)
+
         break
       }
     }
+    // console.log('payload.biz_code', payload.data)
   }
 
   onMounted(() => {

+ 72 - 21
Web/src/components/livestream-agora.vue

@@ -6,19 +6,38 @@
       <template v-if="livePara.liveState && dronePara.isDockLive">
         <span class="mr10">Lens:</span>
         <a-radio-group v-model:value="dronePara.lensSelected" button-style="solid">
-          <a-radio-button v-for="lens in dronePara.lensList" :key="lens" :value="lens">{{ lens }}</a-radio-button>
+          <a-radio-button v-for="lens in dronePara.lensList" :key="lens" :value="lens">{{lens}}</a-radio-button>
         </a-radio-group>
       </template>
       <template v-else>
-        <a-select style="width:150px" placeholder="Select Drone" v-model:value="dronePara.droneSelected">
-          <a-select-option v-for="item in dronePara.droneList" :key="item.value" :value="item.value"
-            @click="onDroneSelect(item)">{{ item.label }}</a-select-option>
-        </a-select>
-        <a-select class="ml10" style="width:150px" placeholder="Select Camera" v-model:value="dronePara.cameraSelected">
-          <a-select-option v-for="item in dronePara.cameraList" :key="item.value" :value="item.value"
-            @click="onCameraSelect(item)">{{ item.label }}</a-select-option>
-        </a-select>
-        <!-- <a-select
+      <a-select
+        style="width:150px"
+        placeholder="Select Drone"
+        v-model:value="dronePara.droneSelected"
+      >
+        <a-select-option
+          v-for="item in dronePara.droneList"
+          :key="item.value"
+          :value="item.value"
+          @click="onDroneSelect(item)"
+          >{{ item.label }}</a-select-option
+        >
+      </a-select>
+      <a-select
+        class="ml10"
+        style="width:150px"
+        placeholder="Select Camera"
+        v-model:value="dronePara.cameraSelected"
+      >
+        <a-select-option
+          v-for="item in dronePara.cameraList"
+          :key="item.value"
+          :value="item.value"
+          @click="onCameraSelect(item)"
+          >{{ item.label }}</a-select-option
+        >
+      </a-select>
+      <!-- <a-select
         class="ml10"
         style="width:150px"
         placeholder="Select Lens"
@@ -32,9 +51,18 @@
         >
       </a-select> -->
       </template>
-      <a-select class="ml10" style="width:150px" placeholder="Select Clarity" @select="onClaritySelect">
-        <a-select-option v-for="item in clarityList" :key="item.value" :value="item.value">{{ item.label
-          }}</a-select-option>
+      <a-select
+        class="ml10"
+        style="width:150px"
+        placeholder="Select Clarity"
+        @select="onClaritySelect"
+      >
+        <a-select-option
+          v-for="item in clarityList"
+          :key="item.value"
+          :value="item.value"
+          >{{ item.label }}</a-select-option
+        >
       </a-select>
     </div>
     <p class="fz16 mt10">
@@ -44,18 +72,30 @@
       <span class="mr10">AppId:</span>
       <a-input v-model:value="agoraPara.appid" placeholder="APP ID"></a-input>
       <span class="ml10">Token:</span>
-      <a-input class="ml10" v-model:value="agoraPara.token" placeholder="Token"></a-input>
+      <a-input
+        class="ml10"
+        v-model:value="agoraPara.token"
+        placeholder="Token"
+      ></a-input>
       <span class="ml10">Channel:</span>
-      <a-input class="ml10" v-model:value="agoraPara.channel" placeholder="Channel"></a-input>
+      <a-input
+        class="ml10"
+        v-model:value="agoraPara.channel"
+        placeholder="Channel"
+      ></a-input>
     </div>
     <div class="mt20 flex-row flex-justify-center flex-align-center">
-      <a-button v-if="livePara.liveState && dronePara.isDockLive" type="primary" large @click="onSwitch">Switch
-        Lens</a-button>
+      <a-button v-if="livePara.liveState && dronePara.isDockLive" type="primary" large @click="onSwitch">Switch Lens</a-button>
       <a-button v-else type="primary" large @click="onStart">Play</a-button>
-      <a-button class="ml20" type="primary" large @click="onStop">Stop</a-button>
-      <a-button class="ml20" type="primary" large @click="onUpdateQuality">Update Clarity</a-button>
-      <a-button v-if="!livePara.liveState || !dronePara.isDockLive" class="ml20" type="primary" large
-        @click="onRefresh">Refresh Live Capacity</a-button>
+      <a-button class="ml20" type="primary" large @click="onStop"
+        >Stop</a-button
+      >
+      <a-button class="ml20" type="primary" large @click="onUpdateQuality"
+        >Update Clarity</a-button
+      >
+      <a-button v-if="!livePara.liveState || !dronePara.isDockLive" class="ml20" type="primary" large @click="onRefresh"
+        >Refresh Live Capacity</a-button
+      >
     </div>
   </div>
 </template>
@@ -139,11 +179,14 @@ const onRefresh = async () => {
     .then(res => {
       if (res.code === 0) {
         if (res.data === null) {
+          console.warn('warning: get live capacity is null!!!')
           return
         }
         dronePara.livestreamSource = res.data
         dronePara.droneList = []
 
+        console.log('live_capacity:', dronePara.livestreamSource)
+
         if (dronePara.livestreamSource) {
           dronePara.livestreamSource.forEach((ele: any) => {
             dronePara.droneList.push({ label: ele.name + '-' + ele.sn, value: ele.sn, more: ele.cameras_list })
@@ -195,6 +238,13 @@ const handleJoinChannel = (uid: any) => {
 }
 const onStart = async () => {
   const that = this
+  console.log(
+    'drone parameter:',
+    dronePara.droneSelected,
+    dronePara.cameraSelected,
+    dronePara.videoSelected,
+    dronePara.claritySelected
+  )
   const timestamp = new Date().getTime().toString()
   const liveTimestamp = timestamp
   if (
@@ -213,6 +263,7 @@ const onStart = async () => {
     dronePara.droneSelected +
     '/' +
     dronePara.cameraSelected + '/' + (dronePara.videoSelected || nonSwitchable + '-0')
+  console.log(agoraPara)
 
   livePara.url =
     'channel=' +

+ 1 - 1
Web/src/components/livestream-others.vue

@@ -428,7 +428,7 @@ const playWebrtc = (videoElement: HTMLMediaElement, url: string) => {
   webrtc = new srs.SrsRtcWhipWhepAsync()
   videoElement.srcObject = webrtc.stream
   webrtc.play(url).then(function (session: any) {
-    // console.info(session)
+    console.info(session)
   }).catch(function (reason: any) {
     webrtc.close()
     console.error(reason)

+ 1 - 0
Web/src/components/task/use-task-ws-event.ts

@@ -29,6 +29,7 @@ export function useTaskWsEvent(funcs: UseTaskWsEventParams): void {
         break
       }
     }
+    // console.log('payload', payload.data)
   }
 
   onMounted(() => {

+ 1 - 1
Web/src/constants/index.ts

@@ -19,4 +19,4 @@ export const AMapConfig = {
     'AMap.MouseTool',
     'AMap.MoveAnimation'
   ]
-}
+}

+ 8 - 10
Web/src/constants/map.ts

@@ -1,13 +1,12 @@
 
 export enum MapElementColor {
-  Blue = '#2D8CF0',
-  Green = '#19BE6B',
-  Yellow = '#FFBB00',
-  Red = '#E23C39',
-  Orange = '#B620E0',
-  Default = '#212121'
-}
-
+    Blue = '#2D8CF0',
+    Green = '#19BE6B',
+    Yellow = '#FFBB00',
+    Red = '#E23C39',
+    Orange = '#B620E0',
+    Default = '#212121'
+  }
 export const MapElementDefaultColor = MapElementColor.Default
 
 export enum MapDoodleColor {
@@ -21,5 +20,4 @@ export enum MapElementEnum {
   LINE = 1,
   POLY = 2
 }
-
-export type MapDoodleType = 'pin' | 'polyline' | 'polygon' | 'off' | 'circle'
+export type MapDoodleType = 'pin' | 'polyline' | 'polygon' | 'off' | 'circle'

+ 1 - 1
Web/src/constants/mock-layers.ts

@@ -135,4 +135,4 @@ export const mapLayers = {
       elements: []
     }]
   }
-}
+}

+ 2 - 2
Web/src/directives/drag-window.ts

@@ -1,6 +1,6 @@
 import { nextTick, App } from 'vue'
 
-export default function useDragWindowDirective(app: App): void {
+export default function useDragWindowDirective (app: App): void {
   app.directive('drag-window', async (el) => {
     await nextTick()
 
@@ -35,4 +35,4 @@ export default function useDragWindowDirective(app: App): void {
       }
     }
   })
-}
+}

+ 2 - 2
Web/src/directives/index.ts

@@ -1,6 +1,6 @@
 import { App } from 'vue'
 import useDragWindowDirective from './drag-window'
 
-export function useDirectives(app: App): void {
+export function useDirectives (app: App): void {
   useDragWindowDirective(app)
-}
+}

+ 0 - 9
Web/src/env.d.ts

@@ -1,9 +0,0 @@
-// Environment variable definition
-// https://cn.vitejs.dev/guide/env-and-mode.html#env-files
-
-interface ImportMetaEnv {
-  VITE_APP_ENVIRONMENT: 'DEV' | 'STAG' | 'UAT' | 'PROD',
-  // api gateway
-  VITE_APP_APIGATEWAY_BACKEND_HOST: string
-  // More environment variables...
-}

+ 1 - 1
Web/src/event-bus/index.ts

@@ -13,4 +13,4 @@ type Events = {
 
 const emitter: Emitter<Events> = mitt<Events>()
 
-export default emitter;
+export default emitter

+ 1 - 1
Web/src/hooks/use-connect-websocket.ts

@@ -7,7 +7,7 @@ import { getWebsocketUrl } from '/@/websocket/util/config'
  * 接收一个message函数
  * @param messageHandler
  */
-export function useConnectWebSocket(messageHandler: MessageHandler) {
+export function useConnectWebSocket (messageHandler: MessageHandler) {
   const webSocket = new ConnectWebSocket(getWebsocketUrl())
 
   onMounted(() => {

+ 20 - 20
Web/src/hooks/use-g-map-cover.ts

@@ -9,7 +9,7 @@ import { getRoot } from '/@/root'
 import rootStore from '/@/store'
 import { GeojsonCoordinate } from '/@/types/map'
 
-export function useGMapCover() {
+export function useGMapCover () {
   const root = getRoot()
   const AMap = root.$aMap
 
@@ -22,15 +22,15 @@ export function useGMapCover() {
   }
   const disableColor = '#b3b3b3'
 
-  function AddCoverToMap(cover: any) {
+  function AddCoverToMap (cover :any) {
     root.$map.add(cover)
     coverMap[cover.getExtData().id] = [cover]
   }
 
-  function getPinIcon(color?: string) {
+  function getPinIcon (color?:string) {
     // console.log('color', color)
     const colorObj: {
-      [key: number | string]: any
+      [key: number| string]: any
     } = {
       '2d8cf0': pin2d8cf0,
       '19be6b': pin19be6b,
@@ -48,7 +48,7 @@ export function useGMapCover() {
     })
   }
 
-  function init2DPin(name: string, coordinates: GeojsonCoordinate, color?: string, data?: {}) {
+  function init2DPin (name: string, coordinates:GeojsonCoordinate, color?:string, data?:{}) {
     const pin = new AMap.Marker({
       position: new AMap.LngLat(coordinates[0], coordinates[1]),
       title: name,
@@ -61,12 +61,12 @@ export function useGMapCover() {
     AddCoverToMap(pin)
   }
 
-  function AddOverlayGroup(overlayGroup) {
+  function AddOverlayGroup (overlayGroup) {
     root.$map.add(overlayGroup)
     const id = overlayGroup.getExtData().id
     coverMap[id] = [...(coverMap[id] || []), overlayGroup]
   }
-  function initPolyline(name: string, coordinates: GeojsonCoordinate[], color?: string, data?: {}) {
+  function initPolyline (name: string, coordinates:GeojsonCoordinate[], color?:string, data?:{}) {
     const path = [] as GeojsonCoordinate[]
     coordinates.forEach(coordinate => {
       path.push(new AMap.LngLat(coordinate[0], coordinate[1]))
@@ -83,7 +83,7 @@ export function useGMapCover() {
     AddOverlayGroup(polyline)
   }
 
-  function initPolygon(name: string, coordinates: GeojsonCoordinate[][], color?: string, data?: {}) {
+  function initPolygon (name: string, coordinates:GeojsonCoordinate[][], color?:string, data?:{}) {
     const path = [] as GeojsonCoordinate[]
     coordinates[0].forEach(coordinate => {
       path.push(new AMap.LngLat(coordinate[0], coordinate[1]))
@@ -102,16 +102,16 @@ export function useGMapCover() {
     AddOverlayGroup(Polygon)
   }
 
-  function removeCoverFromMap(id: string) {
+  function removeCoverFromMap (id:string) {
     coverMap[id].forEach(cover => root.$map.remove(cover))
     coverMap[id] = []
   }
 
-  function getElementFromMap(id: string): any[] {
+  function getElementFromMap (id:string): any[] {
     return coverMap[id]
   }
 
-  function updatePinElement(id: string, name: string, coordinates: GeojsonCoordinate, color?: string) {
+  function updatePinElement (id:string, name: string, coordinates:GeojsonCoordinate, color?:string) {
     const elements = getElementFromMap(id)
     if (elements && elements.length > 0) {
       const element = elements[0]
@@ -128,7 +128,7 @@ export function useGMapCover() {
     }
   }
 
-  function updatePolylineElement(id: string, name: string, coordinates: GeojsonCoordinate[], color?: string) {
+  function updatePolylineElement (id:string, name: string, coordinates:GeojsonCoordinate[], color?:string) {
     const elements = getElementFromMap(id)
     if (elements && elements.length > 0) {
       const element = elements[0]
@@ -143,7 +143,7 @@ export function useGMapCover() {
     }
   }
 
-  function updatePolygonElement(id: string, name: string, coordinates: GeojsonCoordinate[][], color?: string) {
+  function updatePolygonElement (id:string, name: string, coordinates:GeojsonCoordinate[][], color?:string) {
     const elements = getElementFromMap(id)
     if (elements && elements.length > 0) {
       const element = elements[0]
@@ -159,7 +159,7 @@ export function useGMapCover() {
     }
   }
 
-  function initTextInfo(content: string, coordinates: GeojsonCoordinate, id: string) {
+  function initTextInfo (content: string, coordinates: GeojsonCoordinate, id: string) {
     const info = new AMap.Text({
       text: content,
       position: new AMap.LngLat(coordinates[0], coordinates[1]),
@@ -174,7 +174,7 @@ export function useGMapCover() {
     AddOverlayGroup(info)
   }
 
-  function initFlightAreaCircle(name: string, radius: number, position: GeojsonCoordinate, data: { id: string, type: EFlightAreaType, enable: boolean }) {
+  function initFlightAreaCircle (name: string, radius: number, position: GeojsonCoordinate, data: { id: string, type: EFlightAreaType, enable: boolean }) {
     const circle = new AMap.Circle({
       strokeColor: data.enable ? flightAreaColorMap[data.type] : disableColor,
       strokeOpacity: 1,
@@ -191,7 +191,7 @@ export function useGMapCover() {
     initTextInfo(name, position, data.id)
   }
 
-  function updateFlightAreaCircle(id: string, name: string, radius: number, position: GeojsonCoordinate, enable: boolean, type: EFlightAreaType) {
+  function updateFlightAreaCircle (id: string, name: string, radius: number, position: GeojsonCoordinate, enable: boolean, type: EFlightAreaType) {
     const elements = getElementFromMap(id)
     if (elements && elements.length > 0) {
       let textIndex = elements.findIndex(ele => ele.getExtData()?.type === 'text')
@@ -216,12 +216,12 @@ export function useGMapCover() {
     }
   }
 
-  function calcPolygonPosition(coordinate: GeojsonCoordinate[]): GeojsonCoordinate {
+  function calcPolygonPosition (coordinate: GeojsonCoordinate[]): GeojsonCoordinate {
     const index = coordinate.length - 1
     return [(coordinate[0][0] + coordinate[index][0]) / 2.0, (coordinate[0][1] + coordinate[index][1]) / 2]
   }
 
-  function initFlightAreaPolygon(name: string, coordinates: GeojsonCoordinate[], data: { id: string, type: EFlightAreaType, enable: boolean }) {
+  function initFlightAreaPolygon (name: string, coordinates: GeojsonCoordinate[], data: { id: string, type: EFlightAreaType, enable: boolean }) {
     const path = [] as GeojsonCoordinate[]
     coordinates.forEach(coordinate => {
       path.push(new AMap.LngLat(coordinate[0], coordinate[1]))
@@ -242,7 +242,7 @@ export function useGMapCover() {
     initTextInfo(name, calcPolygonPosition(coordinates), data.id)
   }
 
-  function updateFlightAreaPolygon(id: string, name: string, coordinates: GeojsonCoordinate[], enable: boolean, type: EFlightAreaType) {
+  function updateFlightAreaPolygon (id: string, name: string, coordinates: GeojsonCoordinate[], enable: boolean, type: EFlightAreaType) {
     const elements = getElementFromMap(id)
     if (elements && elements.length > 0) {
       let textIndex = elements.findIndex(ele => ele.getExtData()?.type === 'text')
@@ -284,4 +284,4 @@ export function useGMapCover() {
     updateFlightAreaCircle,
     calcPolygonPosition,
   }
-}
+}

+ 18 - 8
Web/src/hooks/use-g-map-tsa.ts

@@ -7,7 +7,7 @@ import dockIcon from '/@/assets/icons/dock.png'
 import rcIcon from '/@/assets/icons/rc.png'
 import droneIcon from '/@/assets/icons/drone.png'
 
-export function deviceTsaUpdate() {
+export function deviceTsaUpdate () {
   const root = getRoot()
   let AMap = root.$aMap
 
@@ -20,7 +20,7 @@ export function deviceTsaUpdate() {
   const paths = store.state.markerInfo.pathMap
 
   let trackLine = null as any
-  function getTrackLineInstance() {
+  function getTrackLineInstance () {
     if (!trackLine) {
       trackLine = new AMap.Polyline({
         map: root.$map,
@@ -30,7 +30,7 @@ export function deviceTsaUpdate() {
     return trackLine
   }
 
-  function initIcon(type: number) {
+  function initIcon (type: number) {
     return new AMap.Icon({
       image: icons.get(type),
       imageSize: new AMap.Size(40, 40),
@@ -38,7 +38,7 @@ export function deviceTsaUpdate() {
     })
   }
 
-  function initMarker(type: number, name: string, sn: string, lng?: number, lat?: number) {
+  function initMarker (type: number, name: string, sn: string, lng?: number, lat?: number) {
     if (markers[sn]) {
       return
     }
@@ -54,9 +54,19 @@ export function deviceTsaUpdate() {
       offset: [0, -20],
     })
     root.$map.add(markers[sn])
+    // markers[sn].on('moving', function (e: any) {
+    //   let path = paths[sn]
+    //   if (!path) {
+    //     paths[sn] = e.passedPath
+    //     return
+    //   }
+    //   path.push(e.passedPath[0])
+    //   path.push(e.passedPath[1])
+    //   getTrackLineInstance().setPath(path)
+    // })
   }
 
-  function removeMarker(sn: string) {
+  function removeMarker (sn: string) {
     if (!markers[sn]) {
       return
     }
@@ -66,7 +76,7 @@ export function deviceTsaUpdate() {
     delete paths[sn]
   }
 
-  function addMarker(sn: string, lng?: number, lat?: number) {
+  function addMarker (sn: string, lng?: number, lat?: number) {
     getDeviceBySn(localStorage.getItem(ELocalStorageKey.WorkspaceId)!, sn)
       .then(data => {
         if (data.code !== 0) {
@@ -77,7 +87,7 @@ export function deviceTsaUpdate() {
       })
   }
 
-  function moveTo(sn: string, lng: number, lat: number) {
+  function moveTo (sn: string, lng: number, lat: number) {
     let marker = markers[sn]
     if (!marker) {
       addMarker(sn, lng, lat)
@@ -96,4 +106,4 @@ export function deviceTsaUpdate() {
     removeMarker,
     moveTo
   }
-}
+}

+ 3 - 3
Web/src/hooks/use-g-map.ts

@@ -2,14 +2,14 @@ import AMapLoader from '@amap/amap-jsapi-loader'
 import { App, reactive } from 'vue'
 import { AMapConfig } from '/@/constants/index'
 
-export function useGMapManage() {
+export function useGMapManage () {
   const state = reactive({
     aMap: null, // Map类
     map: null, // 地图对象
     mouseTool: null,
   })
 
-  async function initMap(container: string, app: App) {
+  async function initMap (container: string, app:App) {
     AMapLoader.load({
       ...AMapConfig
     }).then((AMap) => {
@@ -29,7 +29,7 @@ export function useGMapManage() {
     })
   }
 
-  function globalPropertiesConfig(app: App) {
+  function globalPropertiesConfig (app:App) {
     initMap('g-container', app)
   }
 

+ 3 - 3
Web/src/hooks/use-map-tool.ts

@@ -1,16 +1,16 @@
 import { GeojsonCoordinate } from '../utils/genjson'
 import { getRoot } from '/@/root'
 
-export function useMapTool() {
+export function useMapTool () {
   const root = getRoot()
   const map = root.$map
   const AMap = root.$aMap
 
-  function panTo(coordinate: GeojsonCoordinate) {
+  function panTo (coordinate: GeojsonCoordinate) {
     map.panTo(coordinate, 100)
     map.setZoom(18, false, 100)
   }
   return {
     panTo,
   }
-}
+}

+ 8 - 8
Web/src/hooks/use-mouse-tool.ts

@@ -6,7 +6,7 @@ import { MapDoodleEnum } from '/@/types/map-enum'
 import { EFlightAreaType } from '../types/flight-area'
 import { message } from 'ant-design-vue'
 
-export function useMouseTool() {
+export function useMouseTool () {
   const root = getRoot()
 
   const state = reactive({
@@ -19,7 +19,7 @@ export function useMouseTool() {
     [EFlightAreaType.DFENCE]: '#19be6b',
     [EFlightAreaType.NFZ]: '#ff0000',
   }
-  function drawPin(type: MapDoodleType, getDrawCallback: Function) {
+  function drawPin (type:MapDoodleType, getDrawCallback:Function) {
     root?.$mouseTool.marker({
       title: type + state.pinNum,
       icon: pin2d8cf0,
@@ -28,7 +28,7 @@ export function useMouseTool() {
     root?.$mouseTool.on('draw', getDrawCallback)
   }
 
-  function drawPolyline(type: MapDoodleType, getDrawCallback: Function) {
+  function drawPolyline (type:MapDoodleType, getDrawCallback:Function) {
     root?.$mouseTool.polyline({
       strokeColor: '#2d8cf0',
       strokeOpacity: 1,
@@ -39,7 +39,7 @@ export function useMouseTool() {
     root?.$mouseTool.on('draw', getDrawCallback)
   }
 
-  function drawPolygon(type: MapDoodleType, getDrawCallback: Function) {
+  function drawPolygon (type:MapDoodleType, getDrawCallback:Function) {
     root?.$mouseTool.polygon({
       strokeColor: '#2d8cf0',
       strokeOpacity: 1,
@@ -51,12 +51,12 @@ export function useMouseTool() {
     root?.$mouseTool.on('draw', getDrawCallback)
   }
 
-  function drawOff(type: MapDoodleType) {
+  function drawOff (type:MapDoodleType) {
     root?.$mouseTool.close()
     root?.$mouseTool.off('draw')
   }
 
-  function drawFlightAreaPolygon(type: EFlightAreaType, getDrawFlightAreaCallback: Function) {
+  function drawFlightAreaPolygon (type: EFlightAreaType, getDrawFlightAreaCallback: Function) {
     root?.$mouseTool.polygon({
       strokeColor: flightAreaColorMap[type],
       strokeOpacity: 1,
@@ -73,7 +73,7 @@ export function useMouseTool() {
     root?.$mouseTool.on('draw', getDrawFlightAreaCallback)
   }
 
-  function drawFlightAreaCircle(type: EFlightAreaType, getDrawFlightAreaCallback: Function) {
+  function drawFlightAreaCircle (type: EFlightAreaType, getDrawFlightAreaCallback: Function) {
     root?.$mouseTool.circle({
       strokeColor: flightAreaColorMap[type],
       strokeOpacity: 1,
@@ -90,7 +90,7 @@ export function useMouseTool() {
     root?.$mouseTool.on('draw', getDrawFlightAreaCallback)
   }
 
-  function mouseTool(type: MapDoodleType, getDrawCallback: Function, flightAreaType?: EFlightAreaType) {
+  function mouseTool (type: MapDoodleType, getDrawCallback: Function, flightAreaType?: EFlightAreaType) {
     state.currentType = type
     if (flightAreaType) {
       switch (type) {

+ 1 - 1
Web/src/main.ts

@@ -15,4 +15,4 @@ app.use(router)
 app.use(CommonComponents)
 app.use(antComponents)
 app.use(useDirectives)
-app.mount('#demo-app')
+app.mount('#demo-app')

+ 1 - 1
Web/src/mqtt/config.ts

@@ -9,4 +9,4 @@ export const OPTIONS: IClientOptions = {
   resubscribe: true, // 断开重连后,再次订阅原订阅
   reconnectPeriod: 10000, // 重连间隔时间: 5s
   keepalive: 1, // 心跳间隔时间:1s
-}
+}

+ 1 - 1
Web/src/mqtt/index.ts

@@ -18,7 +18,7 @@ export class UranusMqtt extends EventEmitter {
   _client: MqttClient | null
   _hasInit: boolean
 
-  constructor(url?: string, options?: IClientOptions) {
+  constructor (url?: string, options?: IClientOptions) {
     super()
     this._url = url || ''
     this._options = options

+ 15 - 17
Web/src/pages/page-pilot/pilot-bind.vue

@@ -1,21 +1,19 @@
 <template>
   <a-layout class="flex-display" style="height: 100vh; background-color: white;">
-    <div class="height100 width100 flex-column flex-justify-start flex-align-start">
-      <a-row class="pt20 pl20" style="height: 45px; width: 100vw" align="middle">
-        <a-col :span="1">
-          <span style="color: #1fa3f6" class="fz26">
-            <SendOutlined rotate="90" />
-          </span>
-        </a-col>
-        <a-col :span="20">
-          <span class="fz20 pl5">{{ drone.data.model }}</span>
-        </a-col>
-        <a-col :span="3">
-          <span class="fz16" v-if="drone.data.bound_status" style="color: #737373">Bound</span>
-          <a-button type="primary" @click="onBindDevice" v-else>Bind</a-button>
-        </a-col>
-      </a-row>
-    </div>
+  <div class="height100 width100 flex-column flex-justify-start flex-align-start">
+    <a-row class="pt20 pl20" style="height: 45px; width: 100vw" align="middle">
+      <a-col :span="1">
+        <span style="color: #1fa3f6" class="fz26"><SendOutlined rotate="90" /></span>
+      </a-col>
+      <a-col :span="20">
+        <span class="fz20 pl5">{{ drone.data.model }}</span>
+      </a-col>
+      <a-col :span="3">
+        <span class="fz16" v-if="drone.data.bound_status" style="color: #737373">Bound</span>
+        <a-button type="primary" @click="onBindDevice" v-else>Bind</a-button>
+      </a-col>
+    </a-row>
+  </div>
   </a-layout>
 </template>
 
@@ -37,7 +35,7 @@ const drone = reactive<DeviceStatusData>({
   data: JSON.parse(localStorage.getItem(ELocalStorageKey.Device)!)
 })
 
-function onBindDevice() {
+function onBindDevice () {
   const bindParam: BindBody = {
     device_sn: drone.data.sn,
     user_id: localStorage.getItem(ELocalStorageKey.UserId)!,

+ 26 - 33
Web/src/pages/page-pilot/pilot-home.vue

@@ -14,23 +14,21 @@
             </div>
             <div style="height: 50%;">
               <CloudSyncOutlined v-if="thingState === EStatusValue.CONNECTED" style="color: #75c5f6" />
-              <SyncOutlined spin v-else />
+              <SyncOutlined spin v-else/>
               <span style="color: #737373; margin-left: 3px;">{{ thingState }}</span>
             </div>
-            <a-drawer placement="right" v-model:visible="drawerVisible" width="340px">
+            <a-drawer  placement="right" v-model:visible="drawerVisible" width="340px">
               <div class="mb10 flex-row flex-justify-center flex-align-center">
                 <p class="fz14" style="font-weight: 100;">Module State</p>
               </div>
-              <div class="width-100 mb10 flex-align-start" v-for="m in modules" :key="m.name" style="height: 30px;">
+              <div class= "width-100 mb10 flex-align-start" v-for="m in modules" :key="m.name" style="height: 30px;">
 
-                <div class="ml5" style="float: left; color: #000000;">{{ m.name }}:</div>
+                <div class="ml5" style="float: left; color: #000000;">{{m.name}}:</div>
                 <div class="ml10" style="float: right; margin-bottom: 8px;">
-                  <span :key="m.state" :class="m.state.value === EStatusValue.CONNECTED ? 'green' : 'red'">{{
-                    m.state.value }}&nbsp;</span>
-                  <a-button-group>
-                    <a-button class="ml5" type="primary" size="small" @click.stop="moduleInstall(m)">install</a-button>
-                    <a-button class="ml5 mr5" type="danger" size="small"
-                      @click.stop="moduleUninstall(m)">uninstall</a-button>
+                  <span :key="m.state" :class="m.state.value === EStatusValue.CONNECTED ? 'green' : 'red'">{{ m.state.value }}&nbsp;</span>
+                  <a-button-group >
+                  <a-button class="ml5" type="primary" size="small" @click.stop="moduleInstall(m)">install</a-button>
+                  <a-button class="ml5 mr5" type="danger" size="small" @click.stop="moduleUninstall(m)">uninstall</a-button>
                   </a-button-group>
                 </div>
                 <a-divider />
@@ -40,11 +38,11 @@
           </a-layout-content>
 
         </a-layout>
-        <a-divider style="height: 2px; background-color: #f5f5f5; margin-top: 3vh;" />
+        <a-divider  style="height: 2px; background-color: #f5f5f5; margin-top: 3vh;" />
 
         <a-button id="exitBtn" class="fz18" @click="confirmAgain"
-          style="width: 10vw; height: 10vh; position: fixed; bottom: 13vh; left: 15vw; background-color: #e6e6e6; color: red; border: 0;"
-          type="primary">Exit
+        style="width: 10vw; height: 10vh; position: fixed; bottom: 13vh; left: 15vw; background-color: #e6e6e6; color: red; border: 0;"
+        type="primary">Exit
         </a-button>
         <a-modal v-model:visible="exitVisible" width="300px" :closable="false">
           <template #footer>
@@ -62,18 +60,17 @@
       <div class="fz16" style="background-color: white; border-radius: 4px;">
         <a-row style="border-bottom: 1px solid #f4f8f9; height: 45px;" align="middle">
           <a-col :span="1"></a-col>
-          <a-col :span="9">
+            <a-col :span="9">
             Remote Control Sn
-          </a-col>
+            </a-col>
           <a-col :span="13" class="flex-align-end flex-column">
             <span style="color: #737373">{{ device.data.gateway_sn }}</span>
           </a-col>
         </a-row>
-        <a-row style="border-bottom: 1px solid #f4f8f9; height: 45px;" align="middle"
-          v-if="device.data.online_status && device.data.sn">
+        <a-row style="border-bottom: 1px solid #f4f8f9; height: 45px;" align="middle" v-if="device.data.online_status && device.data.sn">
           <a-col :span="1"></a-col>
           <a-col :span="9">Aircraft Sn</a-col>
-          <a-col :span="13" class="flex-align-end flex-column">
+          <a-col :span="13" class="flex-align-end flex-column" >
             <span style="color: #737373">{{ device.data.sn }}</span>
           </a-col>
         </a-row>
@@ -82,8 +79,7 @@
         <span class="ml5" style="color: #939393;">Settings</span>
       </div>
       <div class="fz16" style="background-color: white; border-radius: 4px;">
-        <a-row v-if="device.data.online_status && device.data.sn"
-          style="border-bottom: 1px solid #f4f8f9; height: 45px;" align="middle" @click="bindingDevice">
+        <a-row v-if="device.data.online_status && device.data.sn" style="border-bottom: 1px solid #f4f8f9; height: 45px;" align="middle" @click="bindingDevice">
           <a-col :span="1"></a-col>
           <a-col :span="11">
             Device Binding
@@ -92,7 +88,7 @@
             <span v-if="device.data.bound_status" style="color: #737373">Aircraft bound</span>
             <span v-else style="color: #737373">Aircraft not bound</span>
           </a-col>
-          <a-col :span="2" class="flex-align-center flex-column">
+          <a-col :span="2" class="flex-align-center flex-column" >
             <RightOutlined style="color: #8894a0; font-size: 20px;" />
           </a-col>
         </a-row>
@@ -101,7 +97,7 @@
           <a-col :span="21">
             Media File Upload
           </a-col>
-          <a-col :span="2" class="flex-align-center flex-column">
+          <a-col :span="2" class="flex-align-center flex-column" >
             <RightOutlined style="color: #8894a0; font-size: 20px;" />
           </a-col>
         </a-row>
@@ -219,6 +215,7 @@ const messageHandler = async (payload: any) => {
   }
   switch (payload.biz_code) {
     case EBizCode.DeviceOnline: {
+      console.info('online: ', payload)
       if (payload.data.sn === device.data.gateway_sn) {
         localStorage.setItem(ELocalStorageKey.GatewayOnline, gatewayState.value.toString())
         break
@@ -230,6 +227,7 @@ const messageHandler = async (payload: any) => {
       break
     }
     case EBizCode.DeviceOffline: {
+      console.info('offline: ', payload)
       if (payload.data.sn === device.data.sn) {
         device.data.online_status = payload.data.online_status
         localStorage.setItem(ELocalStorageKey.Device, JSON.stringify(device.data))
@@ -402,7 +400,7 @@ const showStatus = async () => {
   drawerVisible.value = true
 }
 
-function setWorkspaceInfo() {
+function setWorkspaceInfo () {
   if (localStorage.getItem(ELocalStorageKey.WorkspaceName)) {
     apiPilot.setPlatformMessage(
       '' + localStorage.getItem(ELocalStorageKey.PlatformName),
@@ -429,7 +427,7 @@ function setWorkspaceInfo() {
   })
 }
 
-function refreshStatus() {
+function refreshStatus () {
   thingState.value = apiPilot.thingGetConnectState() ? EStatusValue.CONNECTED : EStatusValue.DISCONNECT
   apiState.value = apiPilot.isComponentLoaded(EComponentName.Api) ? EStatusValue.CONNECTED : EStatusValue.DISCONNECT
   liveState.value = apiPilot.isComponentLoaded(EComponentName.Liveshare) ? EStatusValue.CONNECTED : EStatusValue.DISCONNECT
@@ -442,7 +440,7 @@ function refreshStatus() {
   waylineState.value = apiPilot.isComponentLoaded(EComponentName.Mission) ? EStatusValue.CONNECTED : EStatusValue.DISCONNECT
 }
 
-function moduleInstall(m: any) {
+function moduleInstall (m: any) {
   let param
   switch (m.module) {
     case EComponentName.Thing:
@@ -478,13 +476,13 @@ function moduleInstall(m: any) {
   refreshStatus()
 }
 
-function moduleUninstall(m: any) {
+function moduleUninstall (m: any) {
   message.info('uninstall ' + m.module)
   apiPilot.unloadComponent(m.module)
   refreshStatus()
 }
 
-function getDeviceInfo() {
+function getDeviceInfo () {
   if (!device.data.sn || device.data.sn === EStatusValue.DISCONNECT) {
     return
   }
@@ -503,21 +501,18 @@ function getDeviceInfo() {
 
 <style lang="scss" scoped>
 @import '/@/styles/index.scss';
-
 .page {
   display: flex;
   position: absolute;
   transition: width 0.2s ease;
   height: 100%;
   width: 100%;
-
   .left {
     height: 90%;
     background-color: white;
     margin-top: 6vh;
     margin-left: 2vh;
   }
-
   .right {
     height: 90%;
     margin-top: 6vh;
@@ -525,15 +520,12 @@ function getDeviceInfo() {
     margin-right: 5vh;
   }
 }
-
 .green {
   color: green
 }
-
 .red {
   color: red;
 }
-
 #exitBtn:hover :active {
   background-color: rgb(77, 75, 75);
   width: 10vw;
@@ -543,4 +535,5 @@ function getDeviceInfo() {
   left: 15vw;
   line-height: 10vh;
 }
+
 </style>

+ 29 - 15
Web/src/pages/page-pilot/pilot-index.vue

@@ -1,25 +1,41 @@
 <template>
   <div class="login flex-column flex-justify-center flex-align-center m0 b0">
-    <a-image style="width: 17vw; height: 10vw; margin-bottom: 50px" :src="djiLogo" />
+    <a-image
+      style="width: 17vw; height: 10vw; margin-bottom: 50px"
+      :src="djiLogo"
+    />
     <p class="logo fz35 pb50">Pilot Cloud API Demo</p>
-    <a-form layout="inline" :model="formState" class="flex-row flex-justify-center flex-align-center">
+    <a-form
+      layout="inline"
+      :model="formState"
+      class="flex-row flex-justify-center flex-align-center"
+    >
       <a-form-item>
         <a-input v-model:value="formState.username" placeholder="Username">
-          <template #prefix>
-            <UserOutlined style="color: rgba(0, 0, 0, 0.25)" />
-          </template>
+          <template #prefix
+            ><UserOutlined style="color: rgba(0, 0, 0, 0.25)"
+          /></template>
         </a-input>
       </a-form-item>
       <a-form-item>
-        <a-input v-model:value="formState.password" type="password" placeholder="Password">
-          <template #prefix>
-            <LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
-          </template>
+        <a-input
+          v-model:value="formState.password"
+          type="password"
+          placeholder="Password"
+        >
+          <template #prefix
+            ><LockOutlined style="color: rgba(0, 0, 0, 0.25)"
+          /></template>
         </a-input>
       </a-form-item>
       <a-form-item>
-        <a-button class="m0" type="primary" html-type="submit"
-          :disabled="formState.user === '' || formState.password === ''" @click="onSubmit">
+        <a-button
+          class="m0"
+          type="primary"
+          html-type="submit"
+          :disabled="formState.user === '' || formState.password === ''"
+          @click="onSubmit"
+        >
           Login
         </a-button>
       </a-form-item>
@@ -110,7 +126,7 @@ const onSubmit = async (e: any) => {
     })
 }
 
-function verifyLicense() {
+function verifyLicense () {
   isVerified.value = apiPilot.platformVerifyLicense(CURRENT_CONFIG.appId, CURRENT_CONFIG.appKey, CURRENT_CONFIG.appLicense) &&
     apiPilot.isPlatformVerifySuccess()
   if (isVerified.value) {
@@ -123,13 +139,11 @@ function verifyLicense() {
 
 <style lang="scss" scoped>
 @import '/@/styles/index.scss';
-
 .login {
   // background-color: $dark-highlight;
   height: 100vh;
 }
-
 .logo {
   color: $primary;
 }
-</style>
+</style>

+ 62 - 45
Web/src/pages/page-pilot/pilot-liveshare.vue

@@ -1,15 +1,25 @@
 <template>
-  <div class="width100 flex-column flex-justify-start flex-align-start" style="background-color: white;">
+    <div class="width100 flex-column flex-justify-start flex-align-start" style="background-color: white;">
 
-    <p class="fz16 ml10 mt15 mb10 color-text-title color-font-bold" style="color: #939393">
-      Before starting manually, please select the publish mode and livestream type
-    </p>
-    <div class="mt15 flex-row flex-align-center flex-justify-between" style="width: 100%;">
+      <p class="fz16 ml10 mt15 mb10 color-text-title color-font-bold" style="color: #939393">
+        Before starting manually, please select the publish mode and livestream type
+      </p>
+    <div
+      class="mt15 flex-row flex-align-center flex-justify-between"
+      style="width: 100%;">
       <p class="ml10 mb0 fz16" style="color: black">
         Select Video Publish Mode:
       </p>
-      <a-select style="width: 200px; margin-right: 20px;" placeholder="Select Mode" @select="onPublishModeSelect">
-        <a-select-option v-for="item in publishModeList" :key="item.label" :value="item.value">
+      <a-select
+        style="width: 200px; margin-right: 20px;"
+        placeholder="Select Mode"
+        @select="onPublishModeSelect"
+      >
+        <a-select-option
+          v-for="item in publishModeList"
+          :key="item.label"
+          :value="item.value"
+        >
           {{ item.label }}
         </a-select-option>
       </a-select>
@@ -18,11 +28,22 @@
     <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
       <a-divider />
     </div>
-    <div class="flex-row flex-align-center flex-justify-between" style="width: 100%; margin-top: -10px;">
+    <div
+      class="flex-row flex-align-center flex-justify-between"
+      style="width: 100%; margin-top: -10px;"
+    >
       <p class="ml10 mb0 fz16">Select Livestream Type:</p>
-      <a-select style="width: 200px; margin-right: 20px;" placeholder="Select Live Type" :value="liveStreamStatus.type"
-        @select="onLiveTypeSelect">
-        <a-select-option v-for="item in liveTypeList" :key="item.label" :value="item.value">
+      <a-select
+        style="width: 200px; margin-right: 20px;"
+        placeholder="Select Live Type"
+        :value="liveStreamStatus.type"
+        @select="onLiveTypeSelect"
+      >
+        <a-select-option
+          v-for="item in liveTypeList"
+          :key="item.label"
+          :value="item.value"
+        >
           {{ item.label }}
         </a-select-option>
       </a-select>
@@ -37,20 +58,25 @@
           <div class="flex-col flex-justify-center flex-align-center">
             <div>
               <span class="ml10">Token:</span>
-              <a-input class="ml10" v-model:value="agoraParam.token" placeholder="Token"></a-input>
+              <a-input
+                class="ml10"
+                v-model:value="agoraParam.token"
+                placeholder="Token"
+              ></a-input>
             </div>
             <div>
               <span class="ml10">Channel:</span>
-              <a-input class="ml10" v-model:value="agoraParam.channelId" placeholder="Channel"></a-input>
+              <a-input
+                class="ml10"
+                v-model:value="agoraParam.channelId"
+                placeholder="Channel"
+              ></a-input>
             </div>
           </div>
         </span>
-        <span v-else-if="liveStreamStatus.type === ELiveTypeValue.RTMP"
-          style="word-break: break-all; color: #75c5f6;">{{ rtmpParam }}</span>
-        <span v-else-if="liveStreamStatus.type === ELiveTypeValue.RTSP"
-          style="word-break: break-all; color: #75c5f6;">{{ rtspParam }}</span>
-        <span v-else-if="liveStreamStatus.type === ELiveTypeValue.GB28181"
-          style="word-break: break-all; color: #75c5f6;">{{ gb28181Param }}</span>
+        <span v-else-if="liveStreamStatus.type === ELiveTypeValue.RTMP" style="word-break: break-all; color: #75c5f6;">{{ rtmpParam }}</span>
+        <span v-else-if="liveStreamStatus.type === ELiveTypeValue.RTSP" style="word-break: break-all; color: #75c5f6;">{{ rtspParam }}</span>
+        <span v-else-if="liveStreamStatus.type === ELiveTypeValue.GB28181" style="word-break: break-all; color: #75c5f6;">{{ gb28181Param }}</span>
         <span v-else></span>
       </div>
 
@@ -58,56 +84,45 @@
     <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
       <a-divider />
     </div>
-    <div class="mb20 flex-row flex-align-center flex-justify-center" style="width: 100%; ">
-      <a-button class="flex-column fz20 flex-align-center flex-justify-center" style="width: 100px;" type="ghost"
-        @click="onPlay">Play</a-button>
-      <a-button class="flex-column fz20 flex-align-center flex-justify-center ml40" style="width: 100px;" type="ghost"
-        @click="onStop">Stop</a-button>
+    <div class="mb20 flex-row flex-align-center flex-justify-center"
+      style="width: 100%; ">
+      <a-button class="flex-column fz20 flex-align-center flex-justify-center" style="width: 100px;" type="ghost" @click="onPlay">Play</a-button>
+      <a-button class="flex-column fz20 flex-align-center flex-justify-center ml40" style="width: 100px;" type="ghost" @click="onStop">Stop</a-button>
     </div>
     <a-button v-if="playVisiable" class="flex-column flex-align-center" shape="circle" @click="showLivingStatus"
       style="position: fixed; top: 13vh; left: 5vw; opacity: 0.8; background-color: rgb(0,0,0,0)">
-      <template #icon>
-        <CaretRightFilled style="font-size: 26px; color: " />
-      </template>
+      <template #icon><CaretRightFilled style="font-size: 26px; color: " /></template>
     </a-button>
 
-    <a-drawer placement="right" v-model:visible="drawerVisible" width="280px" :mask="false" @close="closeDrawer">
+    <a-drawer  placement="right" v-model:visible="drawerVisible" width="280px" :mask="false" @close="closeDrawer">
       <div class="fz16 width-100">
         <div class="mt20" style=" margin-bottom: -10px;">
           <span class="fz20 flex-row flex-align-center flex-justify-center">
-            <font
-              :color="liveState === EStatusValue.LIVING ? 'green' : liveState === EStatusValue.CONNECTED ? 'blue' : 'red'">
-              {{ liveState }}</font>
-          </span>
+            <font :color="liveState === EStatusValue.LIVING ? 'green' : liveState === EStatusValue.CONNECTED ? 'blue' : 'red'">{{ liveState }}</font></span>
         </div>
         <a-divider />
         <div style=" margin-top: -10px; margin-bottom: -15px;">
-          <span>Frame Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.fps }}<span
-              v-if="liveStreamStatus.fps != -1"> fps</span></span><br />
+          <span>Frame Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.fps }}<span v-if="liveStreamStatus.fps != -1"> fps</span></span><br/>
         </div>
         <a-divider />
         <div style=" margin-top: -10px; margin-bottom: -10px;">
-          <span>Video Bit Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.videoBitRate
-            }}<span v-if="liveStreamStatus.videoBitRate != -1"> kbps</span></span><br />
+          <span>Video Bit Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.videoBitRate }}<span v-if="liveStreamStatus.videoBitRate != -1"> kbps</span></span><br/>
         </div>
         <a-divider />
         <div style=" margin-top: -10px; margin-bottom: -10px;">
-          <span>Audio Bit Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.audioBitRate
-            }}<span v-if="liveStreamStatus.audioBitRate != -1"> kbps</span></span><br />
+          <span>Audio Bit Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.audioBitRate }}<span v-if="liveStreamStatus.audioBitRate != -1"> kbps</span></span><br/>
         </div>
         <a-divider />
         <div style=" margin-top: -10px; margin-bottom: -10px;">
-          <span>Packet Loss Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.dropRate }}<span
-              v-if="liveStreamStatus.dropRate != -1"> %</span></span><br />
+          <span>Packet Loss Rate:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.dropRate }}<span v-if="liveStreamStatus.dropRate != -1"> %</span></span><br/>
         </div>
         <a-divider />
         <div style=" margin-top: -10px; margin-bottom: -10px;">
-          <span>RTT:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.rtt }}<span
-              v-if="liveStreamStatus.rtt != -1"> ms</span></span><br />
+          <span>RTT:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.rtt }}<span v-if="liveStreamStatus.rtt != -1"> ms</span></span><br/>
         </div>
         <a-divider />
         <div style=" margin-top: -10px;">
-          <span>Jitter:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.jitter }}</span><br />
+          <span >Jitter:</span><span style="float: right; color: #75c5f6;">{{ liveStreamStatus.jitter }}</span><br/>
         </div>
       </div>
     </a-drawer>
@@ -230,7 +245,7 @@ const liveStatusCallback = async (arg: LiveStreamStatus) => {
       liveState.value = EStatusValue.DISCONNECT
   }
 }
-function refreshLiveType() {
+function refreshLiveType () {
   switch (liveStreamStatus.type) {
     case ELiveTypeValue.Agora:
       liveTypeSelected.value = ELiveTypeName.Agora
@@ -315,4 +330,6 @@ const onStop = () => {
 }
 </script>
 
-<style lang="scss" scoped>
+<style lang="scss" scoped>
+// @import '/@/styles/index.scss';
+</style>

+ 64 - 34
Web/src/pages/page-pilot/pilot-media.vue

@@ -1,41 +1,69 @@
 <template>
   <a-layout>
-    <div class="width100 flex-column flex-justify-start flex-align-start" style="background-color: white;">
+  <div class="width100 flex-column flex-justify-start flex-align-start" style="background-color: white;">
 
-      <p class="fz16 ml10 mt15 mb10 color-text-title color-font-bold" style="color: #939393">
-        When enabled, photos and videos will be automatically uploaded to this server
+    <p class="fz16 ml10 mt15 mb10 color-text-title color-font-bold" style="color: #939393">
+      When enabled, photos and videos will be automatically uploaded to this server
+    </p>
+    <div
+      class="flex-row flex-align-center mt20"
+      style="width: 100%;"
+    >
+      <p class="ml10 mb0 fz16" style="margin-right: 73vw;">Auto Photo Upload</p>
+      <a-switch
+        v-model:checked="enablePhotoUpload"
+        @change="onPhotoUpload"
+      ></a-switch>
+    </div>
+    <div
+      class="flex-row flex-align-center flex-justify-between"
+      style="width: 100%"
+    >
+      <a-radio-group
+        class="mt10 ml20"
+        v-if="enablePhotoUpload === true"
+        v-model:value="photoType"
+        defaultChecked="0"
+        @change="onPhototype"
+      >
+        <a-radio :value="EPhotoType.Original">Original Photo</a-radio>
+        <a-radio class="ml20" :value="EPhotoType.Preview">Preview Photo</a-radio>
+      </a-radio-group>
+    </div>
+    <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
+      <a-divider />
+    </div>
+    <div
+      class="flex-row flex-align-center"
+      style="width: 100%; margin-top: -10px;"
+    >
+      <p class="ml10 mb0 fz16" style="margin-right: 73vw;">Auto Video Upload</p>
+      <a-switch
+        @change="onVideoUpload"
+        v-model:checked="enableVideoUpload"
+      ></a-switch>
+    </div>
+    <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
+      <a-divider />
+    </div>
+    <div
+      class="flex-row flex-align-center flex-justify-between mb15"
+      style="width: 100%; margin-top: -10px;"
+    >
+      <p class="ml10 mb0 fz16 color-font-bold">
+        Path for uploading media resources in dual-controller mode
       </p>
-      <div class="flex-row flex-align-center mt20" style="width: 100%;">
-        <p class="ml10 mb0 fz16" style="margin-right: 73vw;">Auto Photo Upload</p>
-        <a-switch v-model:checked="enablePhotoUpload" @change="onPhotoUpload"></a-switch>
-      </div>
-      <div class="flex-row flex-align-center flex-justify-between" style="width: 100%">
-        <a-radio-group class="mt10 ml20" v-if="enablePhotoUpload === true" v-model:value="photoType" defaultChecked="0"
-          @change="onPhototype">
-          <a-radio :value="EPhotoType.Original">Original Photo</a-radio>
-          <a-radio class="ml20" :value="EPhotoType.Preview">Preview Photo</a-radio>
-        </a-radio-group>
-      </div>
-      <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
-        <a-divider />
-      </div>
-      <div class="flex-row flex-align-center" style="width: 100%; margin-top: -10px;">
-        <p class="ml10 mb0 fz16" style="margin-right: 73vw;">Auto Video Upload</p>
-        <a-switch @change="onVideoUpload" v-model:checked="enableVideoUpload"></a-switch>
-      </div>
-      <div class="ml10 mr10" style="width: 96%; margin-top: -10px;">
-        <a-divider />
-      </div>
-      <div class="flex-row flex-align-center flex-justify-between mb15" style="width: 100%; margin-top: -10px;">
-        <p class="ml10 mb0 fz16 color-font-bold">
-          Path for uploading media resources in dual-controller mode
-        </p>
-        <a-radio-group class="mt0 mb0" v-model:value="uploadPath" button-style="solid" @change="onUploadPath">
-          <a-radio-button :value="EDownloadOwner.Mine">Mine</a-radio-button>
-          <a-radio-button :value="EDownloadOwner.Others">Another</a-radio-button>
-        </a-radio-group>
-      </div>
+      <a-radio-group
+        class="mt0 mb0"
+        v-model:value="uploadPath"
+        button-style="solid"
+        @change="onUploadPath"
+      >
+        <a-radio-button :value="EDownloadOwner.Mine">Mine</a-radio-button>
+        <a-radio-button :value="EDownloadOwner.Others">Another</a-radio-button>
+      </a-radio-group>
     </div>
+  </div>
   </a-layout>
 </template>
 
@@ -71,4 +99,6 @@ onMounted(() => {
 })
 </script>
 
-<style lang="scss" scoped>
+<style lang="scss" scoped>
+// @import '/@/styles/index.scss';
+</style>

+ 1 - 0
Web/src/pages/page-web/projects/flight-area.vue

@@ -83,6 +83,7 @@ const addArea = (area: FlightAreaUpdate) => {
 useFlightAreaUpdateEvent(addArea, deleteArea, updateArea)
 
 const clickArea = (area: GetFlightArea) => {
+  console.info(area)
   let coordinate
   switch (area.content.geometry.type) {
     case EGeometryType.CIRCLE:

+ 1 - 0
Web/src/pages/page-web/projects/tsa.vue

@@ -315,6 +315,7 @@ function getUnreadHms (sn: string) {
       hmsInfo.value[sn] = res.data
     }
   })
+  console.info(hmsInfo.value)
 }
 
 function getOnlineDeviceHms () {

+ 7 - 5
Web/src/root.ts

@@ -1,4 +1,5 @@
-import { createApp, ComponentCustomProperties, App as VueApp } from 'vue'
+import { createApp, ComponentCustomProperties, App as VueApp } from 'vue';
+
 declare module '@vue/runtime-core' {
   interface ComponentCustomProperties {
     $aMap: any // Map类
@@ -6,19 +7,20 @@ declare module '@vue/runtime-core' {
     $mouseTool: any
   }
 }
+
 let root: ComponentCustomProperties
 let app = null as any
 
-export function createInstance (App: any): VueApp {
+export function createInstance(App: any): VueApp {
   app = createApp(App)
   root = app.config.globalProperties as ComponentCustomProperties
   return app
 }
 
-export function getRoot (): ComponentCustomProperties {
+export function getRoot(): ComponentCustomProperties {
   return root
 }
 
-export function getApp (): VueApp {
+export function getApp(): VueApp {
   return app
-}
+}

+ 1 - 0
Web/src/router/index.ts

@@ -17,6 +17,7 @@ const routes: Array<RouteRecordRaw> = [
     name: ERouterName.PROJECT,
     component: () => import('/@/pages/page-web/index.vue')
   },
+  // members, devices
   {
     path: '/' + ERouterName.HOME,
     name: ERouterName.HOME,

+ 0 - 0
Web/src/shims-mqtt.d.ts → Web/src/typings/shims-mqtt.d.ts


+ 0 - 0
Web/src/shims-vue.d.ts → Web/src/typings/shims-vue.d.ts


+ 0 - 0
Web/src/vite-env.d.ts → Web/src/typings/vite-env.d.ts


+ 2 - 2
Web/src/use-common-components.ts

@@ -5,9 +5,9 @@ const components: Record<string, DefineComponent<{}, {}, any>> = {
 }
 
 export const CommonComponents = {
-  install (app: App): void {
+  install(app: App): void {
     Object.keys(components).forEach(name => {
       app.component(name, components[name])
     })
   }
-}
+}

+ 1 - 1
Web/src/utils/logger.ts

@@ -25,4 +25,4 @@ export function testEnvLog(...args: Parameters<typeof console.log>) {
   if (import.meta.env.VITE_APP_ENVIRONMENT !== 'PROD') {
     console.log.apply(null, args)
   }
-}
+}

+ 11 - 0
Web/src/vendors/srs.sdk.js

@@ -78,11 +78,14 @@ function SrsRtcPublisherAsync() {
         api: conf.apiUrl, tid: conf.tid, streamurl: conf.streamUrl,
         clientip: null, sdp: offer.sdp
       };
+      console.log("Generated offer: ", data);
+
       const xhr = new XMLHttpRequest();
       xhr.onload = function () {
         if (xhr.readyState !== xhr.DONE) return;
         if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);
         const data = JSON.parse(xhr.responseText);
+        console.log("Got answer: ", data);
         return data.code ? reject(xhr) : resolve(data);
       }
       xhr.open('POST', conf.apiUrl, true);
@@ -97,11 +100,13 @@ function SrsRtcPublisherAsync() {
     return session;
   };
 
+  // Close the publisher.
   self.close = function () {
     self.pc && self.pc.close();
     self.pc = null;
   };
 
+  // The callback when got local stream.
   // @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrack
   self.ontrack = function (event) {
     // Add track to stream of SDK.
@@ -308,11 +313,14 @@ function SrsRtcPlayerAsync() {
         api: conf.apiUrl, tid: conf.tid, streamurl: conf.streamUrl,
         clientip: null, sdp: offer.sdp
       };
+      console.log("Generated offer: ", data);
+
       const xhr = new XMLHttpRequest();
       xhr.onload = function () {
         if (xhr.readyState !== xhr.DONE) return;
         if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);
         const data = JSON.parse(xhr.responseText);
+        console.log("Got answer: ", data);
         return data.code ? reject(xhr) : resolve(data);
       }
       xhr.open('POST', conf.apiUrl, true);
@@ -572,11 +580,14 @@ function SrsRtcWhipWhepAsync() {
     var offer = await self.pc.createOffer();
     await self.pc.setLocalDescription(offer);
     const answer = await new Promise(function (resolve, reject) {
+      console.log("Generated offer: ", offer);
+
       const xhr = new XMLHttpRequest();
       xhr.onload = function () {
         if (xhr.readyState !== xhr.DONE) return;
         if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);
         const data = xhr.responseText;
+        console.log("Got answer: ", data);
         return data.code ? reject(xhr) : resolve(data);
       }
       xhr.open('POST', url, true);

+ 11 - 11
Web/src/websocket/index.ts

@@ -9,7 +9,7 @@ interface WebSocketOptions {
 }
 
 export interface MessageHandler {
-  (data: { [key: string]: any }): void
+  (data : {[key: string]: any}): void
 }
 
 export interface CommonHostWs<T> {
@@ -27,14 +27,14 @@ class ConnectWebSocket {
   _hasInit: boolean
   _messageHandler: MessageHandler | null
 
-  constructor(url: string) {
+  constructor (url: string) {
     this._url = url
     this._socket = null
     this._hasInit = false
     this._messageHandler = null
   }
 
-  initSocket() {
+  initSocket () {
     if (this._hasInit) {
       return
     }
@@ -57,35 +57,35 @@ class ConnectWebSocket {
     this._socket.addEventListener('message', this._onMessage.bind(this))
   }
 
-  _onOpen() {
+  _onOpen () {
     console.log('连接成功')
   }
 
-  _onClose() {
+  _onClose () {
     console.log('连接已断开')
   }
 
-  _onError() {
+  _onError () {
     console.log('连接 error')
   }
 
-  registerMessageHandler(messageHandler: MessageHandler) {
+  registerMessageHandler (messageHandler: MessageHandler) {
     this._messageHandler = messageHandler
   }
 
-  _onMessage(msg: MessageEvent) {
+  _onMessage (msg: MessageEvent) {
     const data = JSON.parse(msg.data)
     this._messageHandler && this._messageHandler(data)
-    // console.log('socket接受消息', message)
+    // console.log('接受消息', message)
   }
 
   sendMessage = (message: WebSocketOptions): void => {
     this._socket?.send(JSON.stringify(message.data))
   }
 
-  close() {
+  close () {
     this._socket?.close()
   }
 }
 
-export default ConnectWebSocket
+export default ConnectWebSocket

+ 5 - 3
Web/tsconfig.json

@@ -9,7 +9,9 @@
     "resolveJsonModule": true,
     "esModuleInterop": true,
     "baseUrl": ".",
-    "types": ["vite/client"],
+    "types": [
+      "vite/client"
+    ],
     "lib": [
       "esnext",
       "dom"
@@ -24,7 +26,7 @@
     "src/**/*.ts",
     "src/**/*.d.ts",
     "src/**/*.tsx",
-    "src/**/*.vue", 
-    "src/vendors/coordtransform.js"  
+    "src/**/*.vue",
+    "src/vendors/coordtransform.js"
   ]
 }

+ 19 - 22
Web/vite.config.ts

@@ -1,11 +1,11 @@
-import vue from '@vitejs/plugin-vue';
-import path from 'path';
-import { ConfigEnv, defineConfig, UserConfigExport } from 'vite';
-import ViteComponents, { AntDesignVueResolver } from 'vite-plugin-components';
-import OptimizationPersist from 'vite-plugin-optimize-persist';
-import PkgConfig from 'vite-plugin-package-config';
-import viteSvgIcons from 'vite-plugin-svg-icons';
-import { viteVConsole } from 'vite-plugin-vconsole';
+import vue from '@vitejs/plugin-vue'
+import path from 'path'
+import { ConfigEnv, defineConfig, UserConfigExport } from 'vite'
+import ViteComponents, { AntDesignVueResolver } from 'vite-plugin-components'
+import OptimizationPersist from 'vite-plugin-optimize-persist'
+import PkgConfig from 'vite-plugin-package-config'
+import viteSvgIcons from 'vite-plugin-svg-icons'
+import { viteVConsole } from 'vite-plugin-vconsole'
 
 export default ({ command, mode }: ConfigEnv): UserConfigExport => defineConfig({
   plugins: [
@@ -22,6 +22,7 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => defineConfig(
     viteVConsole({
       entry: path.resolve(__dirname, './src/main.ts'), // 入口文件
       localEnabled: command === 'serve', // serve开发环境下
+      // enabled: command !== 'serve' || mode === 'test', // 打包环境下/发布测试包,
       config: { // vconsole 配置项
         maxLogNumber: 1000,
         theme: 'light'
@@ -29,30 +30,26 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => defineConfig(
     }),
     PkgConfig(),
     OptimizationPersist()
+    // [svgBuilder('./src/assets/icons/')] // All svg under src/icons/svg/ have been imported here, no need to import separately
   ],
   server: {
     open: true,
     host: '0.0.0.0',
-    port: 8080,
-    // proxy: {
-    //   '/api': {
-    //     target: 'http://192.168.3.42:6789',
-    //     changeOrigin: true,
-    //     rewrite: (path) => path.replace(/^\/api/, '')
-    //   }
-    // }
+    port: 8080
   },
-  envDir: './env',
   resolve: {
-    alias: [{
-      find: '/@',
-      replacement: path.resolve(__dirname, './src'),
-    }
+    alias: [
+      {
+        find: '/@',
+        replacement: path.resolve(__dirname, './src'),
+      }
     ]
   },
   css: {
     preprocessorOptions: {
       scss: {
+        // example : additionalData: `@import "./src/design/styles/variables";`
+        // dont need include file extend .scss
         additionalData: '@import "./src/styles/variables";'
       },
     }
@@ -62,4 +59,4 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => defineConfig(
     target: ['es2015'], // 最低支持 es2015
     sourcemap: true
   }
-})
+})