From 9169a74e1d7b2d24d20d708b4498d7ca17eda9d8 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期一, 28 四月 2025 13:42:52 +0800 Subject: [PATCH] 1. 新增自动评估监测数据统计导入功能 2. 修改问题审核界面巡查点次统计没有根据场景类型切换的问题 --- src/api/index.js | 2 src/views/fysp/check/ProCheck.vue | 4 src/views/fysp/check/components/CompSubTaskStatistic.vue | 15 +- src/components/SearchBar.vue | 2 src/views/fysp/evaluation/components/CompDataResultEdit.vue | 232 +++++++++++++++++++++++++++++++++++++--------- public/扬尘监测数据月度统计模板.xlsx | 0 src/utils/time-util.js | 2 7 files changed, 202 insertions(+), 55 deletions(-) diff --git "a/public/\346\211\254\345\260\230\347\233\221\346\265\213\346\225\260\346\215\256\346\234\210\345\272\246\347\273\237\350\256\241\346\250\241\346\235\277.xlsx" "b/public/\346\211\254\345\260\230\347\233\221\346\265\213\346\225\260\346\215\256\346\234\210\345\272\246\347\273\237\350\256\241\346\250\241\346\235\277.xlsx" new file mode 100644 index 0000000..99e9c25 --- /dev/null +++ "b/public/\346\211\254\345\260\230\347\233\221\346\265\213\346\225\260\346\215\256\346\234\210\345\272\246\347\273\237\350\256\241\346\250\241\346\235\277.xlsx" Binary files differ diff --git a/src/api/index.js b/src/api/index.js index befc092..69fae9f 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -1,7 +1,7 @@ import axios from 'axios'; import { ElMessage } from 'element-plus'; -const debug = true; +const debug = false; let ip1 = 'http://47.100.191.150:9005/'; let ip1_file = 'http://47.100.191.150:9005/'; diff --git a/src/components/SearchBar.vue b/src/components/SearchBar.vue index 49c3e62..83835cb 100644 --- a/src/components/SearchBar.vue +++ b/src/components/SearchBar.vue @@ -18,7 +18,7 @@ </el-select> </el-form-item> <FYOptionScene - :allOption="true" + :allOption="false" :type="2" v-model:value="formSearch.scenetype" ></FYOptionScene> diff --git a/src/utils/time-util.js b/src/utils/time-util.js index dec4073..e126941 100644 --- a/src/utils/time-util.js +++ b/src/utils/time-util.js @@ -44,7 +44,7 @@ const year = time.getFullYear(); const month = time.getMonth() + 1; const date = time.getDate(); - return ( + return dayjs( year + format + (month < 10 ? '0' + month : month) + diff --git a/src/views/fysp/check/ProCheck.vue b/src/views/fysp/check/ProCheck.vue index 5f02bd7..8090280 100644 --- a/src/views/fysp/check/ProCheck.vue +++ b/src/views/fysp/check/ProCheck.vue @@ -5,6 +5,7 @@ <template #summary> <CompSubTaskStatistic :loading="sideLoading" + :sceneType="sceneTypeId" :subtasks="subtasks" :monitorObjList="curMonitorObjList" /> @@ -103,6 +104,8 @@ mainLoading: false, // 鎬讳换鍔� topTask: {}, + // 鍦烘櫙绫诲瀷id + sceneTypeId: undefined, // 鎬讳换鍔″贰鏌ヨ鍒掓竻鍗� curMonitorObjList: [], //瀛愪换鍔″垪琛� @@ -165,6 +168,7 @@ this.mainLoading = true; this.curProList = []; this.curSubtask = {}; + this.sceneTypeId = formSearch.sceneTypeId const param = { topTaskId: formSearch.topTask.tguid, sceneTypeId: formSearch.sceneTypeId diff --git a/src/views/fysp/check/components/CompSubTaskStatistic.vue b/src/views/fysp/check/components/CompSubTaskStatistic.vue index 58e88cf..7f8d3e9 100644 --- a/src/views/fysp/check/components/CompSubTaskStatistic.vue +++ b/src/views/fysp/check/components/CompSubTaskStatistic.vue @@ -195,6 +195,7 @@ export default { props: { loading: Boolean, + sceneType: Number, subtasks: { type: Array, default: () => [] @@ -269,12 +270,14 @@ reviewTimes: 0 }; this.monitorObjList.forEach((m) => { - _res.total++; - const times = parseInt(m.extension1); - if (times) { - _res.completedScenes++; - _res.completedTimes += times; - _res.reviewTimes += times - 1; + if (this.sceneType == undefined || m.sceneTypeId == this.sceneType) { + _res.total++; + const times = parseInt(m.extension1); + if (times) { + _res.completedScenes++; + _res.completedTimes += times; + _res.reviewTimes += times - 1; + } } }); return _res; diff --git a/src/views/fysp/evaluation/components/CompDataResultEdit.vue b/src/views/fysp/evaluation/components/CompDataResultEdit.vue index 6463e7d..8cb5a18 100644 --- a/src/views/fysp/evaluation/components/CompDataResultEdit.vue +++ b/src/views/fysp/evaluation/components/CompDataResultEdit.vue @@ -1,27 +1,32 @@ <template> - <el-row align="top"> - <el-upload - ref="upload" - class="upload-file" - :limit="1" - accept=".xls,.xlsx" - :on-change="handleChange" - :on-exceed="handleExceed" - :auto-upload="false" + <el-row align="top" justify="space-between"> + <el-row align="top"> + <el-upload + ref="upload" + class="upload-file" + :limit="1" + accept=".xls,.xlsx" + :on-change="handleChange" + :on-exceed="handleExceed" + :auto-upload="false" + > + <template #trigger> + <el-button type="success" :loading="tableLoading">瀵煎叆鏂囦欢</el-button> + </template> + <template #tip> + <div> + <el-text type="danger">{{ tips }}</el-text> + </div> + </template> + </el-upload> + <div v-if="tableLoading"> + <el-icon class="is-loading"><Loading /></el-icon> + <el-text>{{ loadTxt }}</el-text> + </div> + </el-row> + <el-button type="default" icon="download" @click="downloadTemplate" + >涓嬭浇瀵煎叆妯℃澘</el-button > - <template #trigger> - <el-button type="primary" :loading="tableLoading">瀵煎叆鏂囦欢</el-button> - </template> - <template #tip> - <div> - <el-text type="danger">{{ tips }}</el-text> - </div> - </template> - </el-upload> - <div v-if="tableLoading"> - <el-icon class="is-loading"><Loading /></el-icon> - <el-text>{{ loadTxt }}</el-text> - </div> </el-row> <el-table ref="tableRef" @@ -57,19 +62,49 @@ </template> </el-table-column> <el-table-column + v-if="isUploadNewFile" + :show-overflow-tooltip="true" + prop="sceneIndex" + label="鍞竴缂栧彿" + width="70" + > + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.sceneIndex" + @change="(e) => handleSceneNameChange(e, row)" + /> + <span v-else>{{ row.sceneIndex }}</span> + </template> + </el-table-column> + <el-table-column :show-overflow-tooltip="true" prop="drSceneName" - label="鍚嶇О" - width="300" + label="鍦烘櫙鍚嶇О" > <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" size="small" v-model="row.drSceneName" - @change="(e) => handleSceneNameChange(e, row)" /> <span v-else>{{ row.drSceneName }}</span> + </template> + </el-table-column> + <el-table-column + v-if="isUploadNewFile" + :show-overflow-tooltip="true" + prop="drDeviceCode" + label="璁惧鍚嶇О" + > + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.deviceName" + /> + <span v-else>{{ row.deviceName }}</span> </template> </el-table-column> <el-table-column prop="drDeviceCode" label="璁惧鍙�" width="130"> @@ -82,12 +117,12 @@ <span v-else>{{ row.drDeviceCode }}</span> </template> </el-table-column> - <el-table-column prop="drTime" label="鏃堕棿" width="100"> + <el-table-column prop="drTime" label="鏃堕棿" width="70"> <template #default="{ row }"> <span>{{ $fm.formatYM(row.drTime) }}</span> </template> </el-table-column> - <el-table-column prop="drExceedTimes" label="瓒呮爣娆℃暟"> + <el-table-column prop="drExceedTimes" label="瓒呮爣娆℃暟" width="50"> <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" @@ -97,7 +132,7 @@ <span v-else>{{ row.drExceedTimes }}</span> </template> </el-table-column> - <el-table-column prop="drAvg" label="骞冲潎鍊�"> + <el-table-column prop="drAvg" label="骞冲潎鍊�" width="65"> <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" @@ -107,7 +142,7 @@ <span v-else>{{ row.drAvg }}</span> </template> </el-table-column> - <el-table-column prop="drMax" label="鏈�澶у��"> + <el-table-column prop="drMax" label="鏈�澶у��" width="65"> <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" @@ -117,7 +152,7 @@ <span v-else>{{ row.drMax }}</span> </template> </el-table-column> - <el-table-column prop="drMin" label="鏈�灏忓��"> + <el-table-column prop="drMin" label="鏈�灏忓��" width="65"> <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" @@ -127,7 +162,7 @@ <span v-else>{{ row.drMin }}</span> </template> </el-table-column> - <el-table-column prop="drOverAvgPer" label="瓒呭尯鍧囧�肩櫨鍒嗘瘮"> + <el-table-column prop="drOverAvgPer" label="瓒呭尯鍧囧�肩櫨鍒嗘瘮" width="70"> <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" @@ -137,7 +172,7 @@ <span v-else>{{ row.drOverAvgPer }}</span> </template> </el-table-column> - <el-table-column prop="drDataNum" label="鏁版嵁閲�"> + <el-table-column prop="drDataNum" label="鏁版嵁閲�" width="65"> <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" @@ -147,7 +182,7 @@ <span v-else>{{ row.drDataNum }}</span> </template> </el-table-column> - <el-table-column prop="drEffectiveRate" label="鏈夋晥鐜�"> + <el-table-column prop="drEffectiveRate" label="鏈夋晥鐜�" width="65"> <template #default="{ row }"> <el-input v-if="isUploadNewFile && !row.isFound" @@ -164,7 +199,7 @@ <div v-if="!row.isFound" class="p-h-16"> <div v-if="row.notSure"> <el-text type="warning" size="small" - >鏈壘鍒拌鍦烘櫙锛屼絾鎵惧埌浜嗘湁鐩镐技鍚嶇О鐨勫満鏅紝璇风‘瀹氭槸鍝釜鍦烘櫙</el-text + >鏍规嵁鍞竴缂栧彿鍙婅鏀垮尯鍒掓壘鍒颁簡鐩稿叧鍦烘櫙锛屼絾涓庡凡鏈夊満鏅悕绉颁笉鍖归厤锛岃纭畾鏄摢涓満鏅�</el-text > <div class="m-t-8"> <el-button @@ -174,6 +209,7 @@ text bg size="small" + class="m-b-2" @click="handleRadioChange(v, row)" > {{ v.name }} @@ -193,20 +229,25 @@ </div> <div v-else> <el-text type="danger" size="small" - >鏈壘鍒拌鍦烘櫙锛屼篃娌℃湁浠讳綍鐩镐技鍚嶇О鐨勫満鏅紝璇蜂慨鏀瑰満鏅悕绉版垨鍘婚櫎璇ュ満鏅�</el-text + >鏍规嵁鍞竴缂栧彿鍙婅鏀垮尯鍒掓湭鎵惧埌鐩稿叧鍦烘櫙锛岃淇敼鍞竴缂栧彿</el-text > </div> </div> <div v-else class="p-h-16"> <el-text type="success" size="small"> 宸叉纭尮閰嶅埌璇ュ満鏅� </el-text> + <el-text v-if="row.remark" type="success" size="small"> + {{ '锛�' + row.remark }} + </el-text> </div> </div> </template> </el-table-column> </el-table> <el-button + class="m-t-8" type="primary" :loading="uploadLoading" + :disabled="!isUploadNewFile" icon="upload" @click="uploadFile" >涓婁紶缁熻缁撴灉</el-button @@ -214,10 +255,12 @@ </template> <script setup> import { ref, reactive, watch, onMounted, getCurrentInstance } from 'vue'; +import { useMessageBoxTip, useMessageBox } from '@/composables/messageBox'; import { genFileId } from 'element-plus'; import monitordataApi from '@/api/fysp/monitordataApi'; import sceneApi from '@/api/fysp/sceneApi'; import * as XLSX from 'xlsx'; +import { exportDocx } from '@/utils/doc'; const cns = getCurrentInstance(); const $fm = cns.appContext.config.globalProperties.$fm; @@ -264,6 +307,11 @@ upload.value.handleStart(file); } +/** + * 澶勭悊涓婁紶鏂囦欢瑙f瀽 + * @param uploadFile + * @param uploadFiles + */ function handleChange(uploadFile, uploadFiles) { expandRowKeys.value = []; tableLoading.value = true; @@ -280,10 +328,12 @@ } const worksheet = workbook.Sheets[workbook.SheetNames[0]]; const tableData = XLSX.utils.sheet_to_json(worksheet); - data.value = tableData.map((v, i) => { - return reactive({ + const _data = tableData.map((v, i) => { + return { id: i, - drSceneName: v['鍚嶇О'], + sceneIndex: v['鍞竴缂栧彿'], + drSceneName: v['鍦烘櫙鍚嶇О'], + deviceName: v['璁惧鍚嶇О'], drDeviceCode: v['璁惧鍙�'], drTime: $fm.formatDateFromExcel(v['鏃堕棿'], '-'), drExceedTimes: v['瓒呮爣娆℃暟'], @@ -293,8 +343,9 @@ drOverAvgPer: v['瓒呭尯鍧囧�肩櫨鍒嗘瘮'], drDataNum: v['鏁版嵁閲�'], drEffectiveRate: v['鏈夋晥鐜�'] - }); + }; }); + data.value = combineSameScene(_data); // console.log(tableData); setTimeout(() => { tableLoading.value = false; @@ -307,31 +358,96 @@ fileReader.readAsArrayBuffer(uploadFile.raw); } +/** + * 鍚堝苟鐩稿悓鍦烘櫙鐨勫鍙扮洃娴嬭澶囷紝榛樿鍙栧尯鍧囧�兼渶楂樼殑涓�鍙拌澶� + */ +function combineSameScene(dataList) { + // 鏍规嵁鍦烘櫙鍞竴缂栧彿杩涜鐩稿悓璁惧褰掔被 + const tempMap = new Map(); + dataList.forEach((d) => { + if (!tempMap.has(d.sceneIndex)) { + tempMap.set(d.sceneIndex, []); + } + tempMap.get(d.sceneIndex).push(d); + }); + const res = []; + // 鐩稿悓鍦烘櫙涓嬶紝鍙栧尯鍧囧�兼渶楂樼殑涓�鍙拌澶囦綔涓虹粨鏋� + for (const [k, v] of tempMap) { + v.sort((a, b) => b.drAvg - a.drAvg); + if (v.length > 1) { + v[0].remark = `鏈満鏅叡鏈�${v.length}鍙拌澶囷紝宸茶嚜鍔ㄩ�夋嫨鍖哄潎鍊兼渶楂樼殑涓�鍙颁负缁熻缁撴灉`; + } + res.push(reactive(v[0])); + } + return res; +} + // 鏌ヨ浠庢枃浠朵笂浼犵殑姣忎釜鍦烘櫙鏄惁鑳藉湪绯荤粺涓壘鍒板搴旂殑鍦烘櫙淇℃伅 function searchScene(d) { d.loading = true; - if (!d.drSceneName) { + // 鏍规嵁鍦烘櫙鐨勫敮涓�缂栧彿銆佽鏀垮尯鍒掑拰鍦烘櫙绫诲瀷杩涜鏌ユ壘 + if (!d.sceneIndex) { d.isFound = false; d.loading = false; return Promise; } else { sceneApi - .findScene({ name: d.drSceneName }) + .findScene({ + // name: d.drSceneName, + typeid: props.areaInfo.scensetypeid, + provincecode: props.areaInfo.provincecode, + citycode: props.areaInfo.citycode, + districtcode: props.areaInfo.districtcode, + towncode: props.areaInfo.towncode, + index: d.sceneIndex, + // 绛涢�夋煡璇㈠湪绾跨殑鍦烘櫙 + extension1: '1' + }) .then((res) => { setTimeout(() => { if (res.length > 0) { - const findRes = res.find((v) => v.name == d.drSceneName); - if (findRes) { - d.drSceneId = res[0].guid; - d.isFound = true; + // 1. 鏍规嵁鍦烘櫙鍞竴缂栧彿杩涜鏌ヨ鏃讹紝涓�鑸儏鍐典笅搴旇鍙湁涓�涓敮涓�缁撴灉 + // 2-1. 褰撲笂浼犳枃浠朵腑鍦烘櫙鍚嶇О涓虹┖鐧芥椂锛岃嚜鍔ㄥ尮閰嶆煡璇㈡墍寰楀満鏅� + // 2-2. 褰撲笂浼犳枃浠朵腑鍦烘櫙鍚嶇О涓嶄负绌虹櫧鏃讹紝姣斿涓よ�呯殑鍦烘櫙鍚嶇О锛岃嫢涓嶅悓鍒欒繘琛岃鍛婃彁绀� + if (res.length == 1) { + const findRes = res[0]; + if (!d.drSceneName || d.drSceneName == '') { + d.drSceneId = findRes.guid; + d.drSceneName = findRes.name; + d.isFound = true; + d.notSure = false; + if (d.remark) expandRowKeys.value.push(d.id); + } else { + if (d.drSceneName == findRes.name) { + d.drSceneId = findRes.guid; + d.isFound = true; + d.notSure = false; + } else { + d.isFound = false; + d.notSure = true; + expandRowKeys.value.push(d.id); + } + } } else { d.isFound = false; d.notSure = true; expandRowKeys.value.push(d.id); } d.sourceScene = res; + + // const findRes = res.find((v) => v.name == d.drSceneName); + // if (findRes) { + // d.drSceneId = findRes.guid; + // d.isFound = true; + // } else { + // d.isFound = false; + // d.notSure = true; + // expandRowKeys.value.push(d.id); + // } + // d.sourceScene = res; } else { d.isFound = false; + d.notSure = false; expandRowKeys.value.push(d.id); } d.loading = false; @@ -351,6 +467,7 @@ function handleRadioChange(value, row) { const scene = value; + row.sceneIndex = scene.index; row.drSceneId = scene.guid; row.drSceneName = scene.name; searchScene(row); @@ -358,7 +475,30 @@ // 涓婁紶缁熻缁撴灉鏂囨。 function uploadFile() { - monitordataApi.uploadDustDataResult(data.value).then((res) => {}); + useMessageBoxTip({ + confirmMsg: `鏄惁纭涓婁紶锛焋, + confirmTitle: '涓婁紶', + onConfirm: () => { + uploadLoading.value = true; + return monitordataApi + .uploadDustDataResult(data.value) + .finally(() => (uploadLoading.value = false)); + } + }); +} + +/** + * 涓嬭浇妯℃澘鏂囦欢 + */ +function downloadTemplate() { + const fName = '鎵皹鐩戞祴鏁版嵁鏈堝害缁熻妯℃澘.xlsx'; + const path = `/${fName}`; + const link = document.createElement('a'); + link.href = path; + link.download = fName; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); } onMounted(() => { -- Gitblit v1.9.3