数据管理优化,自定义筛选列功能添加

This commit is contained in:
王兴凯 2026-07-22 17:44:58 +08:00
commit 22c00106c1
29 changed files with 2008 additions and 1593 deletions

View File

@ -1,5 +1,23 @@
import request from '@/utils/request';
// 自定义列配置
export function getUserColumnData(data) {
return request({
url: '/sys/usercolumn/getUserColumnData',
method: 'post',
data: data
});
}
// 批量保存自定义列配置
export function batchSaveUserColumn(data) {
return request({
url: '/sys/usercolumn/batchSave',
method: 'post',
data: data
});
}
// 基础信息 集团/公司
export function getCompanyList(data) {
return request({
@ -1037,3 +1055,36 @@ export function deleteVaInfo(data) {
data
});
}
// 鱼类字典 - 新增
export function addFishDictoryInfo(data) {
return request({
url: '/env/fishDictory/add',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
},
data
});
}
// 鱼类字典 - 编辑
export function updateFishDictoryInfo(data) {
return request({
url: '/env/fishDictory/update',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
},
data
});
}
// 鱼类字典 - 删除
export function deleteFishDictoryInfo(data) {
return request({
url: '/env/fishDictory/delete',
method: 'post',
data
});
}

View File

@ -58,7 +58,6 @@
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { BasicColumns } from '@/components/MapModal/column.config';
interface ColumnItem {
name: string;
@ -71,8 +70,18 @@ interface ColumnGroup {
children: ColumnItem[];
}
export interface UserColumnItem {
columnEn: string;
columnName: string;
checked: number;
groupType: string;
orderIndex: number;
defaultConfig: boolean;
}
interface Props {
visible: boolean;
userColumnList: UserColumnItem[];
}
const props = defineProps<Props>();
@ -85,49 +94,50 @@ const emit = defineEmits<{
const groupedColumns = ref<ColumnGroup[]>([]);
const tempSelectedKeys = ref<string[]>([]);
// BasicColumns
// filed
const STATION_NAME_FILED = 'stnm';
// API userColumnList
const buildGroupedColumns = () => {
const groups: ColumnGroup[] = [];
let currentGroup: ColumnGroup | null = null;
const groupMap = new Map<string, ColumnItem[]>();
for (const col of BasicColumns) {
if (!col.name && !col.filed) continue;
// defaultConfig: true
const filteredList = props.userColumnList.filter(item => item.defaultConfig !== true);
if (col.visible === false && col.name) {
currentGroup = {
name: col.name,
children: []
};
groups.push(currentGroup);
} else if (col.name && col.filed) {
if (!currentGroup) {
currentGroup = {
name: '基础信息',
children: []
};
groups.push(currentGroup);
}
const isStationName = col.filed === 'ennm';
currentGroup.children.push({
name: col.name,
filed: col.filed,
disabled: isStationName
});
// groupType
for (const item of filteredList) {
if (!item.groupType) continue;
if (!groupMap.has(item.groupType)) {
groupMap.set(item.groupType, []);
}
const isStationName = item.columnEn === STATION_NAME_FILED;
groupMap.get(item.groupType)!.push({
name: item.columnName,
filed: item.columnEn,
disabled: isStationName
});
}
//
for (const [groupName, children] of groupMap.entries()) {
groups.push({ name: groupName, children });
}
return groups;
};
// filed
const STATION_NAME_FILED = 'ennm';
// +
// API checked
const initSelectedKeys = () => {
const allKeys: string[] = [STATION_NAME_FILED];
for (const group of groupedColumns.value) {
for (const child of group.children) {
if (!child.disabled && child.filed !== STATION_NAME_FILED) {
if (child.disabled) continue;
// userColumnList checked
const apiItem = props.userColumnList.find(
item => item.columnEn === child.filed
);
if (apiItem && apiItem.checked === 1) {
allKeys.push(child.filed);
}
}
@ -225,6 +235,17 @@ watch(
}
}
);
// userColumnList
watch(
() => props.userColumnList,
() => {
if (props.visible) {
groupedColumns.value = buildGroupedColumns();
initSelectedKeys();
}
}
);
</script>
<style lang="scss" scoped>

View File

@ -17,6 +17,7 @@
<!-- 表格组件 -->
<BasicTable
v-if="columnLoaded"
ref="tableRef"
:enableEllipsis="true"
:scrollX="tableScrollX"
@ -50,7 +51,9 @@
<!-- 自定义数据列 Modal -->
<CustomColumnModal
v-if="columnLoaded"
v-model:visible="customColumnVisible"
:user-column-list="userColumnList"
@confirm="handleColumnConfirm"
/>
@ -81,14 +84,18 @@ import {
getPowerTableList,
addPowerInfo,
updatePowerInfo,
deletePowerInfo
deletePowerInfo,
getUserColumnData,
batchSaveUserColumn
} from '@/api/DataQueryMenuModule';
import { getEngInfoById } from '@/api/select';
import { calcTableScrollY } from '@/utils/index';
import { useModelStore } from '@/store/modules/model';
import { BasicColumns } from '@/components/MapModal/column.config';
import { useUserStore } from "@/store/modules/user";
const modelStore = useModelStore();
const userStore = useUserStore();
const sort = ref<any>([
{
@ -115,6 +122,8 @@ const tableScrollY = ref<string | number>(0);
const currentSearchParams = ref<any>({});
const exportLoading = ref(false);
const customColumnVisible = ref(false);
const userColumnList = ref<any[]>([]);
const columnLoaded = ref(false);
//
const editVisible = ref(false);
@ -135,695 +144,103 @@ const dvtpList = ref<any[]>([
{ label: '引水式', value: '1' },
{ label: '混合式', value: '2' }
]);
const columns = ref<any[]>([
{
key: 'stnm',
title: '电站名称',
dataIndex: 'stnm',
visible: true,
width: 150,
fixed: 'left',
sort: true,
ellipsis: true
},
{
key: 'addvcdName',
title: '所在地址',
dataIndex: 'addvcdName',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'stlc',
title: '详细地址',
dataIndex: 'stlc',
visible: true,
width: 200,
sort: true,
ellipsis: true
},
{
key: 'baseName',
title: '基地',
dataIndex: 'baseName',
visible: true,
width: 120,
ellipsis: true
},
{
key: 'reachcdName',
title: '所在河流',
dataIndex: 'reachcdName',
visible: true,
width: 300,
ellipsis: true
},
{
key: 'jcdt',
title: '建设时间',
dataIndex: 'jcdt',
visible: true,
width: 120,
sort: true,
ellipsis: true,
customRender: ({ text }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
}
},
{
key: 'piodt',
title: '第一台机组投产时间',
dataIndex: 'piodt',
visible: true,
width: 160,
sort: true,
ellipsis: true,
customRender: ({ text }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
}
},
{
key: 'aiodt',
title: '全部机组投产时间',
dataIndex: 'aiodt',
visible: true,
width: 150,
sort: true,
ellipsis: true,
customRender: ({ text }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
}
},
{
key: 'bldsttCcodeName',
title: '建设状态',
dataIndex: 'bldsttCcodeName',
visible: false,
width: 100,
sort: true,
ellipsis: true
},
{
key: 'hynm',
title: '所属公司',
dataIndex: 'hynm',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'topHynm',
title: '所属集团',
dataIndex: 'topHynm',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'nrupar',
title: '坝址以上流域面积(km²)',
dataIndex: 'nrupar',
visible: true,
width: 180,
sort: true
},
{
key: 'dstcrvr',
title: '距河源距离(km)',
dataIndex: 'dstcrvr',
visible: true,
width: 150,
sort: true
},
{
key: 'avyrp',
title: '多年平均降雨量(mm)',
dataIndex: 'avyrp',
visible: true,
width: 170,
sort: true
},
{
key: 'avw',
title: '多年平均年径流量(亿m³)',
dataIndex: 'avw',
visible: true,
width: 190,
sort: true
},
{
key: 'avq',
title: '多年平均流量(m³/s)',
dataIndex: 'avq',
visible: true,
width: 160,
sort: true
},
{
key: 'avq01',
title: '1月多年平均流量(m³/s)',
dataIndex: 'avq01',
visible: true,
width: 180,
sort: true
},
{
key: 'avq02',
title: '2月多年平均流量(m³/s)',
dataIndex: 'avq02',
visible: true,
width: 180,
sort: true
},
{
key: 'avq03',
title: '3月多年平均流量(m³/s)',
dataIndex: 'avq03',
visible: true,
width: 180,
sort: true
},
{
key: 'avq04',
title: '4月多年平均流量(m³/s)',
dataIndex: 'avq04',
visible: true,
width: 180,
sort: true
},
{
key: 'avq05',
title: '5月多年平均流量(m³/s)',
dataIndex: 'avq05',
visible: true,
width: 180,
sort: true
},
{
key: 'avq06',
title: '6月多年平均流量(m³/s)',
dataIndex: 'avq06',
visible: true,
width: 180,
sort: true
},
{
key: 'avq07',
title: '7月多年平均流量(m³/s)',
dataIndex: 'avq07',
visible: true,
width: 180,
sort: true
},
{
key: 'avq08',
title: '8月多年平均流量(m³/s)',
dataIndex: 'avq08',
visible: true,
width: 180,
sort: true
},
{
key: 'avq09',
title: '9月多年平均流量(m³/s)',
dataIndex: 'avq09',
visible: true,
width: 180,
sort: true
},
{
key: 'avq10',
title: '10月多年平均流量(m³/s)',
dataIndex: 'avq10',
visible: true,
width: 190,
sort: true
},
{
key: 'avq11',
title: '11月多年平均流量(m³/s)',
dataIndex: 'avq11',
visible: true,
width: 190,
sort: true
},
{
key: 'avq12',
title: '12月多年平均流量(m³/s)',
dataIndex: 'avq12',
visible: true,
width: 190,
sort: true
},
{
key: 'obmxq',
title: '实测最大流量(m³/s)',
dataIndex: 'obmxq',
visible: true,
width: 170,
sort: true
},
{
key: 'obmnq',
title: '实测最小流量(m³/s)',
dataIndex: 'obmnq',
visible: true,
width: 170,
sort: true
},
{
key: 'hmxq',
title: '调查历史最大流量(m³/s)',
dataIndex: 'hmxq',
visible: true,
width: 190,
sort: true
},
{
key: 'dsnfqfrq',
title: '设计入库洪水流量(m³/s)',
dataIndex: 'dsnfqfrq',
visible: true,
width: 190,
sort: true
},
{
key: 'dsrcin',
title: '设计洪水重现期(年)',
dataIndex: 'dsrcin',
visible: true,
width: 160,
sort: true
},
{
key: 'ckfqfqr',
title: '校核入库洪水流量(m³/s)',
dataIndex: 'ckfqfqr',
visible: true,
width: 190,
sort: true
},
{
key: 'chrcin',
title: '校核洪水重现期(年)',
dataIndex: 'chrcin',
visible: true,
width: 160,
sort: true
},
{
key: 'obmxw3',
title: '实测最大洪量(三天)(亿m³)',
dataIndex: 'obmxw3',
visible: true,
width: 220,
sort: true
},
{
key: 'dsw3',
title: '设计洪量(三天)(亿m³)',
dataIndex: 'dsw3',
visible: true,
width: 190,
sort: true
},
{
key: 'ckw3',
title: '校核洪量(三天)(亿m³)',
dataIndex: 'ckw3',
visible: true,
width: 190,
sort: true
},
{
key: 'avsd',
title: '多年平均输沙量(万t)',
dataIndex: 'avsd',
visible: true,
width: 180
},
{
key: 'avs',
title: '多年平均含沙量(kg/m³)',
dataIndex: 'avs',
visible: true,
width: 180,
sort: true
},
{
key: 'obmxs',
title: '实测最大含沙量(kg/m³)',
dataIndex: 'obmxs',
visible: true,
width: 180,
sort: true
},
{
key: 'ckflz',
title: '校核洪水位(m)',
dataIndex: 'ckflz',
visible: true,
width: 140,
sort: true
},
{
key: 'dsflz',
title: '设计洪水位(m)',
dataIndex: 'dsflz',
visible: true,
width: 140,
sort: true
},
{
key: 'normz',
title: '正常蓄水位(m)',
dataIndex: 'normz',
visible: true,
width: 140,
sort: true
},
{
key: 'uzfc',
title: '防洪高水位(m)',
dataIndex: 'uzfc',
visible: true,
width: 140,
sort: true
},
{
key: 'fsltdz',
title: '防洪限制水位(m)',
dataIndex: 'fsltdz',
visible: true,
width: 150,
sort: true
},
{
key: 'ydownz',
title: '年消落水位(m)',
dataIndex: 'ydownz',
visible: true,
width: 140,
sort: true
},
{
key: 'ddz',
title: '死水位(m)',
dataIndex: 'ddz',
visible: true,
width: 120,
sort: true
},
{
key: 'nrzar',
title: '正常蓄水位水库面积(km²)',
dataIndex: 'nrzar',
visible: true,
width: 200,
sort: true
},
{
key: 'bcklen',
title: '回水长度(km)',
dataIndex: 'bcklen',
visible: true,
width: 130,
sort: true
},
{
key: 'ttcp',
title: '总库容(亿m³)',
dataIndex: 'ttcp',
visible: true,
width: 130,
sort: true
},
{
key: 'nmzcp',
title: '正常蓄水位以下库容(亿m³)',
dataIndex: 'nmzcp',
visible: true,
width: 200,
sort: true
},
{
key: 'fldcpStr',
title: '防洪库容(亿m³)',
dataIndex: 'fldcpStr',
visible: true,
width: 140,
sort: true
},
{
key: 'actcp',
title: '调节库容(亿m³)',
dataIndex: 'actcp',
visible: true,
width: 140,
sort: true
},
{
key: 'ddcp',
title: '死库容(亿m³)',
dataIndex: 'ddcp',
visible: true,
width: 130,
sort: true
},
{
key: 'cpsc',
title: '库容系数(%)',
dataIndex: 'cpsc',
visible: true,
width: 120,
sort: true
},
{
key: 'rgcpName',
title: '调节性能',
dataIndex: 'rgcpName',
visible: true,
width: 120,
sort: true,
ellipsis: true
},
{
key: 'dsflzmxq',
title: '设计洪水位时最大下泄流量(m³/s)',
dataIndex: 'dsflzmxq',
visible: true,
width: 250,
sort: true
},
{
key: 'dsflzxyz',
title: '设计洪水位时最大下泄流量相应下游水位(m)',
dataIndex: 'dsflzxyz',
visible: true,
width: 320,
sort: true
},
{
key: 'ckflzmxq',
title: '校核洪水位时最大下泄流量(m³/s)',
dataIndex: 'ckflzmxq',
visible: true,
width: 250,
sort: true
},
{
key: 'ckflzxyz',
title: '校核洪水位时最大下泄流量相应下游水位(m)',
dataIndex: 'ckflzxyz',
visible: true,
width: 320,
sort: true
},
{
key: 'ksqadjq',
title: '枯水期调节流量(m³/s)',
dataIndex: 'ksqadjq',
visible: true,
width: 170,
sort: true
},
{
key: 'ksqxyz',
title: '枯水期调节流量相应下游水位(m)',
dataIndex: 'ksqxyz',
visible: true,
width: 250,
sort: true
},
{
key: 'gemaxrq',
title: '发电最大引用流量(m³/s)',
dataIndex: 'gemaxrq',
visible: true,
width: 190,
sort: true
},
{
key: 'mxgeqxyz',
title: '发电最大引用流量相应下游水位(m)',
dataIndex: 'mxgeqxyz',
visible: true,
width: 260,
sort: true
},
{
key: 'ttpwr',
title: '装机容量',
dataIndex: 'ttpwr',
visible: true,
width: 120,
sort: true,
ellipsis: true
},
{
key: 'gncnt',
title: '装机台数(台)',
dataIndex: 'gncnt',
visible: true,
width: 130,
sort: true,
ellipsis: true
},
{
key: 'gntp',
title: '容量构成(台*MW)',
dataIndex: 'gntp',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'grntpwr',
title: '保证出力(MW)',
dataIndex: 'grntpwr',
visible: true,
width: 130,
sort: true,
ellipsis: true
},
{
key: 'yrge',
title: '多年平均年发电量(亿kW·h)',
dataIndex: 'yrge',
visible: true,
width: 200,
sort: true
},
{
key: 'ushr',
title: '年利用小时数(h)',
dataIndex: 'ushr',
visible: true,
width: 150,
sort: true
},
{
key: 'k',
title: '机组综合出力系数',
dataIndex: 'k',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'dmtp',
title: '坝型',
dataIndex: 'dmtp',
visible: true,
width: 100,
sort: true,
ellipsis: true
},
{
key: 'dmcrel',
title: '坝顶高程(m)',
dataIndex: 'dmcrel',
visible: true,
width: 130,
sort: true
},
{
key: 'mxdmhg',
title: '最大坝高(m)',
dataIndex: 'mxdmhg',
visible: true,
width: 120,
sort: true
},
{
key: 'dmlen',
title: '坝顶长度(m)',
dataIndex: 'dmlen',
visible: true,
width: 130,
sort: true
},
{
key: 'sgyge',
title: '单独年发电量(亿kW·h)',
dataIndex: 'sgyge',
visible: true,
width: 180,
sort: true
},
{
key: 'unyge',
title: '联合年发电量(亿kW·h)',
dataIndex: 'unyge',
visible: true,
width: 180,
sort: true
},
{
key: 'gap',
title: '利用落差(m)',
dataIndex: 'gap',
visible: true,
width: 120,
sort: true
},
{
key: 'dvtpName',
title: '开发方式',
dataIndex: 'dvtpName',
visible: true,
width: 120,
sort: true
},
{
key: 'dtinName',
title: '接入状态',
dataIndex: 'dtinName',
visible: true,
width: 120,
sort: true,
ellipsis: true
},
{
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: isEdit.value ? 180 : 100
}
]);
//
const dateRender = ({ text }: { text: string }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
};
//
const columnMetaMap: Record<string, any> = {
stnm: { width: 150, fixed: 'left', sort: true, ellipsis: true },
addvcdName: { width: 150, sort: true, ellipsis: true },
stlc: { width: 200, sort: true, ellipsis: true },
baseName: { width: 120, ellipsis: true },
jcdt: { width: 120, sort: true, ellipsis: true, customRender: dateRender },
piodt: { width: 160, sort: true, ellipsis: true, customRender: dateRender },
aiodt: { width: 150, sort: true, ellipsis: true, customRender: dateRender },
bldsttCcodeName: { width: 100, sort: true, ellipsis: true },
hynm: { width: 150, sort: true, ellipsis: true },
topHynm: { width: 150, sort: true, ellipsis: true },
nrupar: { width: 180, sort: true },
dstcrvr: { width: 150, sort: true },
avyrp: { width: 170, sort: true },
avw: { width: 190, sort: true },
avq: { width: 160, sort: true },
avq01: { width: 180, sort: true },
avq02: { width: 180, sort: true },
avq03: { width: 180, sort: true },
avq04: { width: 180, sort: true },
avq05: { width: 180, sort: true },
avq06: { width: 180, sort: true },
avq07: { width: 180, sort: true },
avq08: { width: 180, sort: true },
avq09: { width: 180, sort: true },
avq10: { width: 190, sort: true },
avq11: { width: 190, sort: true },
avq12: { width: 190, sort: true },
obmxq: { width: 170, sort: true },
obmnq: { width: 170, sort: true },
hmxq: { width: 190, sort: true },
dsnfqfrq: { width: 190, sort: true },
dsrcin: { width: 160, sort: true },
ckfqfqr: { width: 190, sort: true },
chrcin: { width: 160, sort: true },
obmxw3: { width: 220, sort: true },
dsw3: { width: 190, sort: true },
ckw3: { width: 190, sort: true },
avsd: { width: 180 },
avs: { width: 180, sort: true },
obmxs: { width: 180, sort: true },
ckflz: { width: 140, sort: true },
dsflz: { width: 140, sort: true },
normz: { width: 140, sort: true },
uzfc: { width: 140, sort: true },
fsltdz: { width: 150, sort: true },
ydownz: { width: 140, sort: true },
ddz: { width: 120, sort: true },
nrzar: { width: 200, sort: true },
bcklen: { width: 130, sort: true },
ttcp: { width: 130, sort: true },
nmzcp: { width: 200, sort: true },
fldcpStr: { width: 140, sort: true },
actcp: { width: 140, sort: true },
ddcp: { width: 130, sort: true },
cpsc: { width: 120, sort: true },
rgcpName: { width: 120, sort: true, ellipsis: true },
dsflzmxq: { width: 250, sort: true },
dsflzxyz: { width: 320, sort: true },
ckflzmxq: { width: 250, sort: true },
ckflzxyz: { width: 320, sort: true },
ksqadjq: { width: 170, sort: true },
ksqxyz: { width: 250, sort: true },
gemaxrq: { width: 190, sort: true },
mxgeqxyz: { width: 260, sort: true },
ttpwr: { width: 120, sort: true, ellipsis: true },
gncnt: { width: 130, sort: true, ellipsis: true },
gntp: { width: 150, sort: true, ellipsis: true },
grntpwr: { width: 130, sort: true, ellipsis: true },
yrge: { width: 200, sort: true },
ushr: { width: 150, sort: true },
k: { width: 150, sort: true, ellipsis: true },
dmtp: { width: 100, sort: true, ellipsis: true },
dmcrel: { width: 130, sort: true },
mxdmhg: { width: 120, sort: true },
dmlen: { width: 130, sort: true },
sgyge: { width: 180, sort: true },
unyge: { width: 180, sort: true },
gap: { width: 120, sort: true },
dvtpName: { width: 120, sort: true },
dtinName: { width: 120, sort: true, ellipsis: true }
};
// API columnEn dataIndex
const apiToDataIndexMap: Record<string, string> = {
hbrvcdName: 'reachcdName'
};
const columns = ref<any[]>([]);
const tableScrollX = computed(() =>
Math.max(
@ -868,18 +285,24 @@ const customFilterBtn = () => {
//
const handleColumnConfirm = (selectedFiledKeys: string[]) => {
console.log('选中的 filed keys:', selectedFiledKeys);
// filed dataIndex
const filedToDataIndexMap: Record<string, string> = {
ennm: 'stnm'
};
console.log('选中的 columnEn keys:', selectedFiledKeys);
// filed visible
columns.value.forEach((col: any) => {
if (col.key === 'action') return; //
// filed 使 dataIndex
const filed = filedToDataIndexMap[col.dataIndex] || col.dataIndex;
col.visible = selectedFiledKeys.includes(filed);
// 1. checked
const updatedList = userColumnList.value.map((item: any) => ({
...item,
checked: selectedFiledKeys.includes(item.columnEn) ? 1 : 0
}));
// 2. { recordUser, cfgId, list }
const saveParams = {
recordUser: userStore.userid,
cfgId: 'cgsdbase',
list: updatedList
};
batchSaveUserColumn(saveParams).then(() => {
// 3.
fetchColumnConfig();
initTable(currentSearchParams.value);
});
};
const buildSearchParams = (values: any) => {
@ -1002,6 +425,7 @@ const buildSearchParams = (values: any) => {
};
const initTable = (values: any) => {
if (!tableRef.value) return;
const params = buildSearchParams(values);
tableRef.value.getList(params);
};
@ -1056,8 +480,62 @@ const handleDelete = (record: any) => {
initTable(currentSearchParams.value);
});
};
//
const fetchColumnConfig = () => {
getUserColumnData({
recordUser: userStore.userid,
cfgId: 'cgsdbase'
}).then((res: any) => {
const list = res?.data || [];
userColumnList.value = list;
// API orderIndex checked 1
const sorted = [...list]
.filter((item: any) => item.checked === 1 && item.defaultConfig !== true)
.sort((a: any, b: any) => a.orderIndex - b.orderIndex);
const cols = sorted.map((item: any) => {
const dataIndex = apiToDataIndexMap[item.columnEn] || item.columnEn;
const meta = columnMetaMap[item.columnEn] || {};
return {
key: item.columnEn,
title: item.columnName,
dataIndex,
...meta
};
});
//
cols.push({
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: isEdit.value ? 180 : 100
});
columns.value = cols;
}).catch(() => {
// API
columns.value = [{
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: isEdit.value ? 180 : 100
}];
}).finally(() => {
columnLoaded.value = true;
//
nextTick(() => {
initTable(currentSearchParams.value);
});
});
};
onMounted(() => {
init();
fetchColumnConfig();
nextTick(() => {
tableScrollY.value = calcTableScrollY();
});

View File

@ -0,0 +1,719 @@
<template>
<a-modal
v-model:open="visible"
:title="isAdd ? '新增鱼类' : '编辑鱼类'"
width="80vw"
:confirm-loading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
>
<a-form
ref="formRef"
:model="formData"
:label-col="{ span: 8 }"
:wrapper-col="{ span: 16 }"
:rules="formRules"
class="max-h-[70vh] overflow-y-auto pr-4"
>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="中文名称" name="name">
<a-input
v-model:value="formData.name"
placeholder="请输入中文名称"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="拉丁学名" name="nameEn">
<a-input
v-model:value="formData.nameEn"
placeholder="请输入拉丁学名"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="俗名" name="alias">
<a-input
v-model:value="formData.alias"
placeholder="请输入俗名"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="目" name="orders">
<a-input
v-model:value="formData.orders"
placeholder="请输入目"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="科" name="family">
<a-input
v-model:value="formData.family"
placeholder="请输入科"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="属" name="genus">
<a-input
v-model:value="formData.genus"
placeholder="请输入属"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="种" name="species">
<a-input
v-model:value="formData.species"
placeholder="请输入种"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="分类" name="type">
<a-select
v-model:value="formData.type"
placeholder="请选择分类"
allow-clear
>
<a-select-option :value="1">淡水</a-select-option>
<a-select-option :value="2">海水</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="所属流域" name="rvcd">
<a-select
v-model:value="formData.rvcd"
placeholder="请选择所属流域"
allow-clear
show-search
:loading="shuJuTianBaoStore.lyLoading"
:filter-option="filterOption"
style="width: 100%"
>
<a-select-option
v-for="opt in shuJuTianBaoStore.lyOption"
:key="opt.rvcd"
:value="opt.rvcd"
:label="opt.rvnm"
>{{ opt.rvnm }}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="成鱼大小(cm)" name="fsz">
<a-input
v-model:value="formData.fsz"
placeholder="请输入成鱼大小"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="栖息习性" name="habitation">
<a-input
v-model:value="formData.habitation"
placeholder="请输入栖息习性"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="洄游习性" name="habitMigrat">
<a-input
v-model:value="formData.habitMigrat"
placeholder="请输入洄游习性"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="摄食习性" name="feedingHabit">
<a-input
v-model:value="formData.feedingHabit"
placeholder="请输入摄食习性"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="主要食物" name="food">
<a-input
v-model:value="formData.food"
placeholder="请输入主要食物"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="觅食时段" name="timeFeed">
<a-input
v-model:value="formData.timeFeed"
placeholder="请输入觅食时段"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="产卵期(月)" name="spawnMonth">
<a-input
v-model:value="formData.spawnMonth"
placeholder="请输入产卵期"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="产地及产期" name="orignDate">
<a-input
v-model:value="formData.orignDate"
placeholder="请输入产地及产期"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="适宜温度" name="pretemp">
<a-input
v-model:value="formData.pretemp"
placeholder="请输入适宜温度"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="适宜流速" name="flowRate">
<a-input
v-model:value="formData.flowRate"
placeholder="请输入适宜流速"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="适宜水深(m)" name="depth">
<a-input
v-model:value="formData.depth"
placeholder="请输入适宜水深"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水质要求" name="wqtq">
<a-select
v-model:value="formData.wqtq"
placeholder="请选择水质要求"
allow-clear
>
<a-select-option :value="1">Ⅰ类</a-select-option>
<a-select-option :value="2">Ⅱ类</a-select-option>
<a-select-option :value="3">Ⅲ类</a-select-option>
<a-select-option :value="4">Ⅳ类</a-select-option>
<a-select-option :value="5">Ⅴ类</a-select-option>
<a-select-option :value="6">劣质Ⅴ</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="型(产卵特性)" name="spawnCharact">
<a-input
v-model:value="formData.spawnCharact"
placeholder="请输入产卵特性"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="地质(适宜底质)" name="botmMater">
<a-input
v-model:value="formData.botmMater"
placeholder="请输入适宜底质"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="保护类型" name="ptype">
<a-select
v-model:value="formData.ptype"
placeholder="请选择保护类型"
allow-clear
>
<a-select-option :value="1">濒危</a-select-option>
<a-select-option :value="2">极危</a-select-option>
<a-select-option :value="3">近危</a-select-option>
<a-select-option :value="4">易危</a-select-option>
<a-select-option :value="5">重点保护</a-select-option>
<a-select-option :value="6">无危</a-select-option>
<a-select-option :value="7">国家二级</a-select-option>
<a-select-option :value="8">市二级保护</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="物种来源" name="specOrigin">
<a-select
v-model:value="formData.specOrigin"
placeholder="请选择物种来源"
allow-clear
>
<a-select-option :value="1">本土物种</a-select-option>
<a-select-option :value="2">外来物种</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="数据来源" name="vlsr">
<a-input
v-model:value="formData.vlsr"
placeholder="请输入数据来源"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="形态描述" name="shapedesc">
<a-textarea
v-model:value="formData.shapedesc"
placeholder="请输入形态描述"
:rows="3"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="内容" name="description">
<a-textarea
v-model:value="formData.description"
placeholder="请输入内容"
:rows="3"
/>
</a-form-item>
</a-col>
</a-row>
<!-- 图片上传 -->
<a-row :gutter="16" class="mt-4">
<a-col :span="24">
<a-form-item label="图片" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
<a-upload
v-model:file-list="fileList"
:multiple="true"
:max-count="10"
list-type="picture-card"
:before-upload="handleBeforeUpload"
@remove="handleRemove"
>
<div v-if="fileList.length < 10">
<plus-outlined />
<div class="mt-2">上传图片</div>
</div>
</a-upload>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-modal>
<ConfirmModal
v-model:open="confirmModalVisible"
:diff-list="diffList"
:confirm-loading="confirmLoading"
@confirm="handleConfirmSubmit"
@cancel="handleConfirmCancel"
/>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { message, Upload } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { addFishDictoryInfo, updateFishDictoryInfo } from '@/api/DataQueryMenuModule';
import ConfirmModal from '@/components/ConfirmModal/index.vue';
import { useDraggable } from '@/utils/drag';
import { useShuJuTianBaoStore } from '@/store/modules/shuJuTianBao';
const shuJuTianBaoStore = useShuJuTianBaoStore();
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
const props = defineProps<{
open: boolean;
record?: any;
isAdd?: boolean;
}>();
const emit = defineEmits(['update:open', 'success']);
const visible = computed({
get: () => props.open,
set: val => emit('update:open', val)
});
useDraggable(visible, { boundary: true, resetOnOpen: true });
const formRef = ref();
const confirmLoading = ref(false);
const formData = ref<any>({});
const originalRecord = ref<any>({});
const confirmModalVisible = ref(false);
//
const fileList = ref<any[]>([]);
const handleBeforeUpload = (file: any) => {
// fileList
const isImage = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/webp';
if (!isImage) {
message.error('只能上传图片文件JPG/PNG/GIF/WEBP');
return Upload.LIST_IGNORE;
}
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isLt10M) {
message.error('图片大小不能超过 10MB');
return Upload.LIST_IGNORE;
}
// fileList Ant Design
fileList.value = [...fileList.value, file];
return false; //
};
const handleRemove = () => {
return true;
};
const formRules = ref<any>({
code: [{ required: true, message: '请输入编码', trigger: 'blur' }],
name: [{ required: true, message: '请输入中文名称', trigger: 'blur' }]
});
//
const fieldLabelMap: Record<string, string> = {
code: '编码',
name: '中文名称',
nameEn: '拉丁学名',
alias: '俗名',
orders: '目',
family: '科',
genus: '属',
species: '种',
type: '分类',
rvcd: '所属流域',
fsz: '成鱼大小(cm)',
shapedesc: '形态描述',
habitation: '栖息习性',
habitMigrat: '洄游习性',
feedingHabit: '摄食习性',
food: '主要食物',
timeFeed: '觅食时段',
spawnMonth: '产卵期(月)',
orignDate: '产地及产期',
description: '内容',
pretemp: '适宜温度',
flowRate: '适宜流速',
depth: '适宜水深(m)',
wqtq: '水质要求',
spawnCharact: '型(产卵特性)',
botmMater: '地质(适宜底质)',
ptype: '保护类型',
specOrigin: '物种来源',
inffile: '图片',
vlsr: '数据来源'
};
// select
const selectOptionsMap: Record<string, () => any[]> = {
rvcd: () => shuJuTianBaoStore.lyOption.map((opt: any) => ({
label: opt.rvnm,
value: opt.rvcd
})),
type: () => [
{ label: '淡水', value: 1 },
{ label: '海水', value: 2 }
],
wqtq: () => [
{ label: 'Ⅰ类', value: 1 },
{ label: 'Ⅱ类', value: 2 },
{ label: 'Ⅲ类', value: 3 },
{ label: 'Ⅳ类', value: 4 },
{ label: 'Ⅴ类', value: 5 },
{ label: '劣质Ⅴ', value: 6 }
],
ptype: () => [
{ label: '濒危', value: 1 },
{ label: '极危', value: 2 },
{ label: '近危', value: 3 },
{ label: '易危', value: 4 },
{ label: '重点保护', value: 5 },
{ label: '无危', value: 6 },
{ label: '国家二级', value: 7 },
{ label: '市二级保护', value: 8 }
],
specOrigin: () => [
{ label: '本土物种', value: 1 },
{ label: '外来物种', value: 2 }
]
};
//
const changeOrder = ref<
{ field: string; label: string; oldValue: string; newValue: string }[]
>([]);
const diffList = changeOrder;
const filterOption = (inputValue: string, option: any) => {
const label = option.label || '';
const keyword = inputValue || '';
return label.includes(keyword);
};
const resolveSelectLabel = (field: string, value: any): string => {
if (value === null || value === undefined || value === '') return '空';
const getOptions = selectOptionsMap[field];
if (getOptions) {
const opt = getOptions().find(
(o: any) => String(o.value) === String(value)
);
if (opt) return opt.label;
}
return String(value);
};
// formData
watch(
() => formData.value,
newData => {
const original = originalRecord.value;
for (const key in newData) {
const oldVal = original[key];
const newVal = newData[key];
if (oldVal !== newVal) {
const existingIdx = changeOrder.value.findIndex(c => c.field === key);
const oldNorm =
oldVal === null || oldVal === undefined || oldVal === '-'
? null
: oldVal;
const newNorm = newVal === null || newVal === undefined ? null : newVal;
if (oldNorm === newNorm) continue;
if (
oldNorm !== null &&
newNorm !== null &&
!isNaN(Number(oldNorm)) &&
!isNaN(Number(newNorm)) &&
Number(oldNorm) === Number(newNorm)
)
continue;
const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm)
: oldNorm === null
? '空'
: String(oldNorm);
const newDisplay = isSelect
? resolveSelectLabel(key, newNorm)
: newNorm === null
? '空'
: String(newNorm);
const entry = {
field: key,
label: fieldLabelMap[key] || key,
oldValue: oldDisplay,
newValue: newDisplay
};
if (existingIdx >= 0) {
changeOrder.value[existingIdx] = entry;
} else {
changeOrder.value.push(entry);
}
} else {
changeOrder.value = changeOrder.value.filter(c => c.field !== key);
}
}
},
{ deep: true }
);
// fileList diff
watch(
() => fileList.value,
(newList) => {
const originalIds = (originalRecord.value.inffile || '').split(',').filter(Boolean);
const currentExistingIds = newList
.filter((f: any) => f.isExisting)
.map((f: any) => f.uid);
const currentNewCount = newList.filter((f: any) => f.originFileObj).length;
const deletedCount = originalIds.filter((id: string) => !currentExistingIds.includes(id)).length;
const addedCount = currentNewCount;
if (deletedCount > 0 || addedCount > 0) {
const existingIdx = changeOrder.value.findIndex(c => c.field === 'inffile');
const oldDisplay = `${originalIds.length}张图片`;
const parts: string[] = [];
if (deletedCount > 0) parts.push(`删除${deletedCount}`);
if (addedCount > 0) parts.push(`新增${addedCount}`);
const entry = {
field: 'inffile',
label: '图片',
oldValue: oldDisplay,
newValue: parts.join('')
};
if (existingIdx >= 0) {
changeOrder.value[existingIdx] = entry;
} else {
changeOrder.value.push(entry);
}
} else {
changeOrder.value = changeOrder.value.filter(c => c.field !== 'inffile');
}
},
{ deep: true }
);
// record
watch(
() => props.record,
newRecord => {
if (newRecord) {
const converted = { ...newRecord };
originalRecord.value = { ...converted };
formData.value = { ...converted };
changeOrder.value = [];
//
if (converted.inffile) {
const ids = converted.inffile.split(',').filter(Boolean);
fileList.value = ids.map((id: string) => ({
uid: id,
name: id,
status: 'done',
url: `${baseUrl}/?${id}&view=jpg`,
isExisting: true
}));
} else {
fileList.value = [];
}
}
},
{ deep: true }
);
watch(
() => props.open,
val => {
if (val) {
//
shuJuTianBaoStore.getSelectForOption();
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
fileList.value = [];
} else if (props.record?.inffile) {
// fileList
const ids = props.record.inffile.split(',').filter(Boolean);
fileList.value = ids.map((id: string) => ({
uid: id,
name: id,
status: 'done',
url: `${baseUrl}/?${id}&view=jpg`,
isExisting: true
}));
}
}
}
);
const handleOk = async () => {
try {
await formRef.value?.validateFields();
if (!props.isAdd && changeOrder.value.length === 0) {
message.info('未检测到任何修改');
return;
}
confirmModalVisible.value = true;
} catch (error) {
console.error('验证失败:', error);
}
};
const buildFormData = (engInfo: Record<string, any>, source: string) => {
const formData = new FormData();
const data = {
engInfo,
source: source.trim() || (props.isAdd ? '新增' : '编辑')
};
formData.append('data', JSON.stringify(data));
//
fileList.value.forEach((file: any) => {
if (file.originFileObj) {
formData.append('files', file.originFileObj);
}
});
return formData;
};
const handleConfirmSubmit = async (source: string) => {
confirmLoading.value = true;
try {
const engInfo: Record<string, any> = {};
let res: any;
if (props.isAdd) {
//
Object.assign(engInfo, formData.value);
const fd = buildFormData(engInfo, source);
res = await addFishDictoryInfo(fd);
} else {
//
engInfo.id = formData.value.id;
changeOrder.value.forEach(item => {
engInfo[item.field] = formData.value[item.field];
});
// inffile
const existingIds = fileList.value
.filter((f: any) => f.isExisting)
.map((f: any) => f.uid);
if (existingIds.length > 0) {
engInfo.inffile = existingIds.join(',');
} else {
delete engInfo.inffile;
}
const fd = buildFormData(engInfo, source);
res = await updateFishDictoryInfo(fd);
}
if (res?.code == 0 || res?.success) {
message.success(props.isAdd ? '新增成功' : '编辑成功');
confirmModalVisible.value = false;
visible.value = false;
emit('success');
} else {
message.error(res?.msg || (props.isAdd ? '新增失败' : '编辑失败'));
}
} catch (error) {
message.error('提交失败,请重试');
} finally {
confirmLoading.value = false;
}
};
const handleConfirmCancel = () => {
confirmModalVisible.value = false;
};
const handleCancel = () => {
visible.value = false;
confirmModalVisible.value = false;
formRef.value?.resetFields();
};
</script>

View File

@ -10,6 +10,7 @@
@values-change="onValuesChange"
>
<template #actions>
<a-button type="primary" @click="handleAdd">新增</a-button>
<a-button @click="exportBtn" :loading="exportLoading">导出</a-button>
</template>
</BasicSearch>
@ -33,6 +34,7 @@ const props = defineProps<Props>();
const emit = defineEmits<{
(e: 'reset', values: any): void;
(e: 'search-finish', values: any): void;
(e: 'add'): void;
}>();
const localTypeDate = ref<string>(null);
@ -115,6 +117,10 @@ const onValuesChange = (changedValues: any, allValues: any) => {
}
};
const handleAdd = () => {
emit('add');
};
const handleReset = () => {
localTypeDate.value = null;
emit('reset', initSearchData);

View File

@ -10,6 +10,7 @@
:exportBtn="exportBtn"
@search-finish="onSearchFinish"
@reset="onReset"
@add="handleAdd"
ref="searchRef"
/>
<a-row type="flex" class="w-full h-full" style="height: calc(100% - 80px)">
@ -25,6 +26,18 @@
:enable-row-highlight="true"
@row-click="handleRowClick"
>
<template #action="{ record }">
<a-button
type="link"
class="text-[#2f6b98]"
size="small"
@click="handleEdit(record)"
>编辑</a-button
>
<a-button type="link" danger size="small" @click="handleDelete(record)"
>删除</a-button
>
</template>
</BasicTable>
</a-col>
<a-col flex="25%" class="overflow-hidden">
@ -91,6 +104,23 @@
</div>
</a-col>
</a-row>
<!-- 编辑/新增 Modal -->
<EditFishDictoryModal
v-model:open="editVisible"
:record="editRecord"
:is-add="isAdd"
@success="handleEditSuccess"
/>
<!-- 删除确认 Modal -->
<DeleteConfirmModal
ref="deleteModalRef"
:delete-fn="deleteFishDictoryFn"
:label="'鱼类'"
title="删除鱼类"
@success="handleEditSuccess"
/>
</div>
</template>
<script setup lang="ts">
@ -110,9 +140,12 @@ import { LeftCircleOutlined, RightCircleOutlined } from '@ant-design/icons-vue';
import { getDictItemsByCode } from '@/api/dict';
import {
getFishResourceList,
getFishResourceZYList
getFishResourceZYList,
deleteFishDictoryInfo
} from '@/api/DataQueryMenuModule';
import { calcTableScrollY } from '@/utils/index';
import EditFishDictoryModal from './EditFishDictoryModal.vue';
import DeleteConfirmModal from '@/views/conventionalHydropower/BasicData/DeleteConfirmModal.vue';
const fishResource = ref<any>({
name: '',
logoList: [],
@ -417,6 +450,14 @@ const columns: any = [
width: 150,
sort: true,
ellipsis: true
},
{
key: 'action',
title: '操作',
dataIndex: 'action',
visible: true,
width: 140,
ellipsis: true
}
// {
// "key": "inffile",
@ -438,6 +479,12 @@ const ptypeLoading = ref(false);
const familyLoading = ref(false);
const rightPanelLoading = ref(false);
// /
const editVisible = ref(false);
const editRecord = ref<any>(null);
const isAdd = ref(false);
const deleteModalRef = ref();
//
const exportBtn = () => {
if (exportLoading.value) return;
@ -562,6 +609,39 @@ const buildSearchParams = (values: any) => {
].filter(Boolean)
};
};
//
const handleAdd = () => {
isAdd.value = true;
editRecord.value = null;
editVisible.value = true;
};
//
const handleEdit = (record: any) => {
isAdd.value = false;
editRecord.value = { ...record };
editVisible.value = true;
};
//
const handleEditSuccess = () => {
initTable(currentSearchParams.value);
};
//
const deleteFishDictoryFn = async (record: any, reason: string) => {
return deleteFishDictoryInfo({
ids: [record.id],
source: reason
});
};
const handleDelete = (record: any) => {
deleteModalRef.value?.open(record, () => {
initTable(currentSearchParams.value);
});
};
const init = () => {
ptypeLoading.value = true;
familyLoading.value = true;

View File

@ -53,6 +53,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -78,6 +88,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -284,12 +295,16 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
stcd: '站码',
stnm: '站名',
sttp: '站类',
stlc: '站址',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地',
rstcd: '所属电站',
mway: '监测方式',
@ -414,6 +429,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
//
const loadDropdownData = () => {
baseNameOptions.value = jidiSelectEventStore.jidiData
@ -422,14 +450,13 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
@ -439,6 +466,7 @@ watch(
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
}
}

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -235,7 +246,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入工程编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入工程名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入工程名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
const engInfoOptions = ref<any[]>([]);
@ -250,11 +262,15 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = {
stcd: '工程编码',
stnm: '工程名称',
sttp: '测站类型',
stlc: '位置',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地',
rstcd: '所属电站',
usfl: '是否启用',
@ -378,6 +394,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: {
@ -403,24 +432,24 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
if (val) {
loadDropdownData();
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
}
);

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -279,7 +290,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入站码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
//
@ -295,12 +307,16 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
stcd: '站码',
stnm: '站名',
sttp: '测站类型',
stlc: '站址',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地',
rstcd: '所属电站',
mway: '监测方式',
@ -426,6 +442,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
//
const loadDropdownData = () => {
//
@ -454,14 +483,13 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
@ -471,6 +499,7 @@ watch(
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
}
}

View File

@ -33,7 +33,7 @@
</a-col>
<a-col :span="8">
<a-form-item label="所属电站" name="rstcd">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :filter-option="filterOption">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption">
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-form-item>
@ -172,6 +172,8 @@ const baseNameOptions = ref<any[]>(
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
);
const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = {
stcd: '设施编码', stnm: '设施名称', sttp: '设施类型', stlc: '站址/位置',
baseId: '水电基地', rstcd: '所属电站', lgtd: '经度(°)', lttd: '纬度(°)',
@ -247,6 +249,19 @@ watch(() => props.record, newRecord => {
}
}, { deep: true });
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: { logic: 'and', filters: [{ field: 'sttpCode', operator: 'in', dataType: 'string', value: ['FP', 'FP_1', 'FP_2', 'FP_3', 'FP_4', 'FP_5'] }] }
@ -254,12 +269,25 @@ const loadDropdownData = () => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
});
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
});
};
watch(() => props.open, val => { if (val) { loadDropdownData(); if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; } } });
//
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) {
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
});
const handleOk = async () => {
try {

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -173,7 +184,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入断面编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入断面名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入断面名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
//
@ -188,6 +200,7 @@ const baseNameOptions = ref<any[]>(
value: item.wbsCode
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
@ -199,7 +212,9 @@ const fieldLabelMap: Record<string, string> = {
rstcd: '所属电站',
jcdt: '建成日期',
introduce: '简介',
remark: '备注'
remark: '备注',
lgtd: '经度(°)',
lttd: '纬度(°)'
};
// select
@ -301,6 +316,20 @@ watch(
{ deep: true }
);
// baseId
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
//
const loadDropdownData = () => {
//
@ -329,24 +358,25 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
//
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
if (val) {
loadDropdownData();
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
}
);

View File

@ -31,6 +31,16 @@
<a-input v-model:value="formData.stlc" placeholder="请输入站址" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="水电基地" name="baseId">
<a-select v-model:value="formData.baseId" placeholder="请选择水电基地" allow-clear show-search :filter-option="filterOption">
@ -40,7 +50,7 @@
</a-col>
<a-col :span="8">
<a-form-item label="所属电站" name="rstcd">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :filter-option="filterOption">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption">
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-form-item>
@ -133,11 +143,13 @@ const baseNameOptions = ref<any[]>(
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
);
const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = {
stcd: '栖息地站码', stnm: '栖息地名称', stlc: '站址', baseId: '水电基地',
rstcd: '所属电站', bhdx: '保护对象', bhfw: '保护范围',
bhhxcd: '保护核心长度(km)',
bhhl: '保护河流', bhhd: '保护河段', bhcs: '保护措施', bhfs: '保护方式', inv: '投资(亿元)'
bhhl: '保护河流', bhhd: '保护河段', bhcs: '保护措施', bhfs: '保护方式', inv: '投资(亿元)', lgtd: '经度(°)', lttd: '纬度(°)'
};
const selectOptionsMap: Record<string, () => any[]> = {
@ -195,19 +207,34 @@ watch(() => props.record, newRecord => {
}
}, { deep: true });
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
baseNameOptions.value = jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) {
loadDropdownData();
if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; }
if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; loadEngOptions(); }
}
});

View File

@ -87,6 +87,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -246,7 +247,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入救助站编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入救助站名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入救助站名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
const engInfoOptions = ref<any[]>([]);
@ -261,11 +263,15 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = {
stcd: '救助站编码',
stnm: '救助站名称',
sttp: '测站类型',
stlc: '站址',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地',
rstcd: '所属电站',
place: '地点',
@ -353,6 +359,19 @@ watch(() => props.record, newRecord => {
}
}, { deep: true });
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: {
@ -363,13 +382,23 @@ const loadDropdownData = () => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
});
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) { loadDropdownData(); if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; } }
if (val) {
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
});
const handleOk = async () => {

View File

@ -33,7 +33,7 @@
</a-col>
<a-col :span="8">
<a-form-item label="所属电站" name="rstcd">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :filter-option="filterOption">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption">
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-form-item>
@ -134,11 +134,13 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入设施编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入设施名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入设施名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择设施类型', trigger: 'change' }]
});
const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]);
const engLoading = ref(false);
const baseNameOptions = ref<any[]>(
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
@ -213,6 +215,20 @@ watch(() => props.record, newRecord => {
}
}, { deep: true });
// baseId
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: { logic: 'and', filters: [{ field: 'sttpCode', operator: 'in', dataType: 'string', value: ['EQ', 'EQ_1', 'EQ_2', 'EQ_3', 'EQ_4', 'EQ_5', 'EQ_6'] }] }
@ -220,12 +236,28 @@ const loadDropdownData = () => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
});
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
});
};
watch(() => props.open, val => { if (val) { loadDropdownData(); if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; } } });
//
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) {
// watch
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
// baseId undefined watch
loadEngOptions();
}
loadDropdownData();
// record watch formDatabaseId watch
}
});
const handleOk = async () => {
try {

View File

@ -33,7 +33,7 @@
</a-col>
<a-col :span="12">
<a-form-item label="所属电站" name="rstcd">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :filter-option="filterOption">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption">
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-form-item>
@ -75,7 +75,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入监控点编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入监控点名', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入监控点名', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择监控点类型', trigger: 'change' }]
});
const engInfoOptions = ref<any[]>([]);
@ -84,10 +85,13 @@ const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>(
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
);
const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = {
stcd: '监控点编码', stnm: '监控点名', sttp: '监控点类型',
addvcd: '所属行政区', baseId: '水电基地', rstcd: '所属电站', stlc: '监控点地址'
addvcd: '所属行政区', baseId: '水电基地', rstcd: '所属电站', stlc: '监控点地址',
lgtd: '经度(°)',
lttd: '纬度(°)'
};
const selectOptionsMap: Record<string, () => any[]> = {
@ -146,6 +150,20 @@ watch(() => props.record, newRecord => {
}
}, { deep: true });
// baseId
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: { logic: 'and', filters: [{ field: 'sttpCode', operator: 'in', dataType: 'string', value: ['VD', 'VD_DW', 'VD_EQ', 'VD_EQS', 'VD_FB', 'VD_FBFM', 'VD_FBI', 'VD_FBP', 'VD_FC', 'VD_FH', 'VD_FP', 'VD_FPB', 'VD_FPC', 'VD_GZFC', 'VD_OTTE', 'VD_OTWE', 'VD_PR', 'VD_SG', 'VD_TE', 'VD_VA', 'VD_VP', 'VD_WE', 'VD_WQ', 'VD_WT'] }] }
@ -153,12 +171,25 @@ const loadDropdownData = () => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
});
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
});
};
watch(() => props.open, val => { if (val) { loadDropdownData(); if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; } } });
//
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) {
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
});
const handleOk = async () => {
try {

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -173,7 +184,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入断面编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入断面名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入断面名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
//
@ -188,6 +200,7 @@ const baseNameOptions = ref<any[]>(
value: item.wbsCode
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
@ -199,7 +212,9 @@ const fieldLabelMap: Record<string, string> = {
rstcd: '所属电站',
jcdt: '建成日期',
introduce: '简介',
remark: '备注'
remark: '备注',
lgtd: '经度(°)',
lttd: '纬度(°)'
};
// select
@ -301,6 +316,20 @@ watch(
{ deep: true }
);
// baseId
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
//
const loadDropdownData = () => {
//
@ -329,24 +358,25 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
//
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
if (val) {
loadDropdownData();
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
}
);

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -168,7 +179,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入水温站站码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入测站名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入测站名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
//
@ -184,6 +196,8 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
stcd: '水温站站码',
@ -193,7 +207,9 @@ const fieldLabelMap: Record<string, string> = {
baseId: '水电基地',
jcdt: '建成日期',
mway: '监测方式',
rstcd: '所属电站'
rstcd: '所属电站',
lgtd: '经度(°)',
lttd: '纬度(°)'
};
// select
@ -299,6 +315,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
//
const loadDropdownData = () => {
//
@ -327,14 +356,13 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
@ -344,6 +372,7 @@ watch(
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
}
}

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -199,7 +210,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入水质站站码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入测站名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入测站名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
//
@ -216,6 +228,8 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
stcd: '水质站站码',
@ -228,7 +242,9 @@ const fieldLabelMap: Record<string, string> = {
jcdt: '建成日期',
dtinType: '类别',
wwqtg: '水质要求',
mway: '监测方式'
mway: '监测方式',
lgtd: '经度(°)',
lttd: '纬度(°)'
};
// select
@ -340,6 +356,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
//
const loadDropdownData = () => {
//
@ -376,14 +405,13 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
@ -393,6 +421,7 @@ watch(
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
}
}

View File

@ -96,6 +96,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -234,7 +235,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入站码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择监控类别', trigger: 'change' }]
});
const engInfoOptions = ref<any[]>([]);
@ -249,12 +251,16 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = {
stcd: '站码',
stnm: '站名',
sttp: '监控类别',
mntp: '监控类型',
stlc: '站址',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地',
rstcd: '所属电站',
mway: '监测方式',
@ -370,6 +376,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: {
@ -395,24 +414,24 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
if (val) {
loadDropdownData();
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
}
);

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -227,7 +238,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入设施编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入设施名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入设施名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择设施类型', trigger: 'change' }]
});
//
@ -243,12 +255,16 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
stcd: '设施编码',
stnm: '设施名称',
sttp: '设施类型',
stlc: '站址',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地',
rstcd: '所属电站',
usfl: '是否启用',
@ -368,6 +384,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
//
const loadDropdownData = () => {
//
@ -395,14 +424,13 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
@ -412,6 +440,7 @@ watch(
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
}
}

View File

@ -62,6 +62,16 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select
@ -87,6 +97,7 @@
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
@ -235,7 +246,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入工程编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入工程名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入工程名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
//
@ -251,12 +263,16 @@ const baseNameOptions = ref<any[]>(
}))
);
const engLoading = ref(false);
//
const fieldLabelMap: Record<string, string> = {
stcd: '工程编码',
stnm: '工程名称',
sttp: '测站类型',
stlc: '位置',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地',
rstcd: '所属电站',
usfl: '是否启用',
@ -381,6 +397,19 @@ watch(
{ deep: true }
);
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: {
@ -406,24 +435,24 @@ const loadDropdownData = () => {
label: item.wbsName,
value: item.wbsCode
}));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
});
};
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(
() => props.open,
val => {
if (val) {
loadDropdownData();
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
}
);

View File

@ -24,6 +24,16 @@
<a-input v-model:value="formData.stlc" placeholder="请输入地址" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="测站类型" name="sttp">
<a-select v-model:value="formData.sttp" placeholder="请选择测站类型" allow-clear show-search :filter-option="filterOption">
@ -40,7 +50,7 @@
</a-col>
<a-col :span="8">
<a-form-item label="所属电站" name="rstcd">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :filter-option="filterOption">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption">
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-form-item>
@ -137,7 +147,8 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入增殖站编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入增殖站名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入增殖站名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
const engInfoOptions = ref<any[]>([]);
@ -149,12 +160,14 @@ const baseNameOptions = ref<any[]>(
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
);
const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = {
stcd: '增殖站编码', stnm: '增殖站名称', stlc: '地址', sttp: '测站类型',
baseId: '水电基地', rstcd: '所属电站', swdt: '开工日期', jcdt: '建成日期',
zzfldx: '放流对象', zzflcnt: '放流规模(尾)', zzflfllc: '放流地点',
zzfltm: '放流时间', zzflyzms: '养殖模式', zzflgy: '生产工艺', zzflbjfs: '标记方式',
zzflar: '总占地面积(km²)', inv: '投资(亿元)', zzflrw: '承担放流任务'
zzflar: '总占地面积(km²)', inv: '投资(亿元)', zzflrw: '承担放流任务', lgtd: '经度(°)', lttd: '纬度(°)'
};
const selectOptionsMap: Record<string, () => any[]> = {
@ -213,6 +226,19 @@ watch(() => props.record, newRecord => {
}
}, { deep: true });
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: { logic: 'and', filters: [{ field: 'sttpCode', operator: 'in', dataType: 'string', value: ['FB', 'VD_FB', 'VD_FBP'] }] }
@ -222,13 +248,24 @@ const loadDropdownData = () => {
baseNameOptions.value = jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
});
};
//
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) { loadDropdownData(); if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; } }
if (val) {
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
});
const handleOk = async () => {

View File

@ -24,6 +24,16 @@
<a-input v-model:value="formData.stlc" placeholder="请输入站址" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="水电基地" name="baseId">
<a-select v-model:value="formData.baseId" placeholder="请选择水电基地" allow-clear show-search :filter-option="filterOption">
@ -33,7 +43,7 @@
</a-col>
<a-col :span="12">
<a-form-item label="所属电站" name="rstcd">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :filter-option="filterOption">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption">
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-form-item>
@ -95,11 +105,13 @@ const confirmModalVisible = ref(false);
const formRules = ref<any>({
stcd: [{ required: true, message: '请输入植物园编码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入植物园名称', trigger: 'blur' }]
stnm: [{ required: true, message: '请输入植物园名称', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择测站类型', trigger: 'change' }]
});
const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]);
const engLoading = ref(false);
const baseNameOptions = ref<any[]>(
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
@ -108,7 +120,8 @@ const baseNameOptions = ref<any[]>(
const fieldLabelMap: Record<string, string> = {
stcd: '植物园编码', stnm: '植物园名称', stlc: '站址', sttp: '测站类型',
baseId: '水电基地', rstcd: '所属电站', swdt: '开工日期', jcdt: '建成日期',
bhfs: '保护方式', area: '面积(km²)', inv: '投资(亿元)'
bhfs: '保护方式', area: '面积(km²)', inv: '投资(亿元)',
lgtd: '经度(°)', lttd: '纬度(°)'
};
const selectOptionsMap: Record<string, () => any[]> = {
@ -167,6 +180,19 @@ watch(() => props.record, newRecord => {
}
}, { deep: true });
const loadEngOptions = async (baseId?: string) => {
engLoading.value = true;
try {
const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
} catch (error) {
console.error('获取电站列表失败:', error);
} finally {
engLoading.value = false;
}
};
const loadDropdownData = () => {
sttpGetKendoList({
filter: { logic: 'and', filters: [{ field: 'sttpCode', operator: 'in', dataType: 'string', value: ['VP', 'VD_VP', 'AI_VP_GRAZE', 'AI_VP_WATER'] }] }
@ -174,12 +200,25 @@ const loadDropdownData = () => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
});
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
getEngInfoDropdown({}).then(res => {
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
});
};
watch(() => props.open, val => { if (val) { loadDropdownData(); if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; } } });
//
watch(() => formData.value?.baseId, (newBaseId) => {
formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) {
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
loadDropdownData();
}
});
const handleOk = async () => {
try {

View File

@ -1,5 +1,23 @@
import request from '@/utils/request';
// 自定义列配置
export function getUserColumnData(data) {
return request({
url: '/sys/usercolumn/getUserColumnData',
method: 'post',
data: data
});
}
// 批量保存自定义列配置
export function batchSaveUserColumn(data) {
return request({
url: '/sys/usercolumn/batchSave',
method: 'post',
data: data
});
}
// 基础信息 集团/公司
export function getCompanyList(data) {
return request({

View File

@ -24,7 +24,17 @@
]
}"
:list-url="getApprovalStatusList"
>
>
<template #action="{ record }">
<a-button
type="link"
class="text-[#2f6b98]"
size="small"
@click=" openUrl(record.flpath)"
>下载</a-button
>
</template>
</BasicTable>
</div>
</template>
@ -213,6 +223,14 @@ const columns: any = [
visible: true,
width: 150,
ellipsis: true
},
{
key: 'action',
title: '操作',
dataIndex: 'action',
visible: true,
width: 80,
ellipsis: true
}
];
@ -246,7 +264,7 @@ const buildSearchParams = (values: any) => {
return {
logic: 'and',
filters: [
values.rvcd && values.rvcd !== 'all'
values.rvcd && values.rvcd !== 'all'
? {
field: 'rvcd',
operator: 'contains',
@ -319,7 +337,9 @@ const initTable = (values: any) => {
const params = buildSearchParams(values);
tableRef.value.getList(params);
};
const openUrl = (url:string)=>{
window.open(url)
}
onMounted(() => {
nextTick(() => {
tableScrollY.value = calcTableScrollY();

View File

@ -58,7 +58,6 @@
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { BasicColumns } from '@/components/MapModal/column.config';
interface ColumnItem {
name: string;
@ -71,8 +70,18 @@ interface ColumnGroup {
children: ColumnItem[];
}
export interface UserColumnItem {
columnEn: string;
columnName: string;
checked: number;
groupType: string;
orderIndex: number;
defaultConfig: boolean;
}
interface Props {
visible: boolean;
userColumnList: UserColumnItem[];
}
const props = defineProps<Props>();
@ -85,49 +94,50 @@ const emit = defineEmits<{
const groupedColumns = ref<ColumnGroup[]>([]);
const tempSelectedKeys = ref<string[]>([]);
// BasicColumns
// filed
const STATION_NAME_FILED = 'stnm';
// API userColumnList
const buildGroupedColumns = () => {
const groups: ColumnGroup[] = [];
let currentGroup: ColumnGroup | null = null;
const groupMap = new Map<string, ColumnItem[]>();
for (const col of BasicColumns) {
if (!col.name && !col.filed) continue;
// defaultConfig: true
const filteredList = props.userColumnList.filter(item => item.defaultConfig !== true);
if (col.visible === false && col.name) {
currentGroup = {
name: col.name,
children: []
};
groups.push(currentGroup);
} else if (col.name && col.filed) {
if (!currentGroup) {
currentGroup = {
name: '基础信息',
children: []
};
groups.push(currentGroup);
}
const isStationName = col.filed === 'ennm';
currentGroup.children.push({
name: col.name,
filed: col.filed,
disabled: isStationName
});
// groupType
for (const item of filteredList) {
if (!item.groupType) continue;
if (!groupMap.has(item.groupType)) {
groupMap.set(item.groupType, []);
}
const isStationName = item.columnEn === STATION_NAME_FILED;
groupMap.get(item.groupType)!.push({
name: item.columnName,
filed: item.columnEn,
disabled: isStationName
});
}
//
for (const [groupName, children] of groupMap.entries()) {
groups.push({ name: groupName, children });
}
return groups;
};
// filed
const STATION_NAME_FILED = 'ennm';
// +
// API checked
const initSelectedKeys = () => {
const allKeys: string[] = [STATION_NAME_FILED];
for (const group of groupedColumns.value) {
for (const child of group.children) {
if (!child.disabled && child.filed !== STATION_NAME_FILED) {
if (child.disabled) continue;
// userColumnList checked
const apiItem = props.userColumnList.find(
item => item.columnEn === child.filed
);
if (apiItem && apiItem.checked === 1) {
allKeys.push(child.filed);
}
}
@ -225,6 +235,17 @@ watch(
}
}
);
// userColumnList
watch(
() => props.userColumnList,
() => {
if (props.visible) {
groupedColumns.value = buildGroupedColumns();
initSelectedKeys();
}
}
);
</script>
<style lang="scss" scoped>

View File

@ -16,6 +16,7 @@
<!-- 表格组件 -->
<BasicTable
v-if="columnLoaded"
ref="tableRef"
:enableEllipsis="true"
:scrollX="tableScrollX"
@ -49,7 +50,9 @@
<!-- 自定义数据列 Modal -->
<CustomColumnModal
v-if="columnLoaded"
v-model:visible="customColumnVisible"
:user-column-list="userColumnList"
@confirm="handleColumnConfirm"
/>
@ -79,15 +82,16 @@ import {
getCompanyList,
getPowerTableList,
updatePowerInfo,
deletePowerInfo
deletePowerInfo,
getUserColumnData,
batchSaveUserColumn
} from '@/api/DataQueryMenuModule';
import { getEngInfoById } from '@/api/select';
import { calcTableScrollY } from '@/utils/index';
import { useModelStore } from '@/store/modules/model';
import { BasicColumns } from '@/components/MapModal/column.config';
import { useUserStore } from "@/store/modules/user";
const modelStore = useModelStore();
const userStore = useUserStore();
const sort = ref<any>([
{
field: 'baseStepSort',
@ -113,6 +117,8 @@ const tableScrollY = ref<string | number>(0);
const currentSearchParams = ref<any>({});
const exportLoading = ref(false);
const customColumnVisible = ref(false);
const userColumnList = ref<any[]>([]);
const columnLoaded = ref(false);
//
const editVisible = ref(false);
@ -132,695 +138,103 @@ const dvtpList = ref<any[]>([
{ label: '引水式', value: '1' },
{ label: '混合式', value: '2' }
]);
const columns = ref<any[]>([
{
key: 'stnm',
title: '电站名称',
dataIndex: 'stnm',
visible: true,
width: 150,
fixed: 'left',
sort: true,
ellipsis: true
},
{
key: 'addvcdName',
title: '所在地址',
dataIndex: 'addvcdName',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'stlc',
title: '详细地址',
dataIndex: 'stlc',
visible: true,
width: 200,
sort: true,
ellipsis: true
},
{
key: 'baseName',
title: '基地',
dataIndex: 'baseName',
visible: true,
width: 120,
ellipsis: true
},
{
key: 'reachcdName',
title: '所在河流',
dataIndex: 'reachcdName',
visible: true,
width: 300,
ellipsis: true
},
{
key: 'jcdt',
title: '建设时间',
dataIndex: 'jcdt',
visible: true,
width: 120,
sort: true,
ellipsis: true,
customRender: ({ text }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
}
},
{
key: 'piodt',
title: '第一台机组投产时间',
dataIndex: 'piodt',
visible: true,
width: 160,
sort: true,
ellipsis: true,
customRender: ({ text }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
}
},
{
key: 'aiodt',
title: '全部机组投产时间',
dataIndex: 'aiodt',
visible: true,
width: 150,
sort: true,
ellipsis: true,
customRender: ({ text }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
}
},
{
key: 'bldsttCcodeName',
title: '建设状态',
dataIndex: 'bldsttCcodeName',
visible: false,
width: 100,
sort: true,
ellipsis: true
},
{
key: 'hynm',
title: '所属公司',
dataIndex: 'hynm',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'topHynm',
title: '所属集团',
dataIndex: 'topHynm',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'nrupar',
title: '坝址以上流域面积(km²)',
dataIndex: 'nrupar',
visible: true,
width: 180,
sort: true
},
{
key: 'dstcrvr',
title: '距河源距离(km)',
dataIndex: 'dstcrvr',
visible: true,
width: 150,
sort: true
},
{
key: 'avyrp',
title: '多年平均降雨量(mm)',
dataIndex: 'avyrp',
visible: true,
width: 170,
sort: true
},
{
key: 'avw',
title: '多年平均年径流量(亿m³)',
dataIndex: 'avw',
visible: true,
width: 190,
sort: true
},
{
key: 'avq',
title: '多年平均流量(m³/s)',
dataIndex: 'avq',
visible: true,
width: 160,
sort: true
},
{
key: 'avq01',
title: '1月多年平均流量(m³/s)',
dataIndex: 'avq01',
visible: true,
width: 180,
sort: true
},
{
key: 'avq02',
title: '2月多年平均流量(m³/s)',
dataIndex: 'avq02',
visible: true,
width: 180,
sort: true
},
{
key: 'avq03',
title: '3月多年平均流量(m³/s)',
dataIndex: 'avq03',
visible: true,
width: 180,
sort: true
},
{
key: 'avq04',
title: '4月多年平均流量(m³/s)',
dataIndex: 'avq04',
visible: true,
width: 180,
sort: true
},
{
key: 'avq05',
title: '5月多年平均流量(m³/s)',
dataIndex: 'avq05',
visible: true,
width: 180,
sort: true
},
{
key: 'avq06',
title: '6月多年平均流量(m³/s)',
dataIndex: 'avq06',
visible: true,
width: 180,
sort: true
},
{
key: 'avq07',
title: '7月多年平均流量(m³/s)',
dataIndex: 'avq07',
visible: true,
width: 180,
sort: true
},
{
key: 'avq08',
title: '8月多年平均流量(m³/s)',
dataIndex: 'avq08',
visible: true,
width: 180,
sort: true
},
{
key: 'avq09',
title: '9月多年平均流量(m³/s)',
dataIndex: 'avq09',
visible: true,
width: 180,
sort: true
},
{
key: 'avq10',
title: '10月多年平均流量(m³/s)',
dataIndex: 'avq10',
visible: true,
width: 190,
sort: true
},
{
key: 'avq11',
title: '11月多年平均流量(m³/s)',
dataIndex: 'avq11',
visible: true,
width: 190,
sort: true
},
{
key: 'avq12',
title: '12月多年平均流量(m³/s)',
dataIndex: 'avq12',
visible: true,
width: 190,
sort: true
},
{
key: 'obmxq',
title: '实测最大流量(m³/s)',
dataIndex: 'obmxq',
visible: true,
width: 170,
sort: true
},
{
key: 'obmnq',
title: '实测最小流量(m³/s)',
dataIndex: 'obmnq',
visible: true,
width: 170,
sort: true
},
{
key: 'hmxq',
title: '调查历史最大流量(m³/s)',
dataIndex: 'hmxq',
visible: true,
width: 190,
sort: true
},
{
key: 'dsnfqfrq',
title: '设计入库洪水流量(m³/s)',
dataIndex: 'dsnfqfrq',
visible: true,
width: 190,
sort: true
},
{
key: 'dsrcin',
title: '设计洪水重现期(年)',
dataIndex: 'dsrcin',
visible: true,
width: 160,
sort: true
},
{
key: 'ckfqfqr',
title: '校核入库洪水流量(m³/s)',
dataIndex: 'ckfqfqr',
visible: true,
width: 190,
sort: true
},
{
key: 'chrcin',
title: '校核洪水重现期(年)',
dataIndex: 'chrcin',
visible: true,
width: 160,
sort: true
},
{
key: 'obmxw3',
title: '实测最大洪量(三天)(亿m³)',
dataIndex: 'obmxw3',
visible: true,
width: 220,
sort: true
},
{
key: 'dsw3',
title: '设计洪量(三天)(亿m³)',
dataIndex: 'dsw3',
visible: true,
width: 190,
sort: true
},
{
key: 'ckw3',
title: '校核洪量(三天)(亿m³)',
dataIndex: 'ckw3',
visible: true,
width: 190,
sort: true
},
{
key: 'avsd',
title: '多年平均输沙量(万t)',
dataIndex: 'avsd',
visible: true,
width: 180
},
{
key: 'avs',
title: '多年平均含沙量(kg/m³)',
dataIndex: 'avs',
visible: true,
width: 180,
sort: true
},
{
key: 'obmxs',
title: '实测最大含沙量(kg/m³)',
dataIndex: 'obmxs',
visible: true,
width: 180,
sort: true
},
{
key: 'ckflz',
title: '校核洪水位(m)',
dataIndex: 'ckflz',
visible: true,
width: 140,
sort: true
},
{
key: 'dsflz',
title: '设计洪水位(m)',
dataIndex: 'dsflz',
visible: true,
width: 140,
sort: true
},
{
key: 'normz',
title: '正常蓄水位(m)',
dataIndex: 'normz',
visible: true,
width: 140,
sort: true
},
{
key: 'uzfc',
title: '防洪高水位(m)',
dataIndex: 'uzfc',
visible: true,
width: 140,
sort: true
},
{
key: 'fsltdz',
title: '防洪限制水位(m)',
dataIndex: 'fsltdz',
visible: true,
width: 150,
sort: true
},
{
key: 'ydownz',
title: '年消落水位(m)',
dataIndex: 'ydownz',
visible: true,
width: 140,
sort: true
},
{
key: 'ddz',
title: '死水位(m)',
dataIndex: 'ddz',
visible: true,
width: 120,
sort: true
},
{
key: 'nrzar',
title: '正常蓄水位水库面积(km²)',
dataIndex: 'nrzar',
visible: true,
width: 200,
sort: true
},
{
key: 'bcklen',
title: '回水长度(km)',
dataIndex: 'bcklen',
visible: true,
width: 130,
sort: true
},
{
key: 'ttcp',
title: '总库容(亿m³)',
dataIndex: 'ttcp',
visible: true,
width: 130,
sort: true
},
{
key: 'nmzcp',
title: '正常蓄水位以下库容(亿m³)',
dataIndex: 'nmzcp',
visible: true,
width: 200,
sort: true
},
{
key: 'fldcpStr',
title: '防洪库容(亿m³)',
dataIndex: 'fldcpStr',
visible: true,
width: 140,
sort: true
},
{
key: 'actcp',
title: '调节库容(亿m³)',
dataIndex: 'actcp',
visible: true,
width: 140,
sort: true
},
{
key: 'ddcp',
title: '死库容(亿m³)',
dataIndex: 'ddcp',
visible: true,
width: 130,
sort: true
},
{
key: 'cpsc',
title: '库容系数(%)',
dataIndex: 'cpsc',
visible: true,
width: 120,
sort: true
},
{
key: 'rgcpName',
title: '调节性能',
dataIndex: 'rgcpName',
visible: true,
width: 120,
sort: true,
ellipsis: true
},
{
key: 'dsflzmxq',
title: '设计洪水位时最大下泄流量(m³/s)',
dataIndex: 'dsflzmxq',
visible: true,
width: 250,
sort: true
},
{
key: 'dsflzxyz',
title: '设计洪水位时最大下泄流量相应下游水位(m)',
dataIndex: 'dsflzxyz',
visible: true,
width: 320,
sort: true
},
{
key: 'ckflzmxq',
title: '校核洪水位时最大下泄流量(m³/s)',
dataIndex: 'ckflzmxq',
visible: true,
width: 250,
sort: true
},
{
key: 'ckflzxyz',
title: '校核洪水位时最大下泄流量相应下游水位(m)',
dataIndex: 'ckflzxyz',
visible: true,
width: 320,
sort: true
},
{
key: 'ksqadjq',
title: '枯水期调节流量(m³/s)',
dataIndex: 'ksqadjq',
visible: true,
width: 170,
sort: true
},
{
key: 'ksqxyz',
title: '枯水期调节流量相应下游水位(m)',
dataIndex: 'ksqxyz',
visible: true,
width: 250,
sort: true
},
{
key: 'gemaxrq',
title: '发电最大引用流量(m³/s)',
dataIndex: 'gemaxrq',
visible: true,
width: 190,
sort: true
},
{
key: 'mxgeqxyz',
title: '发电最大引用流量相应下游水位(m)',
dataIndex: 'mxgeqxyz',
visible: true,
width: 260,
sort: true
},
{
key: 'ttpwr',
title: '装机容量',
dataIndex: 'ttpwr',
visible: true,
width: 120,
sort: true,
ellipsis: true
},
{
key: 'gncnt',
title: '装机台数(台)',
dataIndex: 'gncnt',
visible: true,
width: 130,
sort: true,
ellipsis: true
},
{
key: 'gntp',
title: '容量构成(台*MW)',
dataIndex: 'gntp',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'grntpwr',
title: '保证出力(MW)',
dataIndex: 'grntpwr',
visible: true,
width: 130,
sort: true,
ellipsis: true
},
{
key: 'yrge',
title: '多年平均年发电量(亿kW·h)',
dataIndex: 'yrge',
visible: true,
width: 200,
sort: true
},
{
key: 'ushr',
title: '年利用小时数(h)',
dataIndex: 'ushr',
visible: true,
width: 150,
sort: true
},
{
key: 'k',
title: '机组综合出力系数',
dataIndex: 'k',
visible: true,
width: 150,
sort: true,
ellipsis: true
},
{
key: 'dmtp',
title: '坝型',
dataIndex: 'dmtp',
visible: true,
width: 100,
sort: true,
ellipsis: true
},
{
key: 'dmcrel',
title: '坝顶高程(m)',
dataIndex: 'dmcrel',
visible: true,
width: 130,
sort: true
},
{
key: 'mxdmhg',
title: '最大坝高(m)',
dataIndex: 'mxdmhg',
visible: true,
width: 120,
sort: true
},
{
key: 'dmlen',
title: '坝顶长度(m)',
dataIndex: 'dmlen',
visible: true,
width: 130,
sort: true
},
{
key: 'sgyge',
title: '单独年发电量(亿kW·h)',
dataIndex: 'sgyge',
visible: true,
width: 180,
sort: true
},
{
key: 'unyge',
title: '联合年发电量(亿kW·h)',
dataIndex: 'unyge',
visible: true,
width: 180,
sort: true
},
{
key: 'gap',
title: '利用落差(m)',
dataIndex: 'gap',
visible: true,
width: 120,
sort: true
},
{
key: 'dvtpName',
title: '开发方式',
dataIndex: 'dvtpName',
visible: true,
width: 120,
sort: true
},
{
key: 'dtinName',
title: '接入状态',
dataIndex: 'dtinName',
visible: true,
width: 120,
sort: true,
ellipsis: true
},
{
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: isEdit.value ? 180 : 100
}
]);
//
const dateRender = ({ text }: { text: string }) => {
if (!text || text === '-') return '-';
const date = dayjs(text);
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
};
//
const columnMetaMap: Record<string, any> = {
stnm: { width: 150, fixed: 'left', sort: true, ellipsis: true },
addvcdName: { width: 150, sort: true, ellipsis: true },
stlc: { width: 200, sort: true, ellipsis: true },
baseName: { width: 120, ellipsis: true },
jcdt: { width: 120, sort: true, ellipsis: true, customRender: dateRender },
piodt: { width: 160, sort: true, ellipsis: true, customRender: dateRender },
aiodt: { width: 150, sort: true, ellipsis: true, customRender: dateRender },
bldsttCcodeName: { width: 100, sort: true, ellipsis: true },
hynm: { width: 150, sort: true, ellipsis: true },
topHynm: { width: 150, sort: true, ellipsis: true },
nrupar: { width: 180, sort: true },
dstcrvr: { width: 150, sort: true },
avyrp: { width: 170, sort: true },
avw: { width: 190, sort: true },
avq: { width: 160, sort: true },
avq01: { width: 180, sort: true },
avq02: { width: 180, sort: true },
avq03: { width: 180, sort: true },
avq04: { width: 180, sort: true },
avq05: { width: 180, sort: true },
avq06: { width: 180, sort: true },
avq07: { width: 180, sort: true },
avq08: { width: 180, sort: true },
avq09: { width: 180, sort: true },
avq10: { width: 190, sort: true },
avq11: { width: 190, sort: true },
avq12: { width: 190, sort: true },
obmxq: { width: 170, sort: true },
obmnq: { width: 170, sort: true },
hmxq: { width: 190, sort: true },
dsnfqfrq: { width: 190, sort: true },
dsrcin: { width: 160, sort: true },
ckfqfqr: { width: 190, sort: true },
chrcin: { width: 160, sort: true },
obmxw3: { width: 220, sort: true },
dsw3: { width: 190, sort: true },
ckw3: { width: 190, sort: true },
avsd: { width: 180 },
avs: { width: 180, sort: true },
obmxs: { width: 180, sort: true },
ckflz: { width: 140, sort: true },
dsflz: { width: 140, sort: true },
normz: { width: 140, sort: true },
uzfc: { width: 140, sort: true },
fsltdz: { width: 150, sort: true },
ydownz: { width: 140, sort: true },
ddz: { width: 120, sort: true },
nrzar: { width: 200, sort: true },
bcklen: { width: 130, sort: true },
ttcp: { width: 130, sort: true },
nmzcp: { width: 200, sort: true },
fldcpStr: { width: 140, sort: true },
actcp: { width: 140, sort: true },
ddcp: { width: 130, sort: true },
cpsc: { width: 120, sort: true },
rgcpName: { width: 120, sort: true, ellipsis: true },
dsflzmxq: { width: 250, sort: true },
dsflzxyz: { width: 320, sort: true },
ckflzmxq: { width: 250, sort: true },
ckflzxyz: { width: 320, sort: true },
ksqadjq: { width: 170, sort: true },
ksqxyz: { width: 250, sort: true },
gemaxrq: { width: 190, sort: true },
mxgeqxyz: { width: 260, sort: true },
ttpwr: { width: 120, sort: true, ellipsis: true },
gncnt: { width: 130, sort: true, ellipsis: true },
gntp: { width: 150, sort: true, ellipsis: true },
grntpwr: { width: 130, sort: true, ellipsis: true },
yrge: { width: 200, sort: true },
ushr: { width: 150, sort: true },
k: { width: 150, sort: true, ellipsis: true },
dmtp: { width: 100, sort: true, ellipsis: true },
dmcrel: { width: 130, sort: true },
mxdmhg: { width: 120, sort: true },
dmlen: { width: 130, sort: true },
sgyge: { width: 180, sort: true },
unyge: { width: 180, sort: true },
gap: { width: 120, sort: true },
dvtpName: { width: 120, sort: true },
dtinName: { width: 120, sort: true, ellipsis: true }
};
// API columnEn dataIndex
const apiToDataIndexMap: Record<string, string> = {
hbrvcdName: 'reachcdName'
};
const columns = ref<any[]>([]);
const tableScrollX = computed(() =>
Math.max(
@ -861,22 +275,30 @@ const exportBtn = () => {
//
const customFilterBtn = () => {
customColumnVisible.value = true;
//
fetchColumnConfig();
};
//
const handleColumnConfirm = (selectedFiledKeys: string[]) => {
console.log('选中的 filed keys:', selectedFiledKeys);
// filed dataIndex
const filedToDataIndexMap: Record<string, string> = {
ennm: 'stnm'
};
console.log('选中的 columnEn keys:', selectedFiledKeys);
// filed visible
columns.value.forEach((col: any) => {
if (col.key === 'action') return; //
// filed 使 dataIndex
const filed = filedToDataIndexMap[col.dataIndex] || col.dataIndex;
col.visible = selectedFiledKeys.includes(filed);
// 1. checked
const updatedList = userColumnList.value.map((item: any) => ({
...item,
checked: selectedFiledKeys.includes(item.columnEn) ? 1 : 0
}));
// 2. { recordUser, cfgId, list }
const saveParams = {
recordUser: userStore.userid,
cfgId: 'cgsdbase',
list: updatedList
};
batchSaveUserColumn(saveParams).then(() => {
// 3.
fetchColumnConfig();
initTable(currentSearchParams.value);
});
};
const buildSearchParams = (values: any) => {
@ -999,6 +421,7 @@ const buildSearchParams = (values: any) => {
};
const initTable = (values: any) => {
if (!tableRef.value) return;
const params = buildSearchParams(values);
tableRef.value.getList(params);
};
@ -1046,8 +469,62 @@ const handleDelete = (record: any) => {
initTable(currentSearchParams.value);
});
};
//
const fetchColumnConfig = () => {
getUserColumnData({
recordUser: userStore.userid,
cfgId: 'cgsdbase'
}).then((res: any) => {
const list = res?.data || [];
userColumnList.value = list;
// API orderIndex checked 1
const sorted = [...list]
.filter((item: any) => item.checked === 1 && item.defaultConfig !== true)
.sort((a: any, b: any) => a.orderIndex - b.orderIndex);
const cols = sorted.map((item: any) => {
const dataIndex = apiToDataIndexMap[item.columnEn] || item.columnEn;
const meta = columnMetaMap[item.columnEn] || {};
return {
key: item.columnEn,
title: item.columnName,
dataIndex,
...meta
};
});
//
cols.push({
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: isEdit.value ? 180 : 100
});
columns.value = cols;
}).catch(() => {
// API
columns.value = [{
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: isEdit.value ? 180 : 100
}];
}).finally(() => {
columnLoaded.value = true;
//
nextTick(() => {
initTable(currentSearchParams.value);
});
});
};
onMounted(() => {
init();
fetchColumnConfig();
nextTick(() => {
tableScrollY.value = calcTableScrollY();
});

View File

@ -9,6 +9,7 @@
@cancel="handleCancel"
@ok="handleOk"
>
<a-spin :spinning="loading || localLoading" style="min-height: 200px">
<a-form
ref="formRef"
:model="formData"
@ -190,6 +191,7 @@
/>
</div>
</a-form>
</a-spin>
</a-modal>
</template>
@ -548,6 +550,17 @@ watch(
{ immediate: false }
);
//
watch(
() => props.initialValues,
(newVal) => {
if (newVal && modalVisible.value) {
initForm();
}
},
{ deep: true }
);
onBeforeUnmount(() => {
destroySortable();
});

View File

@ -39,6 +39,7 @@
ref="disposeManageFormRef"
v-model:visible="editModalVisible"
:initial-values="currentRecord"
:loading="editLoading"
@cancel="editModalCancel"
@ok="handleEditSubmit"
/>
@ -121,6 +122,7 @@ const searchParams = ref({});
//
const currentRecord = ref<any | null>(null);
const editModalVisible = ref(false);
const editLoading = ref(false);
//
const handleAdd = () => {
@ -160,14 +162,19 @@ const handleExport = async () => {
}
};
// -
// -
const handleEdit = async (record: any) => {
editLoading.value = true;
currentRecord.value = null;
editModalVisible.value = true;
try {
const res = await threedroambGetKendoById({ id: record.id });
currentRecord.value = res?.data || res;
editModalVisible.value = true;
} catch (error) {
message.error('获取数据失败');
editModalVisible.value = false;
} finally {
editLoading.value = false;
}
};