Browse Source

机场列表更新样式

李富豪 1 year ago
parent
commit
bddbbac65b

+ 4 - 0
Web/src/api/custom/index.ts

@@ -97,6 +97,10 @@ export type FetchTrajectoryMapApi = (taskId: string) => Promise<any>;
 export type AddPilotApi = (data: AddPilotApiParams) => Promise<any>;
 export type FetchPilotPasswordApi = (params: FetchPilotPasswordApiParams) => Promise<any>;
 
+export const getUploadPath = () => {
+    return `api/media/api/v1/files/${getWorkspaceId()}/file/upload`;
+}
+
 // 密钥登录
 const signLoginApi: SignLoginApi = async (data) => {
     const res = await request.post('/manage/api/v1/signLogin', data);

+ 84 - 81
Web/src/components/airport/index.vue

@@ -14,38 +14,54 @@
     </div>
     <div class="content-info">
       <div class="content-info-left">
-        <div class="content-info-left-one">
-          {{ dock.gateway.callsign }} - {{ dock.callsign }}
+        <div class="content-info-left-style">
+          <div class="content-info-left-style-title">
+            {{ dock.gateway.callsign }} - {{ dock.callsign }}
+          </div>
         </div>
-        <div class="content-info-left-two">
-          <div class="content-info-left-two-info">
-            <img class="content-info-left-three-info-icon" :src="aircraftSrc">
-            <div class="content-info-left-two-info-text">
-              <span class="scrollable-text">
-                {{ getTextByModeCode(deviceInfo[dock.sn] ? deviceInfo[dock.sn].mode_code : EModeCode.Disconnected) }}
-              </span>
+        <div class="content-info-left-style">
+          <div class="content-info-left-style-info">
+            <img class="content-info-left-style-info-icon" :src="aircraftSrc">
+            <div class="content-info-left-style-info-text"
+              :style="deviceInfo[dock.sn] && deviceInfo[dock.sn].mode_code !== EModeCode.Disconnected ? 'color:#00EE8B' : 'color:red'">
+              {{ getTextByModeCode(deviceInfo[dock.sn] ? deviceInfo[dock.sn].mode_code : EModeCode.Disconnected) }}
             </div>
           </div>
-          <div class="content-info-left-two-other">
+          <div :class="[
+            'content-info-left-style-other',
+            hmsInfo[dock.sn] && hmsInfo[dock.sn][0].level === 0 ? 'notice' : '',
+            hmsInfo[dock.sn] && hmsInfo[dock.sn][0].level === 1 ? 'caution' : '',
+            hmsInfo[dock.sn] && hmsInfo[dock.sn][0].level === 2 ? 'warn' : '',
+          ]">
             <div v-if="aircraftLogInfo">
-              {{ aircraftLogInfo }}
+              <span class="word-loop">
+                {{ aircraftLogInfo }}
+              </span>
             </div>
             <div v-else>
               N/A
             </div>
           </div>
         </div>
-        <div class="content-info-left-three">
-          <div class="content-info-left-three-info">
-            <img class="content-info-left-three-info-icon" :src="dockSrc">
-            <div class="content-info-left-three-info-text">
+        <div class="content-info-left-style">
+          <div class="content-info-left-style-info">
+            <img class="content-info-left-style-info-icon" :src="dockSrc">
+            <div class="content-info-left-style-info-text"
+              :style="dockInfo[dock.gateway.sn] && dockInfo[dock.gateway.sn].basic_osd?.mode_code !== EDockModeCode.Disconnected ? 'color:#00EE8B' : 'color:red'">
               {{ getTextByDockModeCode(dockInfo[dock.gateway.sn] ? dockInfo[dock.gateway.sn].basic_osd?.mode_code
                 : EDockModeCode.Disconnected) }}
             </div>
           </div>
-          <div class="content-info-left-three-other">
+          <div :class="[
+            'content-info-left-style-other',
+            hmsInfo[dock.gateway.sn] && hmsInfo[dock.gateway.sn][0].level === 0 ? 'notice' : '',
+            hmsInfo[dock.gateway.sn] && hmsInfo[dock.gateway.sn][0].level === 1 ? 'caution' : '',
+            hmsInfo[dock.gateway.sn] && hmsInfo[dock.gateway.sn][0].level === 2 ? 'warn' : '',
+          ]">
             <div v-if="hangarLogInfo">
-              {{ hangarLogInfo }}
+              <span class="word-loop">
+                {{ hangarLogInfo }}
+              </span>
             </div>
             <div v-else>
               N/A
@@ -90,15 +106,16 @@ const root: any = getRoot()
 
 const store = useMyStore()
 
-const deviceInfo = computed(() => store.state.deviceState.deviceInfo)
-const dockInfo = computed(() => store.state.deviceState.dockInfo)
+const deviceInfo = computed(() => store.state.deviceState.deviceInfo);
+const dockInfo = computed(() => store.state.deviceState.dockInfo);
+const hmsInfo = computed(() => store.state.hmsInfo);
 
 // 飞行器告警信息
 const aircraftLogInfo = computed(() => {
-  const hmsList = store.state.hmsInfo[props.dock.sn] || [];
-  const hmsInfo = hmsList[hmsList.length - 1];
-  if (hmsInfo) {
-    return hmsInfo.message_zh;
+  const hmsList = hmsInfo.value[props.dock.sn] || [];
+  const info = hmsList[0];
+  if (info) {
+    return info.message_zh;
   } else {
     return ''
   }
@@ -106,10 +123,10 @@ const aircraftLogInfo = computed(() => {
 
 // 机库告警信息
 const hangarLogInfo = computed(() => {
-  const hmsList = store.state.hmsInfo[props.dock.gateway.sn] || [];
-  const hmsInfo = hmsList[hmsList.length - 1];
-  if (hmsInfo) {
-    return hmsInfo.message_zh;
+  const hmsList = hmsInfo.value[props.dock.gateway.sn] || [];
+  const info = hmsList[0];
+  if (info) {
+    return info.message_zh;
   } else {
     return ''
   }
@@ -142,7 +159,7 @@ const onClickLocation = () => {
     align-items: center;
 
     &-left {
-      width: 80px;
+      width: 105px;
       height: 100%;
       padding-left: 5px;
       background: #4d4d4d;
@@ -169,54 +186,21 @@ const onClickLocation = () => {
       padding: 5px;
       font-size: 12px;
 
-      &-one {
-        width: 100%;
-        height: 24px;
-      }
-
-      &-two {
+      &-style {
         width: 100%;
         height: 24px;
         display: flex;
         margin-bottom: 5px;
 
-        &-info {
-          width: 75px;
-          padding-left: 5px;
-          background: #3d3d3d;
-          display: flex;
-          align-items: center;
-
-          &-icon {
-            width: 14px;
-            height: 14px;
-            margin-right: 5px;
-          }
-
-          &-text {
-            width: 50px;
-            white-space: nowrap;
-            overflow: hidden;
-          }
-        }
-
-        &-other {
-          width: calc(100% - 75px);
-          padding-left: 5px;
-          background: #4a4d4e;
-          display: flex;
-          align-items: center;
+        &-title {
+          font-size: 13px;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
         }
-      }
-
-      &-three {
-        width: 100%;
-        height: 24px;
-        display: flex;
-        margin-bottom: 5px;
 
         &-info {
-          width: 75px;
+          width: 100px;
           padding-left: 5px;
           background: #3d3d3d;
           display: flex;
@@ -236,13 +220,18 @@ const onClickLocation = () => {
         }
 
         &-other {
-          width: calc(100% - 75px);
+          width: calc(100% - 100px);
           padding-left: 5px;
           background: #4a4d4e;
           display: flex;
           align-items: center;
+          overflow: hidden;
         }
       }
+
+      &-style:first-child {
+        margin: 0;
+      }
     }
 
     &-right {
@@ -258,21 +247,35 @@ const onClickLocation = () => {
       }
     }
   }
+}
 
-  .scrollable-text {
-    width: 100%;
-    display: inline-block;
-    animation: scroll-left 5s linear infinite;
+.notice {
+  background: $success;
+}
 
-    @keyframes scroll-left {
-      0% {
-        transform: translateX(100%);
-      }
+.caution {
+  background: orange;
+}
 
-      100% {
-        transform: translateX(-100%);
-      }
-    }
+.warn {
+  background: red;
+}
+
+.word-loop {
+  white-space: nowrap;
+  display: inline-block;
+  animation: 5s loop linear infinite normal;
+}
+
+@keyframes loop {
+  0% {
+    transform: translateX(20px);
+    -webkit-transform: translateX(20px);
+  }
+
+  100% {
+    transform: translateX(-100%);
+    -webkit-transform: translateX(-100%);
   }
 }
 </style>

+ 33 - 9
Web/src/components/devices/deviceList/components/FeedbackCreateModal.vue

@@ -8,21 +8,22 @@
             </a-form-item>
             <a-form-item label='发生时间' name="date" :rules="[{ required: true, message: '发生时间不能为空' }]">
                 <a-date-picker style="width: 100%;" showTime valueFormat="YYYY-MM-DD HH:mm:ss"
-                    v-model:value="formModel.date" />
+                    v-model:value="formModel.date" placeholder="请选择发生时间" />
             </a-form-item>
             <a-form-item label='联系电话' name="phone">
                 <a-input style="width: 100%;" v-model:value="formModel.phone" placeholder="请输入联系电话" />
             </a-form-item>
             <a-form-item label='联系邮箱' name="email">
-                <a-input style="width: 100%;" v-model:value="formModel.email" placeholder="请输入发生时间" />
+                <a-input style="width: 100%;" v-model:value="formModel.email" placeholder="请输入联系邮箱" />
             </a-form-item>
-            <a-form-item label='附件' name="file">
-                <div style="display: flex;align-items: center;">
+            <a-form-item label='附件'>
+                <a-upload :action="getUploadPath()" method="POST" :headers="getHeaders()"
+                    :file-list="formModel.fileList" @change="handleChangeUpload">
                     <a-button>上传附件</a-button>
-                    <div style="font-size: 12px;color: rgba(0,0,0,.45);margin-left: 10px;">
+                </a-upload>
+                <!-- <div style="font-size: 12px;color: rgba(0,0,0,.45);margin-left: 10px;">
                         支持上传:图片、文档、视频、RAR 及 ZIP 等文件(至多上传 3 个文件)
-                    </div>
-                </div>
+                    </div> -->
             </a-form-item>
             <a-form-item label='上传日志' name="linkageSelect">
                 <div style="display: flex;align-items: center;">
@@ -64,7 +65,9 @@
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted } from 'vue';
-import { apis } from '/@/api/custom';
+import { apis, getUploadPath } from '/@/api/custom';
+import { getHeaders } from '/@/api/http/request';
+import { message } from 'ant-design-vue';
 
 interface Props {
     visible: boolean,
@@ -83,7 +86,7 @@ const formModel = reactive({
     date: undefined,
     phone: undefined,
     email: undefined,
-    file: undefined,
+    fileList: [] as any[],
     linkageSelect: undefined
 })
 
@@ -107,6 +110,27 @@ onMounted(async () => {
     // await fetchList();
 })
 
+const handleChangeUpload = (info: any) => {
+    const list = info.fileList.slice(-3);
+    const newFileList = list.map((file: any) => {
+        const data = file.response?.data;
+        return {
+            uid: data?.id || file.uid,
+            name: file.name,
+            url: data?.url || file.url,
+        }
+    });
+    formModel.fileList = newFileList;
+    if (info.file.status === 'done') {// 上传成功
+        const { code, message } = info.file.response;
+        if (code === 0) {
+            message.success('上传成功');
+        } else {
+            message.error(message);
+        }
+    }
+};
+
 // 表格
 const airportLogColumns = [
     { title: '机场日志', dataIndex: 'time', width: 100, slots: { customRender: 'log_time' } },

+ 54 - 71
Web/src/components/onLineDevice/index.vue

@@ -2,36 +2,41 @@
   <div class="content" @click="onClickLocation">
     <div class="content-info">
       <div class="content-info-left">
-        <div class="content-info-left-one">
-          {{ device.callsign }}
+        <div class="content-info-left-style">
+          <div class="content-info-left-style-title">
+            {{ device.callsign }}
+          </div>
         </div>
-        <div class="content-info-left-two">
-          <div class="content-info-left-two-info">
-            <img class="content-info-left-three-info-icon" :src="aircraftSrc">
-            <div class="content-info-left-two-info-text">
-              <span class="scrollable-text">
-                {{ getTextByModeCode(deviceInfo[device.sn] ? deviceInfo[device.sn].mode_code : EModeCode.Disconnected)
-                }}
-              </span>
+        <div class="content-info-left-style">
+          <div class="content-info-left-style-info">
+            <img class="content-info-left-style-info-icon" :src="aircraftSrc">
+            <div class="content-info-left-style-info-text"
+              :style="deviceInfo[device.sn] && deviceInfo[device.sn].mode_code !== EModeCode.Disconnected ? 'color:#00EE8B' : 'color:red'">
+              {{ getTextByModeCode(deviceInfo[device.sn] ? deviceInfo[device.sn].mode_code : EModeCode.Disconnected) }}
             </div>
           </div>
-          <div class="content-info-left-two-other">
+          <div :class="['content-info-left-style-other', deviceReason ? 'warn' : '']">
             <div v-if="deviceReason">
-              {{ deviceReason }}
+              <span class="word-loop">
+                {{ deviceReason }}
+              </span>
             </div>
             <div v-else>
               N/A
             </div>
           </div>
         </div>
-        <div class="content-info-left-three">
-          <div class="content-info-left-three-info">
-            <img class="content-info-left-three-info-icon" :src="controllerSrc">
-            <div class="content-info-left-three-info-text">
+        <div class="content-info-left-style">
+          <div class="content-info-left-style-info">
+            <img class="content-info-left-style-info-icon" :src="controllerSrc">
+            <div class="content-info-left-style-info-text" v-if="capacity">
               {{ device.gateway.callsign }}
             </div>
+            <div class="content-info-left-style-info-text" style="color: red;" v-else>
+              未连接
+            </div>
           </div>
-          <div class="content-info-left-three-other">
+          <div class="content-info-left-style-other">
             <div class="capacity" v-if="capacity">
               <img :src="batteryOneSrc" v-if="capacity >= 75">
               <img :src="batteryTwoSrc" v-else-if="capacity >= 50 && capacity < 75">
@@ -95,7 +100,7 @@ const deviceReason = computed(() => {
   if (device) {
     return device.modeCodeReason;
   } else {
-    return ''
+    return '';
   }
 })
 
@@ -136,54 +141,21 @@ const onClickLocation = () => {
       padding: 5px;
       font-size: 12px;
 
-      &-one {
-        width: 100%;
-        height: 24px;
-      }
-
-      &-two {
+      &-style {
         width: 100%;
         height: 24px;
         display: flex;
         margin-bottom: 5px;
 
-        &-info {
-          width: 75px;
-          padding-left: 5px;
-          background: #3d3d3d;
-          display: flex;
-          align-items: center;
-
-          &-icon {
-            width: 14px;
-            height: 14px;
-            margin-right: 5px;
-          }
-
-          &-text {
-            width: 50px;
-            white-space: nowrap;
-            overflow: hidden;
-          }
+        &-title {
+          font-size: 13px;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
         }
 
-        &-other {
-          width: calc(100% - 75px);
-          padding-left: 5px;
-          background: #4a4d4e;
-          display: flex;
-          align-items: center;
-        }
-      }
-
-      &-three {
-        width: 100%;
-        height: 24px;
-        display: flex;
-        margin-bottom: 5px;
-
         &-info {
-          width: 75px;
+          width: 100px;
           padding-left: 5px;
           background: #3d3d3d;
           display: flex;
@@ -203,12 +175,13 @@ const onClickLocation = () => {
         }
 
         &-other {
-          width: calc(100% - 75px);
+          width: calc(100% - 100px);
           height: 100%;
           padding-left: 5px;
           background: #4a4d4e;
           display: flex;
           align-items: center;
+          overflow: hidden;
 
           .capacity {
             width: 100%;
@@ -224,6 +197,10 @@ const onClickLocation = () => {
           }
         }
       }
+
+      &-style:first-child {
+        margin: 0;
+      }
     }
 
     &-right {
@@ -239,21 +216,27 @@ const onClickLocation = () => {
       }
     }
   }
+}
 
-  .scrollable-text {
-    width: 100%;
-    display: inline-block;
-    animation: scroll-left 5s linear infinite;
+.warn {
+  background: red;
+}
 
-    @keyframes scroll-left {
-      0% {
-        transform: translateX(100%);
-      }
+.word-loop {
+  white-space: nowrap;
+  display: inline-block;
+  animation: 5s loop linear infinite normal;
+}
 
-      100% {
-        transform: translateX(-100%);
-      }
-    }
+@keyframes loop {
+  0% {
+    transform: translateX(20px);
+    -webkit-transform: translateX(20px);
+  }
+
+  100% {
+    transform: translateX(-100%);
+    -webkit-transform: translateX(-100%);
   }
 }
 </style>