From bf42ef43fccdf3d3486eec84ad4073b0c7650aba Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期三, 13 八月 2025 17:35:37 +0800 Subject: [PATCH] 新增场景信息文件导入功能 --- public/现场监管场景信息导入模板.xlsx | 0 src/views/fysp/scene/CompSceneImport.vue | 103 +++++++++++++++++--- src/components/table/FYTable.vue | 2 src/views/fysp/data-product/ProdLawEnforceList.vue | 43 ++------ src/api/index.js | 2 src/components/button/FYDownloadTableButton.vue | 33 ++++++ src/api/fysp/sceneApi.js | 5 + src/components.d.ts | 1 src/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue | 32 ++++- src/components/map/SceneMap.vue | 56 +++++++--- src/utils/excel.js | 2 11 files changed, 203 insertions(+), 76 deletions(-) diff --git "a/public/\347\216\260\345\234\272\347\233\221\347\256\241\345\234\272\346\231\257\344\277\241\346\201\257\345\257\274\345\205\245\346\250\241\346\235\277.xlsx" "b/public/\347\216\260\345\234\272\347\233\221\347\256\241\345\234\272\346\231\257\344\277\241\346\201\257\345\257\274\345\205\245\346\250\241\346\235\277.xlsx" new file mode 100644 index 0000000..af2ebb6 --- /dev/null +++ "b/public/\347\216\260\345\234\272\347\233\221\347\256\241\345\234\272\346\231\257\344\277\241\346\201\257\345\257\274\345\205\245\346\250\241\346\235\277.xlsx" Binary files differ diff --git a/src/api/fysp/sceneApi.js b/src/api/fysp/sceneApi.js index 2d51a0c..82d5f40 100644 --- a/src/api/fysp/sceneApi.js +++ b/src/api/fysp/sceneApi.js @@ -93,5 +93,10 @@ */ findScene(scene) { return $fysp.post('scense/search', scene).then((res) => res.data); + }, + + importScene(file) { + return $fysp.post('scense/import', file).then((res) => res.data); } + }; diff --git a/src/api/index.js b/src/api/index.js index 766ad71..a839aee 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.d.ts b/src/components.d.ts index 3b9ac0b..19bc486 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -86,6 +86,7 @@ FYBgTaskCard: typeof import('./components/bg-task/FYBgTaskCard.vue')['default'] FYBgTaskDialog: typeof import('./components/bg-task/FYBgTaskDialog.vue')['default'] FYBgTaskItem: typeof import('./components/bg-task/FYBgTaskItem.vue')['default'] + FYDownloadTableButton: typeof import('./components/button/FYDownloadTableButton.vue')['default'] FYForm: typeof import('./components/form/FYForm.vue')['default'] FYImageSelectDialog: typeof import('./components/FYImageSelectDialog.vue')['default'] FYInfoSearch: typeof import('./components/search-option/FYInfoSearch.vue')['default'] diff --git a/src/components/button/FYDownloadTableButton.vue b/src/components/button/FYDownloadTableButton.vue new file mode 100644 index 0000000..a5c90f2 --- /dev/null +++ b/src/components/button/FYDownloadTableButton.vue @@ -0,0 +1,33 @@ +<template> + <el-button + icon="Download" + type="primary" + plain + @click="download" + :loading="dlLoading" + >{{ label }}</el-button + > +</template> +<script setup> +import { ref } from 'vue'; +import { conversionFromTable } from '@/utils/excel'; + +const props = defineProps({ + // 涓嬭浇鏂囦欢鍚嶇О + fileName: String, + // 琛ㄦ牸鍏冪礌id + tableId: String, + label: { + type: String, + default: '涓嬭浇' + } +}); + +const dlLoading = ref(false); + +function download() { + dlLoading.value = true; + conversionFromTable(props.tableId, props.fileName); + dlLoading.value = false; +} +</script> diff --git a/src/components/map/SceneMap.vue b/src/components/map/SceneMap.vue index e301ec3..3abe4c6 100644 --- a/src/components/map/SceneMap.vue +++ b/src/components/map/SceneMap.vue @@ -9,12 +9,20 @@ ></FYOptionScene> <slot name="left-top"></slot> </el-row> + <!-- <el-row class="right-wrap"> + <el-col :span="4"> + <el-button>close</el-button> + </el-col> + <el-col :span="20"> + + </el-col> + </el-row> --> <el-scrollbar class="right-wrap"> <div v-for="s in selectedSceneList" :key="s.guid"> <el-checkbox v-model="s._checked" :label="s.name" - @change="handleChange" + @change="handleChange(s)" /> <!-- <el-text>{{ s.name }}</el-text> --> </div> @@ -53,7 +61,7 @@ if (nV != oV) { clearSceneMarks(); createSceneMarks(); - filterMarkViews(); + filterMarkViews(true); } }, { immediate: true } @@ -62,14 +70,20 @@ watch(scenetype, (nV, oV) => { if (nV != oV) { clearSceneMarks(); - filterMarkViews(); + filterMarkViews(true); } }); -function handleChange(value) { - console.log(value); - - filterMarkViews(); +function handleChange(scene) { + const mv = markViewList.find((v) => { + return scene.guid == v.getExtData().guid; + }); + if (scene._checked) { + map.add(mv); + } else { + map.remove(mv); + } + // filterMarkViews(); } function createSceneMarks() { @@ -111,8 +125,11 @@ /** * 绛涢�夋墍閫夌被鍨嬬殑鍦烘櫙 */ -function filterMarkViews() { +function filterMarkViews(setFitView) { onMapMounted(() => { + if (markViewList.length > 0) { + map.remove(markViewList); + } if (scenetype.value == undefined) { markViewList = allMarkViews; } else { @@ -125,21 +142,21 @@ } markViewList = markViewList.filter((v) => { const _index = selectedSceneList.value.findIndex((s) => { - console.log(s.guid, v.getExtData().guid); - - s.guid == v.getExtData().guid; + return s.guid == v.getExtData().guid && s._checked; }); return _index != -1; }); map.add(markViewList); - setTimeout(() => { - map.setFitView(markViewList); - // const list = markViewList.map((v) => { - // const _extData = v.getExtData(); - // return [_extData.longitude, _extData.latitude]; - // }); - // mapUtil.setBound(list); - }, 1000); + if (setFitView) { + setTimeout(() => { + map.setFitView(markViewList); + // const list = markViewList.map((v) => { + // const _extData = v.getExtData(); + // return [_extData.longitude, _extData.latitude]; + // }); + // mapUtil.setBound(list); + }, 1000); + } }); } @@ -166,5 +183,6 @@ border-radius: 4px; padding: 2px 8px; max-width: 300px; + box-shadow: var(--el-box-shadow); } </style> diff --git a/src/components/table/FYTable.vue b/src/components/table/FYTable.vue index 4a5d520..b759ee0 100644 --- a/src/components/table/FYTable.vue +++ b/src/components/table/FYTable.vue @@ -28,7 +28,7 @@ <slot name="options-expand2"></slot> </div> <el-table - id="fyTable" + v-bind="$attrs" ref="tableRef" :data="tableData" v-loading="loading" diff --git a/src/utils/excel.js b/src/utils/excel.js index a42c45f..07a0cc2 100644 --- a/src/utils/excel.js +++ b/src/utils/excel.js @@ -20,7 +20,7 @@ // } // } // } - console.log(tables); + // console.log(tables); //------鏀惧叆浠ヤ笂鎷垮埌switch鐘舵�侊紝浠ュ強涓嬫媺妗嗕唬鐮侊紝濡傛灉娌″厠闅嗗厓绱犲垯浼氬奖鍝嶅埌鍘熻〃鏍�-------------// diff --git a/src/views/fysp/data-product/ProdLawEnforceList.vue b/src/views/fysp/data-product/ProdLawEnforceList.vue index 2dccfb8..940d70d 100644 --- a/src/views/fysp/data-product/ProdLawEnforceList.vue +++ b/src/views/fysp/data-product/ProdLawEnforceList.vue @@ -1,5 +1,6 @@ <template> <FYTable + id="fyTable" @search="onSearch" :data="tableData" :pagination="false" @@ -47,15 +48,12 @@ </el-descriptions> </template> <template #buttons> - <el-button - icon="Download" - type="primary" - plain - @click="download" - :loading="dlLoading" + <FYDownloadTableButton + label="涓嬭浇娓呭崟" + table-id="fyTable" + :file-name="fileName" :disabled="downloadDisabled" - >涓嬭浇娓呭崟</el-button - > + ></FYDownloadTableButton> </template> <template #table-column="{ size }"> <el-table-column fixed="left" label="搴忓彿" width="53"> @@ -160,13 +158,8 @@ import evaluateApi from '@/api/fysp/evaluateApi'; import problemApi from '@/api/fysp/problemApi'; import sceneApi from '@/api/fysp/sceneApi'; -import { conversionFromTable } from "@/utils/excel"; import { envCreditCode } from '@/constants/index'; import { useTablePaste } from '@/composables/tablePaste'; -import { useCloned } from '@vueuse/core'; -import { useMessageBoxTip } from '@/composables/messageBox'; -import * as XLSX from 'xlsx'; -import FileSaver from 'file-saver'; export default { setup() { @@ -239,6 +232,12 @@ }); return b; } + }, + fileName() { + const { locations, scenetype, time } = this.formSearch; + return `${locations.dName}${dayjs(time).format( + 'YYYY骞碝M鏈�' + )}鑱斿悎鎵ф硶娓呭崟`; } }, methods: { @@ -327,24 +326,6 @@ const property = column['property']; return row[property] === value; }, - download() { - // const workbook = XLSX.utils.book_new(); - // const worksheet = XLSX.utils.json_to_sheet(this.tableData); - // XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); - // const excelData = XLSX.write(workbook, { - // bookType: 'xlsx', - // type: 'array' - // }); - // const blob = new Blob([excelData], { - // type: 'application/vnd.openxmlformats-officedocumnet.spreadsheetml.sheet' - // }); - const { locations, scenetype, time } = this.formSearch; - const name = `${locations.dName}${dayjs(time).format( - 'YYYY骞碝M鏈�' - )}鑱斿悎鎵ф硶娓呭崟.xlsx`; - // FileSaver.saveAs(blob, name); - conversionFromTable('fyTable', name) - } }, mounted() { this.addRefreshEvent(this.$refs.tableRef.doLayout); diff --git a/src/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue b/src/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue index 72291e6..b5ee0fe 100644 --- a/src/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue +++ b/src/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue @@ -1,5 +1,6 @@ <template> <FYTable + id="fyTable" @search="onSearch" :data="showData" :pagination="false" @@ -34,7 +35,14 @@ <el-radio :value="2">鎸夐棶棰樼被鍨嬬粺璁�</el-radio> </el-radio-group> </template> - <template #buttons> </template> + <template #buttons> + <FYDownloadTableButton + label="涓嬭浇娓呭崟" + table-id="fyTable" + :file-name="fileName" + :disabled="downloadDisabled" + ></FYDownloadTableButton> + </template> <template #table-column="{ size }"> <!-- <el-table-column fixed="left" label="搴忓彿" width="53"> <template #default="{ row }"> @@ -58,14 +66,9 @@ </el-table-column> <el-table-column prop="townName" label="琛楅晣" width="110"> </el-table-column> - <el-table-column prop="problemType" label="闂绫诲瀷" width="110"> + <el-table-column prop="problemType" label="闂绫诲瀷" width="170"> </el-table-column> - <el-table-column - v-if="radio == 1" - prop="problemName" - label="闂鍚嶇О" - width="200" - > + <el-table-column v-if="radio == 1" prop="problemName" label="闂鍚嶇О"> </el-table-column> <el-table-column prop="proNum" label="闂鏁�" width="70"> </el-table-column> @@ -134,6 +137,19 @@ return res; }); +const fileName = computed(() => { + const { locations, scenetype, timeArr } = formSearch.value; + return `${locations.dName}${dayjs(timeArr[0]).format( + 'YYYY骞碝M鏈圖D鏃�' + )}鑷�${dayjs(timeArr[1]).format('YYYY骞碝M鏈圖D鏃�')}${ + scenetype.label + }闂澶嶅彂娓呭崟`; +}); + +const downloadDisabled = computed(() => { + return tableData.value.length == 0; +}); + function onSearch(page, callback) { fetchProbRecurrence().finally(() => callback()); } diff --git a/src/views/fysp/scene/CompSceneImport.vue b/src/views/fysp/scene/CompSceneImport.vue index bd3bf3e..40f591b 100644 --- a/src/views/fysp/scene/CompSceneImport.vue +++ b/src/views/fysp/scene/CompSceneImport.vue @@ -1,5 +1,7 @@ <template> - <el-button disabled icon="Upload" type="success" @click="dialogVisible = true">鎵归噺瀵煎叆</el-button> + <el-button icon="Upload" type="success" @click="dialogVisible = true" + >鎵归噺瀵煎叆</el-button + > <el-dialog v-model="dialogVisible" title="鍦烘櫙淇℃伅鎵归噺瀵煎叆" @@ -9,31 +11,102 @@ <el-upload class="upload-demo" drag - action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" - multiple + :limit="1" + v-model:file-list="fileList" + :auto-upload="false" accept=".xlsx" + :on-change="handleChange" + :on-exceed="handleExceed" > <el-icon class="el-icon--upload"><upload-filled /></el-icon> <div class="el-upload__text">鎷栧姩鏂囦欢鎴�<em>鐐瑰嚮涓婁紶</em></div> <template #tip> - <!-- <div class="el-upload__tip">jpg/png files with a size less than 500kb</div> --> + <el-text type="danger" size="small">{{ errMsg }}</el-text> </template> </el-upload> <template #footer> - <div class="dialog-footer"> - <el-button @click="dialogVisible = false">鍙栨秷</el-button> - <el-button type="primary" @click="dialogVisible = false">纭畾</el-button> - </div> + <el-row justify="space-between"> + <el-button type="primary" plain @click="downloadTemplate" + >涓嬭浇妯℃澘</el-button + > + <div class="dialog-footer"> + <el-button @click="handleClose">鍙栨秷</el-button> + + <el-button type="primary" @click="uploadFile" :loading="loading" + >纭畾</el-button + > + </div> + </el-row> </template> </el-dialog> </template> -<script> -export default { - data() { - return { - dialogVisible: false - }; +<script setup> +import { ref } from 'vue'; +import sceneApi from '@/api/fysp/sceneApi'; +import { ElMessage } from 'element-plus'; + +const dialogVisible = ref(false); +const fileList = ref([]); +const errMsg = ref(''); +const loading = ref(false); + +function handleChange(file) { + console.log(file); + const ext = file.name.split('.').pop(); + if (ext !== 'xlsx') { + ElMessage.error('璇蜂笂浼燛xcel鏂囦欢'); + fileList.value.splice(0, 1); + return; } -}; + fileList.value = [file]; +} + +function handleExceed(files, fileList) { + ElMessage.error('鏈�澶氬彧鑳戒笂浼犱竴涓枃浠�'); +} + +function uploadFile() { + if (fileList.value.length === 0) { + ElMessage.error('璇蜂笂浼犳枃浠�'); + return; + } + const formData = new FormData(); + loading.value = true; + formData.append('file', fileList.value[0].raw); + errMsg.value = ''; + sceneApi + .importScene(formData) + .then((res) => { + dialogVisible.value = false; + fileList.value = []; + }) + .catch((err) => { + errMsg.value = err; + }) + .finally(() => { + loading.value = false; + }); +} + +function downloadTemplate() { + // 鍒涘缓涓嬭浇閾炬帴 + const link = document.createElement('a'); + // 璁剧疆public鐩綍涓嬬殑鏂囦欢璺緞 + link.href = '/鐜板満鐩戠鍦烘櫙淇℃伅瀵煎叆妯℃澘.xlsx'; + // 璁剧疆涓嬭浇鏂囦欢鍚� + link.download = '鐜板満鐩戠鍦烘櫙淇℃伅瀵煎叆妯℃澘.xlsx'; + // 灏嗛摼鎺ユ坊鍔犲埌椤甸潰 + document.body.appendChild(link); + // 瑙﹀彂鐐瑰嚮涓嬭浇 + link.click(); + // 涓嬭浇瀹屾垚鍚庣Щ闄ら摼鎺� + document.body.removeChild(link); +} + +function handleClose() { + dialogVisible.value = false; + fileList.value = []; + errMsg.value = ''; +} </script> -- Gitblit v1.9.3