public/Ñï³¾ÎÛȾ¼à¹Ü¼ò±¨Ä£°å.docxBinary files differ
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: 'å·¡æ¥æåº¦ç®æ¥' }, ] }, // { 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' ), }, ] } ] }, 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. åå§åechartså®ä¾ 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 }; 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 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 src/views/fysp/data-product/components/ProdQueryOpt.vue
@@ -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, 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, 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å¹´MMæ'); 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> 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); } src/views/fysp/data-product/middle-data-product/ProdProblemCountSummaryProxy.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,83 @@ /** * ProdProblemCountSummary é»è¾ä»£ç */ 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(å¼å§æ¶é´)ãdistrictName(åºååç§°)ãsceneTypeName(åºæ¯ç±»ååç§°) * @param {Object} opt2 - 第äºä¸ªæ¶é´æ®µçé 置对象ï¼å å«startTime(å¼å§æ¶é´) * @param {Array} data - æ°æ®æ°ç»ï¼æ¯ä¸ªå ç´ å å«townName(è¡éåç§°)ãratio(å½åé®é¢æ°åå¼)ãlastRatio(对æ¯é®é¢æ°åå¼) * @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; } }; src/views/fysp/support/JingAnNightConstruction.vue
@@ -40,23 +40,38 @@ <!-- <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>