Browse Source

Merge branch 'feature-v1.0.0' of ssh://gitlab.datameta.com:2224/project/water/data-board-2025 into feature-v1.0.0

feature-v1.0.0
邱伟洋 1 month ago
parent
commit
89dff0640a
  1. 1
      public/img/map/changeScene.svg
  2. BIN
      public/img/map/dike_four.png
  3. BIN
      public/img/map/dike_one.png
  4. BIN
      public/img/map/dike_two_three.png
  5. BIN
      public/img/map/icon-folder.png
  6. BIN
      public/img/map/icon-layer.png
  7. 1
      public/img/map/layer.svg
  8. BIN
      public/img/map/reservoir_big.png
  9. BIN
      public/img/map/reservoir_normal.png
  10. BIN
      public/img/map/reservoir_small.png
  11. BIN
      public/img/map/sluice_big.png
  12. BIN
      public/img/map/sluice_middle.png
  13. BIN
      public/img/map/sluice_small.png
  14. 2
      src/api/axios/axiosCancel.ts
  15. 20
      src/api/safety/index.ts
  16. 1
      src/components.d.ts
  17. 42
      src/hooks/web/useProject.tsx
  18. 42
      src/store/modules/chart.ts
  19. 18
      src/store/modules/project.ts
  20. 37
      src/views/BottomPanel/index.vue
  21. 87
      src/views/Main/DailyPatrolCard/index.vue
  22. 12
      src/views/Main/Map/components/LayerTree.vue
  23. 119
      src/views/Main/ProjectCountCard/index.vue
  24. 125
      src/views/Main/RiskInspectionCard/index.vue
  25. 6
      vite.config.ts

1
public/img/map/changeScene.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
public/img/map/dike_four.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

BIN
public/img/map/dike_one.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

BIN
public/img/map/dike_two_three.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

BIN
public/img/map/icon-folder.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

BIN
public/img/map/icon-layer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

1
public/img/map/layer.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="20" height="20" viewBox="0 0 20 20"><g><g><path d="M9.999699296875,9.385516708984376L17.591379296874997,6.222386708984375C18.104379296875,6.008626708984375,18.104379296875,5.250506708984375,17.591379296874997,5.036746708984375L9.999699296875,1.873626708984375L2.408007296875,5.036746708984375C1.894969796875,5.250506708984375,1.894970896875,6.008626708984375,2.408007296875,6.222386708984375L9.999699296875,9.385516708984376ZM9.999689296875,8.011006708984375L4.284089296875,5.629566708984375L9.999699296875,3.2481267089843753L15.715279296875,5.629566708984375L9.999689296875,8.011006708984375ZM1.873779296875,8.783306708984375L1.873779296875,10.317236708984375L10.000019296875,13.889926708984374L18.123779296875,10.318326708984374L18.123779296875,8.784396708984374L10.000019296875,12.356026708984375L1.873779296875,8.783306708984375ZM1.873779296875,13.024326708984376L1.873779296875,14.558226708984375L10.000139296875,18.130926708984376L18.123779296875,14.559426708984375L18.123779296875,13.025526708984374L10.000139296875,16.597026708984373L1.873779296875,13.024326708984376Z" fill-rule="evenodd" fill="#36B29E" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/img/map/reservoir_big.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/img/map/reservoir_normal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/img/map/reservoir_small.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/img/map/sluice_big.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

BIN
public/img/map/sluice_middle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

BIN
public/img/map/sluice_small.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

2
src/api/axios/axiosCancel.ts

@ -21,6 +21,8 @@ export class AxiosCanceler {
if (url.indexOf('cameras/previewURLs') > 0) return; // 忽略 重复请求获取预览取流地址 if (url.indexOf('cameras/previewURLs') > 0) return; // 忽略 重复请求获取预览取流地址
if (url.indexOf('preview/capture') > 0) return; // 忽略 重复请求获取预览取流地址 if (url.indexOf('preview/capture') > 0) return; // 忽略 重复请求获取预览取流地址
if (url.indexOf('/sy-engine-backer/cameraInfo/') > 0) return; // 忽略 重复请求获取预览取流地址 if (url.indexOf('/sy-engine-backer/cameraInfo/') > 0) return; // 忽略 重复请求获取预览取流地址
if (url.indexOf('/run/statistic/chart') > 0) return;
// 上传接口忽略重复请求 // 上传接口忽略重复请求
if (!url.includes('oss')) { if (!url.includes('oss')) {
config.cancelToken = config.cancelToken =

20
src/api/safety/index.ts

@ -1,4 +1,5 @@
// import axios from 'axios'; // import axios from 'axios';
import { he } from 'element-plus/es/locale';
import { request } from '../axios'; import { request } from '../axios';
// 预警统计 // 预警统计
@ -85,3 +86,22 @@ export const getObjectStatistic = (params: any) => {
params params
}); });
}; };
function getCookie(name: string): string | null {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop()?.split(';').shift() || null;
return null;
}
export function getlStatisticChart(data: any) {
// 获取cookie
const shuili = getCookie('Admin-Token');
return request({
url: `/run/statistic/chart`,
method: 'post',
data,
headers: {
// 'Admin-Token': shuili,
shuili: 'water ' + shuili
}
});
}

1
src/components.d.ts

@ -14,7 +14,6 @@ declare module 'vue' {
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
ElPopover: typeof import('element-plus/es')['ElPopover'] ElPopover: typeof import('element-plus/es')['ElPopover']
ElSelect: typeof import('element-plus/es')['ElSelect'] ElSelect: typeof import('element-plus/es')['ElSelect']
ElTag: typeof import('element-plus/es')['ElTag']
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree'] ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']

42
src/hooks/web/useProject.tsx

@ -1,7 +1,9 @@
import { reactive } from 'vue'; import { reactive } from 'vue';
import * as SyCim from 'sy-cesium-sdk'; import * as SyCim from 'sy-cesium-sdk';
import { LayerTypeEnum } from '@/enums/projectEnum'; import { LayerTypeEnum } from '@/enums/projectEnum';
import { queryLayersByPos } from "@/utils/mapUtils";
import axios from 'axios'; import axios from 'axios';
import { throttle } from "lodash-es";
const clustering = reactive({ const clustering = reactive({
enabled: true, enabled: true,
pixelRange: 200, pixelRange: 200,
@ -105,7 +107,7 @@ const layerActions: Record<string, any> = {
export const getFeatures: any = (data: any, filter: '1=1') => { export const getFeatures: any = (data: any, filter: '1=1') => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const { url } = data; const { url, serviceToken } = data;
let newUrl = decodeURI(url).split("maps/")[0].replace("map-", "data-"); let newUrl = decodeURI(url).split("maps/")[0].replace("map-", "data-");
const reg2 = /([^/]+)$/; const reg2 = /([^/]+)$/;
const decodeUrl: any = decodeURI(url); const decodeUrl: any = decodeURI(url);
@ -113,16 +115,20 @@ export const getFeatures: any = (data: any, filter: '1=1') => {
const l = newLayerName?.split("%40"); const l = newLayerName?.split("%40");
const datasourceName = `${l?.[1]}:${l?.[0]}`; const datasourceName = `${l?.[1]}:${l?.[0]}`;
let queryUrl = `${newUrl}data/featureResults.geojson?returnContent=true`; let queryUrl = `${newUrl}data/featureResults.geojson?returnContent=true`;
let params: any = {
getFeatureMode: 'SQL',
datasetNames: [datasourceName],
maxFeatures: 100000000,
queryParameter: {
attributeFilter: filter
}
};
if (serviceToken) {
params.k = serviceToken;
}
const result = await axios.post( const result = await axios.post(
queryUrl, queryUrl,
JSON.stringify({ JSON.stringify(params),
getFeatureMode: 'SQL',
datasetNames: [datasourceName],
maxFeatures: 100000000,
queryParameter: {
attributeFilter: filter
}
}),
{ {
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
@ -283,6 +289,7 @@ export function useLayer() {
if (!layerType || !(action = layerActions[layerType as string])) return; if (!layerType || !(action = layerActions[layerType as string])) return;
let layer: any = await action(layerData); let layer: any = await action(layerData);
if (isNeedCluster === '1' && layerData.nameCn === "水库点") { if (isNeedCluster === '1' && layerData.nameCn === "水库点") {
let baseUrl = import.meta.env.VITE_BASE_URL;
const data = await getFeatures(layerData); const data = await getFeatures(layerData);
if (data?.features?.[0]?.geometry?.type === 'Point') { if (data?.features?.[0]?.geometry?.type === 'Point') {
let layerConfig = {}; let layerConfig = {};
@ -298,7 +305,7 @@ export function useLayer() {
{ name: "4.0", attr: "image", value: "reservoir_small.png" }, { name: "4.0", attr: "image", value: "reservoir_small.png" },
{ name: "5.0", attr: "image", value: "reservoir_small.png" }, { name: "5.0", attr: "image", value: "reservoir_small.png" },
], ],
image: "reservoir_small.png", image: "map-title-o.png",
}; };
break; break;
} }
@ -306,7 +313,7 @@ export function useLayer() {
data, data,
symbol: { symbol: {
type: "billboardP", type: "billboardP",
imageProxy: "/src/assets/map/", // 图片代理 imageProxy: `${baseUrl}/img/map/`, // 图片代理
style: { style: {
clampToGround: false, clampToGround: false,
image: "reservoir_small.png", image: "reservoir_small.png",
@ -359,10 +366,21 @@ export function useLayer() {
const { layerType } = data; const { layerType } = data;
zoomToLayerActions[layerType as string]?.(data); zoomToLayerActions[layerType as string]?.(data);
}; };
const viewerClick = throttle((e) => {
console.log(e);
}, 500);
const addViewerMouseClick = () => {
window.viewer?.on(SyCim.MouseEventType.MOUSE_MOVE, viewerClick);
};
const removeViewerMouseClick = () => {
window.viewer?.off(SyCim.MouseEventType.MOUSE_MOVE, viewerClick);
};
return { return {
addLayer, addLayer,
removeLayer, removeLayer,
zoomToLayer zoomToLayer,
addViewerMouseClick,
removeViewerMouseClick
}; };
} }

42
src/store/modules/chart.ts

@ -0,0 +1,42 @@
import { defineStore } from 'pinia';
import { store } from '../index';
import { getlStatisticChart } from '@/api/safety';
export interface ChartState {
chartObject: any;
}
export const useChartStore = defineStore('chart', {
state: (): ChartState => ({
chartObject: {
endTime: '',
startTime: '',
adcd: '',
group: ''
}
}),
getters: {
getChartObject(): object {
return this.chartObject;
}
},
actions: {
resetChart() {
this.chartObject = {};
},
async initStatisticChart(data: any) {
const pramas = {
...this.chartObject,
...data
};
getlStatisticChart(pramas).then(res => {
if (res) return res
}).catch(() => {
return false
}).finally(() => {})
}
}
});
export const useChartStoreWithOut = () => {
return useChartStore(store);
};

18
src/store/modules/project.ts

@ -71,6 +71,21 @@ function filterTreeData(data: any[]) {
.filter(Boolean) .filter(Boolean)
); );
} }
function getLayerByName(data: any[], name: string) {
let layer = null;
const fn = (data: any[], name: string) => {
for (const item of data) {
if (item.nameCn === name) {
layer = item;
return;
} else if (item.children && item.children.length >= 0) {
fn(item.children, name);
}
}
};
fn(data, name);
return layer;
}
const { addLayer, removeLayer } = useLayer(); const { addLayer, removeLayer } = useLayer();
export const useProjectStore = defineStore("project", { export const useProjectStore = defineStore("project", {
@ -185,6 +200,9 @@ export const useProjectStore = defineStore("project", {
this.selectedLayers = _nodeTemp.filter((key) => !nodes.includes(key)); this.selectedLayers = _nodeTemp.filter((key) => !nodes.includes(key));
} }
}, },
getLayerByName(name: string) {
return getLayerByName(this.layerData, name);
},
async fetchFirstScene() { async fetchFirstScene() {
const rData = await getFirstScene(); const rData = await getFirstScene();
if (rData.code === 200) { if (rData.code === 200) {

37
src/views/BottomPanel/index.vue

@ -1,15 +1,48 @@
<template> <template>
<div class="bottom-panel"> <div class="bottom-panel">
<div class="tool-item active">水库</div> <!-- <div class="tool-item active">水库</div>
<div class="tool-item">水闸</div> <div class="tool-item">水闸</div>
<div class="tool-item">堤防</div> <div class="tool-item">堤防</div> -->
<div
v-for="(item, index) in layerData"
:class="['tool-item', { active: selectedKeys.includes(item.id) }]"
@click="handleChangeLayer(item)"
>
{{ item.nameCn }}
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed } from "vue";
import { useProjectStore } from "@/store/modules/project";
const projectStore = useProjectStore();
defineOptions({ defineOptions({
name: "bottom-panel", name: "bottom-panel",
}); });
const activeLayers = ref([]);
const listName = ref(["水库点", "堤防", "水闸"]);
const layerData: any = computed(() => {
const list = [];
listName.value.forEach((item, index) => {
const layer = projectStore.getLayerByName(item);
if (layer) {
list.push(layer);
}
});
return list;
});
const selectedKeys = computed(() => projectStore.selectedLayerKeys);
function handleChangeLayer(item: any) {
if (activeLayers.value.includes(item.id)) {
activeLayers.value = activeLayers.value.filter((id: any) => id !== item.id);
projectStore.setLayerVisibility(item.id, false);
} else {
activeLayers.value.push(item.id);
projectStore.setLayerVisibility(item.id, true);
}
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

87
src/views/Main/DailyPatrolCard/index.vue

@ -16,6 +16,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'; import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { useChartStore } from '@/store/modules/chart';
const chartStore = useChartStore();
defineOptions({ defineOptions({
name: 'DailyPatrolCard' name: 'DailyPatrolCard'
}); });
@ -24,20 +28,64 @@ const chartRef = ref();
const handleResize = () => { const handleResize = () => {
chart?.resize(); chart?.resize();
}; };
onMounted(() => { const dailyData: any = ref([]);
chart = echarts.init(chartRef.value); const dailyCount = ref(0);
const pieName = ['一般', '重大', '较大', '紧急']; const getChartData = async () => {
const pieValue = [545, 21, 300, 64]; dailyCount.value = 0
let count: any = 0; dailyData.value = [];
const pramas = {
const pieData: any = []; endTime: '',
for (var i = 0; i < pieName.length; i++) { startTime: '',
pieData.push({ group: 'K6'
name: pieName[i], };
value: pieValue[i] const data: any = await chartStore.initStatisticChart(pramas);
if (data?.yaxis?.length) {
let newArr = data.yaxis.flatMap((v: any) => v.series);
newArr?.forEach((item: any) => {
dailyData.value.push({
name: item.name || '',
value: Number(item.sum)?.toFixed(0) || 0,
unit: item.unit || ''
});
dailyCount.value += Number(item.sum) || 0;
}); });
count += pieValue[i]; // dailyCount.value = newArr
// .map((v: any) => Number(v.sum ?? null))
// .reduce((acc: any, cur: any) => {
// return acc + cur;
// }, 0);
} else {
//
dailyData.value = [
{
name: '一般',
value: 0,
unit: ''
},
{
name: '较大',
value: 0,
unit: ''
},
{
name: '重大',
value: 0,
unit: ''
},
{
name: '紧急',
value: 0,
unit: ''
}
];
} }
await initChart();
};
const initChart = () => {
chart = echarts.init(chartRef.value);
// ['', '', '', '']
const pieName = dailyData.value.map((item: any) => item.name);
const legendStyle = { const legendStyle = {
type: 'scroll', type: 'scroll',
// orient: 'vertical', // orient: 'vertical',
@ -52,8 +100,8 @@ onMounted(() => {
itemGap: 44, // 44 itemGap: 44, // 44
formatter: function (name: any) { formatter: function (name: any) {
for (var i = 0; i < pieName.length; i++) { for (var i = 0; i < pieName.length; i++) {
if (name == pieData[i].name) { if (name == dailyData.value[i].name) {
return '{name|' + name + '}{rate|' + pieValue[i] + '}'; return '{name|' + name + '}{rate|' + dailyData.value[i].value + '}';
} }
} }
}, },
@ -82,7 +130,7 @@ onMounted(() => {
// Chart options // Chart options
const option = { const option = {
tooltip: { tooltip: {
trigger: 'item', trigger: 'item'
// formatter: '{a} <br/>{b}: {c} ({d}%)' // formatter: '{a} <br/>{b}: {c} ({d}%)'
}, },
color: ['#4293F4', '#FFDD77', '#FF9A23', '#F26161'], color: ['#4293F4', '#FFDD77', '#FF9A23', '#F26161'],
@ -118,7 +166,7 @@ onMounted(() => {
labelLine: { labelLine: {
show: false show: false
}, },
data: pieData data: dailyData.value
}, },
{ {
name: '待处理问题', name: '待处理问题',
@ -134,7 +182,7 @@ onMounted(() => {
label: { label: {
position: 'center', position: 'center',
formatter: function () { formatter: function () {
return ['{total|' + count + '}', '{label|待处理问题}'].join('\n'); return ['{total|' + dailyCount.value + '}', '{label|待处理问题}'].join('\n');
}, },
rich: { rich: {
total: { total: {
@ -152,13 +200,16 @@ onMounted(() => {
} }
} }
}, },
data: [{ value: 1, name: '', tooltip: { show: false} }] data: [{ value: 1, name: '', tooltip: { show: false } }]
} }
] ]
}; };
// Set options and render chart // Set options and render chart
chart.setOption(option); chart.setOption(option);
};
onMounted(() => {
getChartData();
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
}); });

12
src/views/Main/Map/components/LayerTree.vue

@ -37,13 +37,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, computed, nextTick } from "vue"; import { ref, watch, computed, nextTick, onMounted, onBeforeUnmount } from "vue";
import SyDialog from "@/components/Dialog/index.vue"; import SyDialog from "@/components/Dialog/index.vue";
import { useProjectStore } from "@/store/modules/project"; import { useProjectStore } from "@/store/modules/project";
import { useLayer } from "@/hooks/web/useProject"; import { useLayer } from "@/hooks/web/useProject";
import { flattenTree } from "@/utils/index"; import { flattenTree } from "@/utils/index";
import Tree from "@/components/Tree/index.vue"; import Tree from "@/components/Tree/index.vue";
const { zoomToLayer } = useLayer(); const { zoomToLayer, addViewerMouseClick, removeViewerMouseClick } = useLayer();
const projectStore = useProjectStore(); const projectStore = useProjectStore();
defineOptions({ defineOptions({
@ -116,4 +116,12 @@ watch(
} }
}, },
); );
onMounted(() => {
addViewerMouseClick();
});
onBeforeUnmount(() => {
removeViewerMouseClick();
});
</script> </script>

119
src/views/Main/ProjectCountCard/index.vue

@ -8,6 +8,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue'; import { onMounted, onBeforeUnmount, ref } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { useChartStore } from '@/store/modules/chart';
const chartStore = useChartStore();
defineOptions({ defineOptions({
name: 'ProjectCountCard' name: 'ProjectCountCard'
}); });
@ -16,28 +20,53 @@ let chart: echarts.ECharts | undefined;
const handleResize = () => { const handleResize = () => {
chart?.resize(); chart?.resize();
}; };
onMounted(() => { const projectCount = ref(0);
if (!chartRef.value) return; const projectData: any = ref([]);
chart = echarts.init(chartRef.value); const getChartData = async () => {
projectCount.value = 0;
// Total count calculation projectData.value = [];
const reservoirCount = 544; const pramas = {
const sluiceCount = 454; endTime: '',
const damCount = 154; startTime: '',
const totalCount = 406; // Hard-coded total value shown in the center group: 'K1'
};
const legendName = ['水库', '水闸', '堤防']; const data: any = await chartStore.initStatisticChart(pramas);
const legendValue = [reservoirCount, sluiceCount, damCount]; if (data?.yaxis?.length) {
const unit = ['座', '座', '段']; let newArr = data.yaxis.flatMap((v: any) => v.series);
newArr?.forEach((item: any) => {
const pieData: any = []; projectData.value.push({
for (var i = 0; i < legendName.length; i++) { name: item.name || '',
pieData.push({ value: Number(item.sum)?.toFixed(0) || 0,
name: legendName[i], unit: item.unit || ''
value: legendValue[i], });
unit: unit[i] projectCount.value += Number(item.sum || 0);
}); });
} else {
//
projectData.value = [
{
name: '水库',
value: 0,
unit: '座'
},
{
name: '水闸',
value: 0,
unit: '座'
},
{
name: '堤防',
value: 0,
unit: '段'
}
];
} }
await initChart();
};
const initChart = () => {
if (!chartRef.value) return;
chart = echarts.init(chartRef.value);
const legendName = projectData.value.map((item: any) => item.name);
// Chart options // Chart options
const option = { const option = {
@ -58,8 +87,10 @@ onMounted(() => {
data: legendName, data: legendName,
formatter: function (name: any) { formatter: function (name: any) {
for (var i = 0; i < legendName.length; i++) { for (var i = 0; i < legendName.length; i++) {
if (name == pieData[i].name) { if (name == projectData.value[i].name) {
return '{name|' + name + '}{rate|' + legendValue[i] + '}{unit|' + unit[i] + '}'; return (
'{name|' + name + '}{rate|' + projectData.value[i].value + '}{unit|' + projectData.value[i].unit + '}'
);
} }
} }
}, },
@ -111,23 +142,25 @@ onMounted(() => {
label: { label: {
show: false show: false
}, },
data: [ color: ['#4293F4', '#30DFBA', '#FF755B', '#FFF03B', '#FFF03B'],
{ data: projectData.value
value: reservoirCount, // [
name: '水库', // {
itemStyle: { color: '#4293F4' } // value: reservoirCount,
}, // name: '',
{ // itemStyle: { color: '#4293F4' }
value: sluiceCount, // },
name: '水闸', // {
itemStyle: { color: '#30DFBA' } // value: sluiceCount,
}, // name: '',
{ // itemStyle: { color: '#30DFBA' }
value: damCount, // },
name: '堤防', // {
itemStyle: { color: '#FF755B' } // value: damCount,
} // name: '',
] // itemStyle: { color: '#FF755B' }
// }
// ]
}, },
{ {
name: '总数', name: '总数',
@ -143,7 +176,7 @@ onMounted(() => {
label: { label: {
position: 'center', position: 'center',
formatter: function () { formatter: function () {
return ['{total|' + totalCount + '}', '{label|总数}'].join('\n'); return ['{total|' + projectCount.value + '}', '{label|总数}'].join('\n');
}, },
rich: { rich: {
total: { total: {
@ -161,14 +194,16 @@ onMounted(() => {
} }
} }
}, },
data: [{ value: 1, name: '总数', tooltip: { show: false} }] data: [{ value: 1, name: '总数', tooltip: { show: false } }]
} }
] ]
}; };
// Set options and render chart // Set options and render chart
chart.setOption(option); chart.setOption(option);
};
onMounted(() => {
getChartData();
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {

125
src/views/Main/RiskInspectionCard/index.vue

@ -19,6 +19,10 @@ import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import 'echarts-liquidfill'; import 'echarts-liquidfill';
import 'echarts-liquidfill/src/liquidFill.js'; import 'echarts-liquidfill/src/liquidFill.js';
import { useChartStore } from '@/store/modules/chart';
const chartStore = useChartStore();
defineOptions({ defineOptions({
name: 'RiskInspectionCard' name: 'RiskInspectionCard'
}); });
@ -30,7 +34,71 @@ const handleResize = () => {
leftChart?.resize(); leftChart?.resize();
rightChart?.resize(); rightChart?.resize();
}; };
onMounted(() => { const problemData: any = ref([]);
const problemCount = ref(0);
const taskData: any = ref([]);
const taskCount = ref(0);
const getChartData = async () => {
problemCount.value = 0;
problemData.value = [];
taskCount.value = 0;
taskData.value = [];
const pramas = {
endTime: '',
startTime: '',
group: 'K5'
};
const data: any = await chartStore.initStatisticChart(pramas);
if (data?.yaxis?.length) {
let newArr = data.yaxis.flatMap((v: any) => v.series);
newArr?.forEach((item: any) => {
if (['问题数', '数量'].includes(item.name)) {
problemData.value.push({
name: item.name || '',
value: Number(item.sum)?.toFixed(0) || 0,
unit: item.unit || ''
});
problemCount.value += Number(item.sum) || 0;
} else {
taskData.value.push({
name: item.name || '',
value: Number(item.sum)?.toFixed(0) || 0,
unit: item.unit || ''
});
taskCount.value += Number(item.sum) || 0;
}
});
} else {
//
problemData.value = [
{
name: '问题数',
value: 0,
unit: ''
},
{
name: '数量',
value: 0,
unit: ''
}
];
taskData.value = [
{
name: '任务数',
value: 0,
unit: ''
},
{
name: '已完成',
value: 0,
unit: ''
}
];
}
initChart();
};
const initChart = () => {
leftChart = echarts.init(problemEchartRef.value); leftChart = echarts.init(problemEchartRef.value);
const color = ['#FFBC37', '#429BF4']; const color = ['#FFBC37', '#429BF4'];
@ -64,18 +132,10 @@ onMounted(() => {
show: false show: false
} }
}; };
const legendName = ['数量', '问题数']; const legendName = problemData.value.map((item: any) => item.name);
const pieValue = [98, 56]; const pieValue = problemData.value.map((item: any) => item.value);
var pieData: any = []; const leftCenterValue = ['50%', '37%'];
for (var i = 0; i < legendName.length; i++) { //
pieData.push({
name: legendName[i],
value: pieValue[i]
});
}
const leftCenterValue = ['50%', '37%']
// Chart options for the left side (nested pie)
const leftOption = { const leftOption = {
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
@ -83,7 +143,7 @@ onMounted(() => {
}, },
color: ['#FFBC37', '#FFBC37'], color: ['#FFBC37', '#FFBC37'],
title: { title: {
text: pieValue[0], text: problemCount.value,
subtext: '工程总数', subtext: '工程总数',
x: 'center', x: 'center',
y: '20%', y: '20%',
@ -134,8 +194,8 @@ onMounted(() => {
data: legendName, data: legendName,
formatter: function (name: any) { formatter: function (name: any) {
for (var i = 0; i < legendName.length; i++) { for (var i = 0; i < legendName.length; i++) {
if (name == pieData[i].name) { if (name == problemData.value[i].name) {
return '{name|' + name + '}{rate|' + pieValue[i] + '}'; return '{name|' + name + '}{rate|' + problemData.value[i].value + '}';
} }
} }
} }
@ -196,27 +256,15 @@ onMounted(() => {
} }
] ]
}; };
// Set options and render left chart
leftChart.setOption(leftOption); leftChart.setOption(leftOption);
rightChart = echarts.init(questEchartRef.value); rightChart = echarts.init(questEchartRef.value);
const li_qu_legend = ['任务数', '已完成']; // ['', '']
const taskNum = 98; const li_qu_legend = taskData.value.map((item: any) => item.name);
const accomplishNum = 30; const taskNum = taskData.value.find((item: any) => item.name === '任务数')?.value;
const li_qu_data = [ const accomplishNum = taskData.value.find((item: any) => item.name === '已完成')?.value;
{
name: li_qu_legend[0],
value: taskNum
},
{
name: li_qu_legend[1],
value: accomplishNum
}
];
// //
const li_qu_count: any = accomplishNum / taskNum; const li_qu_count: any = taskNum ? Number(accomplishNum) / Number(taskNum) : 0;
const titleStyle = { const titleStyle = {
fontSize: 32, fontSize: 32,
@ -227,8 +275,8 @@ onMounted(() => {
textShadowOffsetX: 0, textShadowOffsetX: 0,
textShadowOffsetY: 1 textShadowOffsetY: 1
}; };
const centerValue = ['50%', '37%'] const centerValue = ['50%', '37%'];
// Chart options for the right side (liquidFill) //
const rightOption = { const rightOption = {
title: [ title: [
{ {
@ -280,8 +328,8 @@ onMounted(() => {
data: li_qu_legend, data: li_qu_legend,
formatter: function (name: any) { formatter: function (name: any) {
for (var i = 0; i < li_qu_legend.length; i++) { for (var i = 0; i < li_qu_legend.length; i++) {
if (name == li_qu_data[i].name) { if (name == taskData.value[i].name) {
return '{name|' + name + '}{rate|' + li_qu_data[i].value + '}'; return '{name|' + name + '}{rate|' + taskData.value[i].value + '}';
} }
} }
} }
@ -376,6 +424,9 @@ onMounted(() => {
// Set options and render right chart // Set options and render right chart
rightChart.setOption(rightOption); rightChart.setOption(rightOption);
};
onMounted(() => {
getChartData();
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
}); });

6
vite.config.ts

@ -85,6 +85,12 @@ export default defineConfig(({ mode }) => {
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/iserver/, '/iserver') rewrite: (path) => path.replace(/^\/api\/iserver/, '/iserver')
}, },
// '/api/run': {
// // target: "http://shuili.product.dev.com:30115/",
// target: 'http://172.16.34.80:18082',
// changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, '/tianhui-admin-web')
// },
'/api': { '/api': {
target: 'http://shuili.product.dev.com:30115', // 'http://172.16.34.59:18083' target: 'http://shuili.product.dev.com:30115', // 'http://172.16.34.59:18083'
changeOrigin: true, changeOrigin: true,

Loading…
Cancel
Save