CzRger преди 1 година
родител
ревизия
021129cde9

+ 1 - 1
src/components/easyMap/ol-map.vue

@@ -53,7 +53,7 @@
   } from "vue";
   import { useStore } from "vuex";
   import * as ol from 'ol'
-  import * as style from 'ol/styles'
+  import * as style from 'ol/style'
   import * as layer from 'ol/layer'
   import * as source from 'ol/source'
   import * as geom from 'ol/geom'

+ 1 - 1
src/utils/easyMap.ts

@@ -1,5 +1,5 @@
 import * as ol from 'ol'
-import * as style from 'ol/styles'
+import * as style from 'ol/style'
 import * as layer from 'ol/layer'
 import * as source from 'ol/source'
 import * as geom from 'ol/geom'

+ 1 - 1
src/views/init-speed-track/drawTrack.ts

@@ -1,5 +1,5 @@
 import * as ol from 'ol'
-import * as style from 'ol/styles'
+import * as style from 'ol/style'
 import * as layer from 'ol/layer'
 import * as source from 'ol/source'
 import * as geom from 'ol/geom'

+ 1 - 1
src/views/init-speed-track/index.vue

@@ -85,7 +85,7 @@ import {
 import {useStore} from 'vuex'
 import * as source from "ol/source";
 import * as layer from "ol/layer";
-import * as style from "ol/styles";
+import * as style from "ol/style";
 import * as ol from "ol";
 import * as sphere from "ol/sphere";
 import * as interaction from "ol/interaction";

+ 1 - 1
src/views/init-speed-track/track-style.ts

@@ -1,5 +1,5 @@
 import * as ol from 'ol'
-import * as style from 'ol/styles'
+import * as style from 'ol/style'
 import * as layer from 'ol/layer'
 import * as source from 'ol/source'
 import * as geom from 'ol/geom'

+ 142 - 0
src/views/track-status/heart-line.vue

@@ -0,0 +1,142 @@
+<template>
+  <div class="chart-main" ref="ref_main">
+    <div class="chart-ref" ref="ref_chart"/>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useStore} from 'vuex'
+import {useRouter, useRoute} from 'vue-router'
+import {ElMessage, ElMessageBox} from "element-plus";
+import * as echarts from 'echarts'
+
+export default defineComponent({
+  name: '',
+  components: {},
+  props: {
+    data: {}
+  },
+  setup(props, {emit}) {
+    const store = useStore();
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      resizeObserver: <any>null,
+      chart: <any>null,
+    })
+    const ref_main =ref()
+    const ref_chart =ref()
+    const initChart = () => {
+      const chart = state.chart || echarts.init(ref_chart.value)
+      const option = {
+        grid: {
+          top: 20,
+          left: 40,
+          bottom: 20,
+          right: 20
+        },
+        xAxis: {
+          type: 'category',
+          show: false,
+          data: props.data?.map((v, i) => i) || []
+        },
+        yAxis: {
+          type: 'value',
+          splitNumber: 1,
+          max: 1,
+          min: 0,
+          axisLabel: {
+            formatter: (v) => {
+              if (v === 1) {
+                return '在线'
+              } else if (v === 0) {
+                return '离线'
+              }
+            }
+          }
+        },
+        // visualMap: {
+        //   show: false,
+        //   type: 'piecewise',
+        //   dimension: 0,
+        //   pieces: [
+        //     {gte: 0, lt: 1, color: 'red'},
+        //     {gte: 1, lt: 2,color: 'green'},
+        //   ]
+        // },
+        series: [
+          {
+            type: 'line',
+            data: props.data?.map(v => {
+              if (v.location) {
+                return {
+                  value: 1,
+                  itemStyle: {
+                    color: 'green'
+                  }
+                }
+              } else {
+                return {
+                  value: 0,
+                  itemStyle: {
+                    color: 'red'
+                  }
+                }
+              }
+            }) || []
+          }
+        ]
+      }
+      chart.setOption(option)
+      state.resizeObserver = new ResizeObserver(entries => {
+        for (const entry of entries) {
+          chart && chart.resize()
+        }
+      })
+      state.resizeObserver.observe(ref_main.value)
+      return chart
+    }
+    watch(() => props.data, () => {
+      state.chart = initChart()
+    })
+    onMounted(() => {
+      nextTick(() => {
+        state.chart = initChart()
+      })
+      return () => {
+        state.resizeObserver?.unobserve(ref_main?.value)
+        state.resizeObserver?.disconnect()
+      }
+    })
+    return {
+      ...toRefs(state),
+      ref_main,
+      ref_chart
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+.chart-main {
+  width: 100%;
+  height: 100%;
+  .chart-ref {
+    width: 100%;
+    height: 100%;
+  }
+}
+</style>

+ 208 - 22
src/views/track-status/index.vue

@@ -10,13 +10,32 @@
           <template v-if="item.keyList?.length > 0">
             <el-button v-if="!item.isStart" type="success" @click="onStartKey(item)">开始</el-button>
             <el-button v-else type="danger" @click="onStopKey(item)">暂停</el-button>
+            <el-button v-if="!item.isStart" type="warning" @click="onEditGroup(item)">编辑分组</el-button>
+            <el-button v-if="!item.isStart" type="danger" @click="onDelGroup(item)">删除分组</el-button>
           </template>
           <div>{{item.name}}({{item.second}}秒)</div>
           <div>{{item.cql}}</div>
           <el-divider />
           <div>
             <template v-for="(key, keyIndex) in item.keyList">
-              <div :style="`color: ${key.apiData ? '' : 'red'}`">{{keyIndex + 1}}、{{key.key}}_{{key.apiData || '无信号'}}</div>
+              <div :style="`color: ${key.online ? '' : 'red'}`">
+                {{keyIndex + 1}}、{{key.key}}<el-button v-if="!item.isStart" type="danger" size="small" @click="onDelKey(item, key)">删除</el-button>
+                <template v-if="item.isStart">
+                  <div class="key-content">
+                    <div class="key-position">
+                      <EasyMapComponent
+                          v-if="key.online"
+                          class="map"
+                          @easyMapLoad="(map, func) => initKeyMap(map, key)"
+                      />
+                      <div v-else>无信号</div>
+                    </div>
+                    <div class="key-heart">
+                      <HeartLineChart :data="key.apiData"/>
+                    </div>
+                  </div>
+                </template>
+              </div>
             </template>
           </div>
         </el-card>
@@ -27,7 +46,7 @@
         v-model:show="showGroupDialog"
         @submit="onSaveGroup"
     >
-      <div>
+      <div style="padding: 20px;">
         <CusForm ref="ref_groupForm">
           <CusFormColumn
             label="分组名称"
@@ -60,7 +79,7 @@
         @submit="onSaveKey"
         height="auto"
     >
-      <div>
+      <div style="padding: 20px;">
         <CusForm ref="ref_keyForm">
           <CusFormColumn
               label="KEY"
@@ -90,10 +109,15 @@ import {
 import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
 import {ElMessage, ElMessageBox} from "element-plus";
+import axios from "axios";
+import * as style from 'ol/style'
+import HeartLineChart from './heart-line.vue'
 
 export default defineComponent({
   name: '',
-  components: {},
+  components: {
+    HeartLineChart
+  },
   props: {},
   setup(props, {emit}) {
     const store = useStore();
@@ -150,20 +174,46 @@ export default defineComponent({
     }
     const onSaveGroup = () => {
       ref_groupForm.value.submit().then(() => {
-        const obj = {
-          name: state.groupForm.name,
-          second: state.groupForm.second,
-          cql: state.groupForm.cql,
-          keyList: JSON.stringify([])
-        }
-        const re = state.DB.transaction([state.ObjectStore], 'readwrite').objectStore(state.ObjectStore).add(obj)
-        re.onsuccess = e => {
-          ElMessage.success('添加成功!')
-          state.showGroupDialog = false
-          init()
-        }
-        re.onerror = e => {
-          ElMessage.error('添加失败!')
+        if (!state.groupForm.id) {
+          const obj = {
+            name: state.groupForm.name,
+            second: state.groupForm.second,
+            cql: state.groupForm.cql,
+            keyList: JSON.stringify([])
+          }
+          const re = state.DB.transaction([state.ObjectStore], 'readwrite').objectStore(state.ObjectStore).add(obj)
+          re.onsuccess = e => {
+            ElMessage.success('添加成功!')
+            state.showGroupDialog = false
+            init()
+          }
+          re.onerror = e => {
+            ElMessage.error('添加失败!')
+          }
+        } else {
+          const obj = {
+            name: state.groupForm.name,
+            second: state.groupForm.second,
+            cql: state.groupForm.cql,
+            keyList: JSON.stringify(state.groupForm.keyList.map(v => {
+              return {
+                key: v.key
+              }
+            }))
+          }
+          const re = state.DB.transaction([state.ObjectStore], 'readwrite').objectStore(state.ObjectStore).put(obj, state.groupForm.id)
+          re.onsuccess = e => {
+            ElMessage.success('更新成功!')
+            state.group.forEach(v => {
+              if (v.id === state.groupForm.id) {
+                v = state.groupForm
+              }
+            })
+            state.showGroupDialog = false
+          }
+          re.onerror = e => {
+            ElMessage.error('更新失败!')
+          }
         }
       })
     }
@@ -175,8 +225,10 @@ export default defineComponent({
     }
     const onSaveKey = () => {
       ref_keyForm.value.submit().then(() => {
-        console.log(state.keyForm)
-        const kList = [...state.keyForm.group.keyList, {key: state.keyForm.key}]
+        const kList = [...state.keyForm.group.keyList.map(v => {
+          const o = {key: v.key}
+          return o
+        }), {key: state.keyForm.key}]
         const obj = {
           name: state.keyForm.group.name,
           second: state.keyForm.group.second,
@@ -191,6 +243,7 @@ export default defineComponent({
               v.keyList = JSON.parse(JSON.stringify(kList))
             }
           })
+          state.showKeyDialog = false
         }
         re.onerror = e => {
           ElMessage.error('更新失败!')
@@ -201,7 +254,26 @@ export default defineComponent({
       group.isStart = true
       const handle = () => {
         group.keyList.forEach(v => {
-          v.apiData = '123'
+          let url = `/${store.state.app.apiProxy.rhFindShipApi}/geomesa/queryFusionShip/?cql=`;
+          url += encodeURIComponent(group.cql.split('{KEY}').join(v.key))
+          axios.get(url).then(res => {
+            if (res.data.data?.length > 0) {
+              v.online = true
+              if (v.apiData) {
+                v.apiData = [...v.apiData, res.data.data[0]]
+              } else {
+                v.apiData = [res.data.data[0]]
+              }
+              setKeyMap(v, v.apiData[v.apiData.length - 1])
+            } else {
+              v.online = false
+              if (v.apiData) {
+                v.apiData = [...v.apiData, {}]
+              } else {
+                v.apiData = [{}]
+              }
+            }
+          })
         })
       }
       handle()
@@ -213,6 +285,99 @@ export default defineComponent({
       group.isStart = false
       clearInterval(group.interval)
       group.interval = null
+      group.keyList?.forEach(v => {
+        v.apiData = []
+      })
+    }
+    const setKeyMap = (key, data) => {
+      if (key.MAP) {
+        that.$easyMap.initShape({
+          map: key.MAP,
+          layerName: "MAP",
+          layerZIndex: 9,
+          list: [
+            {
+              easyMapParams: {
+                id: new Date().getTime(),
+                position: data.location,
+                normalStyle: [
+                  new style.Style({
+                    image: new style.Circle({
+                      radius: 5,
+                      fill: new style.Fill({
+                        color: 'red',
+                      }),
+                    }),
+                  })
+                ]
+              }
+            }
+          ]
+        });
+        key.MAP.getView().animate({
+          center: that.$easyMap.formatPosition.wptTcpt(data.location)
+        })
+      }
+    }
+    const initKeyMap = (map, key) => {
+      key.MAP = map
+      if (key.apiData?.length > 0) {
+        const data = key.apiData[key.apiData.length - 1]
+        setKeyMap(key, data)
+      }
+    }
+    const onDelGroup = (group) => {
+      ElMessageBox.confirm(`是否删除分组:${group.name}`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        const re = state.DB.transaction([state.ObjectStore], 'readwrite').objectStore(state.ObjectStore).delete(group.id)
+        re.onsuccess = e => {
+          ElMessage.success('删除成功!')
+          state.group.forEach((v, i) => {
+            if (v.id === group.id) {
+              state.group.splice(i, 1)
+            }
+          })
+        }
+        re.onerror = e => {
+          ElMessage.error('更新失败!')
+        }
+      })
+    }
+    const onEditGroup = (group) => {
+      console.log(group)
+      state.groupForm = group
+      state.showGroupDialog = true
+    }
+    const onDelKey = (group, key) => {
+      ElMessageBox.confirm(`是否删除KEY:${key.key}`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        group.keyList.forEach((v, i) => {
+          if (v.key === key.key) {
+            group.keyList.splice(i, 1)
+          }
+        })
+        const obj = {
+          name: group.name,
+          second: group.second,
+          cql: group.cql,
+          keyList: JSON.stringify(group.keyList.map(v => {
+            return {key: v.key}
+          }))
+        }
+        const re = state.DB.transaction([state.ObjectStore], 'readwrite').objectStore(state.ObjectStore).put(obj, group.id)
+        re.onsuccess = e => {
+          ElMessage.success('更新成功!')
+        }
+        re.onerror = e => {
+          ElMessage.error('更新失败!')
+        }
+      })
     }
     onMounted(() => {
     })
@@ -225,7 +390,11 @@ export default defineComponent({
       onAddKey,
       onSaveKey,
       onStartKey,
-      onStopKey
+      onStopKey,
+      initKeyMap,
+      onEditGroup,
+      onDelGroup,
+      onDelKey
     }
   },
 })
@@ -243,6 +412,23 @@ export default defineComponent({
   .main-content {
     flex: 1;
     overflow: auto;
+    .key-content {
+      width: 100%;
+      height: 140px;
+      display: flex;
+      .key-position {
+        width: 200px;
+        height: 100%;
+        :deep(.easy-map-ol) {
+          .easy-map_ol-default-mouse-position, .easy-map_ol-default-zoom, .easy-map_ol-default-scaleLine {
+            display: none;
+          }
+        }
+      }
+      .key-heart {
+        flex: 1;
+      }
+    }
   }
 }
 </style>