| | |
| | | <template> |
| | | <!-- <BaseCard> |
| | | <template #content> --> |
| | | <el-scrollbar class="clue-card"> |
| | | <el-row justify="space-between"> |
| | | <!-- <el-tag v-if="index == 0" type="danger">最新</el-tag> --> |
| | | <el-text type="primary">{{ |
| | | '切片时间:' + |
| | | item.pollutedData.startTime + |
| | | ' - ' + |
| | | item.pollutedData.endTime |
| | | }}</el-text> |
| | | <el-link |
| | | type="primary" |
| | | :underline="true" |
| | | @click="showMarksAndPolygon(item)" |
| | | <CardDialog |
| | | :model-value="modelValue" |
| | | @update:model-value="handleDialogShow" |
| | | title="污染线索" |
| | | draggable |
| | | :modal="false" |
| | | width="400px" |
| | | > |
| | | {{ item.showMore ? '收起异常' : '定位异常' }} |
| | | </el-link> |
| | | </el-row> |
| | | <div> |
| | | <el-text type="primary"> |
| | | 污染区域:{{ item.pollutedArea.address }} |
| | | </el-text> |
| | | </div> |
| | | <div> |
| | | <el-text type="primary"> |
| | | 溯源距离:{{ formatDistanceType(item.pollutedArea.distanceType) }} |
| | | </el-text> |
| | | </div> |
| | | <div> |
| | | <el-text type="primary"> |
| | | 异常类型:{{ item.pollutedData.exception }} |
| | | </el-text> |
| | | </div> |
| | | <el-row style="border-top: 1px solid white"> |
| | | <el-col :span="6"> |
| | | <el-statistic title="突变因子" :value="item.pollutedData.factorName" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-statistic |
| | | v-if="item.pollutedData.exceptionType == 4" |
| | | title="变化幅度" |
| | | :value="formatPercentage(item.pollutedData.avgPer)" |
| | | /> |
| | | <el-statistic |
| | | v-else-if="item.pollutedData.exceptionType == 9" |
| | | title="变化速率" |
| | | :value="formatPercentage(item.pollutedData.avgPer)" |
| | | /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-statistic title="发生次数" :value="item.pollutedData.times" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-statistic |
| | | title="平均风速" |
| | | :value="item.pollutedData.windSpeed" |
| | | suffix="m/s" |
| | | /> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row justify="space-between"> |
| | | <!-- <el-link |
| | | type="primary" |
| | | underline |
| | | @click="showMarksAndPolygon(item)" |
| | | > |
| | | {{ |
| | | (item.showMore ? '收起溯源场景' : '查看溯源场景') + |
| | | '(' + |
| | | item.pollutedSource.sceneList.length + |
| | | ')' |
| | | }} |
| | | </el-link> --> |
| | | </el-row> |
| | | <!-- <div style="width: 320px; height: 80px"> --> |
| | | <RealTimeLineChart |
| | | v-for="(item1, index1) in item._chartOptions" |
| | | :key="index1" |
| | | :model-value="item1" |
| | | chart-height="80px" |
| | | ></RealTimeLineChart> |
| | | <!-- </div> --> |
| | | <div class="border-dashed"> |
| | | <el-text type="" tag="mark"> |
| | | {{ item.pollutedSource.conclusion }} |
| | | </el-text> |
| | | </div> |
| | | <SceneTable |
| | | :show-marks="item.showMore" |
| | | :scene-list="item.pollutedSource.sceneList" |
| | | ></SceneTable> |
| | | |
| | | <!-- <el-space gap="4"> |
| | | <el-tag :type="item.status == 1 ? 'danger' : 'info'">{{ |
| | | item._statusStr |
| | | }}</el-tag> |
| | | <el-text type="default">{{ item.exception }}</el-text> |
| | | </el-space> |
| | | <el-row gap="4"> |
| | | <el-text type="primary">发生时间:</el-text> |
| | | <el-text type="primary">{{ |
| | | item.startTime + ' 至 ' |
| | | }}</el-text> |
| | | <el-text type="primary">{{ |
| | | item.status == 1 ? '当前' : item.endTime |
| | | }}</el-text> |
| | | </el-row> |
| | | <template #default> |
| | | <template v-if="item"> |
| | | <el-row> |
| | | <el-col :span="6"> |
| | | <el-statistic title="因子" :value="item.factorName" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-statistic title="均值" :value="item.avg" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-statistic title="峰值" :value="item.max" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-statistic title="谷值" :value="item.min" /> |
| | | </el-col> |
| | | <el-text type="primary" size="small">{{ item._timestr }}</el-text> |
| | | </el-row> |
| | | <el-space> |
| | | <el-icon color="#F56C6C" :size="40"><WarnTriangleFilled /></el-icon> |
| | | <el-text type="primary"> |
| | | {{ item.advice }} |
| | | </el-text> |
| | | </el-space> |
| | | <el-row justify="space-between"> |
| | | <el-link |
| | | type="primary" |
| | | @click="item.showMore = !item.showMore" |
| | | > |
| | | {{ |
| | | (item.showMore ? '收起溯源场景' : '查看溯源场景') + |
| | | '(' + |
| | | item.relatedSceneList.length + |
| | | ')' |
| | | }} |
| | | </el-link> |
| | | <el-link type="primary" @click="drawSector(item)"> |
| | | 查看异常 |
| | | <el-text type="primary" size="small"> |
| | | 推荐路线总长{{ item.direction.distance }}米 |
| | | </el-text> |
| | | <el-link type="primary" size="small" @click="showPolyline"> |
| | | {{ lineShow ? '收起路线' : '定位路线' }} |
| | | </el-link> |
| | | </el-row> |
| | | <SceneTable |
| | | v-show="item.showMore" |
| | | :scene-list="item.relatedSceneList" |
| | | ></SceneTable> |
| | | <el-divider /> --> |
| | | </el-scrollbar> |
| | | <!-- </template> |
| | | </BaseCard> --> |
| | | :show-marks="lineShow" |
| | | :scene-list="formatSceneList(item.sortedSceneList)" |
| | | > |
| | | <el-table-column prop="_count" width="42" label="溯源次数" /> |
| | | </SceneTable> |
| | | </template> |
| | | </template> |
| | | <template #footer> </template> |
| | | </CardDialog> |
| | | </template> |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import { ref, onMounted, onUnmounted, reactive, watch } from 'vue'; |
| | | |
| | | import { sceneTypes, sceneIcon } from '@/constant/scene-types'; |
| | | import mapLine from '@/utils/map/line'; |
| | | import mapUtil from '@/utils/map/util'; |
| | | import marks from '@/utils/map/marks'; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: Boolean, |
| | | item: Object |
| | | }); |
| | | |
| | | const emits = defineEmits(['showMarksAndPolygon']); |
| | | const lineShow = ref(true); |
| | | // 上一条导航路线 |
| | | let lastPolyline = undefined; |
| | | // 上一个导航目的地 |
| | | // let lastDestination = undefined; |
| | | // let layer = undefined; |
| | | |
| | | function showMarksAndPolygon(item) { |
| | | emits('showMarksAndPolygon', item); |
| | | const emits = defineEmits(['update:modelValue']); |
| | | |
| | | watch( |
| | | () => [props.item, props.modelValue], |
| | | (nV, oV) => { |
| | | if (nV[0] != oV[0]) { |
| | | const polyline = mapLine.drawDirection( |
| | | nV[0].direction.paths.map((v) => [v.first, v.second]) |
| | | ); |
| | | // polylineList.unshift(polyline); |
| | | if (lastPolyline) { |
| | | mapUtil.removeViews(lastPolyline); |
| | | } |
| | | lastPolyline = polyline; |
| | | lineShow.value = true; |
| | | } else if (nV[1]) { |
| | | showPolyline(true); |
| | | } |
| | | } |
| | | ); |
| | | |
| | | function showPolyline(show) { |
| | | if (typeof show === 'boolean') { |
| | | lineShow.value = show; |
| | | } else { |
| | | lineShow.value = !lineShow.value; |
| | | } |
| | | |
| | | function formatPercentage(value) { |
| | | return Math.round(value * 100) + '%'; |
| | | } |
| | | |
| | | function formatDistanceType(value) { |
| | | switch (value) { |
| | | case 'TYPE1': |
| | | return '50米'; |
| | | case 'TYPE2': |
| | | return '50米 - 500米'; |
| | | case 'TYPE3': |
| | | return '50米 - 1公里'; |
| | | case 'TYPE4': |
| | | return '50米 - 2公里'; |
| | | |
| | | default: |
| | | break; |
| | | if (lineShow.value && lastPolyline) { |
| | | mapUtil.addViews(lastPolyline); |
| | | } else { |
| | | mapUtil.removeViews(lastPolyline); |
| | | } |
| | | } |
| | | |
| | | function formatChangeRate() { |
| | | // function removeLayer() { |
| | | // if (layer != undefined) { |
| | | // mapUtil.removeViews(layer); |
| | | // layer = undefined; |
| | | // } |
| | | // } |
| | | |
| | | // function drawMarks(sceneList) { |
| | | // removeLayer(); |
| | | // if (sceneList.length != 0) { |
| | | // const icons = []; |
| | | // sceneList.forEach((s) => { |
| | | // icons.push(sceneIcon(s.typeId)); |
| | | // }); |
| | | // layer = marks.createLabelMarks(icons, sceneList, false); |
| | | // } |
| | | // } |
| | | |
| | | function formatSceneList(sceneList) { |
| | | return sceneList.map((v) => { |
| | | return { |
| | | ...v.first, |
| | | _count: v.second |
| | | }; |
| | | }); |
| | | } |
| | | |
| | | function handleDialogShow(value) { |
| | | showPolyline(value); |
| | | emits('update:modelValue', value); |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | :deep(.el-statistic) { |
| | | --el-statistic-title-color: rgb(215, 215, 215); |
| | | --el-statistic-content-color: white; |
| | | } |
| | | |
| | | :deep(.el-text.el-text--primary) { |
| | | /* :deep(.el-text.el-text--primary) { |
| | | --el-text-color: white; |
| | | } |
| | | |
| | | :deep(.el-link) { |
| | | --el-link-text-color: #23dad1; |
| | | } |
| | | |
| | | .scrollbar { |
| | | min-width: 300px; |
| | | max-width: 60vw; |
| | | /* height: 35vh; */ |
| | | /* color: #02ffea; */ |
| | | } |
| | | |
| | | .clue-card { |
| | | padding: 0 4px; |
| | | /* margin-right: 2px; */ |
| | | width: 340px; |
| | | height: 35vh; |
| | | border-right: 1px solid white; |
| | | border-radius: 2px; |
| | | } |
| | | |
| | | .border-dashed { |
| | | /* border: 1px dashed white; */ |
| | | border: 1px dashed #ffbc58; |
| | | padding: 0px 1px; |
| | | margin-bottom: 4px; |
| | | } |
| | | } */ |
| | | </style> |