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