WholeProcessPlatform/frontend-sjgl/src/views/conventionalHydropower/BasicData/index.vue

553 lines
15 KiB
Vue
Raw Normal View History

2026-07-20 16:02:51 +08:00
<template>
2026-07-21 18:38:17 +08:00
<div class="w-full h-full flex flex-col pt-[20px] pl-[20px] body_one">
2026-07-20 16:02:51 +08:00
<!-- 搜索组件 -->
<BasicDataSearch
:topHynmList="topHynmList"
:hycdList="hycdList"
:topHynmLoading="topHynmLoading"
:hycdLoading="hycdLoading"
:dvtpList="dvtpList"
2026-07-22 09:06:17 +08:00
@add="handleAdd"
2026-07-20 16:02:51 +08:00
@export-btn="exportBtn"
@custom-filter-btn="customFilterBtn"
@search-finish="onSearchFinish"
@reset="onReset"
ref="searchRef"
/>
<!-- 表格组件 -->
<BasicTable
v-if="columnLoaded"
2026-07-20 16:02:51 +08:00
ref="tableRef"
:enableEllipsis="true"
:scrollX="tableScrollX"
:scrollY="tableScrollY"
:columns="columns"
:searchParams="{
sort: sort
}"
:list-url="getPowerTableList"
>
<template #action="{ record }">
<a-button
type="link"
class="text-[#2f6b98]"
size="small"
@click="handleDetail(record)"
>查看详情</a-button
>
<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>
<!-- 自定义数据列 Modal -->
<CustomColumnModal
v-if="columnLoaded"
2026-07-20 16:02:51 +08:00
v-model:visible="customColumnVisible"
:user-column-list="userColumnList"
2026-07-20 16:02:51 +08:00
@confirm="handleColumnConfirm"
/>
<!-- 编辑电站 Modal -->
<EditPowerModal
v-model:open="editVisible"
2026-07-31 11:13:49 +08:00
:is-add="isAdd"
2026-07-20 16:02:51 +08:00
:dvtp-list="dvtpList"
:record="editRecord"
:top-hynm-list="topHynmList"
:hycd-list="hycdList"
@success="handleEditSuccess"
/>
<!-- 删除确认 Modal -->
<DeleteConfirmModal ref="deleteModalRef" @success="handleEditSuccess" />
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, nextTick } from 'vue';
import dayjs from 'dayjs';
import BasicDataSearch from './BasicDataSearch.vue';
import BasicTable from '@/components/BasicTable/index.vue';
import CustomColumnModal from './CustomColumnModal.vue';
import EditPowerModal from './EditPowerModal.vue';
import DeleteConfirmModal from './DeleteConfirmModal.vue';
import {
getCompanyList,
getPowerTableList,
2026-07-22 09:06:17 +08:00
addPowerInfo,
2026-07-20 16:02:51 +08:00
updatePowerInfo,
deletePowerInfo,
getUserColumnData,
batchSaveUserColumn
2026-07-20 16:02:51 +08:00
} from '@/api/DataQueryMenuModule';
import { getEngInfoById } from '@/api/select';
import { calcTableScrollY } from '@/utils/index';
import { useModelStore } from '@/store/modules/model';
import { useUserStore } from "@/store/modules/user";
2026-07-20 16:02:51 +08:00
const modelStore = useModelStore();
const userStore = useUserStore();
2026-07-20 16:02:51 +08:00
const sort = ref<any>([
{
field: 'baseStepSort',
dir: 'asc'
},
{
field: 'rvcdStepSort',
dir: 'asc'
},
{
field: 'rstcdStepSort',
dir: 'asc'
},
{
field: 'ttpwr',
dir: 'asc'
}
]);
const tableRef = ref();
const searchRef = ref();
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);
2026-07-20 16:02:51 +08:00
// 编辑相关
const editVisible = ref(false);
const editRecord = ref<any>(null);
2026-07-22 09:06:17 +08:00
const isAdd = ref(false);
2026-07-20 16:02:51 +08:00
const deleteModalRef = ref();
// 集团和公司数据
const topHynmList = ref<any>([]);
const hycdList = ref<any>([]);
const topHynmLoading = ref(false);
const hycdLoading = ref(false);
const isEdit = ref(true);
const dvtpList = ref<any[]>([
{ label: '堤坝式', value: '0' },
{ label: '引水式', value: '1' },
{ label: '混合式', value: '2' }
]);
// 日期列渲染函数
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[]>([]);
2026-07-20 16:02:51 +08:00
const tableScrollX = computed(() =>
Math.max(
columns.value.reduce(
(sum: number, col: any) => sum + (col.width || 180),
0
),
600
)
);
const onSearchFinish = (values: any) => {
currentSearchParams.value = values;
initTable(values);
};
const onReset = (values: any) => {
currentSearchParams.value = values;
initTable(values);
};
// 导出
const exportBtn = () => {
if (exportLoading.value) return;
exportLoading.value = true;
searchRef.value.btnLoading = true;
tableRef.value
.exportTable({
fileName: `基础数据_${dayjs().format('YYYY-MM-DD HH-mm-ss')}`
})
.finally(() => {
exportLoading.value = false;
searchRef.value.btnLoading = false;
});
};
// 自定义筛选列
const customFilterBtn = () => {
customColumnVisible.value = true;
};
// 确认自定义列选择
const handleColumnConfirm = (selectedFiledKeys: string[]) => {
console.log('选中的 columnEn keys:', selectedFiledKeys);
// 1. 构建保存数据(更新 checked 字段)
const updatedList = userColumnList.value.map((item: any) => ({
...item,
checked: selectedFiledKeys.includes(item.columnEn) ? 1 : 0
}));
2026-07-20 16:02:51 +08:00
// 2. 按接口要求包装为 { recordUser, cfgId, list }
const saveParams = {
recordUser: userStore.userid,
cfgId: 'cgsdbase',
list: updatedList
};
batchSaveUserColumn(saveParams).then(() => {
// 3. 保存成功后重新请求表头配置和表格数据
fetchColumnConfig();
initTable(currentSearchParams.value);
2026-07-20 16:02:51 +08:00
});
};
const buildSearchParams = (values: any) => {
console.log(values);
return {
logic: 'and',
filters: [
values.rvcd && values.rvcd !== 'all'
? {
field: 'rvcd',
operator: 'contains',
dataType: 'string',
value: values.rvcd
}
: null,
values.rstcd
? {
field: 'stcd',
operator: 'eq',
dataType: 'string',
value: values.rstcd
}
: null,
values.baseId
? {
field: 'baseId',
operator: 'eq',
dataType: 'string',
value: values.baseId
}
: null,
values.hbrvcd
? {
field: 'hbrvcd',
operator: 'eq',
dataType: 'string',
value: values.hbrvcd
}
: null,
values.bldsttCcode != undefined && values.bldsttCcode != ''
? {
field: 'bldsttCcode',
operator: 'eq',
dataType: 'string',
value: values.bldsttCcode
}
: null,
values.hycd
? {
field: 'hycd',
operator: 'eq',
dataType: 'string',
value: values.hycd
}
: null,
values.topHynm
? {
field: 'topHynm',
operator: 'eq',
dataType: 'string',
value: values.topHynm
}
: null,
values.ttpwr && values.ttpwr.min
? {
field: 'ttpwr',
operator: 'gte',
dataType: 'string',
value: values.ttpwr.min * 10
}
: null,
values.ttpwr && values.ttpwr.max
? {
field: 'ttpwr',
operator: 'lte',
dataType: 'string',
value: values.ttpwr.max * 10
}
: null,
values.jcdt && values.jcdt.min
? {
field: 'jcdt',
operator: 'gte',
dataType: 'date',
value: values.jcdt.min
}
: null,
values.jcdt && values.jcdt.max
? {
field: 'jcdt',
operator: 'lte',
dataType: 'date',
value: values.jcdt.max
}
: null,
values.dtin && values.dtin !== 'all'
? {
field: 'dtin',
operator: 'eq',
dataType: 'string',
value: values.dtin
}
: null,
values.dvtp && values.dvtp.length > 0
? {
logic: 'or',
filters: [
...values.dvtp.map((item: any) => ({
field: 'dvtp',
operator: 'eq',
dataType: 'string',
value: item
}))
]
}
: null
].filter(Boolean)
};
};
const initTable = (values: any) => {
if (!tableRef.value) return;
2026-07-20 16:02:51 +08:00
const params = buildSearchParams(values);
tableRef.value.getList(params);
};
const init = () => {
topHynmLoading.value = true;
hycdLoading.value = true;
// 获取集团列表 (lx=1)
getCompanyList({ lx: 1 }).then(res => {
topHynmList.value = res?.data || [];
topHynmLoading.value = false;
});
// 获取公司列表 (lx=2)
getCompanyList({ lx: 2 }).then(res => {
hycdList.value = res?.data || [];
hycdLoading.value = false;
});
};
// 查看详情
const handleDetail = (record: any) => {
modelStore.modalVisible = true;
modelStore.params.sttp = record.sttp || record.sttpCode;
modelStore.params.stcd = record.stcd;
modelStore.title = record.stnm;
};
2026-07-22 09:06:17 +08:00
// 新增
const handleAdd = () => {
isAdd.value = true;
editRecord.value = null;
editVisible.value = true;
};
2026-07-20 16:02:51 +08:00
// 编辑
const handleEdit = (record: any) => {
2026-07-22 09:06:17 +08:00
isAdd.value = false;
2026-07-20 16:02:51 +08:00
getEngInfoById({ stcd: record.stcd }).then(res => {
console.log(res);
editRecord.value = { ...res.data };
});
editVisible.value = true;
};
// 编辑成功回调
const handleEditSuccess = () => {
initTable(currentSearchParams.value);
};
// 删除
const handleDelete = (record: any) => {
deleteModalRef.value?.open(record, () => {
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]
2026-07-31 11:13:49 +08:00
.filter((item: any) => item.checked === 1 && item.enable == 1)
.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);
});
});
};
2026-07-20 16:02:51 +08:00
onMounted(() => {
init();
fetchColumnConfig();
2026-07-20 16:02:51 +08:00
nextTick(() => {
tableScrollY.value = calcTableScrollY();
});
});
</script>
2026-07-21 18:38:17 +08:00
<style scoped lang="scss">
.body_one{
position: relative;
z-index: 900;
pointer-events: all;
}
</style>