Parcourir la source

档案和助手样式

CzRger il y a 2 semaines
Parent
commit
9572e8365c

+ 41 - 2
src/stores/ship-map/ship-map.ts

@@ -8,10 +8,12 @@ import MapStyle from "./map-style";
 import * as ol from "ol";
 import {randomColor, YMDHms} from "@/utils/util";
 import {formatPosition, getShapeView} from "@/utils/easyMap";
+import { v4 } from "uuid";
 
 export const useShipMapStore = defineStore('shipMap', () => {
   const state: any = reactive({
     warningOpen: true,
+    warningInfo: {},
     map: null,
     mapFunc: null,
     zoom: 0,
@@ -22,7 +24,32 @@ export const useShipMapStore = defineStore('shipMap', () => {
       overlayTrack: null,
     },
     trackHoverData: null,
-    trackMap: new Map()
+    trackMap: new Map([['123', {
+      data: {
+        targetSourceJson: '[]'
+      },
+      color: randomColor(1),
+      history: [],
+      real: [{}],
+      trackId: '123',
+      moveToTrack: () => {},
+      // 直接用图层的话declutter: true会报错,Uncaught TypeError: Failed to execute 'clip' on 'CanvasRenderingContext2D': parameter 1 is not of type 'Path2D'.
+      lineLayer: 'lineLayer_' + 123,
+      pointsLayer: 'pointsLayer_' + 123,
+      del: () => {},
+      visibleTrack: (visible) => {},
+      refreshTrackStyle: () => {},
+      showTrack: true,
+      showArchive: true,
+      archiveLayout: {
+        width: 480,
+        top: 10,
+        left: 200
+      },
+      archiveParams: {
+        tab: 1,
+      }
+    }]])
   })
   const initMap = (map, mapFunc, {trackPointDom}) => {
     state.map = map
@@ -47,6 +74,8 @@ export const useShipMapStore = defineStore('shipMap', () => {
       stopEvent: true,
     })
     state.map.addOverlay(state.ws.overlayTrack)
+    // 预警助手
+    initWarningWS()
   }
   const mapPointerMove = (ev) => {
     let pixel = ev.pixel
@@ -153,7 +182,7 @@ export const useShipMapStore = defineStore('shipMap', () => {
           showTrack: true,
           showArchive: true,
           archiveLayout: {
-            width: 350,
+            width: 480,
             top: 10,
             left: state.mapFunc.mapWidth - 350 - 10
           },
@@ -354,8 +383,18 @@ export const useShipMapStore = defineStore('shipMap', () => {
     });
     state.ws.layerShip.setSource(vectorSource)
   }
+
+  const mockWarningWS = () => {
+    state.warningInfo = {
+      name: v4(),
+      time: new Date().getTime(),
+    }
+  }
+  const initWarningWS = () => {
+  }
   return {
     ...toRefs(state),
     initMap,
+    mockWarningWS,
   }
 })

+ 17 - 2
src/views/web/index.vue

@@ -64,6 +64,15 @@
             <img src="@/assets/images/web/tools-ship.png"/>
           </div>
         </el-tooltip>
+        <el-tooltip
+          effect="light"
+          content="Dasdas"
+          placement="right"
+        >
+          <div class="tools-item __hover" @click="ShipMapStore.mockWarningWS()">
+            <img src="@/assets/images/web/tools-ship.png"/>
+          </div>
+        </el-tooltip>
       </div>
       <configCom ref="ref_config" v-model:show="state.tools.showConfig" :map="state.map" :mapFunc="state.mapFunc"/>
       <archiveCom v-model:show="state.tools.showArchive"/>
@@ -73,12 +82,13 @@
       <trackPointCom ref="ref_trackPoint"/>
       <trackArchiveCom/>
     </div>
+    <assistantCom v-if="state.map" v-model:show="state.showAssistant" :mapHeight="state.mapFunc?.mapHeight"/>
     <div class="layout-foot"></div>
   </div>
 </template>
 
 <script setup lang="ts">
-import {computed, getCurrentInstance, reactive, ref, watch} from "vue";
+import {computed, getCurrentInstance, nextTick, onMounted, reactive, ref, watch} from "vue";
 import configCom from './config/index.vue'
 import archiveCom from './archive/index.vue'
 import warningCom from './warning/index.vue'
@@ -87,6 +97,7 @@ import exampleCom from './example.vue'
 import trackArchiveCom from './track/archive.vue'
 import {useShipMapStore} from "@/stores";
 import trackPointCom from './track/track-point.vue'
+import assistantCom from './warning/assistant.vue'
 
 const ShipMapStore = useShipMapStore()
 const {proxy} = getCurrentInstance()
@@ -98,7 +109,8 @@ const state: any = reactive({
     showArchive: false,
     showWarning: false,
     showExample: false,
-  }
+  },
+  showAssistant: false
 })
 const ref_web = ref()
 const ref_trackPoint = ref()
@@ -110,6 +122,9 @@ const mapLoad = (map, mapFunc) => {
   state.map = map
   state.mapFunc = mapFunc
   // ShipMapStore.initMap(state.map, state.mapFunc, {trackPointDom: ref_trackPoint.value.$el})
+  nextTick(() => {
+    state.showAssistant = true
+  })
 }
 const mapParamsListener = (p) => {
   ref_web.value?.style.setProperty('--easy-map-height',  p.resizeMapHeight + 'px')

+ 52 - 44
src/views/web/track/archive.vue

@@ -16,7 +16,6 @@
         <div class="imgs">
           <el-carousel
               trigger="click"
-              height="180px"
           >
             <el-carousel-item v-for="(item, index) in getShipImg(value.data)" :key="index">
               <img
@@ -70,6 +69,7 @@
               <div>MMSI:<span>1</span></div>
             </template>
           </div>
+          <div class="line"/>
           <div class="other">
             <template v-if="value.archiveParams.tab == 1">
               <div>经度:{{ Number(value.data.targetLongitude).toFixed(6) }}</div>
@@ -88,6 +88,9 @@
             </template>
           </div>
         </div>
+        <div class="update">
+          更新时间:2024-33-33 99:99:99
+        </div>
       </div>
     </DragWindow>
   </template>
@@ -180,78 +183,83 @@ const filterShipNum = (data) => {
 
 <style lang="scss" scoped>
 .track-archive {
-  padding: 12px 10px;
+  padding: 20px 24px;
   display: flex;
   flex-direction: column;
   .tabs {
-    height: 20px;
+    height: 48px;
     display: flex;
-    gap: 4px;
+    gap: 16px;
     >div {
       flex: 1;
-      background-image: url("@/assets/images/web/track-archive-tab.png");
-      background-size: 99% 100%;
-      font-size: 12px;
-      text-align: center;
+      background: rgba(88, 148, 235, 0.8);
+      border-radius: 8px;
       font-weight: 400;
-      color: #90d0fe;
-      line-height: 20px;
-      &.active {
-        background-image: url("@/assets/images/web/track-archive-tab-active.png");
-        font-size: 14px;
-        color: #ffffff;
-      }
+      font-size: 20px;
+      color: #FFFFFF;
+      display: flex;
+      align-items: center;
+      justify-content: center;
     }
   }
-  .imgs {
-    margin-top: 6px;
-    height: 180px;
-    border: 2px solid rgba(21, 254, 254, 0.2);
-    .carousel-img {
-      object-fit: fill;
-      width: 100%;
-      height: calc(100% - 4px);
+  :deep(.imgs) {
+    margin-top: 16px;
+    height: 228px;
+    border: 1px solid #AED0FF;
+    .el-carousel {
+      height: 100%;
+      .el-carousel__container {
+        height: 100%;
+        .carousel-img {
+          object-fit: fill;
+          width: 100%;
+          height: 100%;
+        }
+      }
     }
   }
   .infos {
-    margin-top: 6px;
-    border: 2px solid rgba(21, 254, 254, 0.2);
-    padding: 10px;
+    margin-top: 16px;
+    background: rgba(88, 148, 235, 0.2);
+    border-radius: 8px;
     .numbers {
+      padding: 16px;
       display: flex;
       flex-wrap: wrap;
-      gap: 4px;
-      border-bottom: 2px solid rgba(21, 254, 254, 0.2);
-      padding-bottom: 6px;
+      gap: 10px 4px;
       >div {
         min-width: calc(50% - 2px);
-        font-size: 14px;
-        color: #1cfdff;
-        >span {
-          color: #FFFFFF;
-        }
+        font-weight: 400;
+        font-size: 16px;
+        color: #FFFFFF;
       }
     }
+    .line {
+      width: 100%;
+      height: 1px;
+      background-color: rgba(255, 255, 255, 0.2);
+    }
     .other {
-      margin-top: 8px;
+      padding: 16px;
       display: flex;
       flex-wrap: wrap;
-      gap: 4px;
+      gap: 10px 4px;
       >div {
         min-width: calc(50% - 2px);
-        font-size: 13px;
+        font-weight: 400;
+        font-size: 16px;
         color: #FFFFFF;
         display: flex;
         align-items: center;
-        &:before {
-          content: '';
-          background-image: url("@/assets/images/web/track-archive-icon.png");
-          width: 10px;
-          height: 8px;
-          margin-right: 4px;
-        }
       }
     }
   }
+  .update {
+    font-weight: 400;
+    font-size: 16px;
+    color: rgba(255, 255, 255, 0.5);
+    margin-top: 16px;
+    margin-left: auto;
+  }
 }
 </style>

+ 127 - 0
src/views/web/warning/assistant.vue

@@ -0,0 +1,127 @@
+<template>
+  <DragWindow
+    ref="ref_assistant"
+    v-if="show"
+    @onClose="$emit('update:show', false)"
+    title="预警详情"
+    v-model:layout="state.layout"
+    close
+  >
+    <div class="assistant" v-if="show" v-loading="state.loading">
+      <div class="title">
+        北斗终端异常古
+        <div class="__hover">查看详情</div>
+      </div>
+      <div class="target">琼海123456</div>
+      <div class="content">
+        <div class="img">
+          <img src="@/assets/images/web/ship.png">
+        </div>
+        <div class="infos">
+          <div>预警时间</div>
+          <div>2024-02-22 12:33:44</div>
+          <div>预警区域</div>
+          <div>海口海域</div>
+        </div>
+      </div>
+    </div>
+  </DragWindow>
+</template>
+
+<script setup lang="ts">
+import {computed, getCurrentInstance, markRaw, onBeforeMount, onMounted, reactive, ref, watch} from "vue";
+import DragWindow from '../components/drag-window.vue'
+import {useDictionaryStore, useShipMapStore} from "@/stores";
+import {ElMessage} from "element-plus";
+
+const DictionaryStore = useDictionaryStore()
+const ShipMapStore = useShipMapStore()
+const {proxy} = getCurrentInstance()
+const props = defineProps({
+  show: {},
+  mapFunc: {},
+  mapHeight: {},
+})
+const state: any = reactive({
+  layout: {
+    width: 506,
+    left: 85,
+    top: props.mapHeight - 60 - (300 + 60)
+  },
+})
+const ref_assistant = ref()
+watch(() => props.show, (n) => {
+  if (n) {
+  }
+})
+onMounted(() => {
+})
+</script>
+
+<style lang="scss" scoped>
+.assistant {
+  height: 300px;
+  padding: 24px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  .title {
+    width: 100%;
+    height: 40px;
+    background: rgba(88,148,235,0.2);
+    border-radius: 8px;
+    display: flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 20px;
+    color: #FFFFFF;
+    &:before {
+      content: '';
+      width: 6px;
+      height: 100%;
+      background: linear-gradient(0deg, rgba(255,255,255,0.11), rgba(255,255,255,0.75));
+      box-shadow: 0px 2px 0px 0px rgba(81,129,228,0.4);
+      border-radius: 8px 0px 0px 8px;
+      margin-right: 10px;
+    }
+    >div {
+      margin-left: auto;
+      margin-right: 24px;
+      font-weight: 400;
+      font-size: 16px;
+      color: #FFFFFF;
+    }
+  }
+  .target {
+    font-weight: 400;
+    font-size: 18px;
+    color: #FFFFFF;
+  }
+  .content {
+    display: flex;
+    gap: 22px;
+    .img {
+      width: 240px;
+      height: 150px;
+      border-radius: 4px;
+      border: 1px solid #AED0FF;
+      padding: 9px;
+      >img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .infos {
+      display: flex;
+      flex-direction: column;
+      font-weight: 400;
+      font-size: 16px;
+      color: #FFFFFF;
+      line-height: 27px;
+      >:nth-child(3) {
+        margin-top: 10px;
+      }
+    }
+  }
+}
+</style>

+ 10 - 4
src/views/web/warning/index.vue

@@ -50,9 +50,9 @@
                   <img src="@/assets/images/web/ship.png"/>
                 </div>
                 <div class="info-detail">
-                  <div class="info-item">预警名称:{{item.ruleName}}</div>
-                  <div class="info-item">预警时间:{{item.warnTime}}</div>
-                  <div class="info-item">预警区域:{{item.areaName}}<span style="color: #1CFEFF; margin-left: 10px">查看区域</span></div>
+                  <div class="info-item">预警名称:<div>{{item.ruleName}}</div></div>
+                  <div class="info-item">预警时间:<div>{{$util.YMDHms(item.warnTime)}}</div></div>
+                  <div class="info-item">预警区域:<div>{{item.areaName}}<span class="__hover" style="color: #1CFEFF; margin-left: 10px">查看区域</span></div></div>
                 </div>
               </div>
             </div>
@@ -161,7 +161,7 @@ const props = defineProps({
 })
 const state: any = reactive({
   layout: {
-    width: 400,
+    width: 440,
     left: 85,
     top: 110
   },
@@ -363,6 +363,12 @@ $mapHeight: var(--easy-map-height);
             display: flex;
             flex-direction: column;
             gap: 16px;
+            .info-item {
+              display: flex;
+              >div {
+                flex: 1;
+              }
+            }
           }
         }
       }