Browse Source

更新网络请求配置

李富豪 1 year ago
parent
commit
001d297f85

+ 8 - 0
Web/env/.env.development

@@ -0,0 +1,8 @@
+# 开发环境配置
+VITE_APP_ENV = 'development'
+
+# Api 地址
+VITE_APP_API_URL = 'http://192.168.3.42:6789'
+
+# WebSocket 地址
+VITE_APP_WEBSOCKET_URL = 'ws://192.168.3.42:6789/api/v1/ws'

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

@@ -0,0 +1,8 @@
+# 生产环境配置
+VITE_APP_ENV = 'production'
+
+# Api 地址
+VITE_APP_API_URL = 'http://49.234.30.234:6789'
+
+# WebSocket 地址
+VITE_APP_WEBSOCKET_URL = 'ws://49.234.30.234:6789/api/v1/ws'

+ 0 - 6
Web/src/api/http/config.ts

@@ -3,12 +3,6 @@ export const CURRENT_CONFIG = {
   appId: '146815',
   appKey: '7c9e9108f2ddcbab32d2b508f452151',
   appLicense: 'ZK7Dzih4Qc9JCZhDiyDsWJwTW+1rhnnzT1SqDxbdSPVV24bbDC4r1KNjXo7tIPBnPne7ipnXeefP0lJ0OHvxMpkKiag5lFCIndKSvYYdQkyScT3dahCXjmYsd0YyWyHj4tvXoR2DRVq1PdBHLB1iUo2FGLCIZ8QHbGyqglyGdHY=',
-  // 网络请求
-  baseURL: '/api',
-  //apiURL: 'http://192.168.3.42:6789',
-  //websocketURL: 'ws://192.168.3.42:6789/api/v1/ws',
-  apiURL: 'http://49.234.30.234:6789',
-  websocketURL: 'ws://49.234.30.234:6789/api/v1/ws',
   // livestreaming
   // RTMP  Note: This IP is the address of the streaming server. If you want to see livestream on web page, you need to convert the RTMP stream to WebRTC stream.
   rtmpURL: 'Please enter the rtmp access address.', // Example: 'rtmp://192.168.1.1/live/'

+ 1 - 1
Web/src/api/http/request.ts

@@ -20,7 +20,7 @@ const instance = axios.create({
 instance.interceptors.request.use(
   config => {
     config.headers[ELocalStorageKey.Token] = getAuthToken()
-    config.baseURL = CURRENT_CONFIG.baseURL
+    config.baseURL = '/api';
     return config
   },
   error => {

+ 54 - 54
Web/src/api/pilot-bridge.ts

@@ -6,11 +6,11 @@ import { getRoot } from '/@/root'
 
 const root = getRoot()
 export const components = new Map()
-declare let window:any
-interface JsResponse{
-  code:number,
-  message:string,
-  data:any
+declare let window: any
+interface JsResponse {
+  code: number,
+  message: string,
+  data: any
 }
 
 export interface ThingParam {
@@ -47,7 +47,7 @@ export interface MediaParam {
   autoUploadVideo: boolean // 是否自动上传视频, 非必需
 }
 
-function returnBool (response: string): boolean {
+function returnBool(response: string): boolean {
   const res: JsResponse = JSON.parse(response)
   const isError = errorHint(res)
   if (JSON.stringify(res.data) !== '{}') {
@@ -56,17 +56,17 @@ function returnBool (response: string): boolean {
   return isError
 }
 
-function returnString (response: string): string {
+function returnString(response: string): string {
   const res: JsResponse = JSON.parse(response)
   return errorHint(res) ? res.data : ''
 }
 
-function returnNumber (response: string): number {
+function returnNumber(response: string): number {
   const res: JsResponse = JSON.parse(response)
   return errorHint(res) ? res.data : -1
 }
 
-function errorHint (response: JsResponse): boolean {
+function errorHint(response: JsResponse): boolean {
   if (response.code !== 0) {
     message.error(response.message)
     console.error(response.message)
@@ -76,7 +76,7 @@ function errorHint (response: JsResponse): boolean {
 }
 
 export default {
-  init (): Map<EComponentName, any> {
+  init(): Map<EComponentName, any> {
     const thingParam: ThingParam = {
       host: '',
       connectCallback: '',
@@ -95,7 +95,7 @@ export default {
     }
     components.set(EComponentName.Map, mapParam)
     const wsParam: WsParam = {
-      host: CURRENT_CONFIG.websocketURL,
+      host: import.meta.env.VITE_APP_WEBSOCKET_URL,
       token: '',
       connectCallback: 'wsConnectCallback'
     }
@@ -117,76 +117,76 @@ export default {
     return components
   },
 
-  getComponentParam (key:EComponentName): any {
+  getComponentParam(key: EComponentName): any {
     return components.get(key)
   },
-  setComponentParam (key:EComponentName, value:any) {
+  setComponentParam(key: EComponentName, value: any) {
     components.set(key, value)
   },
-  loadComponent (name:string, param:any):string {
+  loadComponent(name: string, param: any): string {
     return returnString(window.djiBridge.platformLoadComponent(name, JSON.stringify(param)))
   },
-  unloadComponent (name:string) :string {
+  unloadComponent(name: string): string {
     return returnString(window.djiBridge.platformUnloadComponent(name))
   },
-  isComponentLoaded (module:string): boolean {
+  isComponentLoaded(module: string): boolean {
     return returnBool(window.djiBridge.platformIsComponentLoaded(module))
   },
-  setWorkspaceId (uuid:string):string {
+  setWorkspaceId(uuid: string): string {
     return returnString(window.djiBridge.platformSetWorkspaceId(uuid))
   },
-  setPlatformMessage (platformName:string, title:string, desc:string): boolean {
+  setPlatformMessage(platformName: string, title: string, desc: string): boolean {
     return returnBool(window.djiBridge.platformSetInformation(platformName, title, desc))
   },
-  getRemoteControllerSN () :string {
+  getRemoteControllerSN(): string {
     return returnString(window.djiBridge.platformGetRemoteControllerSN())
   },
-  getAircraftSN ():string {
+  getAircraftSN(): string {
     return returnString(window.djiBridge.platformGetAircraftSN())
   },
-  stopwebview ():string {
+  stopwebview(): string {
     return returnString(window.djiBridge.platformStopSelf())
   },
-  setLogEncryptKey (key:string):string {
+  setLogEncryptKey(key: string): string {
     return window.djiBridge.platformSetLogEncryptKey(key)
   },
-  clearLogEncryptKey ():string {
+  clearLogEncryptKey(): string {
     return window.djiBridge.platformClearLogEncryptKey()
   },
-  getLogPath ():string {
+  getLogPath(): string {
     return returnString(window.djiBridge.platformGetLogPath())
   },
-  platformVerifyLicense (appId:string, appKey:string, appLicense:string): boolean {
+  platformVerifyLicense(appId: string, appKey: string, appLicense: string): boolean {
     return returnBool(window.djiBridge.platformVerifyLicense(appId, appKey, appLicense))
   },
-  isPlatformVerifySuccess (): boolean {
+  isPlatformVerifySuccess(): boolean {
     return returnBool(window.djiBridge.platformIsVerified())
   },
-  isAppInstalled (pkgName: string): boolean {
+  isAppInstalled(pkgName: string): boolean {
     return returnBool(window.djiBridge.platformIsAppInstalled(pkgName))
   },
-  getVersion (): string {
+  getVersion(): string {
     return window.djiBridge.platformGetVersion()
   },
 
   // thing
-  thingGetConnectState (): boolean {
+  thingGetConnectState(): boolean {
     return returnBool(window.djiBridge.thingGetConnectState())
   },
 
-  thingGetConfigs (): ThingParam {
+  thingGetConfigs(): ThingParam {
     const thingParam = JSON.parse(window.djiBridge.thingGetConfigs())
     return thingParam.code === 0 ? JSON.parse(thingParam.data) : {}
   },
 
   // api
-  getToken () : string {
+  getToken(): string {
     return returnString(window.djiBridge.apiGetToken())
   },
-  setToken (token:string):string {
+  setToken(token: string): string {
     return returnString(window.djiBridge.apiSetToken(token))
   },
-  getHost (): string {
+  getHost(): string {
     return returnString(window.djiBridge.apiGetHost())
   },
 
@@ -198,7 +198,7 @@ export default {
    * video-by-manual:手动点播,配置好直播类型参数之后,在图传页面可修改直播参数,停止直播
    * video-demand-aux-manual: 混合模式,支持服务器点播,以及图传页面修改直播参数,停止直播
    */
-  setVideoPublishType (type:string): boolean {
+  setVideoPublishType(type: string): boolean {
     return returnBool(window.djiBridge.liveshareSetVideoPublishType(type))
   },
 
@@ -207,65 +207,65 @@ export default {
    * @returns
    * type: liveshare type, 0:unknown, 1:agora, 2:rtmp, 3:rtsp, 4:gb28181
    */
-  getLiveshareConfig (): string {
+  getLiveshareConfig(): string {
     return returnString(window.djiBridge.liveshareGetConfig())
   },
 
-  setLiveshareConfig (type:number, params:string):string {
+  setLiveshareConfig(type: number, params: string): string {
     return window.djiBridge.liveshareSetConfig(type, params)
   },
 
-  setLiveshareStatusCallback (callbackFunc:string) :string {
+  setLiveshareStatusCallback(callbackFunc: string): string {
     return window.djiBridge.liveshareSetStatusCallback(callbackFunc)
   },
-  getLiveshareStatus (): LiveStreamStatus {
+  getLiveshareStatus(): LiveStreamStatus {
     return JSON.parse(JSON.parse(window.djiBridge.liveshareGetStatus()).data)
   },
-  startLiveshare (): boolean {
+  startLiveshare(): boolean {
     return returnBool(window.djiBridge.liveshareStartLive())
   },
-  stopLiveshare (): boolean {
+  stopLiveshare(): boolean {
     return returnBool(window.djiBridge.liveshareStopLive())
   },
   // WebSocket
-  wsGetConnectState (): boolean {
+  wsGetConnectState(): boolean {
     return returnBool(window.djiBridge.wsGetConnectState())
   },
-  wsConnect (host: string, token: string, callback: string): string {
+  wsConnect(host: string, token: string, callback: string): string {
     return window.djiBridge.wsConnect(host, token, callback)
   },
-  wsDisconnect (): string {
+  wsDisconnect(): string {
     return window.djiBridge.wsConnect()
   },
-  wsSend (message: string): string {
+  wsSend(message: string): string {
     return window.djiBridge.wsSend(message)
   },
   // media
-  setAutoUploadPhoto (auto:boolean):string {
+  setAutoUploadPhoto(auto: boolean): string {
     return window.djiBridge.mediaSetAutoUploadPhoto(auto)
   },
-  getAutoUploadPhoto (): boolean {
+  getAutoUploadPhoto(): boolean {
     return returnBool(window.djiBridge.mediaGetAutoUploadPhoto())
   },
-  setUploadPhotoType (type:number):string {
+  setUploadPhotoType(type: number): string {
     return window.djiBridge.mediaSetUploadPhotoType(type)
   },
-  getUploadPhotoType (): number {
+  getUploadPhotoType(): number {
     return returnNumber(window.djiBridge.mediaGetUploadPhotoType())
   },
-  setAutoUploadVideo (auto:boolean):string {
+  setAutoUploadVideo(auto: boolean): string {
     return window.djiBridge.mediaSetAutoUploadVideo(auto)
   },
-  getAutoUploadVideo (): boolean {
+  getAutoUploadVideo(): boolean {
     return returnBool(window.djiBridge.mediaGetAutoUploadVideo())
   },
-  setDownloadOwner (rcIndex:number):string {
+  setDownloadOwner(rcIndex: number): string {
     return window.djiBridge.mediaSetDownloadOwner(rcIndex)
   },
-  getDownloadOwner (): number {
+  getDownloadOwner(): number {
     return returnNumber(window.djiBridge.mediaGetDownloadOwner())
   },
-  onBackClickReg () {
+  onBackClickReg() {
     window.djiBridge.onBackClick = () => {
       if (root.$router.currentRoute.value.path === '/' + ERouterName.PILOT_HOME) {
         return false
@@ -275,7 +275,7 @@ export default {
       }
     }
   },
-  onStopPlatform () {
+  onStopPlatform() {
     window.djiBridge.onStopPlatform = () => {
       localStorage.clear()
     }

+ 80 - 0
Web/src/components/devices/changeRecord/components/Search.vue

@@ -0,0 +1,80 @@
+<template>
+  <a-row style="margin-bottom: 20px;" justify="end">
+    <a-col>
+      <a-form ref="formRef" layout="inline" :model="formModel" :colon="false">
+        <a-form-item name="date">
+          <a-range-picker v-model:value="formModel.date" />
+        </a-form-item>
+        <a-form-item name="device_name">
+          <a-select style="width: 200px;margin-right: 10px;" placeholder="请选择设备型号"
+            v-model:value="formModel.device_name">
+            <a-select-option value="1">
+              1
+            </a-select-option>
+            <a-select-option value="2">
+              2
+            </a-select-option>
+            <a-select-option value="3">
+              3
+            </a-select-option>
+            <a-select-option value="4">
+              4
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item name="keyword">
+          <a-input style="width: 200px;margin-right: 10px;" placeholder="设备SN、设备名称" v-model:value="formModel.keyword" />
+        </a-form-item>
+        <a-form-item>
+          <a-button style="margin-right: 10px;" @click="handleClicSekarch">
+            <template #icon>
+              <SearchOutlined />
+            </template>
+          </a-button>
+          <a-button @click="handleClickReset">
+            <template #icon>
+              <ReloadOutlined />
+            </template>
+          </a-button>
+        </a-form-item>
+      </a-form>
+    </a-col>
+  </a-row>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive } from 'vue';
+import { SearchOutlined, ReloadOutlined } from '@ant-design/icons-vue';
+
+interface Props {
+  onClickSearch: (query: any) => Promise<any>,
+  onClickReset: (query: any) => Promise<any>,
+};
+
+const props = withDefaults(defineProps<Props>(), {
+
+});
+
+const formRef = ref();
+
+const formModel = reactive({
+  date: [],
+  device_name: undefined,
+  keyword: '',
+})
+
+// 点击查询
+const handleClicSekarch = async () => {
+  const values = formRef.value?.getFieldsValue();
+  await props.onClickSearch(values);
+}
+
+// 点击重置
+const handleClickReset = async () => {
+  formRef.value?.resetFields();
+  const values = formRef.value?.getFieldsValue();
+  await props.onClickReset(values);
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 17 - 12
Web/src/components/devices/changeRecord/index.vue

@@ -1,10 +1,9 @@
 <template>
   <div class="changeRecord">
+    <Search :onClickSearch="async () => { }" :onClickReset="async () => { }" />
     <div class="changeRecord-table">
       <a-table :scroll="{ x: '100%', y: 600 }" rowKey="id" :loading="state.listLoading" :columns="columns"
-        :dataSource="state.list" :pagination="paginationConfig">
-
-      </a-table>
+        :dataSource="state.list" :pagination="paginationConfig" />
     </div>
   </div>
 </template>
@@ -13,9 +12,10 @@
 import { reactive, onMounted } from 'vue';
 import { Modal } from 'ant-design-vue';
 import { DeleteOutlined, FileSearchOutlined } from '@ant-design/icons-vue';
+import Search from './components/Search.vue';
 import Drawer from './components/Drawer.vue';
 import { apis } from '/@/api/custom/index';
-import {IPage} from "/@/api/http/type";
+import { IPage } from "/@/api/http/type";
 
 interface State {
   listLoading: boolean,
@@ -44,9 +44,9 @@ const paginationConfig = reactive({
 onMounted(async () => {
   state.listLoading = true;
   try {
-    const res = await apis.fetchChangeRecordList({page : paginationConfig.current, page_size: paginationConfig.pageSize});
+    const res = await apis.fetchChangeRecordList({ page: paginationConfig.current, page_size: paginationConfig.pageSize });
     console.log(res, 'list');
-    if(res.code === 0) {
+    if (res.code === 0) {
       paginationConfig.total = res.data.pagination.total
       paginationConfig.current = res.data.pagination.page
       paginationConfig.pageSize = res.data.pagination.page_size
@@ -120,12 +120,17 @@ const onClickDelete = (id: number) => {
 }
 </script>
 
-<style lang="scss" scoped>
+<style lang="scss">
 .changeRecord {
-  &-table {
-    background-color: white;
-    margin: 20px;
-    padding: 0 20px;
-  }
+  padding: 20px;
+}
+
+.ant-table {
+  border-top: 1px solid rgb(0, 0, 0, 0.06);
+  border-bottom: 1px solid rgb(0, 0, 0, 0.06);
+}
+
+.ant-table-tbody tr td {
+  border: 0;
 }
 </style>

+ 23 - 26
Web/src/components/devices/device-upgrade/DeviceFirmwareUpgrade.vue

@@ -1,25 +1,22 @@
 <template>
-<div class="firmware_upgrade_wrap">
-  <!-- 版本 -->
-  <span class="version"> {{ device.firmware_version }}</span>
-  <!-- tag -->
-  <span v-if="getTagStatus(device)"
-        class="status-tag pointer">
-    <a-tag class="pointer"
-           :color="getFirmwareTag(device.firmware_status).color"
-           @click="deviceUpgrade(device)">
-      {{ getFirmwareTag(device.firmware_status).text }}
-    </a-tag>
-  </span>
-  <!-- 进度 -->
-  <span v-if="device.firmware_status === DeviceFirmwareStatusEnum.DuringUpgrade">
-  {{ `${device.firmware_progress}`}}
-  </span>
-</div>
+  <div class="firmware_upgrade_wrap">
+    <!-- 版本 -->
+    <span class="version"> {{ device.firmware_version }}</span>
+    <!-- tag -->
+    <span v-if="getTagStatus(device)" class="status-tag pointer">
+      <a-tag class="pointer" :color="getFirmwareTag(device.firmware_status).color" @click="deviceUpgrade(device)">
+        {{ getFirmwareTag(device.firmware_status).text }}
+      </a-tag>
+    </span>
+    <!-- 进度 -->
+    <span v-if="device.firmware_status === DeviceFirmwareStatusEnum.DuringUpgrade">
+      {{ `${device.firmware_progress}` }}
+    </span>
+  </div>
 </template>
 
 <script lang="ts" setup>
-import { defineProps, defineEmits, ref, watch, computed } from 'vue'
+import { defineProps, defineEmits, computed } from 'vue'
 import { Device, DeviceFirmwareStatusEnum, DeviceFirmwareStatus, DeviceFirmwareStatusColor } from '/@/types/device'
 
 const props = defineProps<{
@@ -27,33 +24,33 @@ const props = defineProps<{
 }>()
 
 const emit = defineEmits(['device-upgrade'])
+
 const needUpgrade = computed(() => {
   return props.device.firmware_status === DeviceFirmwareStatusEnum.ConsistencyUpgrade ||
-         props.device.firmware_status === DeviceFirmwareStatusEnum.ToUpgraded
+    props.device.firmware_status === DeviceFirmwareStatusEnum.ToUpgraded
 })
 
-function getTagStatus (record: Device) {
+function getTagStatus(record: Device) {
   return record.firmware_status && record.firmware_status !== DeviceFirmwareStatusEnum.None
 }
 
-function getFirmwareTag (status: DeviceFirmwareStatusEnum) {
+function getFirmwareTag(status: DeviceFirmwareStatusEnum) {
   return {
     text: DeviceFirmwareStatus[status] || '',
     color: DeviceFirmwareStatusColor[status] || ''
   }
 }
 
-function deviceUpgrade (record: Device) {
+function deviceUpgrade(record: Device) {
   if (!needUpgrade.value) return
   emit('device-upgrade', record)
 }
-
 </script>
 
 <style lang="scss" scoped>
-.firmware_upgrade_wrap{
+.firmware_upgrade_wrap {
 
-  .status-tag{
+  .status-tag {
     margin-left: 10px;
   }
 
@@ -61,4 +58,4 @@ function deviceUpgrade (record: Device) {
     cursor: pointer;
   }
 }
-</style>
+</style>

+ 105 - 0
Web/src/components/devices/deviceList/components/Search.vue

@@ -0,0 +1,105 @@
+<template>
+  <a-row style="margin-bottom: 20px;" justify="space-between">
+    <a-col>
+      <a-button style="margin-right: 10px;">
+        机场设备绑定码
+        <MenuOutlined />
+      </a-button>
+      <a style="margin-right: 10px;">
+        如何绑定机场?
+      </a>
+      <a-button>
+        删除
+      </a-button>
+    </a-col>
+    <a-col>
+      <a-form ref="formRef" layout="inline" :model="formModel" :colon="false">
+        <a-form-item name="status">
+          <a-select style="width: 200px;margin-right: 10px;" placeholder="请选择状态" v-model:value="formModel.status">
+            <a-select-option value="1">
+              1
+            </a-select-option>
+            <a-select-option value="2">
+              2
+            </a-select-option>
+            <a-select-option value="3">
+              3
+            </a-select-option>
+            <a-select-option value="4">
+              4
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item name="device_name">
+          <a-select style="width: 200px;margin-right: 10px;" placeholder="请选择设备型号"
+            v-model:value="formModel.device_name">
+            <a-select-option value="1">
+              1
+            </a-select-option>
+            <a-select-option value="2">
+              2
+            </a-select-option>
+            <a-select-option value="3">
+              3
+            </a-select-option>
+            <a-select-option value="4">
+              4
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item name="keyword">
+          <a-input style="width: 200px;margin-right: 10px;" placeholder="设备SN、设备名称" v-model:value="formModel.keyword" />
+        </a-form-item>
+        <a-form-item>
+          <a-button style="margin-right: 10px;" @click="handleClicSekarch">
+            <template #icon>
+              <SearchOutlined />
+            </template>
+          </a-button>
+          <a-button @click="handleClickReset">
+            <template #icon>
+              <ReloadOutlined />
+            </template>
+          </a-button>
+        </a-form-item>
+      </a-form>
+    </a-col>
+  </a-row>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive } from 'vue';
+import { MenuOutlined, SearchOutlined, ReloadOutlined } from '@ant-design/icons-vue';
+
+interface Props {
+  onClickSearch: (query: any) => Promise<any>,
+  onClickReset: (query: any) => Promise<any>,
+};
+
+const props = withDefaults(defineProps<Props>(), {
+
+});
+
+const formRef = ref();
+
+const formModel = reactive({
+  status: undefined,
+  device_name: undefined,
+  keyword: '',
+})
+
+// 点击查询
+const handleClicSekarch = async () => {
+  const values = formRef.value?.getFieldsValue();
+  await props.onClickSearch(values);
+}
+
+// 点击重置
+const handleClickReset = async () => {
+  formRef.value?.resetFields();
+  const values = formRef.value?.getFieldsValue();
+  await props.onClickReset(values);
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 147 - 176
Web/src/components/devices/deviceList/index.vue

@@ -1,114 +1,99 @@
 <template>
-  <div class="device-table-wrap table flex-display flex-column">
-    <a-table :columns="columns" :data-source="data.device" :pagination="paginationProp" @change="refreshData"
-      row-key="device_sn" :expandedRowKeys="expandRows" :row-selection="rowSelection" :rowClassName="rowClassName"
-      :scroll="{ x: 'max-content', y: 600 }" :expandIcon="expandIcon" :loading="loading">
-      <template v-for="col in ['nickname']" #[col]="{ text, record }" :key="col">
-        <div>
-          <a-input v-if="editableData[record.device_sn]" v-model:value="editableData[record.device_sn][col]"
-            style="margin: -5px 0" />
-          <template v-else>
-            <a-tooltip :title="text">
-              {{ text }}
-            </a-tooltip>
-          </template>
-        </div>
-      </template>
-      <template v-for="col in ['sn', 'workspace']" #[col]="{ text }" :key="col">
-        <a-tooltip :title="text">
-          <span>{{ text }}</span>
-        </a-tooltip>
-      </template>
-      <!-- 固件版本 -->
-      <template #firmware_version="{ record }">
-        <span v-if="judgeCurrentType(EDeviceTypeName.Dock)">
-          <DeviceFirmwareUpgrade :device="record" class="table-flex-col" @device-upgrade="onDeviceUpgrade" />
-        </span>
-        <span v-else>
-          {{ record.firmware_version }}
-        </span>
-      </template>
-      <!-- 固件升级 -->
-      <template #firmware_status="{ text }">
-        <div v-if="text === -1">
-          不支持
-        </div>
-        <div v-else>
-          {{ DeviceFirmwareStatus[text] }}
-        </div>
-      </template>
-      <!-- 状态 -->
-      <template #status="{ text }">
-        <span v-if="text" class="flex-row flex-align-center">
-          <span class="mr5" style="width: 12px; height: 12px; border-radius: 50%; background-color: green;" />
-          <span>在线</span>
-        </span>
-        <span class="flex-row flex-align-center" v-else>
-          <span class="mr5" style="width: 12px; height: 12px; border-radius: 50%; background-color: red;" />
-          <span>离线</span>
-        </span>
-      </template>
-      <!-- 操作 -->
-      <template #action="{ record }">
-        <div class="editable-row-operations">
+  <div class="deviceList">
+    <Search :onClickSearch="async () => { }" :onClickReset="async () => { }" />
+    <div class="deviceList-table">
+      <a-table :columns="columns" :data-source="data.device" :pagination="paginationProp" @change="refreshData"
+        row-key="device_sn" :expandedRowKeys="expandRows" :row-selection="rowSelection" :rowClassName="rowClassName"
+        :scroll="{ x: '100%', y: 600 }" :expandIcon="expandIcon" :loading="loading">
+        <template v-for="col in ['nickname']" #[col]="{ text, record }" :key="col">
+          <div>
+            <a-input v-if="editableData[record.device_sn]" v-model:value="editableData[record.device_sn][col]" />
+            <template v-else>
+              <a-tooltip :title="text">
+                {{ text }}
+              </a-tooltip>
+            </template>
+          </div>
+        </template>
+        <template v-for="col in ['sn', 'workspace']" #[col]="{ text }" :key="col">
+          <a-tooltip :title="text">
+            <span>{{ text }}</span>
+          </a-tooltip>
+        </template>
+        <!-- 固件版本 -->
+        <template #firmware_version="{ record }">
+          <span v-if="judgeCurrentType(EDeviceTypeName.Dock)">
+            <DeviceFirmwareUpgrade :device="record" class="table-flex-col" @device-upgrade="onDeviceUpgrade" />
+          </span>
+          <span v-else>
+            {{ record.firmware_version }}
+          </span>
+        </template>
+        <!-- 固件升级 -->
+        <template #firmware_status="{ text }">
+          <div v-if="text === -1">
+            不支持
+          </div>
+          <div v-else>
+            {{ DeviceFirmwareStatus[text] }}
+          </div>
+        </template>
+        <!-- 状态 -->
+        <template #status="{ text }">
+          <span v-if="text" class="flex-row flex-align-center">
+            <span class="mr5" style="width: 12px; height: 12px; border-radius: 50%; background-color: green;" />
+            <span>在线</span>
+          </span>
+          <span class="flex-row flex-align-center" v-else>
+            <span class="mr5" style="width: 12px; height: 12px; border-radius: 50%; background-color: red;" />
+            <span>离线</span>
+          </span>
+        </template>
+        <!-- 操作 -->
+        <template #action="{ record }">
           <!-- 编辑态操作 -->
           <div v-if="editableData[record.device_sn]">
             <a-tooltip title="确定">
-              <span @click="save(record)" style="color: #28d445;">
-                <CheckOutlined />
-              </span>
+              <CheckOutlined style="color: #28d445;margin-right: 10px;" @click="save(record)" />
             </a-tooltip>
             <a-tooltip title="取消">
-              <span @click="() => delete editableData[record.device_sn]" style="color: #e70102;">
-                <CloseOutlined />
-              </span>
+              <CloseOutlined style="color: #e70102;" @click="() => delete editableData[record.device_sn]" />
             </a-tooltip>
           </div>
           <!-- 非编辑态操作 -->
           <div v-else class="flex-align-center flex-row" style="color: #2d8cf0">
             <a-tooltip v-if="current.indexOf(EDeviceTypeName.Dock) !== -1" title="设备日志">
-              <CloudServerOutlined @click="showDeviceLogUploadRecord(record)" />
+              <CloudServerOutlined style="margin-right: 10px;" @click="showDeviceLogUploadRecord(record)" />
             </a-tooltip>
             <a-tooltip v-if="current.indexOf(EDeviceTypeName.Dock) !== -1" title="告警信息">
-              <FileSearchOutlined @click="showHms(record)" />
+              <FileSearchOutlined style="margin-right: 10px;" @click="showHms(record)" />
             </a-tooltip>
             <a-tooltip title="编辑">
-              <EditOutlined @click="edit(record)" />
+              <EditOutlined style="margin-right: 10px;" @click="edit(record)" />
             </a-tooltip>
             <a-tooltip title="删除">
-              <DeleteOutlined @click="() => { deleteTip = true, deleteSn = record.device_sn }" />
+              <DeleteOutlined @click="onClickDelete(record)" />
             </a-tooltip>
           </div>
-        </div>
-      </template>
-    </a-table>
-    <a-modal v-model:visible="deleteTip" width="450px" :closable="false" centered :okButtonProps="{ danger: true }"
-      @ok="unbind">
-      <p class="pt10 pl20" style="height: 50px;">从工作区中删除设备吗?</p>
-      <template #title>
-        <div class="flex-row flex-justify-center">
-          <span>删除设备</span>
-        </div>
-      </template>
-    </a-modal>
-    <!-- 设备升级 -->
-    <DeviceFirmwareUpgradeModal title="设备升级" v-model:visible="deviceFirmwareUpgradeModalVisible"
-      :device="selectedDevice" @ok="onUpgradeDeviceOk"></DeviceFirmwareUpgradeModal>
-    <!-- 设备日志上传记录 -->
-    <DeviceLogUploadRecordDrawer v-model:visible="deviceLogUploadRecordVisible" :device="currentDevice">
-    </DeviceLogUploadRecordDrawer>
-    <!-- hms 信息 -->
-    <DeviceHmsDrawer v-model:visible="hmsVisible" :device="currentDevice">
-    </DeviceHmsDrawer>
+        </template>
+      </a-table>
+      <!-- 设备升级 -->
+      <DeviceFirmwareUpgradeModal title="设备升级" v-model:visible="deviceFirmwareUpgradeModalVisible"
+        :device="selectedDevice" @ok="onUpgradeDeviceOk" />
+      <!-- 设备日志上传记录 -->
+      <DeviceLogUploadRecordDrawer v-model:visible="deviceLogUploadRecordVisible" :device="currentDevice" />
+      <!-- hms 信息 -->
+      <DeviceHmsDrawer v-model:visible="hmsVisible" :device="currentDevice" />
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
 import { h, onMounted, reactive, ref, UnwrapRef } from 'vue'
-import { notification } from 'ant-design-vue'
-import { ColumnProps, TableState } from 'ant-design-vue/lib/table/interface'
-import { getBindingDevices, unbindDevice, updateDevice } from '/@/api/manage'
+import { Modal, notification } from 'ant-design-vue'
 import { EditOutlined, CheckOutlined, CloseOutlined, DeleteOutlined, FileSearchOutlined, CloudServerOutlined } from '@ant-design/icons-vue'
+import Search from './components/Search.vue'
+import { getBindingDevices, unbindDevice, updateDevice } from '/@/api/manage'
 import { Device, DeviceFirmwareStatus, DeviceFirmwareStatusEnum } from '/@/types/device'
 import DeviceFirmwareUpgrade from '/@/components/devices/device-upgrade/DeviceFirmwareUpgrade.vue'
 import DeviceFirmwareUpgradeModal from '/@/components/devices/device-upgrade/DeviceFirmwareUpgradeModal.vue'
@@ -120,47 +105,75 @@ import DeviceHmsDrawer from '/@/components/devices/device-hms/DeviceHmsDrawer.vu
 import { IPage } from '/@/api/http/type'
 import { EDeviceTypeName, ELocalStorageKey } from '/@/types'
 
-interface DeviceData {
-  device: Device[]
-}
-
 const loading = ref(true)
-const deleteTip = ref<boolean>(false)
-const deleteSn = ref<string>()
 
-const columns: ColumnProps[] = [
+const columns = [
+  {
+    title: '设备型号',
+    dataIndex: 'device_name',
+    width: 150,
+    ellipsis: true,
+    sorter: (a: any, b: any) => a.nickname.localeCompare(b.nickname),
+  },
   {
-    title: '设备型号', dataIndex: 'device_name', width: 150,
-    sorter: (a: Device, b: Device) => a.nickname.localeCompare(b.nickname),
-    className: 'titleStyle'
+    title: '设备SN',
+    dataIndex: 'device_sn',
+    width: 200,
+    ellipsis: true,
+    slots: { customRender: 'sn' }
   },
-  { title: '设备SN', dataIndex: 'device_sn', width: 100, className: 'titleStyle', ellipsis: true, slots: { customRender: 'sn' } },
   {
     title: '设备名称',
     dataIndex: 'nickname',
     width: 150,
-    sorter: (a: Device, b: Device) => a.nickname.localeCompare(b.nickname),
-    className: 'titleStyle',
     ellipsis: true,
+    sorter: (a: any, b: any) => a.nickname.localeCompare(b.nickname),
     slots: { customRender: 'nickname' }
   },
-  { title: '固件版本', dataIndex: 'firmware_version', width: 150, className: 'titleStyle', slots: { customRender: 'firmware_version' } },
-  { title: '固件升级', dataIndex: 'firmware_status', width: 150, className: 'titleStyle', slots: { customRender: 'firmware_status' } },
-  { title: '当前状态', dataIndex: 'status', width: 100, className: 'titleStyle', slots: { customRender: 'status' } },
-  { title: '加入项目时间', dataIndex: 'bound_time', width: 150, sorter: (a: Device, b: Device) => a.bound_time.localeCompare(b.bound_time), className: 'titleStyle' },
-  { title: '最后在线时间', dataIndex: 'login_time', width: 150, sorter: (a: Device, b: Device) => a.login_time.localeCompare(b.login_time), className: 'titleStyle' },
+  {
+    title: '固件版本',
+    dataIndex: 'firmware_version',
+    width: 150,
+    ellipsis: true,
+    slots: { customRender: 'firmware_version' },
+  },
+  {
+    title: '固件升级',
+    dataIndex: 'firmware_status',
+    width: 150,
+    ellipsis: true,
+    slots: { customRender: 'firmware_status' },
+  },
+  {
+    title: '当前状态',
+    dataIndex: 'status',
+    width: 100,
+    ellipsis: true,
+    slots: { customRender: 'status' }
+  },
+  {
+    title: '加入项目时间',
+    dataIndex: 'bound_time',
+    width: 200,
+    sorter: (a: any, b: any) => a.bound_time.localeCompare(b.bound_time),
+  },
+  {
+    title: '最后在线时间',
+    dataIndex: 'login_time',
+    width: 200,
+    sorter: (a: any, b: any) => a.login_time.localeCompare(b.login_time),
+  },
   {
     title: '操作',
     dataIndex: 'actions',
     fixed: 'right',
     width: 150,
-    className: 'titleStyle',
-    slots: { customRender: 'action' }
+    slots: { customRender: 'action' },
   },
 ]
 
 const expandIcon = (props: any) => {
-  if (judgeCurrentType(EDeviceTypeName.Dock) && !props.expanded) {
+  if (!props.expanded) {
     return h('div',
       {
         style: 'border-left: 2px solid rgb(200,200,200); border-bottom: 2px solid rgb(200,200,200); height: 16px; width: 16px; float: left;',
@@ -181,7 +194,10 @@ const rowClassName = (record: any, index: number) => {
 }
 
 const expandRows = ref<string[]>([])
-const data = reactive<DeviceData>({
+
+const data: {
+  device: Device[]
+} = reactive({
   device: []
 })
 
@@ -189,7 +205,7 @@ const paginationProp = reactive({
   pageSizeOptions: ['20', '50', '100'],
   showQuickJumper: true,
   showSizeChanger: true,
-  pageSize: 50,
+  pageSize: 20,
   current: 1,
   total: 0
 })
@@ -218,9 +234,8 @@ const rowSelection = {
   }),
 }
 
-type Pagination = TableState['pagination']
-
 const workspaceId: string = localStorage.getItem(ELocalStorageKey.WorkspaceId) || ''
+
 const editableData: UnwrapRef<Record<string, Device>> = reactive({})
 
 const current = ref([EDeviceTypeName.Dock])
@@ -288,12 +303,10 @@ function getDevices(domain: number, closeLoading?: boolean) {
     resData.forEach((val: any) => {
       if (val.children) {
         val.children = [val.children]
-      }
-      if (judgeCurrentType(EDeviceTypeName.Dock)) {
-        expandRows.value.push(val.device_sn)
+        expandRows.value.push(val.device_sn);
       }
     })
-    data.device = resData
+    data.device = resData;
     paginationProp.total = res.data.pagination.total
     paginationProp.current = res.data.pagination.page
     paginationProp.pageSize = res.data.pagination.page_size
@@ -301,7 +314,7 @@ function getDevices(domain: number, closeLoading?: boolean) {
   })
 }
 
-function refreshData(page: Pagination) {
+function refreshData(page: any) {
   paginationProp.current = page?.current!
   paginationProp.pageSize = page?.pageSize!
   getDevices(current.value[0])
@@ -318,15 +331,20 @@ function save(record: Device) {
   updateDevice({ nickname: record.nickname }, workspaceId, record.device_sn)
 }
 
-// 解绑
-function unbind() {
-  deleteTip.value = false
-  unbindDevice(deleteSn.value?.toString()!).then(res => {
-    if (res.code !== 0) {
-      return
-    }
-    getDevices(current.value[0])
-  })
+// 点击删除
+const onClickDelete = (record: Device) => {
+  Modal.confirm({
+    title: '提示',
+    content: `确定删除${record.device_name}吗?`,
+    onOk: async () => {
+      unbindDevice(record.device_sn).then(res => {
+        if (res.code !== 0) {
+          return
+        }
+        getDevices(current.value[0])
+      })
+    },
+  });
 }
 
 const currentDevice = ref({} as Device)
@@ -350,25 +368,9 @@ onMounted(() => {
 })
 </script>
 
-<style lang="scss" scoped>
-.device-table-wrap {
-  .editable-row-operations {
-    div>span {
-      margin-right: 10px;
-    }
-  }
-}
-</style>
-
 <style lang="scss">
-.table {
-  background-color: white;
-  margin: 20px;
-  padding: 0 20px;
-}
-
-.table-striped {
-  background-color: #f7f9fa;
+.deviceList {
+  padding: 20px;
 }
 
 .ant-table {
@@ -380,42 +382,11 @@ onMounted(() => {
   border: 0;
 }
 
-.ant-table td {
-  white-space: nowrap;
-}
-
-.ant-table-thead tr th {
-  background: white !important;
-  border: 0;
-}
-
-th.ant-table-selection-column {
-  background-color: white !important;
-}
-
-.ant-table-header {
-  background-color: white !important;
+.table-striped {
+  background-color: #f7f9fa;
 }
 
 .child-row {
   height: 70px;
 }
-
-.notice {
-  background: $success;
-  overflow: hidden;
-  cursor: pointer;
-}
-
-.caution {
-  background: orange;
-  cursor: pointer;
-  overflow: hidden;
-}
-
-.warn {
-  background: red;
-  cursor: pointer;
-  overflow: hidden;
-}
 </style>

+ 97 - 0
Web/src/components/devices/feedbackRecord/components/Search.vue

@@ -0,0 +1,97 @@
+<template>
+  <a-row style="margin-bottom: 20px;" justify="end">
+    <a-col>
+      <a-form ref="formRef" layout="inline" :model="formModel" :colon="false">
+        <a-form-item name="date">
+          <a-range-picker v-model:value="formModel.date" />
+        </a-form-item>
+        <a-form-item name="status">
+          <a-select style="width: 200px;margin-right: 10px;" placeholder="请选择状态" v-model:value="formModel.status">
+            <a-select-option value="1">
+              1
+            </a-select-option>
+            <a-select-option value="2">
+              2
+            </a-select-option>
+            <a-select-option value="3">
+              3
+            </a-select-option>
+            <a-select-option value="4">
+              4
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item name="device_name">
+          <a-select style="width: 200px;margin-right: 10px;" placeholder="请选择反馈人" v-model:value="formModel.device_name">
+            <a-select-option value="1">
+              1
+            </a-select-option>
+            <a-select-option value="2">
+              2
+            </a-select-option>
+            <a-select-option value="3">
+              3
+            </a-select-option>
+            <a-select-option value="4">
+              4
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item name="keyword">
+          <a-input style="width: 200px;margin-right: 10px;" placeholder="设备SN、设备异常描述"
+            v-model:value="formModel.keyword" />
+        </a-form-item>
+        <a-form-item>
+          <a-button style="margin-right: 10px;" @click="handleClicSekarch">
+            <template #icon>
+              <SearchOutlined />
+            </template>
+          </a-button>
+          <a-button @click="handleClickReset">
+            <template #icon>
+              <ReloadOutlined />
+            </template>
+          </a-button>
+        </a-form-item>
+      </a-form>
+    </a-col>
+  </a-row>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive } from 'vue';
+import { MenuOutlined, SearchOutlined, ReloadOutlined } from '@ant-design/icons-vue';
+
+interface Props {
+  onClickSearch: (query: any) => Promise<any>,
+  onClickReset: (query: any) => Promise<any>,
+};
+
+const props = withDefaults(defineProps<Props>(), {
+
+});
+
+const formRef = ref();
+
+const formModel = reactive({
+  date: [],
+  status: undefined,
+  device_name: undefined,
+  keyword: '',
+})
+
+// 点击查询
+const handleClicSekarch = async () => {
+  const values = formRef.value?.getFieldsValue();
+  await props.onClickSearch(values);
+}
+
+// 点击重置
+const handleClickReset = async () => {
+  formRef.value?.resetFields();
+  const values = formRef.value?.getFieldsValue();
+  await props.onClickReset(values);
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 17 - 10
Web/src/components/devices/feedbackRecord/index.vue

@@ -1,6 +1,7 @@
 <template>
-  <div class="changeRecord">
-    <div class="changeRecord-table">
+  <div class="feedbackRecord">
+    <Search :onClickSearch="async () => { }" :onClickReset="async () => { }" />
+    <div class="feedbackRecord-table">
       <a-table :scroll="{ x: 'max-content', y: 600 }" rowKey="id" :loading="state.listLoading" :columns="columns"
         :dataSource="state.list" :pagination="paginationConfig">
         <!-- 操作 -->
@@ -26,6 +27,7 @@
 import { reactive, onMounted } from 'vue';
 import { Modal } from 'ant-design-vue';
 import { DeleteOutlined, FileSearchOutlined } from '@ant-design/icons-vue';
+import Search from './components/Search.vue';
 import Drawer from './components/Drawer.vue';
 import { apis } from '/@/api/custom/index';
 
@@ -55,7 +57,7 @@ const paginationConfig = reactive({
 onMounted(async () => {
   state.listLoading = true;
   try {
-    //const res = await apis.fetchChangeRecordList();
+    //const res = await apis.fetchfeedbackRecordList();
     //console.log(res, 'list');
     const list = [
       {
@@ -158,12 +160,17 @@ const onClickDelete = (id: number) => {
 }
 </script>
 
-<style lang="scss" scoped>
-.changeRecord {
-  &-table {
-    background-color: white;
-    margin: 20px;
-    padding: 0 20px;
-  }
+<style lang="scss">
+.feedbackRecord {
+  padding: 20px;
+}
+
+.ant-table {
+  border-top: 1px solid rgb(0, 0, 0, 0.06);
+  border-bottom: 1px solid rgb(0, 0, 0, 0.06);
+}
+
+.ant-table-tbody tr td {
+  border: 0;
 }
 </style>

+ 10 - 10
Web/src/pages/page-pilot/pilot-home.vue

@@ -11,13 +11,13 @@
             <div style="height: 50%;">
               <a-dropdown :trigger="['click']">
                 <span style="font-size: 16px; font-weight: bolder">{{ workspaceName }}</span>
-<!--                <template #overlay>-->
-<!--                  <a-menu v-model:selectedKeys="state.selectedKeys" @select="handSelectMenu">-->
-<!--                    <a-menu-item v-for="item in state.projectList" :key="item.id">-->
-<!--                      {{ item.workspace_name }}-->
-<!--                    </a-menu-item>-->
-<!--                  </a-menu>-->
-<!--                </template>-->
+                <!--                <template #overlay>-->
+                <!--                  <a-menu v-model:selectedKeys="state.selectedKeys" @select="handSelectMenu">-->
+                <!--                    <a-menu-item v-for="item in state.projectList" :key="item.id">-->
+                <!--                      {{ item.workspace_name }}-->
+                <!--                    </a-menu-item>-->
+                <!--                  </a-menu>-->
+                <!--                </template>-->
               </a-dropdown>
               <RightOutlined style="float: right; margin-top: 5px; color: #8894a0" @click="showStatus" />
             </div>
@@ -128,7 +128,7 @@
 <script lang="ts" setup>
 import { message } from 'ant-design-vue'
 import { onMounted, reactive, ref } from 'vue'
-import {BindBody, bindDevice, getDeviceBySn, getPlatformInfo, getUserInfo, unbindDevice} from '/@/api/manage'
+import { BindBody, bindDevice, getDeviceBySn, getPlatformInfo, getUserInfo, unbindDevice } from '/@/api/manage'
 import apiPilot, { ApiParam, MapParam, ThingParam, WsParam } from '/@/api/pilot-bridge'
 import { getRoot } from '/@/root'
 import { EBizCode, EComponentName, EDownloadOwner, ELocalStorageKey, ERouterName, EStatusValue } from '/@/types'
@@ -182,8 +182,8 @@ const state = reactive({
 const handSelectMenu = (items: any) => {
   console.log("selectMenu====")
   state.selectedKeys = items
-  localStorage.setItem(ELocalStorageKey.WorkspaceName,items[0].workspace_name)
-  localStorage.setItem(ELocalStorageKey.WorkspaceId,items[0].id)
+  localStorage.setItem(ELocalStorageKey.WorkspaceName, items[0].workspace_name)
+  localStorage.setItem(ELocalStorageKey.WorkspaceId, items[0].id)
   //解绑设备
   unbindDevice(device.data.gateway_sn).then(unbindRes => {
     if (unbindRes.code !== 0) {

+ 2 - 9
Web/src/pages/page-pilot/pilot-index.vue

@@ -34,7 +34,6 @@ import { CURRENT_CONFIG } from '/@/api/http/config'
 import { login, LoginBody, refreshToken } from '/@/api/manage'
 import apiPilot from '/@/api/pilot-bridge'
 import { getRoot } from '/@/root'
-import router from '/@/router'
 import { EComponentName, ELocalStorageKey, ERouterName, EUserType } from '/@/types'
 import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
 import djiLogo from '/@/assets/icons/dji_logo.png'
@@ -60,21 +59,16 @@ onMounted(async () => {
   if (token) {
     await refreshToken({})
       .then(res => {
-        console.log('1111111111111111');
         apiPilot.setComponentParam(EComponentName.Api, {
-          host: CURRENT_CONFIG.apiURL,
+          host: import.meta.env.VITE_APP_API_URL,
           token: res.data.access_token
         })
-        console.log('22222222222222');
         const jsres = apiPilot.loadComponent(EComponentName.Api, apiPilot.getComponentParam(EComponentName.Api))
-        console.log('33333333',jsres+"aaaaaaa");
         if (!jsres) {
           message.error('加载api模块失败')
           return
         }
-        console.log('444444');
         apiPilot.setToken(res.data.access_token)
-        console.log('5555555');
         localStorage.setItem(ELocalStorageKey.Token, res.data.access_token)
         root.$router.push(ERouterName.PILOT_HOME)
       })
@@ -84,7 +78,6 @@ onMounted(async () => {
   }
 })
 const onSubmit = async (e: any) => {
-  console.log("formState",formState)
   await login(formState)
     .then(res => {
       if (!isVerified.value) {
@@ -94,7 +87,7 @@ const onSubmit = async (e: any) => {
       console.log('login res:', res)
       if (res.code === 0) {
         apiPilot.setComponentParam(EComponentName.Api, {
-          host: CURRENT_CONFIG.apiURL,
+          host: import.meta.env.VITE_APP_API_URL,
           token: res.data.access_token
         })
         const jsres = apiPilot.loadComponent(

+ 3 - 3
Web/src/pages/page-web/projects/media/index.vue

@@ -1,7 +1,7 @@
 <template>
-    <div class="project-media-wrapper">
-      <MediaPanel />
-    </div>
+  <div class="project-media-wrapper">
+    <MediaPanel />
+  </div>
 </template>
 
 <script lang="ts" setup>

+ 4 - 4
Web/src/types/device.ts

@@ -22,7 +22,7 @@ export enum DOMAIN {
 export enum DRONE_TYPE {
   M30 = 67,
   M300 = 60,
-  Mavic3EnterpriseAdvanced= 77,
+  Mavic3EnterpriseAdvanced = 77,
   M350 = 89,
   M3D = 91,
 }
@@ -184,7 +184,7 @@ export interface OnlineDevice {
 // 固件升级类型
 export enum DeviceFirmwareTypeEnum {
   ToUpgraded = 3, // 普通升级
-  ConsistencyUpgrade =2, // 一致性升级
+  ConsistencyUpgrade = 2, // 一致性升级
 }
 
 // 固件升级状态
@@ -245,7 +245,7 @@ export interface OSDVisible {
   is_dock: boolean,
   gateway_sn: string,
   gateway_callsign: string,
-  payloads: null | PayloadInfo [],
+  payloads: null | PayloadInfo[],
 }
 
 export interface GatewayOsd {
@@ -402,7 +402,7 @@ export interface DockLinkOsd {
     down_quality: string,
     frequency_band: number,
   },
-  wireless_link?:{ // 图传链路<会包括4G和sdr信息
+  wireless_link?: { // 图传链路<会包括4G和sdr信息
     dongle_number: number, // dongle 数量
     ['4g_link_state']: FourGLinkStateEnum, // 4g_link_state
     sdr_link_state: SdrLinkStateEnum, // sdr链路连接状态

+ 2 - 2
Web/src/websocket/util/config.ts

@@ -1,8 +1,8 @@
 import { ELocalStorageKey } from '/@/types/enums'
 import { CURRENT_CONFIG } from '/@/api/http/config'
 
-export function getWebsocketUrl () {
+export function getWebsocketUrl() {
   const token: string = localStorage.getItem(ELocalStorageKey.Token) || '' as string
-  const url = CURRENT_CONFIG.websocketURL + '?x-auth-token=' + encodeURI(token)
+  const url = import.meta.env.VITE_APP_WEBSOCKET_URL + '?x-auth-token=' + encodeURI(token)
   return url
 }

+ 63 - 61
Web/vite.config.ts

@@ -1,68 +1,70 @@
 import vue from '@vitejs/plugin-vue'
 import path from 'path'
-import { CURRENT_CONFIG } from './src/api/http/config';
-import { ConfigEnv, defineConfig, UserConfigExport } from 'vite'
+import { ConfigEnv, defineConfig, loadEnv } from 'vite'
 import { viteVConsole } from 'vite-plugin-vconsole'
 
-export default ({ command, mode }: ConfigEnv): UserConfigExport => defineConfig({
-  base: '/',
-  css: {
-    preprocessorOptions: {
-      scss: {
-        additionalData: '@import "./src/styles/variables";'
-      },
-    }
-  },
-  resolve: {
-    alias: [
-      {
-        find: '/@',
-        replacement: path.resolve(__dirname, './src'),
+export default defineConfig(({ mode, command }: ConfigEnv) => {
+  const env = loadEnv(mode, process.cwd());
+  return {
+    base: '/',
+    css: {
+      preprocessorOptions: {
+        scss: {
+          additionalData: '@import "./src/styles/variables";'
+        },
       }
-    ]
-  },
-  server: {
-    // 监听所有地址
-    host: '0.0.0.0',
-    // 自定义端口号
-    port: 3010,
-    // 自动打开浏览器
-    open: true,
-    // 开启热更新
-    hmr: true,
-    // 若端口被占用,自动尝试下一个可用端口
-    strictPort: false,
-    // 代理规则
-    proxy: {
-      '/api': {
-        // 开启跨域
-        changeOrigin: true,
-        // 转发地址
-        target: CURRENT_CONFIG.apiURL,
-        // 路径重写
-        rewrite: (path) => path.replace(/^\/api/, ''),
+    },
+    resolve: {
+      alias: [
+        {
+          find: '/@',
+          replacement: path.resolve(__dirname, './src'),
+        }
+      ]
+    },
+    server: {
+      // 监听所有地址
+      host: '0.0.0.0',
+      // 自定义端口号
+      port: 3010,
+      // 自动打开浏览器
+      open: true,
+      // 开启热更新
+      hmr: true,
+      // 若端口被占用,自动尝试下一个可用端口
+      strictPort: false,
+      // 代理规则
+      proxy: {
+        '/api': {
+          // 开启跨域
+          changeOrigin: true,
+          // 转发地址
+          target: env.VITE_APP_API_URL,
+          // 路径重写
+          rewrite: (path) => path.replace(/^\/api/, ''),
+        }
       }
-    }
-  },
-  build: {
-    outDir: 'dist',// 指定打包文件根目录
-    sourcemap: false,// 构建后不生成源代码
-    write: true,// 构建的文件写入磁盘
-    chunkSizeWarningLimit: 10240,// 触发警告的chunk大小10M
-  },
-  esbuild: {
-    drop: mode === 'production' ? ['console', 'debugger'] : [],
-  },
-  plugins: [
-    vue(),
-    viteVConsole({
-      entry: path.resolve(__dirname, './src/main.ts'), // 入口文件
-      localEnabled: command === 'serve', // serve开发环境下
-      // enabled: command !== 'serve' || mode === 'test', // 打包环境下/发布测试包,
-      config: { // vconsole 配置项
-        maxLogNumber: 1000,
-        theme: 'light'
-      }
-    }),
-  ],
+    },
+    build: {
+      outDir: 'dist',// 指定打包文件根目录
+      sourcemap: false,// 构建后不生成源代码
+      write: true,// 构建的文件写入磁盘
+      chunkSizeWarningLimit: 10240,// 触发警告的chunk大小10M
+    },
+    esbuild: {
+      drop: mode === 'production' ? ['console', 'debugger'] : [],
+    },
+    plugins: [
+      vue(),
+      viteVConsole({
+        entry: path.resolve(__dirname, './src/main.ts'), // 入口文件
+        localEnabled: command === 'serve', // serve开发环境下
+        // enabled: command !== 'serve' || mode === 'test', // 打包环境下/发布测试包,
+        config: { // vconsole 配置项
+          maxLogNumber: 1000,
+          theme: 'light'
+        }
+      }),
+    ],
+  }
 })