riku
2025-07-04 d6e6f8b5b31e132e4597eb531168d3e88f3bda72
src/views/sourcetrace/UnderwayAdvice.vue
@@ -1,29 +1,108 @@
<template>
  <CardDialog
    v-model="dialogVisible"
    title="走航路线推荐"
    title="走航智能分析"
    draggable
    :modal="false"
    width="400px"
  >
    <template #default> </template>
    <template #default>
      <!-- <template v-if="latestResult">
        <el-row>
          <el-text size="small">{{ latestResult._timestr }}</el-text>
        </el-row>
        <el-space>
          <el-icon color="#F56C6C" :size="40"><WarnTriangleFilled /></el-icon>
          <el-text>
            {{ latestResult.advice }}
          </el-text>
        </el-space>
        <el-row justify="end">
          <el-link type="primary" :underline="true" @click="showPolyline">
            {{ lineShow ? '收起路线' : '定位路线' }}
          </el-link>
          <el-text size="small">
            推荐路线总长{{ latestResult.direction.distance }}米
          </el-text>
        </el-row>
      </template> -->
      <el-button icon="Plus" @click="addAdvice"></el-button>
      <el-button icon="Minus" @click="removeAdvice"></el-button>
      <el-scrollbar height="200">
        <TransitionGroup name="list">
          <div v-for="(item, index) in analysisResultList" :key="index">
            <template v-if="index == 0">
              <el-row justify="space-between">
                <el-text size="small">{{ item._timestr }}</el-text>
                <el-tag type="danger" effect="dark">最新线索</el-tag>
              </el-row>
              <el-space>
                <el-icon color="#F56C6C" :size="40"
                  ><WarnTriangleFilled
                /></el-icon>
                <el-text>
                  {{ item.advice }}
                </el-text>
              </el-space>
              <el-row justify="space-between">
                <el-link type="primary" :underline="true" @click="showPolyline">
                  {{ lineShow ? '收起路线' : '定位路线' }}
                </el-link>
                <el-text size="small">
                  推荐路线总长{{ item.direction.distance }}米
                </el-text>
              </el-row>
              <el-divider>历史线索</el-divider>
            </template>
            <template v-else>
              <el-row>
                <el-text size="small">{{ item._timestr }}</el-text>
              </el-row>
              <el-space>
                <!-- <el-icon color="#F56C6C" :size="40"><WarnTriangleFilled /></el-icon> -->
                <el-text>
                  {{ item.advice }}
                </el-text>
              </el-space>
              <!-- <el-row justify="space-between">
              <el-link type="primary" :underline="true" @click="showPolyline">
                {{ lineShow ? '收起路线' : '定位路线' }}
              </el-link>
              <el-text size="small">
                推荐路线总长{{ item.direction.distance }}米
              </el-text>
            </el-row> -->
              <el-divider></el-divider>
            </template>
          </div>
        </TransitionGroup>
      </el-scrollbar>
    </template>
    <template #footer> </template>
  </CardDialog>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import moment from 'moment';
import { ref, onMounted, onUnmounted, reactive } from 'vue';
import websocket from '@/api/websocket';
import websocketMsgParser from '@/views/sourcetrace/websocketMsgParser.js';
import mapLine from '@/utils/map/line';
import mapUtil from '@/utils/map/util';
const dialogVisible = ref(true);
const dialogVisible = ref(false);
const lineShow = ref(true);
const latestResult = ref();
let latestPolyline = undefined;
const analysisResultList = reactive([]);
const polylineList = [];
onMounted(() => {
  websocket.registerReceiveEvent(dealMsg);
});
onUnmounted(() => {
  websocket.removeReceiveEvent(dealMsg);
  showPolyline(false);
});
function dealMsg(data) {
@@ -32,13 +111,78 @@
  if (type == '2') {
    const obj = JSON.parse(content);
    console.log('污染分析结果: ', obj);
    obj._timestr = timeFormatter(obj.time);
    analysisResultList.unshift(obj);
    latestResult.value = obj;
    obj.sortedSceneList;
    obj.time;
    obj.advice;
    obj.direction;
    // obj.sortedSceneList;
    // obj.time;
    // obj.advice;
    // obj.direction;
    mapLine.drawDirection(obj.direction.paths.map((v) => [v.first, v.second]));
    const polyline = mapLine.drawDirection(
      obj.direction.paths.map((v) => [v.first, v.second])
    );
    polylineList.unshift(polyline);
    if (latestPolyline) {
      mapUtil.removeViews(latestPolyline);
    }
    latestPolyline = polyline;
    dialogVisible.value = true;
  }
}
function showPolyline(show) {
  if (typeof show === 'boolean') {
    lineShow.value = show;
  } else {
    lineShow.value = !lineShow.value;
  }
  if (lineShow.value) {
    mapUtil.addViews(latestPolyline);
  } else {
    mapUtil.removeViews(latestPolyline);
  }
}
function timeFormatter(time) {
  return moment(time).format('YYYY-MM-DD HH:mm:ss');
}
function addAdvice() {
  analysisResultList.unshift(analysisResultList[0]);
}
function removeAdvice() {
  analysisResultList.splice(0, 1);
}
</script>
<style scoped>
:deep(.el-text) {
  --el-text-color: white;
}
:deep(.el-link) {
  --el-link-text-color: #23dad1;
  /* color: #ffd82a; */
}
</style>
<!-- <style>
.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(-30px);
}
/* 确保将离开的元素从布局流中删除
  以便能够正确地计算移动的动画。 */
.list-leave-active {
  position: absolute;
}
</style> -->