From 10c3c33ad0d62a63288d8f08d4c76634cbf4ce98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=88=E5=85=86=E5=A2=9E?= <你的邮箱@example.com> Date: Mon, 27 Apr 2026 19:11:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=85=A5=E6=B5=81=E7=A8=8B=E8=B5=B0?= =?UTF-8?q?=E9=80=9A=EF=BC=8C=E9=A2=84=E8=A7=88=E5=AF=BC=E5=85=A5=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=92=8C=E8=A7=86=E9=A2=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot --- frontend/.env.development | 1 + frontend/.env.production | 1 + frontend/src/components/BasicSearch/index.vue | 2 + frontend/src/components/BasicTable/index.vue | 23 +- frontend/src/components/gis/GisView.vue | 69 +-- frontend/src/components/gis/map.ol.ts | 1 - .../guoYuSheShiShuJuTianBaoForm.vue | 3 + .../guoYuSheShiShuJuTianBaoSearch.vue | 10 +- .../guoYuSheShiShuJuTianBaoTable.vue | 126 ++++-- .../guoYuSheShiShuJuTianBao/index.vue | 405 +++++++++++++++--- 10 files changed, 493 insertions(+), 148 deletions(-) diff --git a/frontend/.env.development b/frontend/.env.development index f553b27..d81642f 100644 --- a/frontend/.env.development +++ b/frontend/.env.development @@ -6,3 +6,4 @@ NODE_ENV='development' VITE_APP_TITLE = '水电水利建设项目全过程环境管理信息平台' VITE_APP_PORT = 3000 VITE_APP_BASE_API = '/dev-api' +VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125' diff --git a/frontend/.env.production b/frontend/.env.production index afcb741..508d6f8 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -4,3 +4,4 @@ NODE_ENV='production' VITE_APP_TITLE = 'qgc-buji-web' VITE_APP_PORT = 3000 VITE_APP_BASE_API = '/prod-api' +VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125' diff --git a/frontend/src/components/BasicSearch/index.vue b/frontend/src/components/BasicSearch/index.vue index 3b8fb43..a03b9ec 100644 --- a/frontend/src/components/BasicSearch/index.vue +++ b/frontend/src/components/BasicSearch/index.vue @@ -79,6 +79,7 @@ placeholder="请选择" @change="dataDimensionDataChange" show-search + allow-clear :loading="shuJuTianBaoStore.baseLoading" :filter-option="filterOption" style="width: 135px" @@ -97,6 +98,7 @@ placeholder="请选择电站" @change="stcdIdChange" show-search + allow-clear :loading="shuJuTianBaoStore.engLoading" :filter-option="filterOption" style="width: 135px" diff --git a/frontend/src/components/BasicTable/index.vue b/frontend/src/components/BasicTable/index.vue index 82d4cb0..5fc6919 100644 --- a/frontend/src/components/BasicTable/index.vue +++ b/frontend/src/components/BasicTable/index.vue @@ -34,6 +34,7 @@ interface Props { // 默认每页显示数量 defaultPageSize?: number; getCheckboxProps?: (record: any) => any; + transformData?: (res: any) => { records: any[]; total: number }; } const props = withDefaults(defineProps(), { @@ -41,7 +42,8 @@ const props = withDefaults(defineProps(), { rowKey: "id", searchParams: () => ({}), defaultPageSize: 20, - getCheckboxProps: undefined + getCheckboxProps: undefined, + transformData: undefined, }); const emit = defineEmits<{ @@ -101,20 +103,29 @@ const getList = async (filter?: Record) => { // skip: (page.value - 1) * size.value, // take: size.value, }; - console.log(params); const res = await props.listUrl(params); + let records: any[] = []; + let totalCount: number = 0; + + // [!code ++] 核心逻辑:如果父组件传入了 transformData,则使用父组件的逻辑 + if (props.transformData) { + const result = props.transformData(res); + records = result.records || []; + totalCount = result.total || 0; + } else { + // [!code ++] 否则使用默认逻辑 + records = res?.data?.records || res?.data || []; + totalCount = res?.data?.total || res?.total || 0; + } - // 假设后端返回结构为 { data: { records: [], total: 0 } } - // 请根据实际后端接口调整以下取值逻辑 - const records = res?.data?.records || res?.data?.list || res?.data || []; - const totalCount = res?.data?.total || res?.total || 0; tableData.value = records; total.value = totalCount; // 向父组件暴露当前请求参数和结果 emit("data-loaded", params, { records, total: totalCount }); + } catch (error) { console.error("Fetch table data error:", error); tableData.value = []; diff --git a/frontend/src/components/gis/GisView.vue b/frontend/src/components/gis/GisView.vue index b2f4e37..398b8ae 100644 --- a/frontend/src/components/gis/GisView.vue +++ b/frontend/src/components/gis/GisView.vue @@ -56122,41 +56122,42 @@ const fetchPointData = _.debounce(async () => { // } // } // 基础图层 - // mapClass.addBaseDataLayer({ - // id: "customBaseLayer", - // key: "customBaseLayer", - // type: "wmts", - // name: "qgc_sx_gjjdx_arcgistiles_l13", - // urlType: "gisurl", - // url: - // "/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=qgc_qsj_arcgistiles_l13&STYLE=&TILEMATRIX=EPSG:3857_qgc_qsj_arcgistiles_l13:{z}&TILEMATRIXSET=EPSG:3857_qgc_qsj_arcgistiles_l13&FORMAT=image/png&TILECOL={x}&TILEROW={y}", - // url_3d: - // "/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=qgc_sx_gjjdx_arcgistiles_l13&STYLE=&TILEMATRIX=EPSG:3857_qgc_sx_gjjdx_arcgistiles_l13:{z}&TILEMATRIXSET=EPSG:3857_qgc_sx_gjjdx_arcgistiles_l13&FORMAT=image/png&TILECOL={x}&TILEROW={y}", - // matrixIds_index: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"], - // tileMatrixSetID: "EPSG:3857_qgc_sx_gjjdx_arcgistiles_l13", - // }); + mapClass.addBaseDataLayer({ + id: "customBaseLayer", + key: "customBaseLayer", + type: "wmts", + name: "qgc_sx_gjjdx_arcgistiles_l13", + urlType: "gisurl", + url: + "/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=qgc_qsj_arcgistiles_l13&STYLE=&TILEMATRIX=EPSG:3857_qgc_qsj_arcgistiles_l13:{z}&TILEMATRIXSET=EPSG:3857_qgc_qsj_arcgistiles_l13&FORMAT=image/png&TILECOL={x}&TILEROW={y}", + url_3d: + "/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=qgc_sx_gjjdx_arcgistiles_l13&STYLE=&TILEMATRIX=EPSG:3857_qgc_sx_gjjdx_arcgistiles_l13:{z}&TILEMATRIXSET=EPSG:3857_qgc_sx_gjjdx_arcgistiles_l13&FORMAT=image/png&TILECOL={x}&TILEROW={y}", + matrixIds_index: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"], + tileMatrixSetID: "EPSG:3857_qgc_sx_gjjdx_arcgistiles_l13", + }); // setTimeout(() => { - mapClass.addBaseDataLayer({ - "id": "hydropBase", - "key": "hydropBase", - "urlType": "gisurl", - "url": "https://211.99.26.225:18085/geoserver/gwc/service/tms/1.0.0/qgc%3AstationEra1117@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf", - "geojson_url": "https://211.99.26.225:18085/geoserver/qgc/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=qgc:stationEra1117&maxFeatures=50&outputFormat=application/json&token=bearer a9a0f227-1df3-4e68-b380-2eca5bb49bd1", - "url_3d": "https://211.99.26.225:18085/geoserver/qgc/wms", - "_layer": "stationEra1117", - "layers": "qgc:stationEra1117", - "rasteropacity": 0.5, - "visible": true, - "minZoom": 0, - "maxZoom": 20, - "type": "vector", - "layerType": "line", - "paint": { - "line-color": "#C5C6F3", - "line-width": 1, - "line-opacity": 1 - } -}) + // 单个 +// mapClass.addBaseDataLayer({ +// "id": "hydropBase", +// "key": "hydropBase", +// "urlType": "gisurl", +// "url": "https://211.99.26.225:18085/geoserver/gwc/service/tms/1.0.0/qgc%3AstationEra1117@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf", +// "geojson_url": "https://211.99.26.225:18085/geoserver/qgc/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=qgc:stationEra1117&maxFeatures=50&outputFormat=application/json&token=bearer a9a0f227-1df3-4e68-b380-2eca5bb49bd1", +// "url_3d": "https://211.99.26.225:18085/geoserver/qgc/wms", +// "_layer": "stationEra1117", +// "layers": "qgc:stationEra1117", +// "rasteropacity": 0.5, +// "visible": true, +// "minZoom": 0, +// "maxZoom": 20, +// "type": "vector", +// "layerType": "line", +// "paint": { +// "line-color": "#C5C6F3", +// "line-width": 1, +// "line-opacity": 1 +// } +// }) // }, 2000); // 梯级流域图 diff --git a/frontend/src/components/gis/map.ol.ts b/frontend/src/components/gis/map.ol.ts index 4dc6397..00c8e2c 100644 --- a/frontend/src/components/gis/map.ol.ts +++ b/frontend/src/components/gis/map.ol.ts @@ -439,7 +439,6 @@ export class MapOl implements MapInterface { if (layer.key === 'hydropBase') { // this.hydropBaseConfig = layer; } - console.log(this.geoJsonData1) // ✅ 1. 创建矢量源,关键是要配置投影转换 const vectorSource = new VectorSource({ features: new GeoJSON().readFeatures(this.geoJsonData1, { diff --git a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue index f456c8e..df28a5e 100644 --- a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue +++ b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue @@ -25,6 +25,7 @@ placeholder="请选择流域" :disabled="isView" show-search + allowClear :filter-option="filterOption" @change="baseChange" > @@ -47,6 +48,7 @@ placeholder="请选择电站名称" :disabled="isView" show-search + allowClear :filter-option="filterOption" @change="engChange" > @@ -72,6 +74,7 @@ placeholder="请选择过鱼设施" :disabled="isView" show-search + allowClear :filter-option="filterOption" > + + + 下载模板 + + @@ -217,7 +228,8 @@ import { message, Tag } from "ant-design-vue"; import { ExclamationCircleOutlined } from "@ant-design/icons-vue"; import fishSearch from "@/components/fishSearch/index.vue"; import { getBaseDropdown, getEngInfoDropdown, getFpssDropdown } from "@/api/select"; -import dayjs from "dayjs"; +import { CloseCircleOutlined } from "@ant-design/icons-vue"; +import { es } from "element-plus/es/locale/index.mjs"; const props: any = defineProps({ fileTableData: { type: Array, default: () => [] }, @@ -225,7 +237,7 @@ const props: any = defineProps({ direction: { type: Array, default: () => [] }, }); -const emit = defineEmits(["update:fileTableData"]); +const emit = defineEmits(["update:fileTableData", "preview-click"]); // --- 状态管理 --- const editingRowIndex = ref(null); @@ -236,9 +248,27 @@ const rowStates = reactive>({}); const editingData = ref(null); const modalColumns = ref([ - { dataIndex: "baseName", key: "baseName", dataIndexKey: "baseId", title: "流域", width: 140 }, - { dataIndex: "ennm", key: "ennm", dataIndexKey: "rstcd", title: "电站名称", width: 140 }, - { dataIndex: "stnm", key: "stnm", dataIndexKey: "stcd", title: "过鱼设施名称", width: 150 }, + { + dataIndex: "baseName", + key: "baseName", + dataIndexKey: "baseId", + title: "流域", + width: 140, + }, + { + dataIndex: "ennm", + key: "ennm", + dataIndexKey: "rstcd", + title: "电站名称", + width: 140, + }, + { + dataIndex: "stnm", + key: "stnm", + dataIndexKey: "stcd", + title: "过鱼设施名称", + width: 150, + }, { dataIndex: "strdt", key: "strdt", title: "过鱼时间", width: 190 }, { dataIndex: "ftpName", key: "ftpName", title: "鱼种类", width: 120 }, { @@ -258,17 +288,15 @@ const modalColumns = ref([ key: "direction", title: "游向", width: 120, - customRender: ({ text }: any) => { - console.log(props.direction) - return props.direction.find((item: any) => item.itemCode === text)?.dictName || "-" - } + customRender: ({ text }: any) => props.direction.find((item: any) => item.itemCode === text)?.dictName || "-" + , }, { dataIndex: "fcnt", key: "fcnt", title: "过鱼数量(尾)", width: 120 }, { dataIndex: "fsz", key: "fsz", title: "体长(cm)", width: 160 }, { dataIndex: "fwet", key: "fwet", title: "平均体重(g)", width: 160 }, { dataIndex: "wt", key: "wt", title: "水温(℃)", width: 80 }, - { dataIndex: "picpth", key: "level5", title: "图片", width: 100 }, - { dataIndex: "vdpth", key: "level6", title: "视频", width: 100 }, + { dataIndex: "picpth", key: "picpth", title: "图片", width: 160 }, + { dataIndex: "vdpth", key: "vdpth", title: "视频", width: 160 }, { title: "操作", key: "action", @@ -309,12 +337,14 @@ const ensureRowState = (index: number) => { // --- 级联逻辑 (操作 editingData) --- const handleBaseChange = async (baseId: string, index: number) => { - console.log(baseId) + console.log(baseId); editingData.value.baseName = baseOptions.value.find( (item: any) => item.baseid == baseId )?.basename; if (baseId && editingData.value._warnings) { - editingData.value._warnings = editingData.value._warnings.filter((w: string) => w !== 'baseName'); + editingData.value._warnings = editingData.value._warnings.filter( + (w: string) => w !== "baseName" + ); } const state = ensureRowState(index); // 清空后续字段 @@ -338,7 +368,9 @@ const handleBaseChange = async (baseId: string, index: number) => { const handleEngChange = async (rstcd: string, index: number) => { const state = ensureRowState(index); if (rstcd && editingData.value._warnings) { - editingData.value._warnings = editingData.value._warnings.filter((w: string) => w !== 'ennm'); + editingData.value._warnings = editingData.value._warnings.filter( + (w: string) => w !== "ennm" + ); } editingData.value.ennm = state.engOptions.find( (item: any) => item.stcd === rstcd @@ -360,7 +392,9 @@ const handleEngChange = async (rstcd: string, index: number) => { const handleFpssChange = (stcd: string, index: number) => { const state = ensureRowState(index); if (stcd && editingData.value._warnings) { - editingData.value._warnings = editingData.value._warnings.filter((w: string) => w !== 'stnm'); + editingData.value._warnings = editingData.value._warnings.filter( + (w: string) => w !== "stnm" + ); } editingData.value.stnm = state.fpssOptions.find( (item: any) => item.stcd === stcd @@ -483,22 +517,36 @@ const handleFtpChange = (val: any, opt: any) => { editingData.value.ftpName = opt.name; }; -// --- 辅助函数 --- +// --- 辅助函数 --- const filterOption = (input: string, option: any) => { return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0; }; - -// 统一获取显示值 -const getDisplayValue = (dataIndex: string, record: any) => { - const val = record[dataIndex]; - if (val === undefined || val === null) return "-"; - if (dataIndex === "isfs") return val === 1 ? "是" : "否"; - if (dataIndex === "strdt") return val ? dayjs(val).format("YYYY-MM-DD HH:mm:ss") : "-"; - return val; -}; defineExpose({ - editingRowIndex, + editingRowIndex, editingData, }); + diff --git a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/index.vue b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/index.vue index a82424a..6ea2f5e 100644 --- a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/index.vue +++ b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/index.vue @@ -20,7 +20,8 @@ :list-url="getFishDraftPage" :search-params="{}" :enable-row-selection="true" - :get-checkbox-props="getCheckboxProps" + :get-checkbox-props="getCheckboxProps" + :transform-data="customTransform" @selection-change="handleSelectionChange" > @@ -94,18 +95,17 @@ cancel-text="取消导入" :width="1500" v-model:open="visible" - maskClosable="false" + :maskClosable="false" :confirm-loading="fileLoading" > -
-
@@ -155,10 +235,12 @@