From 925b485e661682a2fcfc8b8a47a8148d16ec818e Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期六, 11 十月 2025 13:08:54 +0800
Subject: [PATCH] 新增最终数据产品月度巡查简报
---
src/views/fysp/data-product/middle-data-product/ProdProblemCountSummaryProxy.js | 83 +++++
src/views/fysp/data-product/components/ProdQueryOptCompare.vue | 6
src/utils/echart-util.js | 42 ++
public/扬尘污染监管简报模板.docx | 0
src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue | 96 +++---
src/views/fysp/data-product/components/BaseProdProcess.vue | 2
src/views/fysp/data-product/components/ProdQueryOpt.vue | 5
src/views/fysp/data-product/final-data-product/ProdMonInspecReport.vue | 501 +++++++++++++++++++++++++++++++++++
src/views/fysp/data-product/components/ProdDownload.vue | 41 ++
src/views/fysp/support/JingAnNightConstruction.vue | 25 +
src/constants/menu.js | 7
src/router/index.js | 15 +
12 files changed, 758 insertions(+), 65 deletions(-)
diff --git "a/public/\346\211\254\345\260\230\346\261\241\346\237\223\347\233\221\347\256\241\347\256\200\346\212\245\346\250\241\346\235\277.docx" "b/public/\346\211\254\345\260\230\346\261\241\346\237\223\347\233\221\347\256\241\347\256\200\346\212\245\346\250\241\346\235\277.docx"
new file mode 100644
index 0000000..9476e07
--- /dev/null
+++ "b/public/\346\211\254\345\260\230\346\261\241\346\237\223\347\233\221\347\256\241\347\256\200\346\212\245\346\250\241\346\235\277.docx"
Binary files differ
diff --git a/src/constants/menu.js b/src/constants/menu.js
index 2ecd4b8..b2d9a36 100644
--- a/src/constants/menu.js
+++ b/src/constants/menu.js
@@ -112,7 +112,12 @@
path: '/fysp/data-product/scenereport',
icon: 'Document',
name: '鍦烘櫙鍒嗘瀽鎶ュ憡'
- }
+ },
+ {
+ path: '/fysp/data-product/final/monInspecReport',
+ icon: 'Document',
+ name: '宸℃煡鏈堝害绠�鎶�'
+ },
]
},
// {
diff --git a/src/router/index.js b/src/router/index.js
index ba8f36f..1fed002 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -208,6 +208,21 @@
]
},
]
+ },
+ {
+ name: 'dataProdFinal',
+ path: 'final',
+ children: [
+ {
+ // 鏈�缁堜骇鍝�-宸℃煡鏈堝害绠�鎶�
+ name: 'MonInspecReport',
+ path: 'monInspecReport',
+ component: () =>
+ import(
+ '@/views/fysp/data-product/final-data-product/ProdMonInspecReport.vue'
+ ),
+ },
+ ]
}
]
},
diff --git a/src/utils/echart-util.js b/src/utils/echart-util.js
index 7f907dd..85d2841 100644
--- a/src/utils/echart-util.js
+++ b/src/utils/echart-util.js
@@ -1,3 +1,5 @@
+import * as echarts from 'echarts';
+
function pieChartOption() {
return {
color: [
@@ -97,7 +99,7 @@
legend: {
show: true,
orient: 'horizontal',
- bottom: '0%', // 鍥句緥搴曢儴姘村钩鎺掑垪
+ bottom: '0%' // 鍥句緥搴曢儴姘村钩鎺掑垪
},
grid: {
// left: '3%',
@@ -114,7 +116,7 @@
alignWithLabel: true
},
axisLabel: {
- rotate: 45,
+ rotate: 45
}
},
yAxis: {
@@ -165,4 +167,38 @@
document.body.removeChild(link);
}
-export { pieChartOption, barChartOption, downloadChartImage };
+function getChartUrl(option) {
+ // 1. 鍒涘缓涓存椂DOM鍏冪礌
+ const div = document.createElement('div');
+ // div.style.width = '330px';
+ // div.style.height = '160px';
+ div.style.width = '800px';
+ div.style.height = '400px';
+ document.body.appendChild(div);
+
+ // 2. 鍒濆鍖杄charts瀹炰緥
+ const myChart = echarts.init(div);
+
+ // 4. 璁剧疆鍥捐〃閰嶇疆椤�
+ myChart.setOption(option);
+
+ return new Promise((resolve, reject) => {
+ // 寤惰繜鎵ц纭繚缁樺埗瀹屾垚
+ setTimeout(() => {
+ // 5. 灏嗗浘琛ㄨ浆鎹负base64鍥剧墖
+ const imageBase64 = myChart.getDataURL({
+ type: 'png',
+ pixelRatio: 2, // 鎻愰珮鍥剧墖娓呮櫚搴�
+ backgroundColor: '#fff',
+ excludeComponents: ['toolbox']
+ });
+
+ // 6. 閿�姣佸疄渚嬪苟绉婚櫎涓存椂DOM
+ myChart.dispose();
+ document.body.removeChild(div);
+ resolve(imageBase64);
+ }, 1000);
+ });
+}
+
+export { pieChartOption, barChartOption, downloadChartImage, getChartUrl };
diff --git a/src/views/fysp/data-product/components/BaseProdProcess.vue b/src/views/fysp/data-product/components/BaseProdProcess.vue
index cc6d0de..66b5d4e 100644
--- a/src/views/fysp/data-product/components/BaseProdProcess.vue
+++ b/src/views/fysp/data-product/components/BaseProdProcess.vue
@@ -74,7 +74,7 @@
>
<div v-show="showStep3Content">
<template v-if="$slots.step3">
- <slot name="step3"></slot>
+ <slot name="step3" :onDownload="onDownload" :queryOpt="queryOpt"></slot>
</template>
<template v-else>
<ProdDownload
diff --git a/src/views/fysp/data-product/components/ProdDownload.vue b/src/views/fysp/data-product/components/ProdDownload.vue
index 8c073f1..c7552a1 100644
--- a/src/views/fysp/data-product/components/ProdDownload.vue
+++ b/src/views/fysp/data-product/components/ProdDownload.vue
@@ -15,8 +15,14 @@
</el-form-item>
<el-form-item label="浜у搧褰㈠紡">
<el-radio-group v-model="downloadType">
- <el-radio value="1"> Excel琛ㄥ崟 </el-radio>
- <el-radio value="2" :disabled="true"> Word鏂囨。 </el-radio>
+ <el-radio
+ v-for="item in _downloadTypeOptions"
+ :key="item.value"
+ :value="item.value"
+ :disabled="item.disabled"
+ >
+ {{ item.label }}
+ </el-radio>
</el-radio-group>
</el-form-item>
</el-form>
@@ -48,11 +54,33 @@
loading: {
type: Boolean,
default: false
+ },
+ downloadTypeOptions: {
+ type: Array,
+ default: () => [
+ {
+ value: '1',
+ label: 'Excel琛ㄥ崟'
+ },
+ {
+ value: '2',
+ label: 'Word鏂囨。'
+ }
+ ]
+ },
+ // 涓嬭浇绫诲瀷鏄惁鏈夋晥
+ downloadTypeValid: {
+ type: Array,
+ default: () => ['1']
+ },
+ defaultDownloadType: {
+ type: String,
+ default: '1'
}
});
const emit = defineEmits(['submit']);
-const downloadType = ref('1');
+const downloadType = ref(props.defaultDownloadType);
const opts = computed(() => {
if (props.queryOpt instanceof Array && props.queryOpt.length > 0) {
return props.queryOpt[0];
@@ -61,6 +89,13 @@
}
});
+const _downloadTypeOptions = computed(() => {
+ return props.downloadTypeOptions.map((item) => ({
+ ...item,
+ disabled: !props.downloadTypeValid.includes(item.value)
+ }));
+});
+
const submit = () => {
emit('submit', {
downloadType: downloadType.value
diff --git a/src/views/fysp/data-product/components/ProdQueryOpt.vue b/src/views/fysp/data-product/components/ProdQueryOpt.vue
index a1ac625..3c4cbc4 100644
--- a/src/views/fysp/data-product/components/ProdQueryOpt.vue
+++ b/src/views/fysp/data-product/components/ProdQueryOpt.vue
@@ -33,7 +33,7 @@
type: Boolean,
default: false
},
- active:{
+ active: {
type: Boolean,
default: true
}
@@ -60,8 +60,7 @@
townName: options.topTask.townname,
startTime: dayjs(options.topTask.starttime).format('YYYY-MM-DD HH:mm:ss'),
endTime: dayjs(options.topTask.endtime)
- .add(1, 'day')
- .add(-1, 'second')
+ .endOf('day')
.format('YYYY-MM-DD HH:mm:ss'),
sceneTypeId: options.sceneTypeId,
sceneTypeName: options.sceneTypeName,
diff --git a/src/views/fysp/data-product/components/ProdQueryOptCompare.vue b/src/views/fysp/data-product/components/ProdQueryOptCompare.vue
index 6f63038..285fa87 100644
--- a/src/views/fysp/data-product/components/ProdQueryOptCompare.vue
+++ b/src/views/fysp/data-product/components/ProdQueryOptCompare.vue
@@ -82,8 +82,7 @@
'YYYY-MM-DD HH:mm:ss'
),
endTime: dayjs(formSearch.value.topTask.endtime)
- .add(1, 'day')
- .add(-1, 'second')
+ .endOf('day')
.format('YYYY-MM-DD HH:mm:ss'),
sceneTypeId: formSearch.value.scenetype.value,
sceneTypeName: formSearch.value.scenetype.label,
@@ -104,8 +103,7 @@
'YYYY-MM-DD HH:mm:ss'
),
endTime: dayjs(formSearch2.value.topTask.endtime)
- .add(1, 'day')
- .add(-1, 'second')
+ .endOf('day')
.format('YYYY-MM-DD HH:mm:ss'),
sceneTypeId: formSearch.value.scenetype.value,
sceneTypeName: formSearch.value.scenetype.label,
diff --git a/src/views/fysp/data-product/final-data-product/ProdMonInspecReport.vue b/src/views/fysp/data-product/final-data-product/ProdMonInspecReport.vue
new file mode 100644
index 0000000..664fcbe
--- /dev/null
+++ b/src/views/fysp/data-product/final-data-product/ProdMonInspecReport.vue
@@ -0,0 +1,501 @@
+<template>
+ <BaseProdProcess
+ v-model:active="active"
+ @onStep1="onStep1"
+ @onStep2="onStep2"
+ @onStep3="onStep3"
+ :loading="loading"
+ >
+ <template #step1="{ onSearch }">
+ <ProdQueryOptCompare
+ :loading="loading"
+ @submit="onSearch"
+ ></ProdQueryOptCompare>
+ </template>
+ <template #step2="{ contentHeight }">
+ <el-scrollbar :height="contentHeight">
+ <el-card shadow="never"> Nothing </el-card>
+ </el-scrollbar>
+ </template>
+ <template #step3="{ onDownload, queryOpt }">
+ <ProdDownload
+ :loading="loading"
+ :queryOpt="queryOpt"
+ :downloadTypeValid="['2']"
+ defaultDownloadType="2"
+ @submit="onDownload"
+ ></ProdDownload>
+ </template>
+ </BaseProdProcess>
+</template>
+<script setup>
+/**
+ * 鏈堝害鐜板満宸℃煡绠�鎶�
+ */
+import { ref } from 'vue';
+import dayjs from 'dayjs';
+import { exportDocx } from '@/utils/doc';
+import BaseProdProcess from '@/views/fysp/data-product/components/BaseProdProcess.vue';
+import ProdQueryOptCompare from '@/views/fysp/data-product/components/ProdQueryOptCompare.vue';
+import ProdDownload from '@/views/fysp/data-product/components/ProdDownload.vue';
+import dataprodbaseApi from '@/api/fysp/dataprodbaseApi.js';
+import dataprodmiddleApi from '@/api/fysp/dataprodmiddleApi.js';
+import { useProdStepChange } from '@/views/fysp/data-product/prod-step-change.js';
+import {
+ pieChartOption,
+ barChartOption,
+ getChartUrl
+} from '@/utils/echart-util.js';
+import ProdProblemCountSummaryProxy from '@/views/fysp/data-product/middle-data-product/ProdProblemCountSummaryProxy.js';
+
+const { active, changeActive } = useProdStepChange();
+const loading = ref(false);
+const templateParam = {
+ districtName: '',
+ year: '',
+ month: '',
+ compareMonth: '',
+ sceneType: '宸ュ湴',
+ // 宸℃煡鎯呭喌姹囨��
+ sceneCount: 0,
+ pointCount: 0,
+ reviewPointCount: 0,
+ stopSceneCount: 0,
+ completeSceneCount: 0,
+ // 闂绫诲瀷姹囨��
+ problemTypeCount: 0,
+ problemCount: 0,
+ proTypeSum:
+ '閬撹矾鎵皹47涓紙鍗犳湰鏈堥棶棰樻�绘暟40.5%锛夛紝杈冧笂鏈堝鍔犵害3%锛涘嚭鍏ュ彛锛堥亾璺級鎵皹22涓紙鍗犳湰鏈堥棶棰樻�绘暟19.0%锛夛紝杈冧笂鏈堝鍔犵害4%锛�',
+ proTypeSumChartUrl: '',
+ // 闂鏁伴噺姹囨��
+ townCount: 0,
+ topThree:
+ '鍏卞拰鏂拌矾琛楅亾锛�2.4涓級銆佽姺姹熻タ璺閬擄紙2.14涓級銆佹浌瀹舵浮琛楅亾鍜屽ぉ鐩タ璺閬擄紙2.0涓級銆�',
+ problemCountByAreaChartUrl: '',
+ // 璇勪及鎯呭喌姹囨��
+ evalLevelABCountSum: 0, // 瑙勮寖宸ュ湴锛堝惈鍩烘湰瑙勮寖锛夊娆�
+ evalLevelABRatioSum: '0%', // 瑙勮寖鐜�
+ evalLevelABRatioDiff: '闄嶄綆绾�7%', // 杈冧笂鏈堣鑼冪巼鍙樺寲
+ evalLevelCDCountSum: 0, // 涓嶈鑼冪被锛堝惈涓ラ噸涓嶈鑼冿級瀹舵
+ evalLevelCDRatioSum: '0%', // 涓嶈鑼冪巼
+ evalLevelCDRatioDiff: '澧炲姞绾�10%', // 杈冧笂鏈堜笉瑙勮寖鐜囧彉鍖�
+ // 鍚勮闀囧満鏅鑼冩�ф帓琛岋紙杈冨ソ鍦ㄥ墠锛�
+ evaluationByArea: [
+ {
+ index: 1,
+ townName: '鐭抽棬浜岃矾琛楅亾',
+ validSceneCount: 2,
+ evaluationCount: 2,
+ evalLevelACount: 2,
+ evalLevelBCount: 0,
+ evalLevelCCount: 0,
+ evalLevelDCount: 0,
+ evalLevelRatioAB: '100%'
+ }
+ ],
+ // 鍚勮闀囧満鏅鑼冩�ф�昏
+ validSceneCountSum: 0,
+ evaluationCountSum: 0,
+ evalLevelACountSum: 0,
+ evalLevelBCountSum: 0,
+ evalLevelCCountSum: 0,
+ evalLevelDCountSum: 0,
+
+ // 鏁存敼鎯呭喌
+ proChangeRatioSum: '0%', // 鏁翠綋闂鏁存敼鐜�
+ sceneChangeRatioSum: '0%', // 锛堝娆★級鏁存敼鍗犳瘮
+ // 鎵皹闃叉不闂鍙婅鑼冩�ц瘎浼版竻鍗曪紙鍚鏍革級
+ changeAndEvalList: [
+ {
+ index: 1,
+ sceneName: '',
+ address: '',
+ townName: '',
+ score: 0,
+ scoreLevel: '',
+ problemCount: 0,
+ problemList: [
+ {
+ index: 1,
+ problemName: ''
+ }
+ ]
+ }
+ ],
+ // 鏈暣鏀规竻鍗�
+ unchangeSceneList: [
+ {
+ index: 1,
+ sceneName: '',
+ address: '',
+ townName: '',
+ problemCount: 0,
+ problemList: [
+ {
+ index: 1,
+ problemName: ''
+ }
+ ]
+ }
+ ]
+};
+
+function onStep1(opts) {
+ const [opt, compareOpt] = opts;
+ loading.value = true;
+ templateParam.districtName = opt.districtName;
+ templateParam.year = dayjs(opt.startTime).year();
+ templateParam.month = dayjs(opt.startTime).month() + 1;
+ templateParam.compareMonth = dayjs(compareOpt.startTime).month() + 1;
+ templateParam.sceneType = opt.sceneTypeName;
+ const p1 = dataprodmiddleApi.fetchInspectionSummary(opt).then((res) => {
+ if (res.success) {
+ Object.assign(templateParam, res.data);
+ }
+ });
+ const p2 = dataprodmiddleApi
+ .fetchProblemTypeSummary(opt)
+ .then(async (res) => {
+ if (res.success) {
+ const data = res.data.sort((a, b) => b.count - a.count);
+ templateParam.problemTypeCount = data.length;
+ templateParam.problemCount = data.reduce(
+ (acc, cur) => acc + cur.count,
+ 0
+ );
+ templateParam.proTypeSum =
+ data
+ .map((item) => {
+ let _ratioDiff;
+ if (item.ratioDiff > 0) {
+ _ratioDiff = `澧炲姞绾�${(Math.abs(item.ratioDiff) * 100).toFixed(
+ 1
+ )}%`;
+ } else if (item.ratioDiff < 0) {
+ _ratioDiff = `鍑忓皯绾�${(Math.abs(item.ratioDiff) * 100).toFixed(
+ 1
+ )}%`;
+ } else {
+ _ratioDiff = '鍩烘湰鎸佸钩';
+ }
+ return `${item.typeName}${item.count}涓紙鍗犳湰鏈堥棶棰樻�绘暟${(
+ item.ratio * 100
+ ).toFixed(1)}%锛夛紝杈冧笂鏈�${_ratioDiff}锛沗;
+ })
+ .join('锛�') + '銆�';
+ templateParam.proTypeSumChartUrl = await genChartProblemTypeSummary(
+ opt,
+ data
+ );
+ }
+ });
+ const p3 = dataprodmiddleApi
+ .fetchProblemCountByArea(opt)
+ .then(async (res) => {
+ if (res.success) {
+ const data = res.data.sort((a, b) => b.ratio - a.ratio);
+ templateParam.townCount = data.length;
+ templateParam.topThree =
+ data
+ .slice(0, 3)
+ .map((item) => `${item.townName}锛�${item.ratio.toFixed(1)}涓級`)
+ .join('銆�') + '銆�';
+
+ const res2 =
+ await dataprodmiddleApi.fetchProblemCountByArea(compareOpt);
+ if (res2.success) {
+ const data2 = res2.data.sort((a, b) => b.ratio - a.ratio);
+ const combineData = ProdProblemCountSummaryProxy.combineData(
+ data,
+ data2
+ );
+ templateParam.problemCountByAreaChartUrl =
+ await genChartProblemCountByArea(opt, compareOpt, combineData);
+ }
+ }
+ });
+ const p4 = dataprodmiddleApi.fetchEvaluationByArea(opt).then(async (res) => {
+ if (res.success) {
+ templateParam.evaluationByArea = [];
+ res.data
+ .sort((a, b) => {
+ return b.evalLevelRatioAB - a.evalLevelRatioAB;
+ })
+ .forEach((item, index) => {
+ templateParam.evaluationByArea.push({
+ index: index + 1,
+ townName: item.townName,
+ validSceneCount: item.validSceneCount,
+ evaluationCount: item.evaluationCount,
+ evalLevelACount: item.evalLevelACount,
+ evalLevelBCount: item.evalLevelBCount,
+ evalLevelCCount: item.evalLevelCCount,
+ evalLevelDCount: item.evalLevelDCount,
+ evalLevelRatioAB: `${(item.evalLevelRatioAB * 100).toFixed(1)}%`
+ });
+ templateParam.validSceneCountSum += item.validSceneCount;
+ templateParam.evaluationCountSum += item.evaluationCount;
+ templateParam.evalLevelACountSum += item.evalLevelACount;
+ templateParam.evalLevelBCountSum += item.evalLevelBCount;
+ templateParam.evalLevelCCountSum += item.evalLevelCCount;
+ templateParam.evalLevelDCountSum += item.evalLevelDCount;
+ });
+ templateParam.evalLevelABCountSum =
+ templateParam.evalLevelACountSum + templateParam.evalLevelBCountSum;
+ templateParam.evalLevelABRatioSum = `${(
+ (templateParam.evalLevelABCountSum / templateParam.evaluationCountSum) *
+ 100
+ ).toFixed(1)}%`;
+ templateParam.evalLevelCDCountSum =
+ templateParam.evalLevelCCountSum + templateParam.evalLevelDCountSum;
+ templateParam.evalLevelCDRatioSum = `${(
+ (templateParam.evalLevelCDCountSum / templateParam.evaluationCountSum) *
+ 100
+ ).toFixed(1)}%`;
+
+ // 鍜屼笂鏈堟儏鍐佃繘琛屽姣�
+ const res2 = await dataprodmiddleApi.fetchEvaluationByArea(compareOpt);
+ if (res2.success) {
+ const compareData = {
+ validSceneCountSum: 0,
+ evaluationCountSum: 0,
+ evalLevelACountSum: 0,
+ evalLevelBCountSum: 0,
+ evalLevelCCountSum: 0,
+ evalLevelDCountSum: 0
+ };
+ res2.data
+ .sort((a, b) => {
+ return b.evalLevelRatioAB - a.evalLevelRatioAB;
+ })
+ .forEach((item, index) => {
+ compareData.validSceneCountSum += item.validSceneCount;
+ compareData.evaluationCountSum += item.evaluationCount;
+ compareData.evalLevelACountSum += item.evalLevelACount;
+ compareData.evalLevelBCountSum += item.evalLevelBCount;
+ compareData.evalLevelCCountSum += item.evalLevelCCount;
+ compareData.evalLevelDCountSum += item.evalLevelDCount;
+ });
+ const ratioABDiff =
+ ((compareData.evalLevelACountSum + compareData.evalLevelBCountSum) /
+ compareData.evaluationCountSum) *
+ 100 -
+ parseFloat(templateParam.evalLevelABRatioSum.replace('%', ''));
+
+ const ratioCDDiff =
+ ((compareData.evalLevelCCountSum + compareData.evalLevelDCountSum) /
+ compareData.evaluationCountSum) *
+ 100 -
+ parseFloat(templateParam.evalLevelCDRatioSum.replace('%', ''));
+
+ if (ratioABDiff > 0) {
+ templateParam.evalLevelABRatioDiff = `澧炲姞绾�${Math.abs(
+ ratioABDiff
+ ).toFixed(1)}%`;
+ } else if (ratioABDiff < 0) {
+ templateParam.evalLevelABRatioDiff = `鍑忓皯绾�${Math.abs(
+ ratioABDiff
+ ).toFixed(1)}%`;
+ } else {
+ templateParam.evalLevelABRatioDiff = '鍩烘湰鎸佸钩';
+ }
+ if (ratioCDDiff > 0) {
+ templateParam.evalLevelCDRatioDiff = `澧炲姞绾�${Math.abs(
+ ratioCDDiff
+ ).toFixed(1)}%`;
+ } else if (ratioCDDiff < 0) {
+ templateParam.evalLevelCDRatioDiff = `鍑忓皯绾�${Math.abs(
+ ratioCDDiff
+ ).toFixed(1)}%`;
+ } else {
+ templateParam.evalLevelCDRatioDiff = '鍩烘湰鎸佸钩';
+ }
+ }
+ }
+ });
+ const p5 = dataprodbaseApi.fetchProdInspectionInfo(opt).then(async (res) => {
+ if (res.success) {
+ // 璁$畻闂鏁存敼鐜囧拰鍦烘櫙鏁存敼鍗犳瘮
+ const problemSum = {
+ // 闂鎬绘暟
+ proTotalCount: 0,
+ // 鏁存敼闂鏁�
+ proChangeCount: 0,
+ // 鎬诲贰鏌ョ偣娆℃暟锛堢浉鍚屽満鏅贰鏌ュ娆′篃浼氳绠楋級
+ sceneTotalCount: 0,
+ // 鏁存敼鐐规锛堟垨瀹舵锛夋暟
+ sceneChangeCount: 0
+ };
+
+ templateParam.changeAndEvalList = [];
+ templateParam.unchangeSceneList = [];
+ // 鑾峰彇璇勪及缁撴灉
+ const evalInfo = await dataprodbaseApi.fetchProdEvaluateInfo(opt);
+ const sceneInfo = await dataprodbaseApi.fetchProdSceneInfo(opt);
+ if (evalInfo.success) {
+ const evalData = evalInfo.data.sort(
+ (a, b) =>
+ parseInt(a.evaluate.resultscorebef) -
+ parseInt(b.evaluate.resultscorebef)
+ );
+ evalData.forEach((item, index) => {
+ // 鏌ユ壘瀵瑰簲鐨勫贰鏌ヤ换鍔¤褰�
+ const inspItem = res.data.find(
+ (i) => i.subTask.stguid === item.subTask.stguid
+ );
+ // 鏌ユ壘瀵瑰簲鐨勭洃绠″満鏅俊鎭�
+ const sceneItem = sceneInfo.data.find(
+ (i) => i.scene.guid === item.subTask.scenseid
+ );
+ // 鐢熸垚妯℃澘鍙傛暟
+ const changeAndEvalItem = {
+ sceneName: item.subTask.scensename,
+ address: item.subTask.scenseaddress,
+ townName: item.subTask.townname
+ };
+ // 鏍规嵁鍦烘櫙鐨勮繍钀ョ姸鎬侊紝鍐冲畾鍙傛暟鍐呭
+ if (sceneItem.statusBool) {
+ const obj = {
+ score: parseInt(item.evaluate.resultscorebef),
+ scoreLevel: item.scoreLevel,
+ problemCount: inspItem.problems.length,
+ // problemsDes: inspItem.problems
+ // .map((p, i) => `${i + 1}銆�${p.problemname}`)
+ // .join('\r\n'),
+ problemList:
+ inspItem.problems.length > 0
+ ? inspItem.problems.map((p, i) => {
+ return {
+ index: i + 1,
+ problemName: p.problemname
+ };
+ })
+ : [
+ {
+ index: '',
+ problemName: '妫�鏌ュ綋澶╃幇鍦烘棤鏄庢樉闂'
+ }
+ ]
+ };
+ Object.assign(changeAndEvalItem, obj);
+
+ // 鏇存柊闂鏁存敼鐜囧拰鍦烘櫙鏁存敼鍗犳瘮
+ problemSum.proTotalCount += inspItem.problems.length;
+ problemSum.sceneTotalCount += 1;
+ const unchangeProList = inspItem.problems.filter(
+ (p) => !p.ischanged
+ );
+ problemSum.proChangeCount +=
+ inspItem.problems.length - unchangeProList.length;
+ // 闄や簡鍏ㄩ儴闂閮芥病鏁存敼鐨勫満鏅紝閮界畻鏁存敼鐐规锛堟垨瀹舵锛夋暟
+ problemSum.sceneChangeCount +=
+ inspItem.problems.length > 0 &&
+ inspItem.problems.length == unchangeProList.length
+ ? 0
+ : 1;
+
+ if (unchangeProList.length > 0) {
+ templateParam.unchangeSceneList.push({
+ index: templateParam.unchangeSceneList.length + 1,
+ sceneName: item.subTask.scensename,
+ address: item.subTask.scenseaddress,
+ townName: item.subTask.townname,
+ problemCount: unchangeProList.length,
+ problemList: unchangeProList.map((p, i) => {
+ return {
+ index: i + 1,
+ problemName: p.problemname
+ };
+ })
+ });
+ }
+ } else {
+ const obj = {
+ score: '/',
+ scoreLevel: '/',
+ problemCount: '/',
+ // problemsDes: inspItem.problems
+ // .map((p, i) => `${i + 1}銆�${p.problemname}`)
+ // .join('\r\n'),
+ problemList: [
+ {
+ index: '',
+ problemName: sceneItem.status
+ }
+ ]
+ };
+ Object.assign(changeAndEvalItem, obj);
+ }
+ templateParam.changeAndEvalList.push({
+ index: index + 1,
+ ...changeAndEvalItem
+ });
+ });
+ }
+
+ templateParam.proChangeRatioSum = `${(
+ (problemSum.proChangeCount / problemSum.proTotalCount) *
+ 100
+ ).toFixed(1)}%`;
+ templateParam.sceneChangeRatioSum = `${(
+ (problemSum.sceneChangeCount / problemSum.sceneTotalCount) *
+ 100
+ ).toFixed(1)}%`;
+ }
+ });
+ Promise.all([p1, p2, p3, p4, p5])
+ .then(() => {
+ changeActive();
+ changeActive();
+ })
+ .finally(() => {
+ loading.value = false;
+ });
+}
+
+function onStep2() {
+ changeActive();
+ // ElMessage.error('鏆備笉鎻愪緵涓嬭浇');
+}
+
+function onStep3(val) {
+ if (val.downloadType == '2') {
+ loading.value = true;
+ exportDocx(
+ '/鎵皹姹℃煋鐩戠绠�鎶ユā鏉�.docx',
+ templateParam,
+ `${templateParam.districtName}${
+ templateParam.month
+ }鏈堟壃灏樻薄鏌撶洃绠$畝鎶�-${dayjs().format('YYYYMMDD')}.docx`,
+ {
+ horizontalHeight: 300,
+ verticalWidth: 600,
+ scale: 2
+ }
+ ).finally(() => (loading.value = false));
+ }
+}
+
+function genChartProblemTypeSummary(opt, data) {
+ const startTime = dayjs(opt.startTime).format('YYYY骞碝M鏈�');
+ const option = pieChartOption();
+ option.title.text = `${startTime}${opt.districtName}鎵皹姹℃煋闂绫诲瀷鍗犳瘮`;
+ option.legend.data = data.map((item) => item.typeName);
+ option.series[0].name = '闂绫诲瀷';
+ option.series[0].data = data.map((item) => ({
+ name: item.typeName,
+ value: item.count
+ }));
+ return getChartUrl(option);
+}
+
+function genChartProblemCountByArea(opt1, opt2, combineData) {
+ const option = ProdProblemCountSummaryProxy.genChartOption(
+ opt1,
+ opt2,
+ combineData
+ );
+ return getChartUrl(option);
+}
+</script>
diff --git a/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue b/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue
index a743ccc..8baf62d 100644
--- a/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue
+++ b/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue
@@ -7,7 +7,10 @@
:loading="loading"
>
<template #step1="{ onSearch }">
- <ProdQueryOptCompare :loading="loading" @submit="onSearch"></ProdQueryOptCompare>
+ <ProdQueryOptCompare
+ :loading="loading"
+ @submit="onSearch"
+ ></ProdQueryOptCompare>
</template>
<template #step2="{ contentHeight }">
<el-scrollbar :height="contentHeight">
@@ -78,11 +81,12 @@
import * as echarts from 'echarts';
import dayjs from 'dayjs';
import BaseProdProcess from '@/views/fysp/data-product/components/BaseProdProcess.vue';
+import ProdQueryOptCompare from '@/views/fysp/data-product/components/ProdQueryOptCompare.vue';
import dataprodmiddleApi from '@/api/fysp/dataprodmiddleApi.js';
import { conversionFromTable } from '@/utils/excel';
import { useProdStepChange } from '@/views/fysp/data-product/prod-step-change.js';
import { barChartOption, downloadChartImage } from '@/utils/echart-util.js';
-import ProdQueryOptCompare from '@/views/fysp/data-product/components/ProdQueryOptCompare.vue';
+import Proxy from '@/views/fysp/data-product/middle-data-product/ProdProblemCountSummaryProxy.js';
const { active, changeActive } = useProdStepChange();
const loading = ref(false);
@@ -92,18 +96,19 @@
let chart;
const tableData = computed(() => {
- return tableData1.value.map((item) => {
- const last = tableData2.value.find(
- (item2) => item2.townCode === item.townCode
- );
- item.ratio = Math.round(item.ratio * 10) / 10 || 0;
- return {
- ...item,
- lastSceneCount: last?.sceneCount || 0,
- lastProblemCount: last?.problemCount || 0,
- lastRatio: Math.round((last?.ratio || 0) * 10) / 10 || 0
- };
- });
+ // return tableData1.value.map((item) => {
+ // const last = tableData2.value.find(
+ // (item2) => item2.townCode === item.townCode
+ // );
+ // item.ratio = Math.round(item.ratio * 10) / 10 || 0;
+ // return {
+ // ...item,
+ // lastSceneCount: last?.sceneCount || 0,
+ // lastProblemCount: last?.problemCount || 0,
+ // lastRatio: Math.round((last?.ratio || 0) * 10) / 10 || 0
+ // };
+ // });
+ return Proxy.combineData(tableData1.value, tableData2.value);
});
function onStep1(opts) {
@@ -147,39 +152,40 @@
if (chart == undefined) {
chart = echarts.init(chartRef.value);
}
- const year = dayjs(opt1.startTime).year();
- const month1 = dayjs(opt1.startTime).month() + 1;
- const month2 = dayjs(opt2.startTime).month() + 1;
- const time = `${year}骞�${month1}鏈堛��${month2}鏈坄;
- const option = barChartOption();
- option.title.text = `${time}${opt1.districtName}鍚勮閬擄紙闀囷級${opt1.sceneTypeName}鎵皹姹℃煋闂鏁板潎鍊煎姣擿;
+ // const year = dayjs(opt1.startTime).year();
+ // const month1 = dayjs(opt1.startTime).month() + 1;
+ // const month2 = dayjs(opt2.startTime).month() + 1;
+ // const time = `${year}骞�${month1}鏈堛��${month2}鏈坄;
+ // const option = barChartOption();
+ // option.title.text = `${time}${opt1.districtName}鍚勮閬擄紙闀囷級${opt1.sceneTypeName}鎵皹姹℃煋闂鏁板潎鍊煎姣擿;
- option.xAxis.name = '琛楅亾锛堥晣锛�';
- option.xAxis.data = tableData.value.map((item) => item.townName);
- option.yAxis.name = '闂鏁板潎鍊�';
+ // option.xAxis.name = '琛楅亾锛堥晣锛�';
+ // option.xAxis.data = tableData.value.map((item) => item.townName);
+ // option.yAxis.name = '闂鏁板潎鍊�';
- option.series = [
- {
- name: `${month1}鏈坄,
- type: 'bar', // 鍥捐〃绫诲瀷鏀逛负鏌辩姸鍥�
- data: tableData.value.map((item) => item.ratio),
- label: {
- show: true,
- position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
- formatter: '{c}' // 鏍囩鏍煎紡锛氭暟閲�
- }
- },
- {
- name: `${month2}鏈坄,
- type: 'bar', // 鍥捐〃绫诲瀷鏀逛负鏌辩姸鍥�
- data: tableData.value.map((item) => item.lastRatio),
- label: {
- show: true,
- position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
- formatter: '{c}' // 鏍囩鏍煎紡锛氭暟閲�
- }
- }
- ];
+ // option.series = [
+ // {
+ // name: `${month1}鏈坄,
+ // type: 'bar', // 鍥捐〃绫诲瀷鏀逛负鏌辩姸鍥�
+ // data: tableData.value.map((item) => item.ratio),
+ // label: {
+ // show: true,
+ // position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
+ // formatter: '{c}' // 鏍囩鏍煎紡锛氭暟閲�
+ // }
+ // },
+ // {
+ // name: `${month2}鏈坄,
+ // type: 'bar', // 鍥捐〃绫诲瀷鏀逛负鏌辩姸鍥�
+ // data: tableData.value.map((item) => item.lastRatio),
+ // label: {
+ // show: true,
+ // position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
+ // formatter: '{c}' // 鏍囩鏍煎紡锛氭暟閲�
+ // }
+ // }
+ // ];
+ const option = Proxy.genChartOption(opt1, opt2, tableData.value);
chart.setOption(option);
}
diff --git a/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummaryProxy.js b/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummaryProxy.js
new file mode 100644
index 0000000..aaefc9c
--- /dev/null
+++ b/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummaryProxy.js
@@ -0,0 +1,83 @@
+/**
+ * ProdProblemCountSummary 閫昏緫浠g悊
+ */
+import dayjs from 'dayjs';
+import { barChartOption, downloadChartImage } from '@/utils/echart-util.js';
+
+export default {
+ /**
+ * 鍚堝苟鏁版嵁
+ * @param {*} data1
+ * @param {*} data2
+ * @returns
+ */
+ combineData(data1, data2) {
+ return data1.map((item) => {
+ const last = data2.find((item2) => item2.townCode === item.townCode);
+ item.ratio = Math.round(item.ratio * 10) / 10 || 0;
+ return {
+ ...item,
+ lastSceneCount: last?.sceneCount || 0,
+ lastProblemCount: last?.problemCount || 0,
+ lastRatio: Math.round((last?.ratio || 0) * 10) / 10 || 0
+ };
+ });
+ },
+
+
+ /**
+ * 鐢熸垚鎵皹姹℃煋闂鏁板姣旀煴鐘跺浘閰嶇疆
+ * @param {Object} opt1 - 绗竴涓椂闂存鐨勯厤缃璞★紝鍖呭惈startTime(寮�濮嬫椂闂�)銆乨istrictName(鍖哄煙鍚嶇О)銆乻ceneTypeName(鍦烘櫙绫诲瀷鍚嶇О)
+ * @param {Object} opt2 - 绗簩涓椂闂存鐨勯厤缃璞★紝鍖呭惈startTime(寮�濮嬫椂闂�)
+ * @param {Array} data - 鏁版嵁鏁扮粍锛屾瘡涓厓绱犲寘鍚玹ownName(琛楅亾鍚嶇О)銆乺atio(褰撳墠闂鏁板潎鍊�)銆乴astRatio(瀵规瘮闂鏁板潎鍊�)
+ * @returns {Object} ECharts鍥捐〃閰嶇疆瀵硅薄
+ */
+ genChartOption(opt1, opt2, data) {
+ // 浠庣涓�涓椂闂撮厤缃腑鑾峰彇骞翠唤
+ const year = dayjs(opt1.startTime).year();
+ // 浠庣涓�涓椂闂撮厤缃腑鑾峰彇鏈堜唤锛堟敞鎰忥細JavaScript鐨勬湀浠芥槸0-11锛屾墍浠ュ姞1锛�
+ const month1 = dayjs(opt1.startTime).month() + 1;
+ // 浠庣浜屼釜鏃堕棿閰嶇疆涓幏鍙栨湀浠�
+ const month2 = dayjs(opt2.startTime).month() + 1;
+ // 鏍煎紡鍖栨椂闂村瓧绗︿覆锛岀敤浜庡浘琛ㄦ爣棰�
+ const time = `${year}骞�${month2}鏈堛��${month1}鏈坄;
+ // 鑾峰彇鍩虹鏌辩姸鍥鹃厤缃ā鏉�
+ const option = barChartOption();
+ // 璁剧疆鍥捐〃鏍囬锛屽寘鍚椂闂存銆佸尯鍩熷悕绉般�佸満鏅被鍨嬬瓑淇℃伅
+ option.title.text = `${time}${opt1.districtName}鍚勮閬擄紙闀囷級${opt1.sceneTypeName}鎵皹姹℃煋闂鏁板潎鍊煎姣擿;
+
+ // 璁剧疆X杞村悕绉颁负琛楅亾锛堥晣锛�
+ option.xAxis.name = '琛楅亾锛堥晣锛�';
+ // 璁剧疆X杞存暟鎹负鍚勮閬撳悕绉�
+ option.xAxis.data = data.map((item) => item.townName);
+ // 璁剧疆Y杞村悕绉颁负闂鏁板潎鍊�
+ option.yAxis.name = '闂鏁板潎鍊�';
+
+ // 閰嶇疆鍥捐〃鏁版嵁绯诲垪
+ option.series = [
+ {
+ name: `${month1}鏈坄, // 褰撳墠鏈堜唤鏁版嵁绯诲垪鍚嶇О
+ type: 'bar', // 鍥捐〃绫诲瀷涓烘煴鐘跺浘
+ data: data.map((item) => item.ratio), // 褰撳墠鏈堜唤鍚勮閬撻棶棰樻暟鍧囧��
+ label: {
+ show: true, // 鏄剧ず鏁版嵁鏍囩
+ position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
+ formatter: '{c}' // 鏍囩鏍煎紡锛氱洿鎺ユ樉绀烘暟鍊�
+ }
+ },
+ {
+ name: `${month2}鏈坄, // 瀵规瘮鏈堜唤鏁版嵁绯诲垪鍚嶇О
+ type: 'bar', // 鍥捐〃绫诲瀷涓烘煴鐘跺浘
+ data: data.map((item) => item.lastRatio), // 瀵规瘮鏈堜唤鍚勮閬撻棶棰樻暟鍧囧��
+ label: {
+ show: true, // 鏄剧ず鏁版嵁鏍囩
+ position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
+ formatter: '{c}' // 鏍囩鏍煎紡锛氱洿鎺ユ樉绀烘暟鍊�
+ }
+ }
+ ];
+
+ // 杩斿洖瀹屾暣鐨勫浘琛ㄩ厤缃璞�
+ return option;
+ }
+};
\ No newline at end of file
diff --git a/src/views/fysp/support/JingAnNightConstruction.vue b/src/views/fysp/support/JingAnNightConstruction.vue
index 2c2f90f..ec5d544 100644
--- a/src/views/fysp/support/JingAnNightConstruction.vue
+++ b/src/views/fysp/support/JingAnNightConstruction.vue
@@ -39,24 +39,39 @@
<el-table-column prop="ncCityName" label="甯�" width="90" /> -->
<!-- <el-table-column prop="ncDistrictName" label="鍖哄幙" width="90" /> -->
<!-- <el-table-column prop="townname" label="琛楅亾" width="110" /> -->
+ <el-table-column
+ prop="ncFileName"
+ label="澶滄柦鏂囦欢"
+ width="170"
+ >
+ <template #default="{ row }">
+ <el-link
+ :underline="true"
+ type="primary"
+ :href="row.ncUrl"
+ target="_blank"
+ >{{ row.ncFileName }}</el-link
+ >
+ </template>
+ </el-table-column>
<el-table-column
prop="ncConstructionUnit"
label="鏂藉伐鍗曚綅"
min-width="100"
/>
- <el-table-column prop="ncPerson" label="鐢宠浜�" width="110" />
+ <el-table-column prop="ncPerson" label="鐢宠浜�" width="70" />
<el-table-column prop="ncApplyContent" label="鐢宠鍐呭" width="110" />
- <el-table-column prop="ncStartDate" label="鐢宠鏃堕棿" width="110">
+ <el-table-column prop="ncStartDate" label="鐢宠鏃堕棿" width="100">
<template #default="{ row }">
{{ $fm.formatYMD(row.ncCreateTime) }}
</template>
</el-table-column>
- <el-table-column prop="ncStartDate" label="宸ユ湡寮�濮�" width="110">
+ <el-table-column prop="ncStartDate" label="宸ユ湡寮�濮�" width="100">
<template #default="{ row }">
{{ $fm.formatYMD(row.ncStartDate) }}
</template>
</el-table-column>
- <el-table-column prop="ncEndDate" label="宸ユ湡缁撴潫" width="110">
+ <el-table-column prop="ncEndDate" label="宸ユ湡缁撴潫" width="100">
<template #default="{ row }">
{{ $fm.formatYMD(row.ncEndDate) }}
</template>
@@ -70,7 +85,7 @@
<template #default="{ row }">
<el-text
:loading="row._loading"
- :type="row._user ? 'primary' : 'danger'"
+ :type="row._user ? 'success' : 'danger'"
>{{ row._user ? row._user.realname : '鏈尮閰�' }}</el-text
>
</template>
--
Gitblit v1.9.3