From cca8d423c4805665bbd48a47e4d9218b16d14ebb Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期五, 28 三月 2025 17:42:35 +0800 Subject: [PATCH] 新增自动评估监测数据上传功能(待完成) --- src/api/fysp/sceneApi.js | 19 ++ src/views/fysp/evaluation/components/CompDataResultEdit.vue | 335 +++++++++++++++++++++++++++++++++++++++++++++-- src/utils/time-util.js | 46 ++++-- 3 files changed, 366 insertions(+), 34 deletions(-) diff --git a/src/api/fysp/sceneApi.js b/src/api/fysp/sceneApi.js index a5159c3..2d51a0c 100644 --- a/src/api/fysp/sceneApi.js +++ b/src/api/fysp/sceneApi.js @@ -35,21 +35,27 @@ subScene: subScene ? JSON.stringify(subScene) : null, sceneDevice: sceneDevice ? sceneDevice : null }; - return $fysp.post(`scense/detail/update?${params}`, rb).then((res) => res.data); + return $fysp + .post(`scense/detail/update?${params}`, rb) + .then((res) => res.data); }, /** * 鏇存柊鍦烘櫙棰濆淇℃伅 */ updateSubScene(typeId, subScene) { - return this.updateSceneDetail(typeId, { subScene: subScene }).then((res) => res.data); + return this.updateSceneDetail(typeId, { subScene: subScene }).then( + (res) => res.data + ); }, /** * 鏇存柊鍦烘櫙璁惧淇℃伅 */ updateSceneDevice(typeId, sceneDevice) { - return this.updateSceneDetail(typeId, { sceneDevice: sceneDevice }).then((res) => res.data); + return this.updateSceneDetail(typeId, { sceneDevice: sceneDevice }).then( + (res) => res.data + ); }, /** @@ -80,5 +86,12 @@ */ getAllScene() { return $fysp.get('scense/alltype').then((res) => res.data); + }, + + /** + * 鏌ユ壘鍦烘櫙 + */ + findScene(scene) { + return $fysp.post('scense/search', scene).then((res) => res.data); } }; diff --git a/src/utils/time-util.js b/src/utils/time-util.js index 951116b..dec4073 100644 --- a/src/utils/time-util.js +++ b/src/utils/time-util.js @@ -1,39 +1,55 @@ -import dayjs from "dayjs"; +import dayjs from 'dayjs'; export default { format(date, template) { - return dayjs(date).format(template) + return dayjs(date).format(template); }, - formatH(date){ + formatH(date) { if (date) { - return this.format(date, 'HH:mm:ss') + return this.format(date, 'HH:mm:ss'); } else { - return '--:--:--' + return '--:--:--'; } }, - formatYM(date){ + formatYM(date) { if (date) { - return this.format(date, 'YYYY-MM') + return this.format(date, 'YYYY-MM'); } else { - return '----/--' + return '----/--'; } }, - formatYMD(date){ + formatYMD(date) { if (date) { - return this.format(date, 'YYYY-MM-DD') + return this.format(date, 'YYYY-MM-DD'); } else { - return '----/--/--' + return '----/--/--'; } }, - formatYMDH(date){ + formatYMDH(date) { if (date) { - return this.format(date, 'YYYY-MM-DD HH:mm:ss') + return this.format(date, 'YYYY-MM-DD HH:mm:ss'); } else { - return '----/--/-- --:--:--' + return '----/--/-- --:--:--'; } }, -} \ No newline at end of file + + formatDateFromExcel(num, format) { + const old = num - 1; + const t = Math.round((old - Math.floor(old)) * 24 * 60 * 60); + const time = new Date(1900, 0, old, 0, 0, t); + const year = time.getFullYear(); + const month = time.getMonth() + 1; + const date = time.getDate(); + return ( + year + + format + + (month < 10 ? '0' + month : month) + + format + + (date < 10 ? '0' + date : date) + ); + } +}; diff --git a/src/views/fysp/evaluation/components/CompDataResultEdit.vue b/src/views/fysp/evaluation/components/CompDataResultEdit.vue index 8837f56..fbfaf1c 100644 --- a/src/views/fysp/evaluation/components/CompDataResultEdit.vue +++ b/src/views/fysp/evaluation/components/CompDataResultEdit.vue @@ -4,61 +4,245 @@ ref="upload" class="upload-file" :limit="1" + accept=".xls,.xlsx" :on-change="handleChange" :on-exceed="handleExceed" :auto-upload="false" > <template #trigger> - <el-button type="primary">涓婁紶鐩戞祴鏁版嵁缁熻缁撴灉</el-button> + <el-button type="primary" :loading="tableLoading" + >涓婁紶鐩戞祴鏁版嵁缁熻缁撴灉</el-button + > + </template> + <template #tip> + <div> + <el-text type="danger">{{ tips }}</el-text> + </div> </template> </el-upload> - <el-text>{{ loadTxt }}</el-text> + <div v-if="tableLoading"> + <el-icon class="is-loading"><Loading /></el-icon> + <el-text>{{ loadTxt }}</el-text> + </div> </el-row> <el-table ref="tableRef" :data="data" - v-loading="loading" + v-loading="tableLoading" table-layout="fixed" - :stripe="true" + row-key="id" + :expand-row-keys="expandRowKeys" + :row-class-name="tableRowClassName" size="small" height="60vh" border > + <!-- <el-table-column type="expand"> + <template #default="{ row }"> + {{ row.drSceneName }} + </template> + </el-table-column> --> + <el-table-column + v-if="isUploadNewFile" + prop="isFound" + label="鍚堣" + width="30" + > + <template #default="{ row }"> + <el-icon class="is-loading" v-if="row.loading"> + <Loading color="#409eff" /> + </el-icon> + <el-icon v-else> + <Check v-if="row.isFound" /> + <Close v-else /> + </el-icon> + </template> + </el-table-column> <el-table-column :show-overflow-tooltip="true" prop="drSceneName" label="鍚嶇О" width="300" - /> - <el-table-column prop="drDeviceCode" label="璁惧鍙�" width="130" /> + > + <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 prop="drDeviceCode" label="璁惧鍙�" width="130"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drDeviceCode" + /> + <span v-else>{{ row.drDeviceCode }}</span> + </template> + </el-table-column> <el-table-column prop="drTime" label="鏃堕棿" width="100"> <template #default="{ row }"> <span>{{ $fm.formatYMD(row.drTime) }}</span> </template> </el-table-column> - <el-table-column prop="drExceedTimes" label="瓒呮爣娆℃暟" /> - <el-table-column prop="drAvg" label="骞冲潎鍊�" /> - <el-table-column prop="drMax" label="鏈�澶у��" /> - <el-table-column prop="drMin" label="鏈�灏忓��" /> - <el-table-column prop="drOverAvgPer" label="瓒呭尯鍧囧�肩櫨鍒嗘瘮" /> - <el-table-column prop="drDataNum" label="鏁版嵁閲�" /> - <el-table-column prop="drEffectiveRate" label="鏈夋晥鐜�" /> + <el-table-column prop="drExceedTimes" label="瓒呮爣娆℃暟"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drExceedTimes" + /> + <span v-else>{{ row.drExceedTimes }}</span> + </template> + </el-table-column> + <el-table-column prop="drAvg" label="骞冲潎鍊�"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drAvg" + /> + <span v-else>{{ row.drAvg }}</span> + </template> + </el-table-column> + <el-table-column prop="drMax" label="鏈�澶у��"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drMax" + /> + <span v-else>{{ row.drMax }}</span> + </template> + </el-table-column> + <el-table-column prop="drMin" label="鏈�灏忓��"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drMin" + /> + <span v-else>{{ row.drMin }}</span> + </template> + </el-table-column> + <el-table-column prop="drOverAvgPer" label="瓒呭尯鍧囧�肩櫨鍒嗘瘮"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drOverAvgPer" + /> + <span v-else>{{ row.drOverAvgPer }}</span> + </template> + </el-table-column> + <el-table-column prop="drDataNum" label="鏁版嵁閲�"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drDataNum" + /> + <span v-else>{{ row.drDataNum }}</span> + </template> + </el-table-column> + <el-table-column prop="drEffectiveRate" label="鏈夋晥鐜�"> + <template #default="{ row }"> + <el-input + v-if="isUploadNewFile && !row.isFound" + size="small" + v-model="row.drEffectiveRate" + placeholder="鍦烘櫙鍚嶇О" + /> + <span v-else>{{ row.drEffectiveRate }}</span> + </template> + </el-table-column> + <el-table-column v-if="isUploadNewFile" type="expand"> + <template #default="{ row }"> + <div class="p-v-4"> + <div v-if="!row.isFound" class="p-h-16"> + <div v-if="row.notSure"> + <el-text type="warning" size="small" + >鏈壘鍒拌鍦烘櫙锛屼絾鎵惧埌浜嗘湁鐩镐技鍚嶇О鐨勫満鏅紝璇风‘瀹氭槸鍝釜鍦烘櫙</el-text + > + <div class="m-t-8"> + <el-button + v-for="(v, i) in row.sourceScene" + :key="v.guid" + type="primary" + text + bg + size="small" + @click="handleRadioChange(v, row)" + > + {{ v.name }} + </el-button> + <!-- <el-radio-group v-model="row.radioValue"> + <el-radio + v-for="(v, i) in row.sourceScene" + :key="v.guid" + :value="i" + size="small" + border + @change="handleRadioChange(v, row)" + >{{ v.name }}</el-radio + > + </el-radio-group> --> + </div> + </div> + <div v-else> + <el-text type="danger" size="small" + >鏈壘鍒拌鍦烘櫙锛屼篃娌℃湁浠讳綍鐩镐技鍚嶇О鐨勫満鏅紝璇蜂慨鏀瑰満鏅悕绉版垨鍘婚櫎璇ュ満鏅�</el-text + > + </div> + </div> + <div v-else class="p-h-16"> + <el-text type="success" size="small"> 宸叉纭尮閰嶅埌璇ュ満鏅� </el-text> + </div> + </div> + </template> + </el-table-column> </el-table> </template> <script setup> -import { ref, watch, onMounted } from 'vue'; +import { ref, reactive, watch, onMounted, getCurrentInstance } from 'vue'; import { genFileId } from 'element-plus'; import monitordataApi from '@/api/fysp/monitordataApi'; +import sceneApi from '@/api/fysp/sceneApi'; import * as XLSX from 'xlsx'; + +const cns = getCurrentInstance(); +const $fm = cns.appContext.config.globalProperties.$fm; const props = defineProps({ areaInfo: { type: Object } }); let workbook; +const isUploadNewFile = ref(false); const data = ref([]); +const expandRowKeys = ref([]); const upload = ref(); +const tableLoading = ref(false); const loadTxt = ref(''); +const tips = ref(''); + +const tableRowClassName = ({ row, rowIndex }) => { + if (row.loading) { + return 'loading-row'; + } else if (row.isFound == undefined) { + return ''; + } else { + return row.isFound + ? 'success-row' + : row.notSure + ? 'warning-row' + : 'danger-row'; + } +}; // 鑾峰彇鍘嗗彶缁熻缁撴灉 function fetchDustDataResult() { @@ -75,14 +259,95 @@ } function handleChange(uploadFile, uploadFiles) { + expandRowKeys.value = []; + tableLoading.value = true; + loadTxt.value = '鏂囦欢瑙f瀽涓�...'; // console.log(uploadFile, uploadFiles); const fileReader = new FileReader(); fileReader.onload = (file) => { - const data = file.target.result; - workbook = XLSX.read(data, { type: 'array' }); + const fileData = file.target.result; + workbook = XLSX.read(fileData, { type: 'array' }); console.log(workbook.SheetNames); + if (workbook.SheetNames.length == 0) { + tips.value = 'excel鏂囦欢閿欒锛屾病鏈塻heet琛ㄥ崟'; + return; + } + const worksheet = workbook.Sheets[workbook.SheetNames[0]]; + const tableData = XLSX.utils.sheet_to_json(worksheet); + data.value = tableData.map((v, i) => { + return reactive({ + id: i, + drSceneName: v['鍚嶇О'], + drDeviceCode: v['璁惧鍙�'], + drTime: $fm.formatDateFromExcel(v['鏃堕棿'], '-'), + drExceedTimes: v['瓒呮爣娆℃暟'], + drAvg: v['骞冲潎鍊�'], + drMax: v['鏈�澶у��'], + drMin: v['鏈�灏忓��'], + drOverAvgPer: v['瓒呭尯鍧囧�肩櫨鍒嗘瘮'], + drDataNum: v['鏁版嵁閲�'], + drEffectiveRate: v['鏈夋晥鐜�'] + }); + }); + // console.log(tableData); + setTimeout(() => { + tableLoading.value = false; + isUploadNewFile.value = true; + data.value.forEach((d) => { + searchScene(d); + }); + }, 1000); }; fileReader.readAsArrayBuffer(uploadFile.raw); +} + +// 鏌ヨ浠庢枃浠朵笂浼犵殑姣忎釜鍦烘櫙鏄惁鑳藉湪绯荤粺涓壘鍒板搴旂殑鍦烘櫙淇℃伅 +function searchScene(d) { + d.loading = true; + if (!d.drSceneName) { + d.isFound = false; + d.loading = false; + return Promise; + } else { + sceneApi + .findScene({ name: d.drSceneName }) + .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; + } else { + d.isFound = false; + d.notSure = true; + expandRowKeys.value.push(d.id); + } + d.sourceScene = res; + } else { + d.isFound = false; + expandRowKeys.value.push(d.id); + } + d.loading = false; + }, 1000); + }) + .finally(() => { + setTimeout(() => { + d.loading = false; + }, 1000); + }); + } +} + +function handleSceneNameChange(newName, row) { + searchScene(row); +} + +function handleRadioChange(value, row) { + const scene = value; + row.drSceneId = scene.guid; + row.drSceneName = scene.name; + searchScene(row); } // 涓婁紶缁熻缁撴灉鏂囨。 @@ -102,4 +367,42 @@ :deep(.el-text) { align-self: auto; } + +:deep(.el-table__expanded-cell) { + padding: 0; + /* background-color: var(--el-bg-color-page); */ +} + +/* :deep(.el-table__body tr>td.hover-cell) { + background-color: red !important; +} */ +/* .el-table--enable-row-hover + .el-table__body + tr:hover + > td + :deep(.el-table__cell) { + background-color: red !important; +} */ +</style> +<style> +.el-table .warning-row { + --el-table-tr-bg-color: var(--el-color-warning-light-5); +} +.el-table .success-row { + --el-table-tr-bg-color: var(--el-color-success-light-7); +} +.el-table .danger-row { + --el-table-tr-bg-color: var(--el-color-danger-light-5); +} +.el-table .loading-row { + color: var(--el-text-color-disabled); + /* --el-table-tr-bg-color: var(--el-text-color-placeholder); */ + --el-table-tr-bg-color: var(--el-bg-color); +} +/* .el-table__body tr>td.hover-cell { + background-color: red !important; +} */ +/* .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell { + background-color: unset; +} */ </style> -- Gitblit v1.9.3