项目bug更改
This commit is contained in:
parent
35db4003a1
commit
6ec994502a
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -405,6 +405,7 @@ const emit = defineEmits<{
|
|||||||
(e: 'finish', values: any): void;
|
(e: 'finish', values: any): void;
|
||||||
(e: 'valuesChange', changedValues: any, allValues: any): void;
|
(e: 'valuesChange', changedValues: any, allValues: any): void;
|
||||||
(e: 'reset'): void;
|
(e: 'reset'): void;
|
||||||
|
(e: 'initDone', values: any): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const formRef = ref<any>();
|
const formRef = ref<any>();
|
||||||
@ -427,7 +428,7 @@ const validSearchList = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// --- 初始化逻辑 ---
|
// --- 初始化逻辑 ---
|
||||||
const initForm = () => {
|
const initForm = async () => {
|
||||||
const initial = JSON.parse(JSON.stringify(props.initialValues || {}));
|
const initial = JSON.parse(JSON.stringify(props.initialValues || {}));
|
||||||
|
|
||||||
// 1. 清空 formData
|
// 1. 清空 formData
|
||||||
@ -437,7 +438,7 @@ const initForm = () => {
|
|||||||
Object.assign(formData, initial);
|
Object.assign(formData, initial);
|
||||||
|
|
||||||
// 3. 过滤掉 searchList 中为 false/null/undefined 的项,并生成规则
|
// 3. 过滤掉 searchList 中为 false/null/undefined 的项,并生成规则
|
||||||
validSearchList.value.forEach(item => {
|
for (const item of validSearchList.value) {
|
||||||
if (item.type == 'waterStation') {
|
if (item.type == 'waterStation') {
|
||||||
// 下拉菜单
|
// 下拉菜单
|
||||||
shuJuTianBaoStore.getBaseOption();
|
shuJuTianBaoStore.getBaseOption();
|
||||||
@ -445,15 +446,23 @@ const initForm = () => {
|
|||||||
shuJuTianBaoStore.getEngOption(formData.rvcd,'rvcd');
|
shuJuTianBaoStore.getEngOption(formData.rvcd,'rvcd');
|
||||||
}
|
}
|
||||||
if (item.type == 'jidiData') {
|
if (item.type == 'jidiData') {
|
||||||
shuJuTianBaoStore.getBaseOption();
|
// 先把默认值摘下并清空显示,等基地数据加载完、判断有无值后再回填,避免 'all' 闪现
|
||||||
shuJuTianBaoStore.getEngOption(formData[item.name] || 'all','baseId');
|
const initialBaseValue = formData[item.name];
|
||||||
|
formData[item.name] = null;
|
||||||
|
await shuJuTianBaoStore.getBaseOption();
|
||||||
|
const hasBaseValue = shuJuTianBaoStore.baseOption.length > 0;
|
||||||
|
if (hasBaseValue) {
|
||||||
|
// 有值才补默认值并加载电站;无值保持 null
|
||||||
|
formData[item.name] = initialBaseValue || 'all';
|
||||||
|
shuJuTianBaoStore.getEngOption(formData[item.name],'baseId');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (item.fieldProps?.required) {
|
if (item.fieldProps?.required) {
|
||||||
rules[item.name] = [
|
rules[item.name] = [
|
||||||
{ required: true, message: `${item.label}不能为空`, trigger: 'blur' }
|
{ required: true, message: `${item.label}不能为空`, trigger: 'blur' }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -501,8 +510,10 @@ const stcdIdChange = (value: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
initForm();
|
await initForm();
|
||||||
|
// 初始化完成(含基地数据加载)后通知外部,供等待时序的页面发起首次查询
|
||||||
|
emit('initDone', { ...formData });
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@ -176,11 +176,11 @@ const columnMetaMap: Record<string, any> = {
|
|||||||
addvcdName: { width: 150, sort: true, ellipsis: true },
|
addvcdName: { width: 150, sort: true, ellipsis: true },
|
||||||
stlc: { width: 200, sort: true, ellipsis: true },
|
stlc: { width: 200, sort: true, ellipsis: true },
|
||||||
baseName: { width: 120, ellipsis: true },
|
baseName: { width: 120, ellipsis: true },
|
||||||
jcdt: { width: 120, sort: true, ellipsis: true, customRender: dateRender },
|
jcdt: { width: 180, sort: true, ellipsis: true, customRender: dateRender },
|
||||||
piodt: { width: 160, sort: true, ellipsis: true, customRender: dateRender },
|
piodt: { width: 160, sort: true, ellipsis: true, customRender: dateRender },
|
||||||
aiodt: { width: 150, sort: true, ellipsis: true, customRender: dateRender },
|
aiodt: { width: 150, sort: true, ellipsis: true, customRender: dateRender },
|
||||||
bldsttCcodeName: { width: 100, sort: true, ellipsis: true },
|
bldsttCcodeName: { width: 100, sort: true, ellipsis: true },
|
||||||
hynm: { width: 150, sort: true, ellipsis: true },
|
hynm: { width: 240, sort: true, ellipsis: true },
|
||||||
topHynm: { width: 150, sort: true, ellipsis: true },
|
topHynm: { width: 150, sort: true, ellipsis: true },
|
||||||
nrupar: { width: 180, sort: true },
|
nrupar: { width: 180, sort: true },
|
||||||
dstcrvr: { width: 150, sort: true },
|
dstcrvr: { width: 150, sort: true },
|
||||||
@ -243,7 +243,7 @@ const columnMetaMap: Record<string, any> = {
|
|||||||
yrge: { width: 200, sort: true },
|
yrge: { width: 200, sort: true },
|
||||||
ushr: { width: 150, sort: true },
|
ushr: { width: 150, sort: true },
|
||||||
k: { width: 150, sort: true, ellipsis: true },
|
k: { width: 150, sort: true, ellipsis: true },
|
||||||
dmtp: { width: 100, sort: true, ellipsis: true },
|
dmtp: { width: 150, sort: true, ellipsis: true },
|
||||||
dmcrel: { width: 130, sort: true },
|
dmcrel: { width: 130, sort: true },
|
||||||
mxdmhg: { width: 120, sort: true },
|
mxdmhg: { width: 120, sort: true },
|
||||||
dmlen: { width: 130, sort: true },
|
dmlen: { width: 130, sort: true },
|
||||||
|
|||||||
@ -103,7 +103,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="opt in shuJuTianBaoStore.lyOption"
|
v-for="opt in fishLyOption"
|
||||||
:key="opt.rvcd"
|
:key="opt.rvcd"
|
||||||
:value="opt.rvcd"
|
:value="opt.rvcd"
|
||||||
:label="opt.rvnm"
|
:label="opt.rvnm"
|
||||||
@ -307,11 +307,8 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
<a-col :span="12">
|
||||||
<!-- 图片上传 -->
|
<a-form-item label="图片" >
|
||||||
<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
|
<a-upload
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
@ -328,6 +325,10 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
<!-- 图片上传 -->
|
||||||
|
<a-row :gutter="16" class="mt-4">
|
||||||
|
|
||||||
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
@ -350,6 +351,11 @@ import { useDraggable } from '@/utils/drag';
|
|||||||
import { useShuJuTianBaoStore } from '@/store/modules/shuJuTianBao';
|
import { useShuJuTianBaoStore } from '@/store/modules/shuJuTianBao';
|
||||||
const shuJuTianBaoStore = useShuJuTianBaoStore();
|
const shuJuTianBaoStore = useShuJuTianBaoStore();
|
||||||
|
|
||||||
|
// 所属流域选项:过滤掉 "当前全部",避免作为默认值选中
|
||||||
|
const fishLyOption = computed(() =>
|
||||||
|
shuJuTianBaoStore.lyOption.filter((opt: any) => opt.rvcd !== 'all')
|
||||||
|
);
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@ -438,7 +444,7 @@ const fieldLabelMap: Record<string, string> = {
|
|||||||
|
|
||||||
// select 选项映射
|
// select 选项映射
|
||||||
const selectOptionsMap: Record<string, () => any[]> = {
|
const selectOptionsMap: Record<string, () => any[]> = {
|
||||||
rvcd: () => shuJuTianBaoStore.lyOption.map((opt: any) => ({
|
rvcd: () => fishLyOption.value.map((opt: any) => ({
|
||||||
label: opt.rvnm,
|
label: opt.rvnm,
|
||||||
value: opt.rvcd
|
value: opt.rvcd
|
||||||
})),
|
})),
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
:zhujianfujian="'fu'"
|
:zhujianfujian="'fu'"
|
||||||
@reset="handleReset"
|
@reset="handleReset"
|
||||||
@finish="onSearchFinish"
|
@finish="onSearchFinish"
|
||||||
|
@init-done="handleInitDone"
|
||||||
>
|
>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<a-button @click="hideBtn">{{ isHide ? '展开' : '隐藏' }}</a-button>
|
<a-button @click="hideBtn">{{ isHide ? '展开' : '隐藏' }}</a-button>
|
||||||
@ -16,7 +17,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import BasicSearch from '@/components/BasicSearch/index.vue';
|
import BasicSearch from '@/components/BasicSearch/index.vue';
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@ -78,9 +79,10 @@ const seeEdit = () => {
|
|||||||
emit('seeEdit');
|
emit('seeEdit');
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
// 等 BasicSearch 初始化完成(基地数据加载、默认值修正)后再发起首次查询
|
||||||
emit('search-finish', { ...initSearchData });
|
const handleInitDone = (values: any) => {
|
||||||
});
|
emit('search-finish', { ...values });
|
||||||
|
};
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
basicSearchRef
|
basicSearchRef
|
||||||
|
|||||||
@ -182,17 +182,6 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="简介" name="introduce" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.introduce"
|
|
||||||
placeholder="请输入简介"
|
|
||||||
:maxlength="1000"
|
|
||||||
show-count
|
|
||||||
:rows="2"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
@ -281,7 +270,6 @@ const fieldLabelMap: Record<string, string> = {
|
|||||||
dtfrqcy: '监测频次',
|
dtfrqcy: '监测频次',
|
||||||
jbtxcs: '基本特性参数',
|
jbtxcs: '基本特性参数',
|
||||||
blprd: '所属建设阶段',
|
blprd: '所属建设阶段',
|
||||||
introduce: '简介',
|
|
||||||
remark: '备注'
|
remark: '备注'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@
|
|||||||
@success="handleEditSuccess"
|
@success="handleEditSuccess"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<OperationLogModal v-model:open="operationLogVisible" :table-name="'SD_OTTE_B_H'" :record-name-title="'工程名称'" />
|
<OperationLogModal v-model:open="operationLogVisible" :table-name="'SD_OTWE_B_H'" :record-name-title="'工程名称'" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -1,71 +1,168 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal v-model:open="visible" :title="isAdd ? '新增过鱼设施' : '编辑过鱼设施'" width="80vw" :confirm-loading="confirmLoading" @ok="handleOk" @cancel="handleCancel">
|
<a-modal
|
||||||
<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">
|
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-row :gutter="16">
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="设施编码" name="stcd">
|
<a-form-item label="设施编码" name="stcd">
|
||||||
<a-input v-model:value="formData.stcd" placeholder="请输入设施编码" :disabled="!isAdd" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.stcd"
|
||||||
|
placeholder="请输入设施编码"
|
||||||
|
:disabled="!isAdd"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="设施名称" name="stnm">
|
<a-form-item label="设施名称" name="stnm">
|
||||||
<a-input v-model:value="formData.stnm" placeholder="请输入设施名称" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.stnm"
|
||||||
|
placeholder="请输入设施名称"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="设施类型" name="sttp">
|
<a-form-item label="设施类型" name="sttp">
|
||||||
<a-select v-model:value="formData.sttp" placeholder="请选择设施类型" allow-clear show-search :filter-option="filterOption">
|
<a-select
|
||||||
<a-select-option v-for="item in sttpOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
|
v-model:value="formData.sttp"
|
||||||
|
placeholder="请选择设施类型"
|
||||||
|
allow-clear
|
||||||
|
show-search
|
||||||
|
:filter-option="filterOption"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="item in sttpOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>{{ item.label }}</a-select-option
|
||||||
|
>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="站址/位置" name="stlc">
|
<a-form-item label="站址/位置" name="stlc">
|
||||||
<a-input v-model:value="formData.stlc" placeholder="请输入站址" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.stlc"
|
||||||
|
placeholder="请输入站址"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="水电基地" name="baseId">
|
<a-form-item label="水电基地" name="baseId">
|
||||||
<a-select v-model:value="formData.baseId" placeholder="请选择水电基地" allow-clear show-search :filter-option="filterOption">
|
<a-select
|
||||||
<a-select-option v-for="item in baseNameOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
|
v-model:value="formData.baseId"
|
||||||
|
placeholder="请选择水电基地"
|
||||||
|
allow-clear
|
||||||
|
show-search
|
||||||
|
:filter-option="filterOption"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="item in baseNameOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>{{ item.label }}</a-select-option
|
||||||
|
>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="所属电站" name="rstcd">
|
<a-form-item label="所属电站" name="rstcd">
|
||||||
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption">
|
<a-select
|
||||||
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
|
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-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="经度(°)" name="lgtd">
|
<a-form-item label="经度(°)" name="lgtd">
|
||||||
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" />
|
<a-input-number
|
||||||
|
v-model:value="formData.lgtd"
|
||||||
|
placeholder="请输入"
|
||||||
|
:precision="6"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="纬度(°)" name="lttd">
|
<a-form-item label="纬度(°)" name="lttd">
|
||||||
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" />
|
<a-input-number
|
||||||
|
v-model:value="formData.lttd"
|
||||||
|
placeholder="请输入"
|
||||||
|
:precision="6"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="高程(m)" name="elev">
|
<a-form-item label="高程(m)" name="elev">
|
||||||
<a-input-number v-model:value="formData.elev" placeholder="请输入" :precision="6" style="width: 100%" />
|
<a-input-number
|
||||||
|
v-model:value="formData.elev"
|
||||||
|
placeholder="请输入"
|
||||||
|
:precision="6"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="开工日期" name="swdt">
|
<a-form-item label="开工日期" name="swdt">
|
||||||
<a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledSwdtDate" placeholder="请选择开工日期" style="width: 100%" />
|
<a-date-picker
|
||||||
|
v-model:value="formData.swdt"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
:disabled-date="disabledSwdtDate"
|
||||||
|
placeholder="请选择开工日期"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="建成日期" name="jcdt">
|
<a-form-item label="建成日期" name="jcdt">
|
||||||
<a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledJcdtDate" placeholder="请选择建成日期" style="width: 100%" />
|
<a-date-picker
|
||||||
|
v-model:value="formData.jcdt"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
:disabled-date="disabledJcdtDate"
|
||||||
|
placeholder="请选择建成日期"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="建设状态" name="bldsttCode">
|
<a-form-item label="建设状态" name="bldsttCode">
|
||||||
<a-select v-model:value="formData.bldsttCode" placeholder="请选择建设状态" allow-clear>
|
<a-select
|
||||||
|
v-model:value="formData.bldsttCode"
|
||||||
|
placeholder="请选择建设状态"
|
||||||
|
allow-clear
|
||||||
|
>
|
||||||
<a-select-option :value="0">规划</a-select-option>
|
<a-select-option :value="0">规划</a-select-option>
|
||||||
<a-select-option :value="1">在建</a-select-option>
|
<a-select-option :value="1">在建</a-select-option>
|
||||||
<a-select-option :value="2">已建</a-select-option>
|
<a-select-option :value="2">已建</a-select-option>
|
||||||
@ -74,59 +171,114 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="投资(亿元)" name="inv">
|
<a-form-item label="投资(亿元)" name="inv">
|
||||||
<a-input-number v-model:value="formData.inv" placeholder="请输入" :precision="4" style="width: 100%" />
|
<a-input-number
|
||||||
|
v-model:value="formData.inv"
|
||||||
|
placeholder="请输入"
|
||||||
|
:precision="4"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="上游码头位置" name="symtlc">
|
<a-form-item label="上游码头位置" name="symtlc">
|
||||||
<a-input v-model:value="formData.symtlc" placeholder="请输入" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.symtlc"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="上游码头型式" name="symtxs">
|
<a-form-item label="上游码头型式" name="symtxs">
|
||||||
<a-input v-model:value="formData.symtxs" placeholder="请输入" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.symtxs"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="下游码头位置" name="xymtlc">
|
<a-form-item label="下游码头位置" name="xymtlc">
|
||||||
<a-input v-model:value="formData.xymtlc" placeholder="请输入" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.xymtlc"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="下游码头型式" name="xymtxs">
|
<a-form-item label="下游码头型式" name="xymtxs">
|
||||||
<a-input v-model:value="formData.xymtxs" placeholder="请输入" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.xymtxs"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="集诱鱼方式" name="jyfs">
|
<a-form-item label="集诱鱼方式" name="jyfs">
|
||||||
<a-input v-model:value="formData.jyfs" placeholder="请输入" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.jyfs"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="运鱼设施方式" name="yyfs">
|
<a-form-item label="运鱼设施方式" name="yyfs">
|
||||||
<a-input v-model:value="formData.yyfs" placeholder="请输入" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.yyfs"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="过鱼规模(尾)" name="sjgycnt">
|
<a-form-item label="过鱼规模(尾)" name="sjgycnt">
|
||||||
<a-input v-model:value="formData.sjgycnt" placeholder="请输入" style="width: 100%" />
|
<a-input
|
||||||
|
v-model:value="formData.sjgycnt"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="过鱼月份" name="fpssmn">
|
<a-form-item label="过鱼月份" name="fpssmn">
|
||||||
<a-select :key="visible" v-model:value="formData.fpssmn" mode="multiple" placeholder="请选择过鱼月份" allow-clear>
|
<a-select
|
||||||
<a-select-option v-for="item in fpssmnOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
|
:key="visible"
|
||||||
|
v-model:value="formData.fpssmn"
|
||||||
|
mode="multiple"
|
||||||
|
placeholder="请选择过鱼月份"
|
||||||
|
allow-clear
|
||||||
|
:max-tag-count="4"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="item in fpssmnOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>{{ item.label }}</a-select-option
|
||||||
|
>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="监测频次(min)" name="dtfrqcy">
|
<a-form-item label="监测频次(min)" name="dtfrqcy">
|
||||||
<a-input-number v-model:value="formData.dtfrqcy" placeholder="请输入" :precision="0" style="width: 100%" />
|
<a-input-number
|
||||||
|
v-model:value="formData.dtfrqcy"
|
||||||
|
placeholder="请输入"
|
||||||
|
:precision="0"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="监测方式" name="mway">
|
<a-form-item label="监测方式" name="mway">
|
||||||
<a-select v-model:value="formData.mway" placeholder="请选择监测方式" allow-clear>
|
<a-select
|
||||||
|
v-model:value="formData.mway"
|
||||||
|
placeholder="请选择监测方式"
|
||||||
|
allow-clear
|
||||||
|
>
|
||||||
<a-select-option :value="1">人工</a-select-option>
|
<a-select-option :value="1">人工</a-select-option>
|
||||||
<a-select-option :value="2">自动</a-select-option>
|
<a-select-option :value="2">自动</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
@ -136,7 +288,13 @@
|
|||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
<ConfirmModal v-model:open="confirmModalVisible" :diff-list="diffList" :confirm-loading="confirmLoading" @confirm="handleConfirmSubmit" @cancel="handleConfirmCancel" />
|
<ConfirmModal
|
||||||
|
v-model:open="confirmModalVisible"
|
||||||
|
:diff-list="diffList"
|
||||||
|
:confirm-loading="confirmLoading"
|
||||||
|
@confirm="handleConfirmSubmit"
|
||||||
|
@cancel="handleConfirmCancel"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -154,7 +312,10 @@ const props = defineProps<{ open: boolean; record?: any; isAdd?: boolean }>();
|
|||||||
const emit = defineEmits(['update:open', 'success']);
|
const emit = defineEmits(['update:open', 'success']);
|
||||||
const jidiSelectEventStore = useJidiSelectEventStore();
|
const jidiSelectEventStore = useJidiSelectEventStore();
|
||||||
|
|
||||||
const visible = computed({ get: () => props.open, set: val => emit('update:open', val) });
|
const visible = computed({
|
||||||
|
get: () => props.open,
|
||||||
|
set: val => emit('update:open', val)
|
||||||
|
});
|
||||||
useDraggable(visible, { boundary: true, resetOnOpen: true });
|
useDraggable(visible, { boundary: true, resetOnOpen: true });
|
||||||
|
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
@ -166,29 +327,53 @@ const confirmModalVisible = ref(false);
|
|||||||
|
|
||||||
const formRules = ref<any>({
|
const formRules = ref<any>({
|
||||||
stcd: [{ required: true, message: '请输入设施编码', trigger: 'blur' }],
|
stcd: [{ required: true, message: '请输入设施编码', trigger: 'blur' }],
|
||||||
stnm: [{ required: true, message: '请输入设施名称', trigger: 'blur' }]
|
stnm: [{ required: true, message: '请输入设施名称', trigger: 'blur' }],
|
||||||
|
sttp: [{ required: true, message: '请输入设施名称', trigger: 'blur' }]
|
||||||
});
|
});
|
||||||
|
|
||||||
const engInfoOptions = ref<any[]>([]);
|
const engInfoOptions = ref<any[]>([]);
|
||||||
const sttpOptions = ref<any[]>([]);
|
const sttpOptions = ref<any[]>([]);
|
||||||
|
|
||||||
const baseNameOptions = computed(() =>
|
const baseNameOptions = computed(() =>
|
||||||
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
|
jidiSelectEventStore.jidiData
|
||||||
|
.filter((item: any) => item.wbsCode !== 'all')
|
||||||
|
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
|
||||||
);
|
);
|
||||||
|
|
||||||
const engLoading = ref(false);
|
const engLoading = ref(false);
|
||||||
|
|
||||||
// 过鱼月份静态选项 1月-12月
|
// 过鱼月份静态选项 1月-12月
|
||||||
const fpssmnOptions = ref(Array.from({ length: 12 }, (_, i) => ({ label: `${i + 1}月`, value: `${i + 1}` })));
|
const fpssmnOptions = ref(
|
||||||
|
Array.from({ length: 12 }, (_, i) => ({
|
||||||
|
label: `${i + 1}月`,
|
||||||
|
value: `${i + 1}`
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
const fieldLabelMap: Record<string, string> = {
|
const fieldLabelMap: Record<string, string> = {
|
||||||
stcd: '设施编码', stnm: '设施名称', sttp: '设施类型', stlc: '站址/位置',
|
stcd: '设施编码',
|
||||||
baseId: '水电基地', rstcd: '所属电站', lgtd: '经度(°)', lttd: '纬度(°)',
|
stnm: '设施名称',
|
||||||
elev: '高程(m)', swdt: '开工日期', jcdt: '建成日期', bldsttCode: '建设状态',
|
sttp: '设施类型',
|
||||||
inv: '投资(亿元)', symtlc: '上游码头位置', symtxs: '上游码头型式',
|
stlc: '站址/位置',
|
||||||
xymtlc: '下游码头位置', xymtxs: '下游码头型式', jyfs: '集诱鱼方式',
|
baseId: '水电基地',
|
||||||
yyfs: '运鱼设施方式', sjgycnt: '过鱼规模(尾)', fpssmn: '过鱼月份',
|
rstcd: '所属电站',
|
||||||
dtfrqcy: '监测频次(min)', mway: '监测方式'
|
lgtd: '经度(°)',
|
||||||
|
lttd: '纬度(°)',
|
||||||
|
elev: '高程(m)',
|
||||||
|
swdt: '开工日期',
|
||||||
|
jcdt: '建成日期',
|
||||||
|
bldsttCode: '建设状态',
|
||||||
|
inv: '投资(亿元)',
|
||||||
|
symtlc: '上游码头位置',
|
||||||
|
symtxs: '上游码头型式',
|
||||||
|
xymtlc: '下游码头位置',
|
||||||
|
xymtxs: '下游码头型式',
|
||||||
|
jyfs: '集诱鱼方式',
|
||||||
|
yyfs: '运鱼设施方式',
|
||||||
|
sjgycnt: '过鱼规模(尾)',
|
||||||
|
fpssmn: '过鱼月份',
|
||||||
|
dtfrqcy: '监测频次(min)',
|
||||||
|
mway: '监测方式'
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectOptionsMap: Record<string, () => any[]> = {
|
const selectOptionsMap: Record<string, () => any[]> = {
|
||||||
@ -207,7 +392,9 @@ const selectOptionsMap: Record<string, () => any[]> = {
|
|||||||
fpssmn: () => fpssmnOptions.value
|
fpssmn: () => fpssmnOptions.value
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeOrder = ref<{ field: string; label: string; oldValue: string; newValue: string }[]>([]);
|
const changeOrder = ref<
|
||||||
|
{ field: string; label: string; oldValue: string; newValue: string }[]
|
||||||
|
>([]);
|
||||||
const diffList = changeOrder;
|
const diffList = changeOrder;
|
||||||
|
|
||||||
const resolveSelectLabel = (field: string, value: any): string => {
|
const resolveSelectLabel = (field: string, value: any): string => {
|
||||||
@ -215,16 +402,21 @@ const resolveSelectLabel = (field: string, value: any): string => {
|
|||||||
// fpssmn 多选:按逗号分隔,分别解析 label 再合并
|
// fpssmn 多选:按逗号分隔,分别解析 label 再合并
|
||||||
if (field === 'fpssmn') {
|
if (field === 'fpssmn') {
|
||||||
const arr = Array.isArray(value) ? value : String(value).split(',');
|
const arr = Array.isArray(value) ? value : String(value).split(',');
|
||||||
return arr.map((v: any) => {
|
return arr
|
||||||
const trimmed = String(v).trim();
|
.map((v: any) => {
|
||||||
if (!trimmed) return '';
|
const trimmed = String(v).trim();
|
||||||
const opt = fpssmnOptions.value.find((o) => String(o.value) === trimmed);
|
if (!trimmed) return '';
|
||||||
return opt ? opt.label : trimmed;
|
const opt = fpssmnOptions.value.find(o => String(o.value) === trimmed);
|
||||||
}).filter(Boolean).join('、');
|
return opt ? opt.label : trimmed;
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
.join('、');
|
||||||
}
|
}
|
||||||
const getOptions = selectOptionsMap[field];
|
const getOptions = selectOptionsMap[field];
|
||||||
if (getOptions) {
|
if (getOptions) {
|
||||||
const opt = getOptions().find((o: any) => String(o.value) === String(value));
|
const opt = getOptions().find(
|
||||||
|
(o: any) => String(o.value) === String(value)
|
||||||
|
);
|
||||||
if (opt) return opt.label;
|
if (opt) return opt.label;
|
||||||
}
|
}
|
||||||
return String(value);
|
return String(value);
|
||||||
@ -257,94 +449,137 @@ const disabledJcdtDate = (current: any) => {
|
|||||||
return current && current < dayjs(formData.value.swdt).startOf('day');
|
return current && current < dayjs(formData.value.swdt).startOf('day');
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(() => formData.value, newData => {
|
watch(
|
||||||
const original = originalRecord.value;
|
() => formData.value,
|
||||||
for (const key in newData) {
|
newData => {
|
||||||
const oldVal = original[key];
|
const original = originalRecord.value;
|
||||||
const newVal = newData[key];
|
for (const key in newData) {
|
||||||
if (oldVal !== newVal) {
|
const oldVal = original[key];
|
||||||
// fpssmn 多选:数组 vs 字符串比较,需标准化
|
const newVal = newData[key];
|
||||||
if (key === 'fpssmn') {
|
if (oldVal !== newVal) {
|
||||||
const normalize = (v: any) => {
|
// fpssmn 多选:数组 vs 字符串比较,需标准化
|
||||||
if (!v) return '';
|
if (key === 'fpssmn') {
|
||||||
const arr = Array.isArray(v) ? v : String(v).split(',');
|
const normalize = (v: any) => {
|
||||||
return arr.map((s: string) => s.trim()).filter(Boolean).sort().join(',');
|
if (!v) return '';
|
||||||
|
const arr = Array.isArray(v) ? v : String(v).split(',');
|
||||||
|
return arr
|
||||||
|
.map((s: string) => s.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.sort()
|
||||||
|
.join(',');
|
||||||
|
};
|
||||||
|
if (normalize(oldVal) === normalize(newVal)) continue;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
? originalLabels.value[key] ?? 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 (normalize(oldVal) === normalize(newVal)) continue;
|
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
|
||||||
|
else changeOrder.value.push(entry);
|
||||||
|
} else {
|
||||||
|
changeOrder.value = changeOrder.value.filter(c => c.field !== key);
|
||||||
}
|
}
|
||||||
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 ? (originalLabels.value[key] ?? 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 });
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
// 监听 record 变化
|
// 监听 record 变化
|
||||||
const isInitLoading = ref(false);
|
const isInitLoading = ref(false);
|
||||||
watch(() => props.record, newRecord => {
|
watch(
|
||||||
if (newRecord) {
|
() => props.record,
|
||||||
isInitLoading.value = true;
|
newRecord => {
|
||||||
const converted = { ...newRecord };
|
if (newRecord) {
|
||||||
// 将 "-" 还原为 null,避免 date-picker 显示 Invalid Date
|
isInitLoading.value = true;
|
||||||
for (const key in converted) {
|
const converted = { ...newRecord };
|
||||||
if (converted[key] === '-') {
|
// 将 "-" 还原为 null,避免 date-picker 显示 Invalid Date
|
||||||
converted[key] = null;
|
for (const key in converted) {
|
||||||
|
if (converted[key] === '-') {
|
||||||
|
converted[key] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
originalRecord.value = { ...converted };
|
||||||
originalRecord.value = { ...converted };
|
// fpssmn 多选回显:逗号分隔字符串 → 数组
|
||||||
// fpssmn 多选回显:逗号分隔字符串 → 数组
|
const fpssmnArr = converted.fpssmn
|
||||||
const fpssmnArr = converted.fpssmn ? String(converted.fpssmn).split(',').map((s: string) => s.trim()).filter(Boolean) : [];
|
? String(converted.fpssmn)
|
||||||
formData.value = { ...converted, fpssmn: fpssmnArr.length > 0 ? fpssmnArr : undefined };
|
.split(',')
|
||||||
changeOrder.value = [];
|
.map((s: string) => s.trim())
|
||||||
// 编辑时必定加载电站选项,保证 rstcd 回显与 diff 解析
|
.filter(Boolean)
|
||||||
loadEngOptions(converted.baseId || undefined);
|
: [];
|
||||||
// 提前解析 select 字段的原始显示名,防止联动刷新选项后丢失 label
|
formData.value = {
|
||||||
const labels: Record<string, string> = {};
|
...converted,
|
||||||
for (const key in converted) {
|
fpssmn: fpssmnArr.length > 0 ? fpssmnArr : undefined
|
||||||
if (selectOptionsMap[key]) {
|
};
|
||||||
labels[key] = resolveOriginalLabel(key);
|
changeOrder.value = [];
|
||||||
|
// 编辑时必定加载电站选项,保证 rstcd 回显与 diff 解析
|
||||||
|
loadEngOptions(converted.baseId || undefined);
|
||||||
|
// 提前解析 select 字段的原始显示名,防止联动刷新选项后丢失 label
|
||||||
|
const labels: Record<string, string> = {};
|
||||||
|
for (const key in converted) {
|
||||||
|
if (selectOptionsMap[key]) {
|
||||||
|
labels[key] = resolveOriginalLabel(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
originalLabels.value = labels;
|
||||||
|
// 表单填充完成后自动复位标志,避免残留 true 导致后续切换流域不清空电站
|
||||||
|
nextTick(() => {
|
||||||
|
isInitLoading.value = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
originalLabels.value = labels;
|
},
|
||||||
// 表单填充完成后自动复位标志,避免残留 true 导致后续切换流域不清空电站
|
{ deep: true }
|
||||||
nextTick(() => {
|
);
|
||||||
isInitLoading.value = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, { deep: true });
|
|
||||||
|
|
||||||
// 选项加载完成后重新解析原始显示名,避免 record 加载时选项未就绪导致存成 code
|
// 选项加载完成后重新解析原始显示名,避免 record 加载时选项未就绪导致存成 code
|
||||||
watch(
|
watch([baseNameOptions, engInfoOptions, sttpOptions], () => {
|
||||||
[baseNameOptions, engInfoOptions, sttpOptions],
|
const original = originalRecord.value;
|
||||||
() => {
|
if (!original || Object.keys(original).length === 0) return;
|
||||||
const original = originalRecord.value;
|
const labels: Record<string, string> = {};
|
||||||
if (!original || Object.keys(original).length === 0) return;
|
for (const key in original) {
|
||||||
const labels: Record<string, string> = {};
|
if (selectOptionsMap[key]) {
|
||||||
for (const key in original) {
|
labels[key] = resolveOriginalLabel(key);
|
||||||
if (selectOptionsMap[key]) {
|
|
||||||
labels[key] = resolveOriginalLabel(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
originalLabels.value = labels;
|
|
||||||
}
|
}
|
||||||
);
|
originalLabels.value = labels;
|
||||||
|
});
|
||||||
|
|
||||||
const loadEngOptions = async (baseId?: string) => {
|
const loadEngOptions = async (baseId?: string) => {
|
||||||
engLoading.value = true;
|
engLoading.value = true;
|
||||||
try {
|
try {
|
||||||
const params = baseId ? { baseId } : {};
|
const params = baseId ? { baseId } : {};
|
||||||
const res = await getEngInfoDropdown(params);
|
const res = await getEngInfoDropdown(params);
|
||||||
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd }));
|
engInfoOptions.value = (res.data || []).map((item: any) => ({
|
||||||
|
label: item.ennm,
|
||||||
|
value: item.stcd
|
||||||
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取电站列表失败:', error);
|
console.error('获取电站列表失败:', error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -354,41 +589,65 @@ const loadEngOptions = async (baseId?: string) => {
|
|||||||
|
|
||||||
const loadDropdownData = () => {
|
const loadDropdownData = () => {
|
||||||
sttpGetKendoList({
|
sttpGetKendoList({
|
||||||
filter: { logic: 'and', filters: [{ field: 'sttpCode', operator: 'in', dataType: 'string', value: ['FP', 'FP_1', 'FP_2', 'FP_3', 'FP_4', 'FP_5'] }] }
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'sttpCode',
|
||||||
|
operator: 'in',
|
||||||
|
dataType: 'string',
|
||||||
|
value: ['FP', 'FP_1', 'FP_2', 'FP_3', 'FP_4', 'FP_5']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
|
sttpOptions.value = (res.data?.data || []).map((item: any) => ({
|
||||||
|
label: item.sttpName,
|
||||||
|
value: item.sttpCode
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
// 从 store 获取水电基地数据(computed 已自动响应,无需手动赋值)
|
// 从 store 获取水电基地数据(computed 已自动响应,无需手动赋值)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 水电基地变化时联动电站
|
// 水电基地变化时联动电站
|
||||||
watch(() => formData.value?.baseId, (newBaseId) => {
|
watch(
|
||||||
// record 加载时已在 record watch 中加载过电站选项,这里仅跳过清空
|
() => formData.value?.baseId,
|
||||||
if (isInitLoading.value) {
|
newBaseId => {
|
||||||
return;
|
// record 加载时已在 record watch 中加载过电站选项,这里仅跳过清空
|
||||||
}
|
if (isInitLoading.value) {
|
||||||
formData.value.rstcd = undefined;
|
return;
|
||||||
loadEngOptions(newBaseId || undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(() => props.open, val => {
|
|
||||||
if (val) {
|
|
||||||
if (props.isAdd) {
|
|
||||||
formData.value = { fpssmn: [] };
|
|
||||||
originalRecord.value = {};
|
|
||||||
changeOrder.value = [];
|
|
||||||
loadEngOptions();
|
|
||||||
}
|
}
|
||||||
loadDropdownData();
|
formData.value.rstcd = undefined;
|
||||||
|
loadEngOptions(newBaseId || undefined);
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
if (props.isAdd) {
|
||||||
|
formData.value = { fpssmn: [] };
|
||||||
|
originalRecord.value = {};
|
||||||
|
changeOrder.value = [];
|
||||||
|
loadEngOptions();
|
||||||
|
}
|
||||||
|
loadDropdownData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
try {
|
try {
|
||||||
await formRef.value?.validateFields();
|
await formRef.value?.validateFields();
|
||||||
if (!props.isAdd && changeOrder.value.length === 0) { message.info('未检测到任何修改'); return; }
|
if (!props.isAdd && changeOrder.value.length === 0) {
|
||||||
|
message.info('未检测到任何修改');
|
||||||
|
return;
|
||||||
|
}
|
||||||
confirmModalVisible.value = true;
|
confirmModalVisible.value = true;
|
||||||
} catch (error) { console.error('验证失败:', error); }
|
} catch (error) {
|
||||||
|
console.error('验证失败:', error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleConfirmSubmit = async (source: string) => {
|
const handleConfirmSubmit = async (source: string) => {
|
||||||
@ -399,7 +658,8 @@ const handleConfirmSubmit = async (source: string) => {
|
|||||||
if (props.isAdd) {
|
if (props.isAdd) {
|
||||||
Object.assign(engInfo, formData.value);
|
Object.assign(engInfo, formData.value);
|
||||||
// fpssmn 多选:数组 → 逗号分隔字符串
|
// fpssmn 多选:数组 → 逗号分隔字符串
|
||||||
if (Array.isArray(engInfo.fpssmn)) engInfo.fpssmn = engInfo.fpssmn.join(',');
|
if (Array.isArray(engInfo.fpssmn))
|
||||||
|
engInfo.fpssmn = engInfo.fpssmn.join(',');
|
||||||
res = await addFpInfo({ engInfo, source: source.trim() || '新增' });
|
res = await addFpInfo({ engInfo, source: source.trim() || '新增' });
|
||||||
} else {
|
} else {
|
||||||
engInfo.stcd = formData.value.stcd;
|
engInfo.stcd = formData.value.stcd;
|
||||||
@ -412,7 +672,8 @@ const handleConfirmSubmit = async (source: string) => {
|
|||||||
engInfo[item.field] = val;
|
engInfo[item.field] = val;
|
||||||
});
|
});
|
||||||
// fpssmn 多选:数组 → 逗号分隔字符串
|
// fpssmn 多选:数组 → 逗号分隔字符串
|
||||||
if (Array.isArray(engInfo.fpssmn)) engInfo.fpssmn = engInfo.fpssmn.join(',');
|
if (Array.isArray(engInfo.fpssmn))
|
||||||
|
engInfo.fpssmn = engInfo.fpssmn.join(',');
|
||||||
res = await updateFpInfo({ engInfo, source: source.trim() || '编辑' });
|
res = await updateFpInfo({ engInfo, source: source.trim() || '编辑' });
|
||||||
}
|
}
|
||||||
if (res?.code == 0 || res?.success) {
|
if (res?.code == 0 || res?.success) {
|
||||||
@ -420,11 +681,22 @@ const handleConfirmSubmit = async (source: string) => {
|
|||||||
confirmModalVisible.value = false;
|
confirmModalVisible.value = false;
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
emit('success');
|
emit('success');
|
||||||
} else { message.error(res?.msg || (props.isAdd ? '新增失败' : '编辑失败')); }
|
} else {
|
||||||
} catch (error) { message.error('提交失败,请重试'); }
|
message.error(res?.msg || (props.isAdd ? '新增失败' : '编辑失败'));
|
||||||
finally { confirmLoading.value = false; }
|
}
|
||||||
|
} catch (error) {
|
||||||
|
message.error('提交失败,请重试');
|
||||||
|
} finally {
|
||||||
|
confirmLoading.value = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleConfirmCancel = () => { confirmModalVisible.value = false; };
|
const handleConfirmCancel = () => {
|
||||||
const handleCancel = () => { visible.value = false; confirmModalVisible.value = false; formRef.value?.resetFields(); };
|
confirmModalVisible.value = false;
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
visible.value = false;
|
||||||
|
confirmModalVisible.value = false;
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -120,17 +120,6 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="简介" name="introduce" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.introduce"
|
|
||||||
placeholder="请输入简介"
|
|
||||||
:maxlength="1000"
|
|
||||||
show-count
|
|
||||||
:rows="3"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
@ -213,7 +202,6 @@ const fieldLabelMap: Record<string, string> = {
|
|||||||
baseId: '水电基地',
|
baseId: '水电基地',
|
||||||
rstcd: '所属电站',
|
rstcd: '所属电站',
|
||||||
jcdt: '建成日期',
|
jcdt: '建成日期',
|
||||||
introduce: '简介',
|
|
||||||
remark: '备注',
|
remark: '备注',
|
||||||
lgtd: '经度(°)',
|
lgtd: '经度(°)',
|
||||||
lttd: '纬度(°)'
|
lttd: '纬度(°)'
|
||||||
|
|||||||
@ -120,6 +120,7 @@
|
|||||||
placeholder="请选择保护对象"
|
placeholder="请选择保护对象"
|
||||||
allow-clear
|
allow-clear
|
||||||
show-search
|
show-search
|
||||||
|
:max-tag-count="2"
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
|
|||||||
@ -67,10 +67,10 @@ const columns = ref<any[]>([
|
|||||||
{ key: 'stcd', title: '栖息地站码', dataIndex: 'stcd', visible: true, width: 320, ellipsis: true },
|
{ key: 'stcd', title: '栖息地站码', dataIndex: 'stcd', visible: true, width: 320, ellipsis: true },
|
||||||
{ key: 'baseName', title: '水电基地', dataIndex: 'baseName', visible: true, width: 120, ellipsis: true },
|
{ key: 'baseName', title: '水电基地', dataIndex: 'baseName', visible: true, width: 120, ellipsis: true },
|
||||||
{ key: 'ennm', title: '所属电站', dataIndex: 'ennm', visible: true, width: 150, ellipsis: true },
|
{ key: 'ennm', title: '所属电站', dataIndex: 'ennm', visible: true, width: 150, ellipsis: true },
|
||||||
{ key: 'bhdxName', title: '保护对象', dataIndex: 'bhdxName', visible: true, width: 240, ellipsis: true },
|
{ key: 'bhdx', title: '保护对象', dataIndex: 'bhdx', visible: true, width: 240, ellipsis: true },
|
||||||
{ key: 'bhhl', title: '保护河流', dataIndex: 'bhhl', visible: true, width: 120, ellipsis: true },
|
{ key: 'bhhl', title: '保护河流', dataIndex: 'bhhl', visible: true, width: 140, ellipsis: true },
|
||||||
{ key: 'bhhd', title: '保护河段', dataIndex: 'bhhd', visible: true, width: 240, ellipsis: true },
|
{ key: 'bhhd', title: '保护河段', dataIndex: 'bhhd', visible: true, width: 240, ellipsis: true },
|
||||||
{ key: 'bhfw', title: '保护范围', dataIndex: 'bhfw', visible: true, width: 120, ellipsis: true },
|
{ key: 'bhfw', title: '保护范围', dataIndex: 'bhfw', visible: true, width: 240, ellipsis: true },
|
||||||
{ key: 'bhhxcd', title: '保护核心长度(km)', dataIndex: 'bhhxcd', visible: true, width: 140 },
|
{ key: 'bhhxcd', title: '保护核心长度(km)', dataIndex: 'bhhxcd', visible: true, width: 140 },
|
||||||
|
|
||||||
{ key: 'bhcs', title: '保护措施', dataIndex: 'bhcs', visible: true, width: 120, ellipsis: true },
|
{ key: 'bhcs', title: '保护措施', dataIndex: 'bhcs', visible: true, width: 120, ellipsis: true },
|
||||||
|
|||||||
@ -130,14 +130,11 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="保护原因" name="bhyy">
|
<a-form-item label="保护原因" name="bhyy">
|
||||||
<a-select
|
<a-input
|
||||||
v-model:value="formData.bhyy"
|
v-model:value="formData.bhyy"
|
||||||
placeholder="请选择保护原因"
|
placeholder="请输入保护原因"
|
||||||
allow-clear
|
style="width: 100%"
|
||||||
>
|
/>
|
||||||
<a-select-option :value="1">是</a-select-option>
|
|
||||||
<a-select-option :value="0">否</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@ -183,17 +180,6 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="简介" name="introduce" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.introduce"
|
|
||||||
placeholder="请输入简介"
|
|
||||||
:maxlength="1000"
|
|
||||||
show-count
|
|
||||||
:rows="2"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
@ -295,10 +281,6 @@ const selectOptionsMap: Record<string, () => any[]> = {
|
|||||||
{ label: '启用', value: 1 },
|
{ label: '启用', value: 1 },
|
||||||
{ label: '禁用', value: 0 }
|
{ label: '禁用', value: 0 }
|
||||||
],
|
],
|
||||||
bhyy: () => [
|
|
||||||
{ label: '是', value: 1 },
|
|
||||||
{ label: '否', value: 0 }
|
|
||||||
],
|
|
||||||
baseId: () => baseNameOptions.value,
|
baseId: () => baseNameOptions.value,
|
||||||
rstcd: () => engInfoOptions.value
|
rstcd: () => engInfoOptions.value
|
||||||
};
|
};
|
||||||
|
|||||||
@ -120,17 +120,6 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="简介" name="introduce" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.introduce"
|
|
||||||
placeholder="请输入简介"
|
|
||||||
:maxlength="1000"
|
|
||||||
show-count
|
|
||||||
:rows="3"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
@ -216,7 +205,6 @@ const fieldLabelMap: Record<string, string> = {
|
|||||||
baseId: '水电基地',
|
baseId: '水电基地',
|
||||||
rstcd: '所属电站',
|
rstcd: '所属电站',
|
||||||
jcdt: '建成日期',
|
jcdt: '建成日期',
|
||||||
introduce: '简介',
|
|
||||||
remark: '备注',
|
remark: '备注',
|
||||||
lgtd: '经度(°)',
|
lgtd: '经度(°)',
|
||||||
lttd: '纬度(°)'
|
lttd: '纬度(°)'
|
||||||
|
|||||||
@ -171,17 +171,6 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="简介" name="introduce" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.introduce"
|
|
||||||
placeholder="请输入简介"
|
|
||||||
:maxlength="1000"
|
|
||||||
show-count
|
|
||||||
:rows="2"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
@ -275,7 +264,6 @@ const fieldLabelMap: Record<string, string> = {
|
|||||||
dtfrqcy: '监测频次',
|
dtfrqcy: '监测频次',
|
||||||
fwdx: '服务对象',
|
fwdx: '服务对象',
|
||||||
gcfs: '观察方式',
|
gcfs: '观察方式',
|
||||||
introduce: '简介',
|
|
||||||
remark: '备注'
|
remark: '备注'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -182,17 +182,6 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="简介" name="introduce" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.introduce"
|
|
||||||
placeholder="请输入简介"
|
|
||||||
:maxlength="1000"
|
|
||||||
show-count
|
|
||||||
:rows="2"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
@ -283,7 +272,6 @@ const fieldLabelMap: Record<string, string> = {
|
|||||||
dtfrqcy: '监测频次',
|
dtfrqcy: '监测频次',
|
||||||
jbtxcs: '基本特性参数',
|
jbtxcs: '基本特性参数',
|
||||||
blprd: '所属建设阶段',
|
blprd: '所属建设阶段',
|
||||||
introduce: '简介',
|
|
||||||
remark: '备注'
|
remark: '备注'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@
|
|||||||
@success="handleEditSuccess"
|
@success="handleEditSuccess"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<OperationLogModal v-model:open="operationLogVisible" :table-name="'SD_OTWE_B_H'" :record-name-title="'工程名称'" />
|
<OperationLogModal v-model:open="operationLogVisible" :table-name="'SD_OTTE_B_H'" :record-name-title="'工程名称'" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -40,13 +40,13 @@ const deleteModalRef = ref();
|
|||||||
const operationLogVisible = ref(false);
|
const operationLogVisible = ref(false);
|
||||||
|
|
||||||
const columns = ref<any[]>([
|
const columns = ref<any[]>([
|
||||||
{ key: 'stnm', title: '增殖站名称', dataIndex: 'stnm', visible: true, width: 160,fixed: 'left', ellipsis: true },
|
{ key: 'stnm', title: '增殖站名称', dataIndex: 'stnm', visible: true, width: 240,fixed: 'left', ellipsis: true },
|
||||||
{ key: 'stcd', title: '增殖站编码', dataIndex: 'stcd', visible: true, width: 180, ellipsis: true },
|
{ key: 'stcd', title: '增殖站编码', dataIndex: 'stcd', visible: true, width: 180, ellipsis: true },
|
||||||
|
|
||||||
{ key: 'baseName', title: '水电基地', dataIndex: 'baseName', visible: true, width: 120, ellipsis: true },
|
{ key: 'baseName', title: '水电基地', dataIndex: 'baseName', visible: true, width: 120, ellipsis: true },
|
||||||
{ key: 'ennm', title: '所属电站', dataIndex: 'ennm', visible: true, width: 100, ellipsis: true },
|
{ key: 'ennm', title: '所属电站', dataIndex: 'ennm', visible: true, width: 100, ellipsis: true },
|
||||||
|
|
||||||
{ key: 'zzfldx', title: '放流对象', dataIndex: 'zzfldx', visible: true, width: 120, ellipsis: true },
|
{ key: 'zzfldx', title: '放流对象', dataIndex: 'zzfldx', visible: true, width: 260, ellipsis: true },
|
||||||
{ key: 'zzflcnt', title: '放流规模(尾)', dataIndex: 'zzflcnt', visible: true, width: 120 },
|
{ key: 'zzflcnt', title: '放流规模(尾)', dataIndex: 'zzflcnt', visible: true, width: 120 },
|
||||||
|
|
||||||
{ key: 'zzflbjfs', title: '标记方式', dataIndex: 'zzflbjfs', visible: true, width: 100, ellipsis: true },
|
{ key: 'zzflbjfs', title: '标记方式', dataIndex: 'zzflbjfs', visible: true, width: 100, ellipsis: true },
|
||||||
@ -56,7 +56,7 @@ const columns = ref<any[]>([
|
|||||||
{ key: 'zzflfllc', title: '放流地点', dataIndex: 'zzflfllc', visible: true, width: 260, ellipsis: true },
|
{ key: 'zzflfllc', title: '放流地点', dataIndex: 'zzflfllc', visible: true, width: 260, ellipsis: true },
|
||||||
|
|
||||||
{ key: 'zzflyzms', title: '养殖模式', dataIndex: 'zzflyzms', visible: true, width: 220, ellipsis: true },
|
{ key: 'zzflyzms', title: '养殖模式', dataIndex: 'zzflyzms', visible: true, width: 220, ellipsis: true },
|
||||||
{ key: 'zzflgy', title: '生产工艺', dataIndex: 'zzflgy', visible: true, width: 180, ellipsis: true },
|
{ key: 'zzflgy', title: '生产工艺', dataIndex: 'zzflgy', visible: true, width: 240, ellipsis: true },
|
||||||
{ key: 'swdt', title: '开工日期', dataIndex: 'swdt', visible: true, width: 110, customRender: ({ text }) => { if (!text || text === '-') return '-'; const date = dayjs(text); return date.isValid() ? date.format('YYYY-MM-DD') : '-'; } },
|
{ key: 'swdt', title: '开工日期', dataIndex: 'swdt', visible: true, width: 110, customRender: ({ text }) => { if (!text || text === '-') return '-'; const date = dayjs(text); return date.isValid() ? date.format('YYYY-MM-DD') : '-'; } },
|
||||||
{ key: 'jcdt', title: '建成日期', dataIndex: 'jcdt', visible: true, width: 110, customRender: ({ text }) => { if (!text || text === '-') return '-'; const date = dayjs(text); return date.isValid() ? date.format('YYYY-MM-DD') : '-'; } },
|
{ key: 'jcdt', title: '建成日期', dataIndex: 'jcdt', visible: true, width: 110, customRender: ({ text }) => { if (!text || text === '-') return '-'; const date = dayjs(text); return date.isValid() ? date.format('YYYY-MM-DD') : '-'; } },
|
||||||
{ key: 'zzfltm', title: '放流时间', dataIndex: 'zzfltm', visible: true, width: 110, customRender: ({ text }) => { if (!text || text === '-') return '-'; const date = dayjs(text); return date.isValid() ? date.format('YYYY-MM-DD') : '-'; } },
|
{ key: 'zzfltm', title: '放流时间', dataIndex: 'zzfltm', visible: true, width: 110, customRender: ({ text }) => { if (!text || text === '-') return '-'; const date = dayjs(text); return date.isValid() ? date.format('YYYY-MM-DD') : '-'; } },
|
||||||
|
|||||||
@ -2,7 +2,8 @@
|
|||||||
<div
|
<div
|
||||||
id="map-baselayer"
|
id="map-baselayer"
|
||||||
class="baselayer-switcher"
|
class="baselayer-switcher"
|
||||||
:style="{ right: drawerOpen ? '480px' : '26px' }"
|
:class="{ 'is-dzzt': hasDzztBottom }"
|
||||||
|
:style="positionStyle"
|
||||||
v-if="uiStore.mapType == '2D'"
|
v-if="uiStore.mapType == '2D'"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -22,6 +23,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
import { useUiStore } from '@/store/modules/ui';
|
import { useUiStore } from '@/store/modules/ui';
|
||||||
import { useMapConfigStore } from '@/modules/map/stores/map-config.store';
|
import { useMapConfigStore } from '@/modules/map/stores/map-config.store';
|
||||||
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
|
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
|
||||||
@ -39,12 +41,32 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
const uiStore = useUiStore();
|
const uiStore = useUiStore();
|
||||||
|
const route = useRoute();
|
||||||
const mapConfigStore = useMapConfigStore();
|
const mapConfigStore = useMapConfigStore();
|
||||||
const mapViewStore = useMapViewStore();
|
const mapViewStore = useMapViewStore();
|
||||||
// 抽屉展开(页面自带抽屉或全局抽屉任一打开)时,底图切换整体左移
|
// 抽屉展开(页面自带抽屉或全局抽屉任一打开)时,底图切换整体左移
|
||||||
const drawerOpen = computed(
|
const drawerOpen = computed(
|
||||||
() => uiStore.drawerOpen || uiStore.globalDrawerOpen
|
() => uiStore.drawerOpen || uiStore.globalDrawerOpen
|
||||||
);
|
);
|
||||||
|
// 仅电站专题页存在底部模块时应用位置覆盖与九宫格居中样式;其余场景(无底部模块/非专题页)保持原始样式绑定
|
||||||
|
const isDzzt = computed(() =>
|
||||||
|
route.path.includes('dianZhanZhuanTi/dianZhanZhuanTi')
|
||||||
|
);
|
||||||
|
const hasDzztBottom = computed(
|
||||||
|
() => isDzzt.value && !!uiStore.mapControlsPosition.baselayerBottom
|
||||||
|
);
|
||||||
|
const positionStyle = computed(() => {
|
||||||
|
const bottom = uiStore.mapControlsPosition.baselayerBottom;
|
||||||
|
if (hasDzztBottom.value && bottom) {
|
||||||
|
return {
|
||||||
|
right:
|
||||||
|
uiStore.mapControlsPosition.baselayerRight ??
|
||||||
|
(drawerOpen.value ? '480px' : '26px'),
|
||||||
|
bottom
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { right: drawerOpen.value ? '480px' : '26px' };
|
||||||
|
});
|
||||||
const layers = [
|
const layers = [
|
||||||
{ key: 's_province_boundaries', name: '矢量', img: shiliangImg },
|
{ key: 's_province_boundaries', name: '矢量', img: shiliangImg },
|
||||||
{ key: 'BASEMAP-white', name: '地形', img: dixingImg },
|
{ key: 'BASEMAP-white', name: '地形', img: dixingImg },
|
||||||
@ -167,5 +189,11 @@ const handleSwitch = (key: string) => {
|
|||||||
width: 100px !important;
|
width: 100px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 电站专题页有底部模块时:九宫格预览块相对底图切换块水平居中,沿垂直轴堆叠
|
||||||
|
&.is-dzzt .nineSectionsImg {
|
||||||
|
left: 50%;
|
||||||
|
right: auto;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -286,6 +286,7 @@ import EcologicalFlow from './components/EcologicalFlow.vue'; // 生态流量
|
|||||||
import Attachment from './components/Attachment.vue'; // 查看报告/批复文件
|
import Attachment from './components/Attachment.vue'; // 查看报告/批复文件
|
||||||
import WaterTemperatureRep from './components/WaterTemperatureRep.vue'; // 水温对比数据
|
import WaterTemperatureRep from './components/WaterTemperatureRep.vue'; // 水温对比数据
|
||||||
import { useModelStore } from '@/store/modules/model';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
|
import { useUiStore } from '@/store/modules/ui';
|
||||||
import { handleTabs } from './setting.config';
|
import { handleTabs } from './setting.config';
|
||||||
import {
|
import {
|
||||||
getMonitorDataWt,
|
getMonitorDataWt,
|
||||||
@ -304,6 +305,7 @@ import { useDraggable } from '@/utils/drag';
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
|
const uiStore = useUiStore();
|
||||||
const tabsConfig = ref([]);
|
const tabsConfig = ref([]);
|
||||||
// 加载状态:等待所有验证完成后再显示 tabs
|
// 加载状态:等待所有验证完成后再显示 tabs
|
||||||
const isLoading = ref(true);
|
const isLoading = ref(true);
|
||||||
@ -362,6 +364,9 @@ const checkPowerStationTopicData = async (stcd: string) => {
|
|||||||
const gotoEngTopic = () => {
|
const gotoEngTopic = () => {
|
||||||
const stcd = modelStore.params?.stcd;
|
const stcd = modelStore.params?.stcd;
|
||||||
if (!stcd) return;
|
if (!stcd) return;
|
||||||
|
// 跳离地图前关闭全局搜索抽屉
|
||||||
|
uiStore.setIsSearchActive(false);
|
||||||
|
uiStore.setGlobalDrawerOpen(false);
|
||||||
router.push({
|
router.push({
|
||||||
path: '/dianZhanZhuanTi/dianZhanZhuanTi',
|
path: '/dianZhanZhuanTi/dianZhanZhuanTi',
|
||||||
query: { stcd }
|
query: { stcd }
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import {
|
|||||||
offset5
|
offset5
|
||||||
} from '@/utils/GisUrlList';
|
} from '@/utils/GisUrlList';
|
||||||
import { LAYOUT_GRID_SKELETONS } from '@/views/dianZhanZhuanTi/layoutGridSkeletons';
|
import { LAYOUT_GRID_SKELETONS } from '@/views/dianZhanZhuanTi/layoutGridSkeletons';
|
||||||
|
import { useUiStore } from '@/store/modules/ui';
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
__lyConfigs?: {
|
__lyConfigs?: {
|
||||||
@ -340,9 +341,7 @@ export const setMapLegendPos = (
|
|||||||
const legend = document.querySelector('#qgc-legendtl') as HTMLElement;
|
const legend = document.querySelector('#qgc-legendtl') as HTMLElement;
|
||||||
const filter = document.querySelector('#map-filter-container') as HTMLElement;
|
const filter = document.querySelector('#map-filter-container') as HTMLElement;
|
||||||
const compassControl = document.querySelector('#map-compassControl') as HTMLElement;
|
const compassControl = document.querySelector('#map-compassControl') as HTMLElement;
|
||||||
const controller = document.querySelector('#map-controller') as HTMLElement;
|
|
||||||
const monitor = document.querySelector('#map-monitor') as HTMLElement;
|
const monitor = document.querySelector('#map-monitor') as HTMLElement;
|
||||||
const baselayer = document.querySelector('#map-baselayer') as HTMLElement;
|
|
||||||
|
|
||||||
const leftList = getListByPosition(data, 'left');
|
const leftList = getListByPosition(data, 'left');
|
||||||
const rightList = getListByPosition(data, 'right');
|
const rightList = getListByPosition(data, 'right');
|
||||||
@ -386,16 +385,29 @@ export const setMapLegendPos = (
|
|||||||
if (compassControl) {
|
if (compassControl) {
|
||||||
compassControl.style.left = hasLeft ? l : b;
|
compassControl.style.left = hasLeft ? l : b;
|
||||||
}
|
}
|
||||||
if (controller) {
|
|
||||||
controller.style.right = hasRight ? w : '0';
|
|
||||||
controller.style.bottom = hasBottom ? `calc(${bottomOffset} + 10px)` : '0';
|
|
||||||
}
|
|
||||||
if (monitor) {
|
if (monitor) {
|
||||||
monitor.style.right = hasRight ? w : '0';
|
monitor.style.right = hasRight ? w : '0';
|
||||||
}
|
}
|
||||||
if (baselayer) {
|
|
||||||
baselayer.style.right = hasRight ? `calc(${w} + 60px)` : '60px';
|
// 地图控制器/底图切换器:通过 store 发布位置覆盖,组件内联样式优先读取,
|
||||||
baselayer.style.bottom = hasBottom ? bottomOffset : '0';
|
// 避免 JS 直写 el.style 与组件自身 :style 绑定互相覆盖(刷新后重叠问题)。
|
||||||
|
const uiStore = useUiStore();
|
||||||
|
if (hasBottom) {
|
||||||
|
// 有底部模块:有右模块时整体左移避让;两者同底(bottomOffset)
|
||||||
|
uiStore.setMapControlsPosition({
|
||||||
|
controllerRight: hasRight ? w : null,
|
||||||
|
controllerBottom: bottomOffset,
|
||||||
|
baselayerRight: hasRight ? `calc(${w} + 60px)` : null,
|
||||||
|
baselayerBottom: bottomOffset
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 无底部模块:完全回退组件自身默认样式(与非电站专题页面一致)
|
||||||
|
uiStore.setMapControlsPosition({
|
||||||
|
controllerRight: null,
|
||||||
|
controllerBottom: null,
|
||||||
|
baselayerRight: null,
|
||||||
|
baselayerBottom: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div
|
<div
|
||||||
id="map-controller"
|
id="map-controller"
|
||||||
class="map-controller"
|
class="map-controller"
|
||||||
:style="{ right: drawerOpen ? '480px' : '26px' }"
|
:style="positionStyle"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="map-controller-group"
|
class="map-controller-group"
|
||||||
@ -60,6 +60,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, toRef, computed, onUnmounted } from 'vue';
|
import { ref, watch, toRef, computed, onUnmounted } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
import { useUiStore } from '@/store/modules/ui';
|
import { useUiStore } from '@/store/modules/ui';
|
||||||
import Calculate from './Calculate.vue';
|
import Calculate from './Calculate.vue';
|
||||||
import LayerController from './LayerController.vue';
|
import LayerController from './LayerController.vue';
|
||||||
@ -74,10 +75,27 @@ const map = toRef(props, 'map');
|
|||||||
|
|
||||||
// 使用 Pinia store
|
// 使用 Pinia store
|
||||||
const uiStore = useUiStore();
|
const uiStore = useUiStore();
|
||||||
|
const route = useRoute();
|
||||||
// 抽屉展开(页面自带抽屉或全局抽屉任一打开)时,控制器整体左移
|
// 抽屉展开(页面自带抽屉或全局抽屉任一打开)时,控制器整体左移
|
||||||
const drawerOpen = computed(
|
const drawerOpen = computed(
|
||||||
() => uiStore.drawerOpen || uiStore.globalDrawerOpen
|
() => uiStore.drawerOpen || uiStore.globalDrawerOpen
|
||||||
);
|
);
|
||||||
|
// 仅电站专题页存在底部模块时应用位置覆盖;其余场景(无底部模块/非专题页)保持原始样式绑定
|
||||||
|
const isDzzt = computed(() =>
|
||||||
|
route.path.includes('dianZhanZhuanTi/dianZhanZhuanTi')
|
||||||
|
);
|
||||||
|
const positionStyle = computed(() => {
|
||||||
|
const bottom = uiStore.mapControlsPosition.controllerBottom;
|
||||||
|
if (isDzzt.value && bottom) {
|
||||||
|
return {
|
||||||
|
right:
|
||||||
|
uiStore.mapControlsPosition.controllerRight ??
|
||||||
|
(drawerOpen.value ? '480px' : '26px'),
|
||||||
|
bottom
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { right: drawerOpen.value ? '480px' : '26px' };
|
||||||
|
});
|
||||||
const tjVisible = ref(false);
|
const tjVisible = ref(false);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@ -730,6 +730,8 @@ const handleAnchorPointChange = (value: string) => {
|
|||||||
uiStore.setIsSearchActive(true);
|
uiStore.setIsSearchActive(true);
|
||||||
uiStore.setDrawerOpen(false);
|
uiStore.setDrawerOpen(false);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
// 若 300ms 内已跳转到电站专题页则不弹(避免抽屉在专题页闪现)
|
||||||
|
if (route.path.includes('dianZhanZhuanTi/dianZhanZhuanTi')) return;
|
||||||
uiStore.setGlobalDrawerOpen(true);
|
uiStore.setGlobalDrawerOpen(true);
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onBeforeMount, onMounted } from 'vue';
|
import { ref, watch, onBeforeMount, onMounted } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { useMapStore } from '@/store/modules/map';
|
import { useMapStore } from '@/store/modules/map';
|
||||||
@ -23,6 +23,21 @@ const buildPageKeyFromPath = (path?: string) => {
|
|||||||
return normalizedPath || '__route-change__';
|
return normalizedPath || '__route-change__';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 根据当前路由同步主/子菜单选中状态(按 path 或 opturl 匹配,未匹配到则保持原状态)
|
||||||
|
const syncActiveFromRoute = () => {
|
||||||
|
permissionStore.routes.forEach((item: any) => {
|
||||||
|
if (item.meta?.hidden) return;
|
||||||
|
const matched = (item.children || []).find(
|
||||||
|
(child: any) => child.path === route.path || child.opturl === route.path
|
||||||
|
);
|
||||||
|
if (matched) {
|
||||||
|
activeKey.value = item.id;
|
||||||
|
subMenus.value = item.children;
|
||||||
|
subActiveKey.value = matched.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 主菜单切换
|
// 主菜单切换
|
||||||
const handleTabChange = (key: string) => {
|
const handleTabChange = (key: string) => {
|
||||||
let data = menus.value.find((item: any) => item.id === key);
|
let data = menus.value.find((item: any) => item.id === key);
|
||||||
@ -61,18 +76,19 @@ onBeforeMount(() => {
|
|||||||
} else {
|
} else {
|
||||||
menus.value.push(item);
|
menus.value.push(item);
|
||||||
}
|
}
|
||||||
if (item.children) {
|
|
||||||
item.children.map((child: any) => {
|
|
||||||
if (child.path === route.path) {
|
|
||||||
activeKey.value = item.id;
|
|
||||||
subMenus.value = item.children;
|
|
||||||
subActiveKey.value = child.id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
syncActiveFromRoute();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 路由变化(如地图弹窗跳转电站专题)时同步导航栏高亮
|
||||||
|
watch(
|
||||||
|
() => route.path,
|
||||||
|
() => {
|
||||||
|
syncActiveFromRoute();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -192,7 +192,7 @@ const scopeDateConfig = computed(() => ({
|
|||||||
value: [dateRange.value[0], dateRange.value[1]] as any,
|
value: [dateRange.value[0], dateRange.value[1]] as any,
|
||||||
picker: (mway.value === '1' ? 'year' : 'date') as const,
|
picker: (mway.value === '1' ? 'year' : 'date') as const,
|
||||||
format: mway.value === '1' ? 'YYYY' : 'YYYY-MM-DD',
|
format: mway.value === '1' ? 'YYYY' : 'YYYY-MM-DD',
|
||||||
width: mway.value === '1' ? '170px' : '215px'
|
width: mway.value === '1' ? '170px' : '220px'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// ==================== 树数据转换 ====================
|
// ==================== 树数据转换 ====================
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import router from '@/router';
|
|||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
import { useUserStoreHook } from '@/store/modules/user';
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
import { usePermissionStoreHook } from '@/store/modules/permission';
|
import { usePermissionStoreHook } from '@/store/modules/permission';
|
||||||
|
import { useUiStore } from '@/store/modules/ui';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
NProgress.configure({ showSpinner: false });
|
NProgress.configure({ showSpinner: false });
|
||||||
@ -130,6 +131,10 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.afterEach(() => {
|
router.afterEach(to => {
|
||||||
NProgress.done();
|
NProgress.done();
|
||||||
|
// 进入非电站专题页时清除地图控件位置覆盖(防止专题页的 store 覆盖值泄漏到其他页面)
|
||||||
|
if (!to.path.includes('dianZhanZhuanTi')) {
|
||||||
|
useUiStore().resetMapControlsPosition();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -18,6 +18,18 @@ export const useUiStore = defineStore('ui', () => {
|
|||||||
const globalDrawerOpen = ref(false);
|
const globalDrawerOpen = ref(false);
|
||||||
// 是否处于锚点搜索状态(选中命中 DRAWER_STTP_CODES 的锚点时 true;清空/切页等 false)
|
// 是否处于锚点搜索状态(选中命中 DRAWER_STTP_CODES 的锚点时 true;清空/切页等 false)
|
||||||
const isSearchActive = ref(false);
|
const isSearchActive = ref(false);
|
||||||
|
// 地图控件(地图控制器/底图切换器)位置覆盖值;null 表示回退组件自身默认(非电站专题页样式)
|
||||||
|
const mapControlsPosition = ref<{
|
||||||
|
controllerRight: string | null;
|
||||||
|
controllerBottom: string | null;
|
||||||
|
baselayerRight: string | null;
|
||||||
|
baselayerBottom: string | null;
|
||||||
|
}>({
|
||||||
|
controllerRight: null,
|
||||||
|
controllerBottom: null,
|
||||||
|
baselayerRight: null,
|
||||||
|
baselayerBottom: null
|
||||||
|
});
|
||||||
|
|
||||||
// 切换抽屉状态
|
// 切换抽屉状态
|
||||||
const toggleDrawer = () => {
|
const toggleDrawer = () => {
|
||||||
@ -39,6 +51,26 @@ export const useUiStore = defineStore('ui', () => {
|
|||||||
const setIsSearchActive = (active: boolean) => {
|
const setIsSearchActive = (active: boolean) => {
|
||||||
isSearchActive.value = active;
|
isSearchActive.value = active;
|
||||||
};
|
};
|
||||||
|
// 部分更新地图控件位置覆盖
|
||||||
|
const setMapControlsPosition = (
|
||||||
|
partial: Partial<{
|
||||||
|
controllerRight: string | null;
|
||||||
|
controllerBottom: string | null;
|
||||||
|
baselayerRight: string | null;
|
||||||
|
baselayerBottom: string | null;
|
||||||
|
}>
|
||||||
|
) => {
|
||||||
|
mapControlsPosition.value = { ...mapControlsPosition.value, ...partial };
|
||||||
|
};
|
||||||
|
// 重置地图控件位置覆盖(恢复组件自身默认样式,即非电站专题页样式)
|
||||||
|
const resetMapControlsPosition = () => {
|
||||||
|
mapControlsPosition.value = {
|
||||||
|
controllerRight: null,
|
||||||
|
controllerBottom: null,
|
||||||
|
baselayerRight: null,
|
||||||
|
baselayerBottom: null
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const markMapSwitchCompleted = () => {
|
const markMapSwitchCompleted = () => {
|
||||||
mapSwitchCompletedTick.value += 1;
|
mapSwitchCompletedTick.value += 1;
|
||||||
@ -57,6 +89,9 @@ export const useUiStore = defineStore('ui', () => {
|
|||||||
setGlobalDrawerOpen,
|
setGlobalDrawerOpen,
|
||||||
isSearchActive,
|
isSearchActive,
|
||||||
setIsSearchActive,
|
setIsSearchActive,
|
||||||
|
mapControlsPosition,
|
||||||
|
setMapControlsPosition,
|
||||||
|
resetMapControlsPosition,
|
||||||
mapType,
|
mapType,
|
||||||
mapSwitchCompletedTick,
|
mapSwitchCompletedTick,
|
||||||
markMapSwitchCompleted
|
markMapSwitchCompleted
|
||||||
|
|||||||
@ -1,115 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- 第一步:输入修改依据 -->
|
|
||||||
<a-modal
|
|
||||||
v-model:open="dataSourceVisible"
|
|
||||||
:title="title"
|
|
||||||
ok-text="确定"
|
|
||||||
cancel-text="取消"
|
|
||||||
@ok="handleDataSourceConfirm"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<p style="color: red; margin-bottom: 8px">请输入修改依据以继续删除操作</p>
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="dataSource"
|
|
||||||
placeholder="请输入修改依据"
|
|
||||||
:rows="4"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
|
|
||||||
<!-- 第二步:确认删除 -->
|
|
||||||
<a-modal
|
|
||||||
v-model:open="confirmVisible"
|
|
||||||
title="确认删除"
|
|
||||||
ok-text="确认删除"
|
|
||||||
cancel-text="取消"
|
|
||||||
:ok-button-props="{ danger: true }"
|
|
||||||
:confirm-loading="confirmLoading"
|
|
||||||
@ok="handleFinalDelete"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<p style="color: red; font-weight: bold">请慎重操作!</p>
|
|
||||||
<p>{{ label }}名称:{{ deleteRecord?.stnm }}</p>
|
|
||||||
<p>修改依据:{{ dataSource || '无' }}</p>
|
|
||||||
<p>确定要删除该{{ label }}吗?</p>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
import { deletePowerInfo } from '@/api/DataQueryMenuModule';
|
|
||||||
import { useDraggable } from '@/utils/drag';
|
|
||||||
|
|
||||||
const props = withDefaults(
|
|
||||||
defineProps<{
|
|
||||||
/** 自定义删除函数,接收 (record, reason) 参数 */
|
|
||||||
deleteFn?: (record: any, reason: string) => Promise<any>;
|
|
||||||
/** 弹窗标题 */
|
|
||||||
title?: string;
|
|
||||||
/** 显示标签(如"电站"、"数据") */
|
|
||||||
label?: string;
|
|
||||||
}>(),
|
|
||||||
{
|
|
||||||
title: '删除电站',
|
|
||||||
label: '电站'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
|
||||||
|
|
||||||
const dataSourceVisible = ref(false);
|
|
||||||
const confirmVisible = ref(false);
|
|
||||||
const confirmLoading = ref(false);
|
|
||||||
const dataSource = ref('');
|
|
||||||
const deleteRecord = ref<any>(null);
|
|
||||||
const onSuccess = ref<Function>(() => {});
|
|
||||||
|
|
||||||
// 打开删除弹窗
|
|
||||||
const open = (record: any, callback: Function) => {
|
|
||||||
deleteRecord.value = record;
|
|
||||||
dataSource.value = '';
|
|
||||||
dataSourceVisible.value = true;
|
|
||||||
onSuccess.value = callback;
|
|
||||||
};
|
|
||||||
useDraggable(dataSourceVisible, { boundary: true, resetOnOpen: true });
|
|
||||||
useDraggable(confirmVisible, { boundary: true, resetOnOpen: true });
|
|
||||||
// 修改依据确认
|
|
||||||
const handleDataSourceConfirm = () => {
|
|
||||||
dataSourceVisible.value = false;
|
|
||||||
confirmVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 最终删除
|
|
||||||
const handleFinalDelete = async () => {
|
|
||||||
confirmLoading.value = true; // 开始加载
|
|
||||||
try {
|
|
||||||
let res: any;
|
|
||||||
if (props.deleteFn) {
|
|
||||||
// 使用外部传入的删除函数
|
|
||||||
res = await props.deleteFn(deleteRecord.value, dataSource.value);
|
|
||||||
} else {
|
|
||||||
// 默认使用电站删除接口
|
|
||||||
const params = {
|
|
||||||
ids: [deleteRecord.value.stcd],
|
|
||||||
source: dataSource.value
|
|
||||||
};
|
|
||||||
res = await deletePowerInfo(params);
|
|
||||||
}
|
|
||||||
if (res?.code == 0 || res?.success) {
|
|
||||||
message.success('删除成功');
|
|
||||||
confirmVisible.value = false;
|
|
||||||
onSuccess.value();
|
|
||||||
} else {
|
|
||||||
message.error(res?.msg || '删除失败');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
message.error('删除失败,请重试');
|
|
||||||
} finally {
|
|
||||||
confirmLoading.value = false; // 结束加载
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
defineExpose({ open });
|
|
||||||
</script>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,16 @@
|
|||||||
sort: sort
|
sort: sort
|
||||||
}"
|
}"
|
||||||
:list-url="getPowerTableList"
|
:list-url="getPowerTableList"
|
||||||
>
|
><template #action="{ record }">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
class="text-[#2f6b98]"
|
||||||
|
size="small"
|
||||||
|
@click="handleDetail(record)"
|
||||||
|
>查看详情</a-button
|
||||||
|
>
|
||||||
|
|
||||||
|
</template>
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
|
|
||||||
<!-- 自定义数据列 Modal -->
|
<!-- 自定义数据列 Modal -->
|
||||||
@ -36,19 +45,6 @@
|
|||||||
:user-column-list="userColumnList"
|
:user-column-list="userColumnList"
|
||||||
@confirm="handleColumnConfirm"
|
@confirm="handleColumnConfirm"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 编辑电站 Modal -->
|
|
||||||
<EditPowerModal
|
|
||||||
v-model:open="editVisible"
|
|
||||||
:dvtp-list="dvtpList"
|
|
||||||
:record="editRecord"
|
|
||||||
:top-hynm-list="topHynmList"
|
|
||||||
:hycd-list="hycdList"
|
|
||||||
@success="handleEditSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 删除确认 Modal -->
|
|
||||||
<DeleteConfirmModal ref="deleteModalRef" @success="handleEditSuccess" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -57,13 +53,9 @@ import dayjs from 'dayjs';
|
|||||||
import BasicDataSearch from './BasicDataSearch.vue';
|
import BasicDataSearch from './BasicDataSearch.vue';
|
||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
import CustomColumnModal from './CustomColumnModal.vue';
|
import CustomColumnModal from './CustomColumnModal.vue';
|
||||||
import EditPowerModal from './EditPowerModal.vue';
|
|
||||||
import DeleteConfirmModal from './DeleteConfirmModal.vue';
|
|
||||||
import {
|
import {
|
||||||
getCompanyList,
|
getCompanyList,
|
||||||
getPowerTableList,
|
getPowerTableList,
|
||||||
updatePowerInfo,
|
|
||||||
deletePowerInfo,
|
|
||||||
getUserColumnData,
|
getUserColumnData,
|
||||||
batchSaveUserColumn
|
batchSaveUserColumn
|
||||||
} from '@/api/DataQueryMenuModule';
|
} from '@/api/DataQueryMenuModule';
|
||||||
@ -435,26 +427,6 @@ const handleDetail = (record: any) => {
|
|||||||
modelStore.params.stcd = record.stcd;
|
modelStore.params.stcd = record.stcd;
|
||||||
modelStore.title = record.stnm;
|
modelStore.title = record.stnm;
|
||||||
};
|
};
|
||||||
// 编辑
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
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 = () => {
|
const fetchColumnConfig = () => {
|
||||||
@ -482,7 +454,13 @@ const fetchColumnConfig = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 添加操作列
|
// 添加操作列
|
||||||
|
cols.push({
|
||||||
|
key: 'action',
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
fixed: 'right',
|
||||||
|
width: isEdit.value ? 180 : 100
|
||||||
|
});
|
||||||
|
|
||||||
columns.value = cols;
|
columns.value = cols;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
@ -1,121 +0,0 @@
|
|||||||
<!-- <template>
|
|
||||||
<BasicSearch
|
|
||||||
ref="basicSearchRef"
|
|
||||||
:searchList="searchList"
|
|
||||||
:initial-values="initSearchData"
|
|
||||||
:zhujianfujian="'fu'"
|
|
||||||
@reset="handleReset"
|
|
||||||
@finish="onSearchFinish"
|
|
||||||
>
|
|
||||||
<template #actions>
|
|
||||||
<a-button @click="hideBtn">{{ isHide ? '展开' : '隐藏' }}</a-button>
|
|
||||||
<a-button type="primary" @click="handleAdd">新增</a-button>
|
|
||||||
</template>
|
|
||||||
</BasicSearch>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, computed, onMounted } from 'vue';
|
|
||||||
import BasicSearch from '@/components/BasicSearch/index.vue';
|
|
||||||
import { sttpGetKendoList } from '@/api/system/map/ConfigManagement';
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'search-finish', values: any): void;
|
|
||||||
(e: 'reset', values: any): void;
|
|
||||||
(e: 'add'): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const basicSearchRef = ref();
|
|
||||||
const isHide = ref<boolean>(false);
|
|
||||||
const sttpOption = ref([]);
|
|
||||||
|
|
||||||
const initSearchData = {
|
|
||||||
baseId: 'all',
|
|
||||||
rstcd: null,
|
|
||||||
stnm: null,
|
|
||||||
sttp: null
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchList: any = computed(() => [
|
|
||||||
{
|
|
||||||
type: 'jidiData',
|
|
||||||
name: 'baseId',
|
|
||||||
label: '水电基地',
|
|
||||||
placeholder: '请输入水电基地名称',
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true
|
|
||||||
},
|
|
||||||
options: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'Input',
|
|
||||||
name: 'stnm',
|
|
||||||
label: '站点名称',
|
|
||||||
placeholder: '请输入站点名称',
|
|
||||||
width: 160,
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
col: isHide.value ? 0 : null,
|
|
||||||
type: 'Select',
|
|
||||||
name: 'sttp',
|
|
||||||
label: '测站类型',
|
|
||||||
width: 160,
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true,
|
|
||||||
placeholder: '请选择测站类型'
|
|
||||||
},
|
|
||||||
options: sttpOption.value
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
const getBaseList = async () => {
|
|
||||||
let params = {
|
|
||||||
"filter": {
|
|
||||||
"logic": "and",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"field": "sttpCode",
|
|
||||||
"operator": "in",
|
|
||||||
"dataType": "string",
|
|
||||||
"value": ["OSGB"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const res = await sttpGetKendoList(params);
|
|
||||||
sttpOption.value = res.data.data.map(item => {
|
|
||||||
return {
|
|
||||||
label: item.sttpName,
|
|
||||||
value: item.sttpCode
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSearchFinish = (values: any) => {
|
|
||||||
emit('search-finish', { ...values });
|
|
||||||
};
|
|
||||||
|
|
||||||
const hideBtn = () => {
|
|
||||||
isHide.value = !isHide.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
emit('reset', initSearchData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAdd = () => {
|
|
||||||
emit('add');
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getBaseList();
|
|
||||||
emit('search-finish', { ...initSearchData });
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
basicSearchRef
|
|
||||||
});
|
|
||||||
</script> -->
|
|
||||||
@ -1,275 +0,0 @@
|
|||||||
<!-- <template>
|
|
||||||
<div class="w-full h-full flex flex-col pt-[20px] pl-[20px] body_one">
|
|
||||||
<PhotoSearch
|
|
||||||
@search-finish="onSearchFinish"
|
|
||||||
@reset="onReset"
|
|
||||||
@add="handleAdd"
|
|
||||||
ref="searchRef"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<BasicTable
|
|
||||||
ref="tableRef"
|
|
||||||
:enableEllipsis="true"
|
|
||||||
:scrollX="tableScrollX"
|
|
||||||
:scrollY="tableScrollY"
|
|
||||||
:columns="columns"
|
|
||||||
:list-url="getOpPageList"
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<EditPhotoModal
|
|
||||||
v-model:open="editVisible"
|
|
||||||
:record="editRecord"
|
|
||||||
:is-add="isAdd"
|
|
||||||
@success="handleEditSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DeleteConfirmModal
|
|
||||||
ref="deleteModalRef"
|
|
||||||
:delete-fn="deleteOpFn"
|
|
||||||
:label="'倾斜摄影站点'"
|
|
||||||
title="删除倾斜摄影站点"
|
|
||||||
@success="handleEditSuccess"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed, onMounted, nextTick } from 'vue';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import PhotoSearch from './PhotoSearch.vue';
|
|
||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
|
||||||
import EditPhotoModal from './EditPhotoModal.vue';
|
|
||||||
import DeleteConfirmModal from '@/views/conventionalHydropower/BasicData/DeleteConfirmModal.vue';
|
|
||||||
import { getOpPageList, deleteOpInfo } from '@/api/DataQueryMenuModule';
|
|
||||||
import { calcTableScrollY } from '@/utils/index';
|
|
||||||
|
|
||||||
const tableRef = ref();
|
|
||||||
const searchRef = ref();
|
|
||||||
const tableScrollY = ref<string | number>(0);
|
|
||||||
const currentSearchParams = ref<any>({});
|
|
||||||
|
|
||||||
// 编辑相关
|
|
||||||
const editVisible = ref(false);
|
|
||||||
const editRecord = ref<any>(null);
|
|
||||||
const isAdd = ref(false);
|
|
||||||
const deleteModalRef = ref();
|
|
||||||
|
|
||||||
const columns = ref<any[]>([
|
|
||||||
{
|
|
||||||
key: 'stnm',
|
|
||||||
title: '站点名称',
|
|
||||||
dataIndex: 'stnm',
|
|
||||||
visible: true,
|
|
||||||
width: 200,
|
|
||||||
fixed: 'left',
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'stcd',
|
|
||||||
title: '站点编码',
|
|
||||||
dataIndex: 'stcd',
|
|
||||||
visible: true,
|
|
||||||
width: 160,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'sttpName',
|
|
||||||
title: '测站类型',
|
|
||||||
dataIndex: 'sttpName',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'stlc',
|
|
||||||
title: '位置',
|
|
||||||
dataIndex: 'stlc',
|
|
||||||
visible: true,
|
|
||||||
width: 160,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'baseName',
|
|
||||||
title: '水电基地',
|
|
||||||
dataIndex: 'baseName',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ennm',
|
|
||||||
title: '所属电站',
|
|
||||||
dataIndex: 'ennm',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'url',
|
|
||||||
title: '在线地址',
|
|
||||||
dataIndex: 'url',
|
|
||||||
visible: true,
|
|
||||||
width: 200,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'usflName',
|
|
||||||
title: '是否启用',
|
|
||||||
dataIndex: 'usflName',
|
|
||||||
visible: true,
|
|
||||||
width: 80,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'jcdt',
|
|
||||||
title: '建成日期',
|
|
||||||
dataIndex: 'jcdt',
|
|
||||||
visible: true,
|
|
||||||
width: 110,
|
|
||||||
customRender: ({ text }) => {
|
|
||||||
if (!text || text === '-') return '-';
|
|
||||||
const date = dayjs(text);
|
|
||||||
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'remark',
|
|
||||||
title: '备注',
|
|
||||||
dataIndex: 'remark',
|
|
||||||
visible: true,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'action',
|
|
||||||
title: '操作',
|
|
||||||
dataIndex: 'action',
|
|
||||||
fixed: 'right',
|
|
||||||
width: 120
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
const tableScrollX = computed(() =>
|
|
||||||
Math.max(
|
|
||||||
columns.value.reduce(
|
|
||||||
(sum: number, col: any) => sum + (col.width || 180),
|
|
||||||
0
|
|
||||||
),
|
|
||||||
600
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const buildSearchParams = (values: any) => {
|
|
||||||
return {
|
|
||||||
logic: 'and',
|
|
||||||
filters: [
|
|
||||||
values.rstcd
|
|
||||||
? {
|
|
||||||
field: 'rstcd',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.rstcd
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.baseId !== 'all'
|
|
||||||
? {
|
|
||||||
field: 'baseId',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.baseId
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.stnm
|
|
||||||
? {
|
|
||||||
field: 'stnm',
|
|
||||||
operator: 'contains',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.stnm
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.sttp
|
|
||||||
? {
|
|
||||||
field: 'sttp',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.sttp
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
].filter(Boolean)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSearchFinish = (values: any) => {
|
|
||||||
currentSearchParams.value = values;
|
|
||||||
initTable(values);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onReset = (values: any) => {
|
|
||||||
currentSearchParams.value = values;
|
|
||||||
initTable(values);
|
|
||||||
};
|
|
||||||
|
|
||||||
const initTable = (values: any) => {
|
|
||||||
const params = buildSearchParams(values);
|
|
||||||
tableRef.value.getList(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增
|
|
||||||
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 deleteOpFn = async (record: any, reason: string) => {
|
|
||||||
return deleteOpInfo({
|
|
||||||
ids: [record.stcd],
|
|
||||||
source: reason
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (record: any) => {
|
|
||||||
deleteModalRef.value?.open(record, () => {
|
|
||||||
initTable(currentSearchParams.value);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
tableScrollY.value = calcTableScrollY();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.body_one {
|
|
||||||
position: relative;
|
|
||||||
z-index: 900;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
</style> -->
|
|
||||||
@ -1,506 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-modal
|
|
||||||
v-model:open="visible"
|
|
||||||
:title="isAdd ? '新增人工产卵场' : '编辑人工产卵场'"
|
|
||||||
width="60vw"
|
|
||||||
: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="stcd">
|
|
||||||
<a-input
|
|
||||||
v-model:value="formData.stcd"
|
|
||||||
placeholder="请输入产卵场编码"
|
|
||||||
:disabled="!isAdd"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="产卵场名称" name="stnm">
|
|
||||||
<a-input
|
|
||||||
v-model:value="formData.stnm"
|
|
||||||
placeholder="请输入产卵场名称"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="测站类型" name="sttp">
|
|
||||||
<a-select
|
|
||||||
v-model:value="formData.sttp"
|
|
||||||
placeholder="请选择测站类型"
|
|
||||||
allow-clear
|
|
||||||
show-search
|
|
||||||
:filter-option="filterOption"
|
|
||||||
>
|
|
||||||
<a-select-option
|
|
||||||
v-for="item in sttpOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>{{ item.label }}</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="站址" name="stlc">
|
|
||||||
<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="baseId">
|
|
||||||
<a-select
|
|
||||||
v-model:value="formData.baseId"
|
|
||||||
placeholder="请选择水电基地"
|
|
||||||
allow-clear
|
|
||||||
show-search
|
|
||||||
:filter-option="filterOption"
|
|
||||||
>
|
|
||||||
<a-select-option
|
|
||||||
v-for="item in baseNameOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>{{ item.label }}</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</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-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>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="保护对象" name="prtcts">
|
|
||||||
<a-input
|
|
||||||
v-model:value="formData.prtcts"
|
|
||||||
placeholder="请输入保护对象"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="产卵场数量(个)" name="cnt">
|
|
||||||
<a-input-number
|
|
||||||
v-model:value="formData.cnt"
|
|
||||||
placeholder="请输入数量"
|
|
||||||
style="width: 100%"
|
|
||||||
:min="0"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="面积(km²)" name="ar">
|
|
||||||
<a-input-number
|
|
||||||
v-model:value="formData.ar"
|
|
||||||
placeholder="请输入面积"
|
|
||||||
style="width: 100%"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="营造型式" name="tp">
|
|
||||||
<a-input
|
|
||||||
v-model:value="formData.tp"
|
|
||||||
placeholder="请输入营造型式"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="实施时间" name="attm">
|
|
||||||
<a-date-picker
|
|
||||||
v-model:value="formData.attm"
|
|
||||||
format="YYYY-MM-DD"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
placeholder="请选择实施时间"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="建成日期" name="jcdt">
|
|
||||||
<a-date-picker
|
|
||||||
v-model:value="formData.jcdt"
|
|
||||||
format="YYYY-MM-DD"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
placeholder="请选择建成日期"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="是否启用" name="usfl">
|
|
||||||
<a-select
|
|
||||||
v-model:value="formData.usfl"
|
|
||||||
placeholder="请选择是否启用"
|
|
||||||
allow-clear
|
|
||||||
>
|
|
||||||
<a-select-option :value="1">启用</a-select-option>
|
|
||||||
<a-select-option :value="0">禁用</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="投资(亿元)" name="inv">
|
|
||||||
<a-input-number
|
|
||||||
v-model:value="formData.inv"
|
|
||||||
placeholder="请输入投资"
|
|
||||||
style="width: 100%"
|
|
||||||
:min="0"
|
|
||||||
:precision="4"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="监测频次(min)" name="dtfrqcy">
|
|
||||||
<a-input-number
|
|
||||||
v-model:value="formData.dtfrqcy"
|
|
||||||
placeholder="请输入监测频次"
|
|
||||||
style="width: 100%"
|
|
||||||
:min="0"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="简介" name="introduce" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.introduce"
|
|
||||||
placeholder="请输入简介"
|
|
||||||
:rows="2"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="备注" name="remark" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.remark"
|
|
||||||
placeholder="请输入备注"
|
|
||||||
:rows="2"
|
|
||||||
/>
|
|
||||||
</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 } from 'ant-design-vue';
|
|
||||||
import { addSgInfo, updateSgInfo } from '@/api/DataQueryMenuModule';
|
|
||||||
import { getEngInfoDropdown } from '@/api/select';
|
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
|
||||||
import { sttpGetKendoList } from '@/api/system/map/ConfigManagement';
|
|
||||||
import ConfirmModal from '@/components/ConfirmModal/index.vue';
|
|
||||||
import { useDraggable } from '@/utils/drag';
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
open: boolean;
|
|
||||||
record?: any;
|
|
||||||
isAdd?: boolean;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:open', 'success']);
|
|
||||||
const jidiSelectEventStore = useJidiSelectEventStore();
|
|
||||||
|
|
||||||
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 formRules = ref<any>({
|
|
||||||
stcd: [{ required: true, message: '请输入产卵场编码', trigger: 'blur' }],
|
|
||||||
stnm: [{ required: true, message: '请输入产卵场名称', trigger: 'blur' }]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 下拉选项
|
|
||||||
const engInfoOptions = ref<any[]>([]);
|
|
||||||
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 fieldLabelMap: Record<string, string> = {
|
|
||||||
stcd: '产卵场编码',
|
|
||||||
stnm: '产卵场名称',
|
|
||||||
sttp: '测站类型',
|
|
||||||
stlc: '站址',
|
|
||||||
baseId: '水电基地',
|
|
||||||
rstcd: '所属电站',
|
|
||||||
prtcts: '保护对象',
|
|
||||||
cnt: '产卵场数量',
|
|
||||||
ar: '面积',
|
|
||||||
tp: '营造型式',
|
|
||||||
attm: '实施时间',
|
|
||||||
jcdt: '建成日期',
|
|
||||||
usfl: '是否启用',
|
|
||||||
inv: '投资',
|
|
||||||
dtfrqcy: '监测频次',
|
|
||||||
introduce: '简介',
|
|
||||||
remark: '备注'
|
|
||||||
};
|
|
||||||
|
|
||||||
// select 选项映射
|
|
||||||
const selectOptionsMap: Record<string, () => any[]> = {
|
|
||||||
sttp: () => sttpOptions.value,
|
|
||||||
usfl: () => [
|
|
||||||
{ label: '启用', value: 1 },
|
|
||||||
{ label: '禁用', value: 0 }
|
|
||||||
],
|
|
||||||
baseId: () => baseNameOptions.value,
|
|
||||||
rstcd: () => engInfoOptions.value
|
|
||||||
};
|
|
||||||
|
|
||||||
// 按修改顺序记录变更
|
|
||||||
const changeOrder = ref<
|
|
||||||
{ field: string; label: string; oldValue: string; newValue: string }[]
|
|
||||||
>([]);
|
|
||||||
const diffList = changeOrder;
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
const filterOption = (inputValue: string, option: any) => {
|
|
||||||
const label = option.label || option.value;
|
|
||||||
const keyword = inputValue || '';
|
|
||||||
return label.includes(keyword);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 监听 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 }
|
|
||||||
);
|
|
||||||
|
|
||||||
// 监听 record 变化
|
|
||||||
watch(
|
|
||||||
() => props.record,
|
|
||||||
newRecord => {
|
|
||||||
if (newRecord) {
|
|
||||||
const converted = { ...newRecord };
|
|
||||||
originalRecord.value = { ...converted };
|
|
||||||
formData.value = { ...converted };
|
|
||||||
changeOrder.value = [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
// 加载下拉数据
|
|
||||||
const loadDropdownData = () => {
|
|
||||||
// 加载测站类型
|
|
||||||
sttpGetKendoList({
|
|
||||||
filter: {
|
|
||||||
logic: 'and',
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
field: 'sttpCode',
|
|
||||||
operator: 'in',
|
|
||||||
dataType: 'string',
|
|
||||||
value: ['SG']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}).then(res => {
|
|
||||||
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 = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
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 handleConfirmSubmit = async (source: string) => {
|
|
||||||
confirmLoading.value = true;
|
|
||||||
try {
|
|
||||||
const engInfo: Record<string, any> = {};
|
|
||||||
let res: any;
|
|
||||||
if (props.isAdd) {
|
|
||||||
Object.assign(engInfo, formData.value);
|
|
||||||
res = await addSgInfo({
|
|
||||||
engInfo,
|
|
||||||
source: source.trim() || '新增'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
engInfo.stcd = formData.value.stcd;
|
|
||||||
changeOrder.value.forEach(item => {
|
|
||||||
engInfo[item.field] = formData.value[item.field];
|
|
||||||
});
|
|
||||||
res = await updateSgInfo({
|
|
||||||
engInfo,
|
|
||||||
source: source.trim() || '编辑'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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>
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
<template>
|
|
||||||
<BasicSearch
|
|
||||||
ref="basicSearchRef"
|
|
||||||
:searchList="searchList"
|
|
||||||
:initial-values="initSearchData"
|
|
||||||
:zhujianfujian="'fu'"
|
|
||||||
@reset="handleReset"
|
|
||||||
@finish="onSearchFinish"
|
|
||||||
>
|
|
||||||
<template #actions>
|
|
||||||
<a-button @click="hideBtn">{{ isHide ? '展开' : '隐藏' }}</a-button>
|
|
||||||
<a-button type="primary" @click="handleAdd">新增</a-button>
|
|
||||||
</template>
|
|
||||||
</BasicSearch>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, computed, onMounted } from 'vue';
|
|
||||||
import BasicSearch from '@/components/BasicSearch/index.vue';
|
|
||||||
import { sttpGetKendoList } from '@/api/system/map/ConfigManagement';
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'search-finish', values: any): void;
|
|
||||||
(e: 'reset', values: any): void;
|
|
||||||
(e: 'add'): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const basicSearchRef = ref();
|
|
||||||
const isHide = ref<boolean>(false);
|
|
||||||
const sttpOption = ref([]);
|
|
||||||
|
|
||||||
const initSearchData = {
|
|
||||||
baseId: 'all',
|
|
||||||
rstcd: null,
|
|
||||||
stnm: null,
|
|
||||||
sttp: null
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchList: any = computed(() => [
|
|
||||||
{
|
|
||||||
type: 'jidiData',
|
|
||||||
name: 'baseId',
|
|
||||||
label: '水电基地',
|
|
||||||
placeholder: '请输入水电基地名称',
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true
|
|
||||||
},
|
|
||||||
options: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'Input',
|
|
||||||
name: 'stnm',
|
|
||||||
label: '产卵场名称',
|
|
||||||
placeholder: '请输入产卵场名称',
|
|
||||||
width: 160,
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
col: isHide.value ? 0 : null,
|
|
||||||
type: 'Select',
|
|
||||||
name: 'sttp',
|
|
||||||
label: '测站类型',
|
|
||||||
width: 160,
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true,
|
|
||||||
placeholder: '请选择测站类型'
|
|
||||||
},
|
|
||||||
options: sttpOption.value
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
const getBaseList = async () => {
|
|
||||||
let params = {
|
|
||||||
"filter": {
|
|
||||||
"logic": "and",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"field": "sttpCode",
|
|
||||||
"operator": "in",
|
|
||||||
"dataType": "string",
|
|
||||||
"value": ["SG"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const res = await sttpGetKendoList(params);
|
|
||||||
sttpOption.value = res.data.data.map(item => {
|
|
||||||
return {
|
|
||||||
label: item.sttpName,
|
|
||||||
value: item.sttpCode
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSearchFinish = (values: any) => {
|
|
||||||
emit('search-finish', { ...values });
|
|
||||||
};
|
|
||||||
|
|
||||||
const hideBtn = () => {
|
|
||||||
isHide.value = !isHide.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
emit('reset', initSearchData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAdd = () => {
|
|
||||||
emit('add');
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getBaseList();
|
|
||||||
emit('search-finish', { ...initSearchData });
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
basicSearchRef
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@ -1,295 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="w-full h-full flex flex-col pt-[20px] pl-[20px] body_one">
|
|
||||||
<!-- 搜索组件 -->
|
|
||||||
<SpawnSearch
|
|
||||||
@search-finish="onSearchFinish"
|
|
||||||
@reset="onReset"
|
|
||||||
@add="handleAdd"
|
|
||||||
ref="searchRef"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表格组件 -->
|
|
||||||
<BasicTable
|
|
||||||
ref="tableRef"
|
|
||||||
:enableEllipsis="true"
|
|
||||||
:scrollX="tableScrollX"
|
|
||||||
:scrollY="tableScrollY"
|
|
||||||
:columns="columns"
|
|
||||||
:list-url="getSgPageList"
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<!-- 编辑/新增 Modal -->
|
|
||||||
<EditSpawnModal
|
|
||||||
v-model:open="editVisible"
|
|
||||||
:record="editRecord"
|
|
||||||
:is-add="isAdd"
|
|
||||||
@success="handleEditSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 删除确认 Modal -->
|
|
||||||
<DeleteConfirmModal
|
|
||||||
ref="deleteModalRef"
|
|
||||||
:delete-fn="deleteSgFn"
|
|
||||||
:label="'人工产卵场'"
|
|
||||||
title="删除人工产卵场"
|
|
||||||
@success="handleEditSuccess"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed, onMounted, nextTick } from 'vue';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import SpawnSearch from './SpawnSearch.vue';
|
|
||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
|
||||||
import EditSpawnModal from './EditSpawnModal.vue';
|
|
||||||
import DeleteConfirmModal from '@/views/conventionalHydropower/BasicData/DeleteConfirmModal.vue';
|
|
||||||
import { getSgPageList, deleteSgInfo } from '@/api/DataQueryMenuModule';
|
|
||||||
import { calcTableScrollY } from '@/utils/index';
|
|
||||||
|
|
||||||
const tableRef = ref();
|
|
||||||
const searchRef = ref();
|
|
||||||
const tableScrollY = ref<string | number>(0);
|
|
||||||
const currentSearchParams = ref<any>({});
|
|
||||||
|
|
||||||
// 编辑相关
|
|
||||||
const editVisible = ref(false);
|
|
||||||
const editRecord = ref<any>(null);
|
|
||||||
const isAdd = ref(false);
|
|
||||||
const deleteModalRef = ref();
|
|
||||||
|
|
||||||
const columns = ref<any[]>([
|
|
||||||
{
|
|
||||||
key: 'stnm',
|
|
||||||
title: '产卵场名称',
|
|
||||||
dataIndex: 'stnm',
|
|
||||||
visible: true,
|
|
||||||
width: 200,
|
|
||||||
fixed: 'left',
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'stcd',
|
|
||||||
title: '产卵场编码',
|
|
||||||
dataIndex: 'stcd',
|
|
||||||
visible: true,
|
|
||||||
width: 200,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'sttpName',
|
|
||||||
title: '测站类型',
|
|
||||||
dataIndex: 'sttpName',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'stlc',
|
|
||||||
title: '站址',
|
|
||||||
dataIndex: 'stlc',
|
|
||||||
visible: true,
|
|
||||||
width: 160,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'baseName',
|
|
||||||
title: '水电基地',
|
|
||||||
dataIndex: 'baseName',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ennm',
|
|
||||||
title: '所属电站',
|
|
||||||
dataIndex: 'ennm',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'prtcts',
|
|
||||||
title: '保护对象',
|
|
||||||
dataIndex: 'prtcts',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'cnt',
|
|
||||||
title: '数量(个)',
|
|
||||||
dataIndex: 'cnt',
|
|
||||||
visible: true,
|
|
||||||
width: 80,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ar',
|
|
||||||
title: '面积(km²)',
|
|
||||||
dataIndex: 'ar',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'jcdt',
|
|
||||||
title: '建成日期',
|
|
||||||
dataIndex: 'jcdt',
|
|
||||||
visible: true,
|
|
||||||
width: 110,
|
|
||||||
customRender: ({ text }) => {
|
|
||||||
if (!text || text === '-') return '-';
|
|
||||||
const date = dayjs(text);
|
|
||||||
return date.isValid() ? date.format('YYYY-MM-DD') : '-';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'usflName',
|
|
||||||
title: '是否启用',
|
|
||||||
dataIndex: 'usflName',
|
|
||||||
visible: true,
|
|
||||||
width: 80,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'remark',
|
|
||||||
title: '备注',
|
|
||||||
dataIndex: 'remark',
|
|
||||||
visible: true,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'action',
|
|
||||||
title: '操作',
|
|
||||||
dataIndex: 'action',
|
|
||||||
fixed: 'right',
|
|
||||||
width: 120
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
const tableScrollX = computed(() =>
|
|
||||||
Math.max(
|
|
||||||
columns.value.reduce(
|
|
||||||
(sum: number, col: any) => sum + (col.width || 180),
|
|
||||||
0
|
|
||||||
),
|
|
||||||
600
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const buildSearchParams = (values: any) => {
|
|
||||||
return {
|
|
||||||
logic: 'and',
|
|
||||||
filters: [
|
|
||||||
values.rstcd
|
|
||||||
? {
|
|
||||||
field: 'rstcd',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.rstcd
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.baseId !== 'all'
|
|
||||||
? {
|
|
||||||
field: 'baseId',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.baseId
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.stnm
|
|
||||||
? {
|
|
||||||
field: 'stnm',
|
|
||||||
operator: 'contains',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.stnm
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.sttp
|
|
||||||
? {
|
|
||||||
field: 'sttp',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.sttp
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
].filter(Boolean)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSearchFinish = (values: any) => {
|
|
||||||
currentSearchParams.value = values;
|
|
||||||
initTable(values);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onReset = (values: any) => {
|
|
||||||
currentSearchParams.value = values;
|
|
||||||
initTable(values);
|
|
||||||
};
|
|
||||||
|
|
||||||
const initTable = (values: any) => {
|
|
||||||
const params = buildSearchParams(values);
|
|
||||||
tableRef.value.getList(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增
|
|
||||||
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 deleteSgFn = async (record: any, reason: string) => {
|
|
||||||
return deleteSgInfo({
|
|
||||||
ids: [record.stcd],
|
|
||||||
source: reason
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (record: any) => {
|
|
||||||
deleteModalRef.value?.open(record, () => {
|
|
||||||
initTable(currentSearchParams.value);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
tableScrollY.value = calcTableScrollY();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.body_one {
|
|
||||||
position: relative;
|
|
||||||
z-index: 900;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,394 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-modal
|
|
||||||
v-model:open="visible"
|
|
||||||
:title="isAdd ? '新增智能告警' : '编辑智能告警'"
|
|
||||||
width="60vw"
|
|
||||||
: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="ruleName">
|
|
||||||
<a-input
|
|
||||||
v-model:value="formData.ruleName"
|
|
||||||
placeholder="请输入预警规则名称"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="预警规则类型" name="ruleType">
|
|
||||||
<a-select
|
|
||||||
v-model:value="formData.ruleType"
|
|
||||||
placeholder="请选择预警规则类型"
|
|
||||||
allow-clear
|
|
||||||
>
|
|
||||||
<a-select-option value="WQLVL">水质预警</a-select-option>
|
|
||||||
<a-select-option value="EQMN">电站生态流量(环保部)</a-select-option>
|
|
||||||
<a-select-option value="EQMNMWR">电站生态流量(水利部)</a-select-option>
|
|
||||||
<a-select-option value="RSVRFSR">水位预警</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="规则编码" name="ruleCode">
|
|
||||||
<a-select
|
|
||||||
v-model:value="formData.ruleCode"
|
|
||||||
placeholder="请选择规则编码"
|
|
||||||
allow-clear
|
|
||||||
>
|
|
||||||
<a-select-option value="global">全局规则</a-select-option>
|
|
||||||
<a-select-option value="common">通用告警规则</a-select-option>
|
|
||||||
<a-select-option value="custom">自定义告警规则</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="所属测站" name="stcd">
|
|
||||||
<a-input
|
|
||||||
v-model:value="formData.stcd"
|
|
||||||
placeholder="请输入所属测站"
|
|
||||||
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"
|
|
||||||
>
|
|
||||||
<a-select-option
|
|
||||||
v-for="item in baseNameOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>{{ item.label }}</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</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-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>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="是否展示告警等级" name="isShow">
|
|
||||||
<a-select
|
|
||||||
v-model:value="formData.isShow"
|
|
||||||
placeholder="请选择"
|
|
||||||
allow-clear
|
|
||||||
>
|
|
||||||
<a-select-option :value="1">展示</a-select-option>
|
|
||||||
<a-select-option :value="0">不展示</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="备注" name="description" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
||||||
<a-textarea
|
|
||||||
v-model:value="formData.description"
|
|
||||||
placeholder="请输入备注"
|
|
||||||
:rows="3"
|
|
||||||
/>
|
|
||||||
</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 } from 'ant-design-vue';
|
|
||||||
import { addWarnInfo, updateWarnInfo } from '@/api/DataQueryMenuModule';
|
|
||||||
import { getEngInfoDropdown } from '@/api/select';
|
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
|
||||||
import ConfirmModal from '@/components/ConfirmModal/index.vue';
|
|
||||||
import { useDraggable } from '@/utils/drag';
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
open: boolean;
|
|
||||||
record?: any;
|
|
||||||
isAdd?: boolean;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:open', 'success']);
|
|
||||||
const jidiSelectEventStore = useJidiSelectEventStore();
|
|
||||||
|
|
||||||
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 formRules = ref<any>({
|
|
||||||
ruleName: [{ required: true, message: '请输入预警规则名称', trigger: 'blur' }],
|
|
||||||
ruleType: [{ required: true, message: '请选择预警规则类型', trigger: 'change' }]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 下拉选项
|
|
||||||
const engInfoOptions = ref<any[]>([]);
|
|
||||||
|
|
||||||
const baseNameOptions = ref<any[]>(
|
|
||||||
jidiSelectEventStore.jidiData
|
|
||||||
.filter((item: any) => item.wbsCode !== 'all')
|
|
||||||
.map((item: any) => ({
|
|
||||||
label: item.wbsName,
|
|
||||||
value: item.wbsCode
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
// 字段名 → 中文名映射
|
|
||||||
const fieldLabelMap: Record<string, string> = {
|
|
||||||
ruleName: '预警规则名称',
|
|
||||||
ruleType: '预警规则类型',
|
|
||||||
ruleCode: '规则编码',
|
|
||||||
stcd: '所属测站',
|
|
||||||
baseId: '水电基地',
|
|
||||||
rstcd: '所属电站',
|
|
||||||
isShow: '是否展示告警等级',
|
|
||||||
description: '备注'
|
|
||||||
};
|
|
||||||
|
|
||||||
// select 选项映射
|
|
||||||
const selectOptionsMap: Record<string, () => any[]> = {
|
|
||||||
ruleType: () => [
|
|
||||||
{ label: '水质预警', value: 'WQLVL' },
|
|
||||||
{ label: '电站生态流量(环保部)', value: 'EQMN' },
|
|
||||||
{ label: '电站生态流量(水利部)', value: 'EQMNMWR' },
|
|
||||||
{ label: '水位预警', value: 'RSVRFSR' }
|
|
||||||
],
|
|
||||||
ruleCode: () => [
|
|
||||||
{ label: '全局规则', value: 'global' },
|
|
||||||
{ label: '通用告警规则', value: 'common' },
|
|
||||||
{ label: '自定义告警规则', value: 'custom' }
|
|
||||||
],
|
|
||||||
isShow: () => [
|
|
||||||
{ label: '展示', value: 1 },
|
|
||||||
{ label: '不展示', value: 0 }
|
|
||||||
],
|
|
||||||
baseId: () => baseNameOptions.value,
|
|
||||||
rstcd: () => engInfoOptions.value
|
|
||||||
};
|
|
||||||
|
|
||||||
// 按修改顺序记录变更
|
|
||||||
const changeOrder = ref<
|
|
||||||
{ field: string; label: string; oldValue: string; newValue: string }[]
|
|
||||||
>([]);
|
|
||||||
const diffList = changeOrder;
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
const filterOption = (inputValue: string, option: any) => {
|
|
||||||
const label = option.label || option.value;
|
|
||||||
const keyword = inputValue || '';
|
|
||||||
return label.includes(keyword);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 监听 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 }
|
|
||||||
);
|
|
||||||
|
|
||||||
// 监听 record 变化
|
|
||||||
watch(
|
|
||||||
() => props.record,
|
|
||||||
newRecord => {
|
|
||||||
if (newRecord) {
|
|
||||||
const converted = { ...newRecord };
|
|
||||||
originalRecord.value = { ...converted };
|
|
||||||
formData.value = { ...converted };
|
|
||||||
changeOrder.value = [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
// 加载下拉数据
|
|
||||||
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(
|
|
||||||
() => props.open,
|
|
||||||
val => {
|
|
||||||
if (val) {
|
|
||||||
loadDropdownData();
|
|
||||||
if (props.isAdd) {
|
|
||||||
formData.value = {};
|
|
||||||
originalRecord.value = {};
|
|
||||||
changeOrder.value = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
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 handleConfirmSubmit = async (source: string) => {
|
|
||||||
confirmLoading.value = true;
|
|
||||||
try {
|
|
||||||
const engInfo: Record<string, any> = {};
|
|
||||||
let res: any;
|
|
||||||
if (props.isAdd) {
|
|
||||||
Object.assign(engInfo, formData.value);
|
|
||||||
res = await addWarnInfo({
|
|
||||||
engInfo,
|
|
||||||
source: source.trim() || '新增'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
engInfo.id = formData.value.id;
|
|
||||||
changeOrder.value.forEach(item => {
|
|
||||||
engInfo[item.field] = formData.value[item.field];
|
|
||||||
});
|
|
||||||
res = await updateWarnInfo({
|
|
||||||
engInfo,
|
|
||||||
source: source.trim() || '编辑'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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>
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
<template>
|
|
||||||
<BasicSearch
|
|
||||||
ref="basicSearchRef"
|
|
||||||
:searchList="searchList"
|
|
||||||
:initial-values="initSearchData"
|
|
||||||
:zhujianfujian="'fu'"
|
|
||||||
@reset="handleReset"
|
|
||||||
@finish="onSearchFinish"
|
|
||||||
>
|
|
||||||
<template #actions>
|
|
||||||
<a-button @click="hideBtn">{{ isHide ? '展开' : '隐藏' }}</a-button>
|
|
||||||
<a-button type="primary" @click="handleAdd">新增</a-button>
|
|
||||||
</template>
|
|
||||||
</BasicSearch>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, computed, onMounted } from 'vue';
|
|
||||||
import BasicSearch from '@/components/BasicSearch/index.vue';
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'search-finish', values: any): void;
|
|
||||||
(e: 'reset', values: any): void;
|
|
||||||
(e: 'add'): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const basicSearchRef = ref();
|
|
||||||
const isHide = ref<boolean>(false);
|
|
||||||
|
|
||||||
const initSearchData = {
|
|
||||||
baseId: 'all',
|
|
||||||
rstcd: null,
|
|
||||||
ruleName: null
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchList: any = computed(() => [
|
|
||||||
{
|
|
||||||
type: 'jidiData',
|
|
||||||
name: 'baseId',
|
|
||||||
label: '水电基地',
|
|
||||||
placeholder: '请输入水电基地名称',
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true
|
|
||||||
},
|
|
||||||
options: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'Input',
|
|
||||||
name: 'ruleName',
|
|
||||||
label: '规则名称',
|
|
||||||
placeholder: '请输入规则名称',
|
|
||||||
width: 160,
|
|
||||||
fieldProps: {
|
|
||||||
allowClear: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
const onSearchFinish = (values: any) => {
|
|
||||||
emit('search-finish', { ...values });
|
|
||||||
};
|
|
||||||
|
|
||||||
const hideBtn = () => {
|
|
||||||
isHide.value = !isHide.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
emit('reset', initSearchData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAdd = () => {
|
|
||||||
emit('add');
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
emit('search-finish', { ...initSearchData });
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
basicSearchRef
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@ -1,255 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="w-full h-full flex flex-col pt-[20px] pl-[20px] body_one">
|
|
||||||
<!-- 搜索组件 -->
|
|
||||||
<WarnSearch
|
|
||||||
@search-finish="onSearchFinish"
|
|
||||||
@reset="onReset"
|
|
||||||
@add="handleAdd"
|
|
||||||
ref="searchRef"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表格组件 -->
|
|
||||||
<BasicTable
|
|
||||||
ref="tableRef"
|
|
||||||
:enableEllipsis="true"
|
|
||||||
:scrollX="tableScrollX"
|
|
||||||
:scrollY="tableScrollY"
|
|
||||||
:columns="columns"
|
|
||||||
:list-url="getWarnPageList"
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<!-- 编辑/新增 Modal -->
|
|
||||||
<EditWarnModal
|
|
||||||
v-model:open="editVisible"
|
|
||||||
:record="editRecord"
|
|
||||||
:is-add="isAdd"
|
|
||||||
@success="handleEditSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 删除确认 Modal -->
|
|
||||||
<DeleteConfirmModal
|
|
||||||
ref="deleteModalRef"
|
|
||||||
:delete-fn="deleteWarnFn"
|
|
||||||
:label="'智能告警'"
|
|
||||||
title="删除智能告警"
|
|
||||||
@success="handleEditSuccess"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed, onMounted, nextTick } from 'vue';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import WarnSearch from './WarnSearch.vue';
|
|
||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
|
||||||
import EditWarnModal from './EditWarnModal.vue';
|
|
||||||
import DeleteConfirmModal from '@/views/conventionalHydropower/BasicData/DeleteConfirmModal.vue';
|
|
||||||
import { getWarnPageList, deleteWarnInfo } from '@/api/DataQueryMenuModule';
|
|
||||||
import { calcTableScrollY } from '@/utils/index';
|
|
||||||
|
|
||||||
const tableRef = ref();
|
|
||||||
const searchRef = ref();
|
|
||||||
const tableScrollY = ref<string | number>(0);
|
|
||||||
const currentSearchParams = ref<any>({});
|
|
||||||
|
|
||||||
// 编辑相关
|
|
||||||
const editVisible = ref(false);
|
|
||||||
const editRecord = ref<any>(null);
|
|
||||||
const isAdd = ref(false);
|
|
||||||
const deleteModalRef = ref();
|
|
||||||
|
|
||||||
const columns = ref<any[]>([
|
|
||||||
{
|
|
||||||
key: 'ruleName',
|
|
||||||
title: '预警规则名称',
|
|
||||||
dataIndex: 'ruleName',
|
|
||||||
visible: true,
|
|
||||||
width: 200,
|
|
||||||
fixed: 'left',
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ruleType',
|
|
||||||
title: '预警规则类型',
|
|
||||||
dataIndex: 'ruleType',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ruleCode',
|
|
||||||
title: '规则编码',
|
|
||||||
dataIndex: 'ruleCode',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'stcd',
|
|
||||||
title: '所属测站',
|
|
||||||
dataIndex: 'stcd',
|
|
||||||
visible: true,
|
|
||||||
width: 160,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'baseName',
|
|
||||||
title: '水电基地',
|
|
||||||
dataIndex: 'baseName',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ennm',
|
|
||||||
title: '所属电站',
|
|
||||||
dataIndex: 'ennm',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'isShow',
|
|
||||||
title: '展示告警等级',
|
|
||||||
dataIndex: 'isShow',
|
|
||||||
visible: true,
|
|
||||||
width: 100,
|
|
||||||
customRender: ({ text }) => {
|
|
||||||
if (text === 1) return '展示';
|
|
||||||
if (text === 0) return '不展示';
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'description',
|
|
||||||
title: '备注',
|
|
||||||
dataIndex: 'description',
|
|
||||||
visible: true,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'action',
|
|
||||||
title: '操作',
|
|
||||||
dataIndex: 'action',
|
|
||||||
fixed: 'right',
|
|
||||||
width: 120
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
const tableScrollX = computed(() =>
|
|
||||||
Math.max(
|
|
||||||
columns.value.reduce(
|
|
||||||
(sum: number, col: any) => sum + (col.width || 180),
|
|
||||||
0
|
|
||||||
),
|
|
||||||
600
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const buildSearchParams = (values: any) => {
|
|
||||||
return {
|
|
||||||
logic: 'and',
|
|
||||||
filters: [
|
|
||||||
values.rstcd
|
|
||||||
? {
|
|
||||||
field: 'rstcd',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.rstcd
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.baseId !== 'all'
|
|
||||||
? {
|
|
||||||
field: 'baseId',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.baseId
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
values.ruleName
|
|
||||||
? {
|
|
||||||
field: 'ruleName',
|
|
||||||
operator: 'contains',
|
|
||||||
dataType: 'string',
|
|
||||||
value: values.ruleName
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
].filter(Boolean)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSearchFinish = (values: any) => {
|
|
||||||
currentSearchParams.value = values;
|
|
||||||
initTable(values);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onReset = (values: any) => {
|
|
||||||
currentSearchParams.value = values;
|
|
||||||
initTable(values);
|
|
||||||
};
|
|
||||||
|
|
||||||
const initTable = (values: any) => {
|
|
||||||
const params = buildSearchParams(values);
|
|
||||||
tableRef.value.getList(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除(使用 id 作为主键)
|
|
||||||
const deleteWarnFn = async (record: any, reason: string) => {
|
|
||||||
return deleteWarnInfo({
|
|
||||||
ids: [record.id],
|
|
||||||
source: reason
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (record: any) => {
|
|
||||||
deleteModalRef.value?.open(record, () => {
|
|
||||||
initTable(currentSearchParams.value);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
tableScrollY.value = calcTableScrollY();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.body_one {
|
|
||||||
position: relative;
|
|
||||||
z-index: 900;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -34,7 +34,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, onMounted, onUnmounted, watch, nextTick, provide,defineAsyncComponent } from 'vue';
|
import { ref, computed, onMounted, onUnmounted, onActivated, onDeactivated, watch, nextTick, provide,defineAsyncComponent } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { getTreeConfiguredps, getPowerSubjectLayout } from '@/api/dianZhanZhuanTi';
|
import { getTreeConfiguredps, getPowerSubjectLayout } from '@/api/dianZhanZhuanTi';
|
||||||
@ -193,7 +193,7 @@ function onTreeSelect(value: any, item: any) {
|
|||||||
waitForMapReady(() => {
|
waitForMapReady(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if ((window as any).mapClass) {
|
if ((window as any).mapClass) {
|
||||||
(window as any).mapClass.flyTopanto([Number(item.lgtd), Number(item.lttd)], 12);
|
(window as any).mapClass.flyTopanto([Number(item.lgtd), Number(item.lttd)], 15);
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
@ -327,6 +327,9 @@ watch(
|
|||||||
const rows = sk?.gridTemplateRows?.split(' ') || [];
|
const rows = sk?.gridTemplateRows?.split(' ') || [];
|
||||||
const bottomRowHeight = rows[rows.length - 1];
|
const bottomRowHeight = rows[rows.length - 1];
|
||||||
nextTick(() => setMapLegendPos(val.type, val, 460, bottomRowHeight));
|
nextTick(() => setMapLegendPos(val.type, val, 460, bottomRowHeight));
|
||||||
|
} else {
|
||||||
|
// 无布局/布局无底部模块或 3D 模式:恢复地图控件默认样式(与非电站专题页一致)
|
||||||
|
uiStore.resetMapControlsPosition();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
@ -348,12 +351,10 @@ watch(
|
|||||||
|
|
||||||
// ==================== 地图控件位置重置 ====================
|
// ==================== 地图控件位置重置 ====================
|
||||||
function resetMapControlPositions() {
|
function resetMapControlPositions() {
|
||||||
|
// 地图控制器/底图切换器:清除 store 位置覆盖,恢复组件自身默认样式(与非电站专题页一致)
|
||||||
|
uiStore.resetMapControlsPosition();
|
||||||
const legend = document.querySelector('#qgc-legendtl') as HTMLElement;
|
const legend = document.querySelector('#qgc-legendtl') as HTMLElement;
|
||||||
const controller = document.querySelector('#map-controller') as HTMLElement;
|
|
||||||
const baselayer = document.querySelector('#map-baselayer') as HTMLElement;
|
|
||||||
if (legend) { legend.style.left = '0px'; legend.style.bottom = '0px'; }
|
if (legend) { legend.style.left = '0px'; legend.style.bottom = '0px'; }
|
||||||
if (controller) { controller.style.right = '12px'; controller.style.bottom = '114px'; }
|
|
||||||
if (baselayer) { baselayer.style.right = '60px'; baselayer.style.bottom = '0px'; }
|
|
||||||
['#map-filter-container', '#map-compassControl', '#map-monitor'].forEach(sel => {
|
['#map-filter-container', '#map-compassControl', '#map-monitor'].forEach(sel => {
|
||||||
const el = document.querySelector(sel) as HTMLElement;
|
const el = document.querySelector(sel) as HTMLElement;
|
||||||
if (el) { el.style.left = ''; el.style.right = ''; el.style.bottom = ''; }
|
if (el) { el.style.left = ''; el.style.right = ''; el.style.bottom = ''; }
|
||||||
@ -366,6 +367,39 @@ function collapseLegend() {
|
|||||||
icon?.parentElement?.click();
|
icon?.parentElement?.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 图例操作轮询定时器(离开页面时清理,避免回调泄漏)
|
||||||
|
let legendOpTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
const clearLegendOpTimer = () => {
|
||||||
|
if (legendOpTimer !== null) {
|
||||||
|
clearTimeout(legendOpTimer);
|
||||||
|
legendOpTimer = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 进入专题页时收缩图例:图例尚未渲染则轮询等待,仅展开态才点击收起 */
|
||||||
|
function collapseLegendOnEnter(retry = 0) {
|
||||||
|
const btn = document.querySelector('.legendBtn') as HTMLElement | null;
|
||||||
|
if (!btn) {
|
||||||
|
if (retry < 30) {
|
||||||
|
legendOpTimer = setTimeout(() => collapseLegendOnEnter(retry + 1), 200);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (btn.querySelector('.icon-fold')) btn.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 离开专题页时展开图例:仅收起态才点击展开 */
|
||||||
|
function expandLegendOnLeave(retry = 0) {
|
||||||
|
const btn = document.querySelector('.legendBtn') as HTMLElement | null;
|
||||||
|
if (!btn) {
|
||||||
|
if (retry < 30) {
|
||||||
|
legendOpTimer = setTimeout(() => expandLegendOnLeave(retry + 1), 200);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (btn.querySelector('.icon-unFold')) btn.click();
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== 监听 3D/2D 切换 ====================
|
// ==================== 监听 3D/2D 切换 ====================
|
||||||
watch(
|
watch(
|
||||||
() => uiStore.mapType,
|
() => uiStore.mapType,
|
||||||
@ -411,6 +445,10 @@ watch(
|
|||||||
|
|
||||||
// ==================== 生命周期 ====================
|
// ==================== 生命周期 ====================
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 进入电站专题页时统一关闭全局搜索抽屉(覆盖从任意页面/地图跳转进来的场景)
|
||||||
|
uiStore.setIsSearchActive(false);
|
||||||
|
uiStore.setGlobalDrawerOpen(false);
|
||||||
|
|
||||||
getTreeConfiguredps()
|
getTreeConfiguredps()
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
const result = res?.data ?? [];
|
const result = res?.data ?? [];
|
||||||
@ -432,13 +470,30 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
switchToSatellite();
|
switchToSatellite();
|
||||||
|
// 进入专题页时收缩图例
|
||||||
|
collapseLegendOnEnter();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
clearLegendOpTimer();
|
||||||
|
// 离开专题页时恢复展开图例
|
||||||
|
expandLegendOnLeave();
|
||||||
switchToVector();
|
switchToVector();
|
||||||
layoutData.value = null;
|
layoutData.value = null;
|
||||||
resetMapControlPositions();
|
resetMapControlPositions();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// keep-alive 缓存场景:回到专题页收起、离开专题页展开(首次挂载时 mounted/activated 双触发,收起操作幂等)
|
||||||
|
onActivated(() => {
|
||||||
|
collapseLegendOnEnter();
|
||||||
|
});
|
||||||
|
|
||||||
|
onDeactivated(() => {
|
||||||
|
clearLegendOpTimer();
|
||||||
|
expandLegendOnLeave();
|
||||||
|
// keep-alive 缓存离开时同样清除地图控件位置覆盖,避免影响其他页面
|
||||||
|
uiStore.resetMapControlsPosition();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user