bug修改,鱼种类修改,流域基地逻辑修改
This commit is contained in:
parent
86f1030b03
commit
2342a3555e
@ -88,11 +88,17 @@ export function getLastImportResult() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
export function deleteFile(params:any) {
|
||||||
// 批量保存草稿
|
|
||||||
export function batchSaveDraft(data:any) {
|
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/batchSaveDraft',
|
url: '/data/fishDraft/deleteFile',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 批量保存草稿
|
||||||
|
export function importBatchSaveDraft(data:any) {
|
||||||
|
return request({
|
||||||
|
url: '/data/fishDraft/importBatchSaveDraft',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
|||||||
@ -8,6 +8,14 @@ export function getBaseDropdown(data:any) {
|
|||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 流域下拉列表
|
||||||
|
export function getSelectForDropdown(data:any) {
|
||||||
|
return request({
|
||||||
|
url: '/env/hbrv/selectForDropdown',
|
||||||
|
method: 'get',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
//电站下拉列表
|
//电站下拉列表
|
||||||
export function getEngInfoDropdown(data:any) {
|
export function getEngInfoDropdown(data:any) {
|
||||||
return request({
|
return request({
|
||||||
@ -16,10 +24,10 @@ export function getEngInfoDropdown(data:any) {
|
|||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 更新导入任务
|
// 重新验证并更新行数据
|
||||||
export function updateImportTask(data:any) {
|
export function revalidateAndUpdateRow(data:any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/importTask/update',
|
url: '/data/fishDraft/revalidateAndUpdateRow',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
|||||||
@ -74,7 +74,8 @@
|
|||||||
<!-- 电站下拉框 -->
|
<!-- 电站下拉框 -->
|
||||||
<div class="flex gap-[10px]" v-else-if="item.type === 'waterStation'">
|
<div class="flex gap-[10px]" v-else-if="item.type === 'waterStation'">
|
||||||
<a-form-item-rest>
|
<a-form-item-rest>
|
||||||
<a-select
|
<!-- 基地下拉框 -->
|
||||||
|
<!-- <a-select
|
||||||
:value="formData.baseId"
|
:value="formData.baseId"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
@change="dataDimensionDataChange"
|
@change="dataDimensionDataChange"
|
||||||
@ -83,7 +84,6 @@
|
|||||||
:loading="shuJuTianBaoStore.baseLoading"
|
:loading="shuJuTianBaoStore.baseLoading"
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
style="width: 135px"
|
style="width: 135px"
|
||||||
|
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="opt in shuJuTianBaoStore.baseOption"
|
v-for="opt in shuJuTianBaoStore.baseOption"
|
||||||
@ -93,7 +93,28 @@
|
|||||||
>
|
>
|
||||||
{{ opt.basename }}
|
{{ opt.basename }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
|
</a-select> -->
|
||||||
|
<!-- 流域下拉框 -->
|
||||||
|
<a-select
|
||||||
|
:value="formData.hbrvcd"
|
||||||
|
placeholder="请选择"
|
||||||
|
@change="lyChange"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
:loading="shuJuTianBaoStore.lyLoading"
|
||||||
|
:filter-option="filterOption"
|
||||||
|
style="width: 135px"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="opt in shuJuTianBaoStore.lyOption"
|
||||||
|
:key="opt.hbrvcd"
|
||||||
|
:value="opt.hbrvcd"
|
||||||
|
:label="opt.hbrvnm"
|
||||||
|
>
|
||||||
|
{{ opt.hbrvnm }}
|
||||||
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
<!-- 电站下拉框 -->
|
||||||
<a-select
|
<a-select
|
||||||
:value="formData.rstcd"
|
:value="formData.rstcd"
|
||||||
placeholder="请选择电站"
|
placeholder="请选择电站"
|
||||||
@ -246,8 +267,9 @@ const initForm = () => {
|
|||||||
validSearchList.value.forEach((item) => {
|
validSearchList.value.forEach((item) => {
|
||||||
if (item.type == "waterStation") {
|
if (item.type == "waterStation") {
|
||||||
// 下拉菜单
|
// 下拉菜单
|
||||||
shuJuTianBaoStore.getBaseOption();
|
// shuJuTianBaoStore.getBaseOption();
|
||||||
shuJuTianBaoStore.getEngOption(formData.baseId);
|
shuJuTianBaoStore.getSelectForOption();
|
||||||
|
shuJuTianBaoStore.getEngOption(formData.hbrvcd);
|
||||||
}
|
}
|
||||||
if (item.fieldProps?.required) {
|
if (item.fieldProps?.required) {
|
||||||
rules[item.name] = [
|
rules[item.name] = [
|
||||||
@ -270,17 +292,27 @@ const triggerManualValuesChange = (changedKey: string, newValue: any) => {
|
|||||||
emit("valuesChange", changedValues, { ...formData });
|
emit("valuesChange", changedValues, { ...formData });
|
||||||
};
|
};
|
||||||
|
|
||||||
const dataDimensionDataChange = (value: any) => {
|
// const dataDimensionDataChange = (value: any) => {
|
||||||
formData.baseId = value;
|
// formData.baseId = value;
|
||||||
|
// formData.rstcd = "";
|
||||||
|
// shuJuTianBaoStore.getEngOption(formData.baseId);
|
||||||
|
|
||||||
|
// // 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
||||||
|
// triggerManualValuesChange("baseId", formData.baseId);
|
||||||
|
// };
|
||||||
|
|
||||||
|
const lyChange = (value: any) => {
|
||||||
|
formData.hbrvcd = value;
|
||||||
formData.rstcd = "";
|
formData.rstcd = "";
|
||||||
shuJuTianBaoStore.getEngOption(formData.baseId);
|
shuJuTianBaoStore.getEngOption(formData.hbrvcd);
|
||||||
|
|
||||||
// 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
// 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
||||||
triggerManualValuesChange("baseId", formData.baseId);
|
triggerManualValuesChange("hbrvcd", formData.hbrvcd);
|
||||||
};
|
};
|
||||||
|
|
||||||
const stcdIdChange = (value: any) => {
|
const stcdIdChange = (value: any) => {
|
||||||
formData.rstcd = value;
|
formData.rstcd = value;
|
||||||
|
shuJuTianBaoStore.getFpssOption(formData.hbrvcd, value);
|
||||||
// 【关键修改】手动触发 valuesChange
|
// 【关键修改】手动触发 valuesChange
|
||||||
triggerManualValuesChange("rstcd", formData.rstcd);
|
triggerManualValuesChange("rstcd", formData.rstcd);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,13 +2,13 @@
|
|||||||
<div
|
<div
|
||||||
class="custom-fish-search-container"
|
class="custom-fish-search-container"
|
||||||
ref="containerRef"
|
ref="containerRef"
|
||||||
@mouseenter="isHovered = true"
|
@mouseenter="handleMouseEnter"
|
||||||
@mouseleave="isHovered = false"
|
@mouseleave="handleMouseLeave"
|
||||||
>
|
>
|
||||||
<!-- 1. 输入框区域 -->
|
<!-- 1. 输入框区域 -->
|
||||||
<div
|
<div
|
||||||
class="fish-input-wrapper"
|
class="fish-input-wrapper"
|
||||||
:class="{ 'is-focused': isOpen }"
|
:class="{ 'is-focused': isOpen, disabled: disabled }"
|
||||||
@click="handleWrapperClick"
|
@click="handleWrapperClick"
|
||||||
>
|
>
|
||||||
<!--
|
<!--
|
||||||
@ -382,7 +382,7 @@ const switchQueryMode = (val: boolean) => {
|
|||||||
isIntelligentQuery.value = val;
|
isIntelligentQuery.value = val;
|
||||||
|
|
||||||
message.success(val ? "智能查询已开启" : "相似度查询已开启");
|
message.success(val ? "智能查询已开启" : "相似度查询已开启");
|
||||||
if (searchKeyword.value) {
|
if (searchKeyword.value) {
|
||||||
executeSearch(); // 切换模式后,用当前的词重新查一次
|
executeSearch(); // 切换模式后,用当前的词重新查一次
|
||||||
} else {
|
} else {
|
||||||
options.value = allOptions.value;
|
options.value = allOptions.value;
|
||||||
@ -415,6 +415,14 @@ const handleClickOutside = (event: MouseEvent) => {
|
|||||||
closeDropdown();
|
closeDropdown();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
if (!props.disabled) {
|
||||||
|
isHovered.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
isHovered.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init();
|
init();
|
||||||
@ -522,6 +530,15 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.disabled {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
&:hover {
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
.single-value {
|
||||||
|
color: rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 下拉面板样式 */
|
/* 下拉面板样式 */
|
||||||
.fish-dropdown-panel {
|
.fish-dropdown-panel {
|
||||||
|
|||||||
@ -1,15 +1,26 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { ref } from 'vue'; // 使用 ref 更简单直观
|
import { ref } from 'vue'; // 使用 ref 更简单直观
|
||||||
import { getBaseDropdown, getEngInfoDropdown, getFpssDropdown } from '@/api/select';
|
import {
|
||||||
|
getBaseDropdown,
|
||||||
|
getSelectForDropdown,
|
||||||
|
getEngInfoDropdown,
|
||||||
|
getFpssDropdown
|
||||||
|
} from '@/api/select';
|
||||||
|
|
||||||
export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
||||||
// 1. 直接使用 ref 定义状态,确保响应式
|
// 水电基地下拉列表
|
||||||
const fpssOption = ref<any[]>([]);
|
|
||||||
const fpssLoading = ref(false);
|
|
||||||
const baseOption = ref<any[]>([]);
|
|
||||||
const baseLoading = ref(false);
|
const baseLoading = ref(false);
|
||||||
|
const baseOption = ref<any[]>([]);
|
||||||
|
// 流域下拉列表
|
||||||
|
const lyLoading = ref(false);
|
||||||
|
const lyOption = ref<any[]>([]);
|
||||||
|
// 电站下拉列表
|
||||||
const engOption = ref<any[]>([]);
|
const engOption = ref<any[]>([]);
|
||||||
const engLoading = ref(false);
|
const engLoading = ref(false);
|
||||||
|
// 流域下拉列表
|
||||||
|
const fpssOption = ref<any[]>([]);
|
||||||
|
const fpssLoading = ref(false);
|
||||||
|
// 鱼类名称下拉列表
|
||||||
const fishOption = ref([]);
|
const fishOption = ref([]);
|
||||||
// 获取水电基地列表
|
// 获取水电基地列表
|
||||||
const getBaseOption = async () => {
|
const getBaseOption = async () => {
|
||||||
@ -27,15 +38,35 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
|||||||
baseLoading.value = false;
|
baseLoading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// 获取流域列表
|
||||||
|
const getSelectForOption = async () => {
|
||||||
|
try {
|
||||||
|
lyLoading.value = true;
|
||||||
|
const res = await getSelectForDropdown({});
|
||||||
|
if (res.data && Array.isArray(res.data)) {
|
||||||
|
const list = [
|
||||||
|
{ hbrvcd: 'all', hbrvnm: '当前全部', baseid: '01' },
|
||||||
|
...res.data
|
||||||
|
];
|
||||||
|
// 直接赋值给 ref,触发响应式更新
|
||||||
|
lyOption.value = list;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取流域列表失败:', error);
|
||||||
|
} finally {
|
||||||
|
lyLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
// 获取电站列表
|
// 获取电站列表
|
||||||
const getEngOption = async (baseId: string) => {
|
const getEngOption = async (hbrvcd: string) => {
|
||||||
try {
|
try {
|
||||||
engLoading.value = true;
|
engLoading.value = true;
|
||||||
const param = baseId === 'all' ? {} : { baseId };
|
const param = hbrvcd === 'all' ? {} : { hbrvcd };
|
||||||
const res = await getEngInfoDropdown(param);
|
const res = await getEngInfoDropdown(param);
|
||||||
if (res.data && Array.isArray(res.data)) {
|
if (res.data && Array.isArray(res.data)) {
|
||||||
// 直接赋值给 ref
|
// 直接赋值给 ref
|
||||||
engOption.value = res.data;
|
engOption.value = res.data;
|
||||||
|
getFpssOption(hbrvcd, '');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取电站列表失败:', error);
|
console.error('获取电站列表失败:', error);
|
||||||
@ -44,16 +75,17 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 获取过鱼设施列表
|
// 获取过鱼设施列表
|
||||||
const getFpssOption = async (baseId: string, rstcd: string) => {
|
const getFpssOption = async (hbrvcd: string, rstcd: string) => {
|
||||||
try {
|
try {
|
||||||
fpssLoading.value = true;
|
fpssLoading.value = true;
|
||||||
const res = await getFpssDropdown({ baseId, rstcd });
|
const param = hbrvcd === 'all' ? {} : { hbrvcd };
|
||||||
console.log(res.data)
|
const res = await getFpssDropdown({...param, rstcd: rstcd});
|
||||||
|
console.log(res.data);
|
||||||
fpssOption.value = res.data;
|
fpssOption.value = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
fpssLoading.value = false;
|
// fpssLoading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const getFishOption = () => {
|
const getFishOption = () => {
|
||||||
@ -66,13 +98,16 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
|||||||
// 在组件中使用时:store.baseOption 会自动解包为数组
|
// 在组件中使用时:store.baseOption 会自动解包为数组
|
||||||
return {
|
return {
|
||||||
fpssOption,
|
fpssOption,
|
||||||
|
lyOption,
|
||||||
baseOption,
|
baseOption,
|
||||||
engOption,
|
engOption,
|
||||||
fishOption,
|
fishOption,
|
||||||
fpssLoading,
|
fpssLoading,
|
||||||
baseLoading,
|
baseLoading,
|
||||||
|
lyLoading,
|
||||||
engLoading,
|
engLoading,
|
||||||
getBaseOption,
|
getBaseOption,
|
||||||
|
getSelectForOption,
|
||||||
getEngOption,
|
getEngOption,
|
||||||
getFpssOption,
|
getFpssOption,
|
||||||
getFishOption,
|
getFishOption,
|
||||||
|
|||||||
@ -37,6 +37,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:where(.css-dev-only-do-not-override-ekaqbe).ant-btn >span {
|
:where(.css-dev-only-do-not-override-ekaqbe).ant-btn > span {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
.ant-image-preview-root {
|
||||||
|
.ant-image-preview-wrap {
|
||||||
|
z-index: 2005 !important;
|
||||||
|
}
|
||||||
|
.ant-image-preview-mask {
|
||||||
|
z-index: 2005 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ant-message {
|
||||||
|
z-index: 2005 !important;
|
||||||
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<a-modal
|
<a-modal
|
||||||
:title="isView ? '查看数据' : isEdit ? '编辑数据' : '新增数据'"
|
:title="isView ? '查看数据' : isEdit ? '编辑数据' : '新增数据'"
|
||||||
v-model:open="modalVisible"
|
v-model:open="modalVisible"
|
||||||
:confirm-loading="loading"
|
:confirm-loading="localLoading"
|
||||||
width="800px"
|
width="800px"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
:footer="isView ? null : undefined"
|
:footer="isView ? null : undefined"
|
||||||
@ -18,7 +18,28 @@
|
|||||||
>
|
>
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="流域" name="baseId">
|
<a-form-item label="流域" name="hbrvcd">
|
||||||
|
<a-select
|
||||||
|
v-model:value="formData.hbrvcd"
|
||||||
|
:loading="hbrvcdLoading"
|
||||||
|
placeholder="请选择流域"
|
||||||
|
:disabled="isView"
|
||||||
|
show-search
|
||||||
|
allowClear
|
||||||
|
:filter-option="filterOption"
|
||||||
|
@change="hbrvcdChange"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="opt in hbrvcdOption"
|
||||||
|
:key="opt.hbrvcd"
|
||||||
|
:value="opt.hbrvcd"
|
||||||
|
:label="opt.hbrvnm"
|
||||||
|
>
|
||||||
|
{{ opt.hbrvnm }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<!-- <a-form-item label="流域" name="baseId">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="formData.baseId"
|
v-model:value="formData.baseId"
|
||||||
:loading="baseLoading"
|
:loading="baseLoading"
|
||||||
@ -38,7 +59,7 @@
|
|||||||
{{ opt.basename }}
|
{{ opt.basename }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item> -->
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="电站名称" name="rstcd">
|
<a-form-item label="电站名称" name="rstcd">
|
||||||
@ -46,7 +67,7 @@
|
|||||||
v-model:value="formData.rstcd"
|
v-model:value="formData.rstcd"
|
||||||
:loading="engLoading"
|
:loading="engLoading"
|
||||||
placeholder="请选择电站名称"
|
placeholder="请选择电站名称"
|
||||||
:disabled="isView || !formData.baseId"
|
:disabled="isView || !formData.hbrvcd"
|
||||||
show-search
|
show-search
|
||||||
allowClear
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
@ -72,7 +93,7 @@
|
|||||||
v-model:value="formData.stcd"
|
v-model:value="formData.stcd"
|
||||||
:loading="fpssLoading"
|
:loading="fpssLoading"
|
||||||
placeholder="请选择过鱼设施"
|
placeholder="请选择过鱼设施"
|
||||||
:disabled="isView || !formData.rstcd"
|
:disabled="isView || !formData.rstcd"
|
||||||
show-search
|
show-search
|
||||||
allowClear
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
@ -218,7 +239,7 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12" class="imgupload" :class="{'imgupload_hidden': isView}">
|
<a-col :span="12" class="imgupload" :class="{ imgupload_hidden: isView }">
|
||||||
<a-form-item label="图片" name="picpth">
|
<a-form-item label="图片" name="picpth">
|
||||||
<a-upload
|
<a-upload
|
||||||
v-model:file-list="imageFileList"
|
v-model:file-list="imageFileList"
|
||||||
@ -258,7 +279,9 @@
|
|||||||
上传视频 (MP4)
|
上传视频 (MP4)
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
<a-button v-else-if="videoFileList.length > 0" @click="handleVideoPreview"> 点击预览视频 </a-button>
|
<a-button v-else-if="videoFileList.length > 0" @click="handleVideoPreview">
|
||||||
|
点击预览视频
|
||||||
|
</a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -270,12 +293,12 @@
|
|||||||
import { ref, reactive, watch, computed } from "vue";
|
import { ref, reactive, watch, computed } from "vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { Upload, message } from "ant-design-vue";
|
import { Upload, message } from "ant-design-vue";
|
||||||
import { UploadOutlined, PlusOutlined } from "@ant-design/icons-vue";
|
|
||||||
import type { Rule } from "ant-design-vue/es/form";
|
|
||||||
import type { UploadProps } from "ant-design-vue";
|
import type { UploadProps } from "ant-design-vue";
|
||||||
|
import type { Rule } from "ant-design-vue/es/form";
|
||||||
|
import { UploadOutlined, PlusOutlined } from "@ant-design/icons-vue";
|
||||||
import fishSearch from "@/components/fishSearch/index.vue";
|
import fishSearch from "@/components/fishSearch/index.vue";
|
||||||
import {
|
import {
|
||||||
getBaseDropdown,
|
getSelectForDropdown,
|
||||||
getEngInfoDropdown,
|
getEngInfoDropdown,
|
||||||
getFpssDropdown,
|
getFpssDropdown,
|
||||||
uploadFile,
|
uploadFile,
|
||||||
@ -289,12 +312,18 @@ interface Props {
|
|||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
isView?: boolean;
|
isView?: boolean;
|
||||||
}
|
}
|
||||||
const baseLoading = ref(false);
|
// 加载状态
|
||||||
|
const localLoading = ref(false);
|
||||||
|
// const baseLoading = ref(false);
|
||||||
|
const hbrvcdLoading = ref(false);
|
||||||
const engLoading = ref(false);
|
const engLoading = ref(false);
|
||||||
const fpssLoading = ref(false);
|
const fpssLoading = ref(false);
|
||||||
const baseOption = ref<any[]>([]);
|
// 下拉列表选项
|
||||||
|
// const baseOption = ref<any[]>([]);
|
||||||
|
const hbrvcdOption = ref<any[]>([]);
|
||||||
const engOption = ref<any[]>([]);
|
const engOption = ref<any[]>([]);
|
||||||
const fpssOption = ref<any[]>([]);
|
const fpssOption = ref<any[]>([]);
|
||||||
|
// 图片视频上传列表
|
||||||
const imageFileList = ref<any[]>([]);
|
const imageFileList = ref<any[]>([]);
|
||||||
const videoFileList = ref<any[]>([]);
|
const videoFileList = ref<any[]>([]);
|
||||||
|
|
||||||
@ -303,29 +332,54 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
initialValues: null,
|
initialValues: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
});
|
});
|
||||||
const getBaseDropdownSelect = async () => {
|
// 获取基地
|
||||||
|
// const getBaseDropdownSelect = async () => {
|
||||||
|
// try {
|
||||||
|
// baseLoading.value = true;
|
||||||
|
// const res = await getBaseDropdown({});
|
||||||
|
// let list = res.data || [];
|
||||||
|
// if (list && list.length > 0) {
|
||||||
|
// list = list.filter((item: any) => item.baseId !== "all");
|
||||||
|
// }
|
||||||
|
// baseOption.value = list;
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("获取基地列表失败:", error);
|
||||||
|
// } finally {
|
||||||
|
// baseLoading.value = false;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// 获取流域列表
|
||||||
|
const getHbrvcdDropdownSelect = async () => {
|
||||||
try {
|
try {
|
||||||
baseLoading.value = true;
|
hbrvcdLoading.value = true;
|
||||||
const res = await getBaseDropdown({});
|
const res = await getSelectForDropdown({});
|
||||||
let list = res.data || [];
|
let list = res.data || [];
|
||||||
if (list.length > 0) list.shift();
|
if (list && list.length > 0) {
|
||||||
baseOption.value = list;
|
list = list.filter((item: any) => item.hbrvcd !== "all");
|
||||||
|
}
|
||||||
|
hbrvcdOption.value = list;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("获取流域列表失败:", error);
|
console.error("获取流域列表失败:", error);
|
||||||
} finally {
|
} finally {
|
||||||
baseLoading.value = false;
|
hbrvcdLoading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const baseChange = async (baseId: string) => {
|
// const baseChange = async (baseId: string) => {
|
||||||
|
// formData.rstcd = undefined;
|
||||||
|
// formData.stcd = undefined;
|
||||||
|
// await getEngInfoDropdownSelect(baseId);
|
||||||
|
// await getFpssDropdownSelect(formData.rstcd, baseId);
|
||||||
|
// };
|
||||||
|
const hbrvcdChange = async (hbrvcd: string) => {
|
||||||
formData.rstcd = undefined;
|
formData.rstcd = undefined;
|
||||||
formData.stcd = undefined;
|
formData.stcd = undefined;
|
||||||
await getEngInfoDropdownSelect(baseId);
|
await getEngInfoDropdownSelect(hbrvcd);
|
||||||
await getFpssDropdownSelect(formData.rstcd, baseId);
|
// await getFpssDropdownSelect(formData.rstcd, hbrvcd);
|
||||||
};
|
};
|
||||||
const getEngInfoDropdownSelect = async (baseId: string) => {
|
const getEngInfoDropdownSelect = async (hbrvcd: string) => {
|
||||||
try {
|
try {
|
||||||
engLoading.value = true;
|
engLoading.value = true;
|
||||||
const res = await getEngInfoDropdown({ baseId });
|
const res = await getEngInfoDropdown({ hbrvcd });
|
||||||
engOption.value = res.data;
|
engOption.value = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("获取电站列表失败", error);
|
console.error("获取电站列表失败", error);
|
||||||
@ -335,12 +389,12 @@ const getEngInfoDropdownSelect = async (baseId: string) => {
|
|||||||
};
|
};
|
||||||
const engChange = async (rstcd: string) => {
|
const engChange = async (rstcd: string) => {
|
||||||
formData.stcd = undefined;
|
formData.stcd = undefined;
|
||||||
await getFpssDropdownSelect(rstcd, formData.baseId);
|
await getFpssDropdownSelect(rstcd, formData.hbrvcd);
|
||||||
};
|
};
|
||||||
const getFpssDropdownSelect = async (rstcd: string, baseId: string) => {
|
const getFpssDropdownSelect = async (rstcd: string, hbrvcd: string) => {
|
||||||
try {
|
try {
|
||||||
fpssLoading.value = true;
|
fpssLoading.value = true;
|
||||||
const res = await getFpssDropdown({ rstcd, baseId });
|
const res = await getFpssDropdown({ rstcd, hbrvcd });
|
||||||
fpssOption.value = res.data;
|
fpssOption.value = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("获取流量列表失败", error);
|
console.error("获取流量列表失败", error);
|
||||||
@ -369,7 +423,7 @@ const weightError = ref<string>("");
|
|||||||
// 表单数据模型
|
// 表单数据模型
|
||||||
const defaultFormData = reactive({
|
const defaultFormData = reactive({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
baseId: undefined,
|
hbrvcd: undefined,
|
||||||
stcd: undefined,
|
stcd: undefined,
|
||||||
rstcd: undefined,
|
rstcd: undefined,
|
||||||
strdt: undefined,
|
strdt: undefined,
|
||||||
@ -394,7 +448,7 @@ const filterOption = (inputValue: string, option: any) => {
|
|||||||
};
|
};
|
||||||
// 验证规则
|
// 验证规则
|
||||||
const rules: Record<string, Rule[]> = {
|
const rules: Record<string, Rule[]> = {
|
||||||
baseId: [{ required: true, message: "请选择流域", trigger: "change" }],
|
hbrvcd: [{ required: true, message: "请选择流域", trigger: "change" }],
|
||||||
rstcd: [{ required: true, message: "请选择电站", trigger: "change" }],
|
rstcd: [{ required: true, message: "请选择电站", trigger: "change" }],
|
||||||
stcd: [{ required: true, message: "请选择过鱼设施", trigger: "change" }],
|
stcd: [{ required: true, message: "请选择过鱼设施", trigger: "change" }],
|
||||||
strdt: [{ required: true, message: "请选择过鱼时间", trigger: "change" }],
|
strdt: [{ required: true, message: "请选择过鱼时间", trigger: "change" }],
|
||||||
@ -589,46 +643,12 @@ const initForm = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
// 视频预览
|
||||||
() => props.visible,
|
|
||||||
(newVisible) => {
|
|
||||||
if (newVisible) {
|
|
||||||
// 弹窗打开时,初始化数据
|
|
||||||
getBaseDropdownSelect();
|
|
||||||
getEngInfoDropdownSelect(formData.baseId);
|
|
||||||
getFpssDropdownSelect(formData.rstcd, formData.baseId);
|
|
||||||
initForm();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: false } // 不需要 immediate,因为初始状态通常是 false
|
|
||||||
);
|
|
||||||
|
|
||||||
// 重置表单
|
|
||||||
const resetForm = () => {
|
|
||||||
if (formRef.value) {
|
|
||||||
formRef.value.resetFields();
|
|
||||||
}
|
|
||||||
Object.assign(formData, defaultFormData);
|
|
||||||
// 清空手动验证的错误信息
|
|
||||||
bodyLengthError.value = "";
|
|
||||||
weightError.value = "";
|
|
||||||
// 清空文件列表
|
|
||||||
imageFileList.value = [];
|
|
||||||
videoFileList.value = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
// 取消操作
|
|
||||||
const handleCancel = () => {
|
|
||||||
emit("update:visible", false);
|
|
||||||
emit("cancel");
|
|
||||||
resetForm();
|
|
||||||
};
|
|
||||||
const handleVideoPreview = () => {
|
const handleVideoPreview = () => {
|
||||||
emit("preview-click", { vdpthList: videoFileList.value }, "formVideo", 0);
|
emit("preview-click", { vdpthList: videoFileList.value }, "formVideo", 0);
|
||||||
};
|
};
|
||||||
// ... 其他导入 ...
|
|
||||||
|
|
||||||
// 新增:自定义图片预览处理
|
// 预览图片
|
||||||
const handleImagePreview = async (file: any) => {
|
const handleImagePreview = async (file: any) => {
|
||||||
if (!props.isView) {
|
if (!props.isView) {
|
||||||
return "";
|
return "";
|
||||||
@ -636,8 +656,6 @@ const handleImagePreview = async (file: any) => {
|
|||||||
emit("preview-click", { picpthList: imageFileList.value }, "formImage", 0);
|
emit("preview-click", { picpthList: imageFileList.value }, "formImage", 0);
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
// ... 其他现有代码 ...
|
|
||||||
// 确认操作
|
// 确认操作
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
try {
|
try {
|
||||||
@ -657,6 +675,7 @@ const handleOk = async () => {
|
|||||||
(file) => !file.url && file.originFileObj
|
(file) => !file.url && file.originFileObj
|
||||||
);
|
);
|
||||||
|
|
||||||
|
localLoading.value = true;
|
||||||
if (newImageFiles.length > 0) {
|
if (newImageFiles.length > 0) {
|
||||||
// 这里需要循环上传,或者使用 Promise.all 并行上传
|
// 这里需要循环上传,或者使用 Promise.all 并行上传
|
||||||
// 伪代码:假设 uploadFile 返回 { data: { url: '...' } }
|
// 伪代码:假设 uploadFile 返回 { data: { url: '...' } }
|
||||||
@ -757,6 +776,45 @@ const handleOk = async () => {
|
|||||||
message.error("请检查表单填写是否正确");
|
message.error("请检查表单填写是否正确");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// 重置表单
|
||||||
|
const resetForm = () => {
|
||||||
|
if (formRef.value) {
|
||||||
|
formRef.value.resetFields();
|
||||||
|
}
|
||||||
|
Object.assign(formData, defaultFormData);
|
||||||
|
// 清空手动验证的错误信息
|
||||||
|
bodyLengthError.value = "";
|
||||||
|
weightError.value = "";
|
||||||
|
// 清空文件列表
|
||||||
|
imageFileList.value = [];
|
||||||
|
videoFileList.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消操作
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit("update:visible", false);
|
||||||
|
emit("cancel");
|
||||||
|
resetForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(newVisible) => {
|
||||||
|
if (newVisible) {
|
||||||
|
// 弹窗打开时,初始化数据
|
||||||
|
// getBaseDropdownSelect();// 基地
|
||||||
|
getHbrvcdDropdownSelect();// 流域
|
||||||
|
getEngInfoDropdownSelect(formData.hbrvcd);
|
||||||
|
getFpssDropdownSelect(formData.rstcd, formData.hbrvcd);
|
||||||
|
initForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: false } // 不需要 immediate,因为初始状态通常是 false
|
||||||
|
);
|
||||||
|
// 暴露变量
|
||||||
|
defineExpose({
|
||||||
|
localLoading
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@ -797,7 +855,7 @@ const handleOk = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.imgupload_hidden{
|
.imgupload_hidden {
|
||||||
:deep(.ant-upload-list-item) {
|
:deep(.ant-upload-list-item) {
|
||||||
/* 删除预览按钮 */
|
/* 删除预览按钮 */
|
||||||
.ant-upload-list-item-actions {
|
.ant-upload-list-item-actions {
|
||||||
|
|||||||
@ -104,7 +104,8 @@ const localTypeDate = ref<string>(null);
|
|||||||
const basicSearchRef = ref<any>();
|
const basicSearchRef = ref<any>();
|
||||||
|
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
baseId: "all",
|
hbrvcd: "all",
|
||||||
|
// baseId: "all",
|
||||||
stcd: null,
|
stcd: null,
|
||||||
rstcd: null,
|
rstcd: null,
|
||||||
ftp: null,
|
ftp: null,
|
||||||
@ -120,7 +121,7 @@ const searchData = ref<any>({ ...initSearchData });
|
|||||||
const searchList: any = computed(() => [
|
const searchList: any = computed(() => [
|
||||||
{
|
{
|
||||||
type: "waterStation",
|
type: "waterStation",
|
||||||
name: "baseId",
|
name: "hbrvcd",
|
||||||
label: "流域",
|
label: "流域",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
@ -191,12 +192,9 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
|||||||
// 同步更新本地 searchData,以便其他逻辑使用
|
// 同步更新本地 searchData,以便其他逻辑使用
|
||||||
if (
|
if (
|
||||||
Object.keys(changedValues)[0] == "rstcd" ||
|
Object.keys(changedValues)[0] == "rstcd" ||
|
||||||
Object.keys(changedValues)[0] == "baseId"
|
Object.keys(changedValues)[0] == "baseId"||
|
||||||
|
Object.keys(changedValues)[0] == "hbrvcd"
|
||||||
) {
|
) {
|
||||||
shuJuTianBaoStore.getFpssOption(
|
|
||||||
allValues.baseId == "all" ? "" : allValues.baseId,
|
|
||||||
allValues.rstcd
|
|
||||||
);
|
|
||||||
const formInstance = basicSearchRef.value?.formData;
|
const formInstance = basicSearchRef.value?.formData;
|
||||||
formInstance.stcd = null;
|
formInstance.stcd = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,8 +29,8 @@
|
|||||||
<template
|
<template
|
||||||
v-else-if="
|
v-else-if="
|
||||||
!isEditing(index) &&
|
!isEditing(index) &&
|
||||||
record._warnings &&
|
record.warnings &&
|
||||||
record._warnings.includes(column.dataIndexKey)
|
record.warnings.includes(column.dataIndexKey)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div style="color: red; display: flex; align-items: center">
|
<div style="color: red; display: flex; align-items: center">
|
||||||
@ -46,7 +46,8 @@
|
|||||||
isEditing(index) && column.dataIndex != 'picpth' && column.dataIndex != 'vdpth'
|
isEditing(index) && column.dataIndex != 'picpth' && column.dataIndex != 'vdpth'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<template v-if="column.dataIndex === 'baseName'">
|
<!-- 基地 -->
|
||||||
|
<!-- <template v-if="column.dataIndex === 'baseName'">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="editingData.baseId"
|
v-model:value="editingData.baseId"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
@ -66,6 +67,28 @@
|
|||||||
{{ opt.basename }}
|
{{ opt.basename }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
</template> -->
|
||||||
|
<!-- 流域名称 -->
|
||||||
|
<template v-if="column.dataIndex === 'hbrvnm'">
|
||||||
|
<a-select
|
||||||
|
v-model:value="editingData.hbrvcd"
|
||||||
|
placeholder="请选择"
|
||||||
|
show-search
|
||||||
|
allowClear
|
||||||
|
:filter-option="filterOption"
|
||||||
|
:loading="rowStates[index]?.hbrvcdLoading"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="(val) => handleHbrvcdChange(val, index, 'input')"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="opt in hbrvcdOptions"
|
||||||
|
:key="opt.hbrvcd"
|
||||||
|
:value="opt.hbrvcd"
|
||||||
|
:label="opt.hbrvnm"
|
||||||
|
>
|
||||||
|
{{ opt.hbrvnm }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 电站名称 -->
|
<!-- 电站名称 -->
|
||||||
@ -78,7 +101,7 @@
|
|||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
:loading="rowStates[index]?.engLoading"
|
:loading="rowStates[index]?.engLoading"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="!editingData.baseId"
|
:disabled="!editingData.hbrvcd"
|
||||||
@change="(val) => handleEngChange(val, index, 'input')"
|
@change="(val) => handleEngChange(val, index, 'input')"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
@ -124,7 +147,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
@change="(val) => delWarning(val,'strdt')"
|
@change="(val) => delWarning(val, 'strdt')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -143,7 +166,7 @@
|
|||||||
v-model:value="editingData.direction"
|
v-model:value="editingData.direction"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="(val) => delWarning(val,'direction')"
|
@change="(val) => delWarning(val, 'direction')"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="item in direction"
|
v-for="item in direction"
|
||||||
@ -174,8 +197,10 @@
|
|||||||
|
|
||||||
<!-- 是否鱼苗 -->
|
<!-- 是否鱼苗 -->
|
||||||
<template v-else-if="column.dataIndex === 'isfs'">
|
<template v-else-if="column.dataIndex === 'isfs'">
|
||||||
<a-radio-group v-model:value="editingData.isfs"
|
<a-radio-group
|
||||||
@change="(val) => delWarning(val,'isfs')">
|
v-model:value="editingData.isfs"
|
||||||
|
@change="(val) => delWarning(val, 'isfs')"
|
||||||
|
>
|
||||||
<a-radio :value="1">是</a-radio>
|
<a-radio :value="1">是</a-radio>
|
||||||
<a-radio :value="0">否</a-radio>
|
<a-radio :value="0">否</a-radio>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
@ -245,24 +270,31 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import _ from "lodash";
|
||||||
import { ref, reactive, onMounted, h } from "vue";
|
import { ref, reactive, onMounted, h } from "vue";
|
||||||
import { message, Tag } from "ant-design-vue";
|
import { message, Tag } from "ant-design-vue";
|
||||||
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
|
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
|
||||||
import fishSearch from "@/components/fishSearch/index.vue";
|
import fishSearch from "@/components/fishSearch/index.vue";
|
||||||
import { getBaseDropdown, getEngInfoDropdown, getFpssDropdown,updateImportTask } from "@/api/select";
|
import {
|
||||||
|
getSelectForDropdown,
|
||||||
|
getEngInfoDropdown,
|
||||||
|
getFpssDropdown,
|
||||||
|
revalidateAndUpdateRow,
|
||||||
|
} from "@/api/select";
|
||||||
|
|
||||||
const props: any = defineProps({
|
const props: any = defineProps({
|
||||||
taskId: { type: String, default: '' },
|
taskId: { type: String, default: "" },
|
||||||
fileTableData: { type: Array, default: () => [] },
|
fileTableData: { type: Array, default: () => [] },
|
||||||
fileLoading: { type: Boolean, default: false },
|
fileLoading: { type: Boolean, default: false },
|
||||||
direction: { type: Array, default: () => [] },
|
direction: { type: Array, default: () => [] },
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["update:fileTableData", "preview-click"]);
|
const emit = defineEmits(["update:fileTableData", "preview-click", "update:fileLoading"]);
|
||||||
|
|
||||||
// --- 状态管理 ---
|
// --- 状态管理 ---
|
||||||
const editingRowIndex = ref<number | null>(null);
|
const editingRowIndex = ref<number | null>(null);
|
||||||
const baseOptions = ref<any[]>([]);
|
const baseOptions = ref<any[]>([]);
|
||||||
|
const hbrvcdOptions = ref<any[]>([]);
|
||||||
const rowStates = reactive<Record<number, any>>({});
|
const rowStates = reactive<Record<number, any>>({});
|
||||||
|
|
||||||
// 【核心】临时编辑数据,只在编辑模式下使用
|
// 【核心】临时编辑数据,只在编辑模式下使用
|
||||||
@ -270,9 +302,9 @@ const editingData = ref<any>(null);
|
|||||||
|
|
||||||
const modalColumns = ref([
|
const modalColumns = ref([
|
||||||
{
|
{
|
||||||
dataIndex: "baseName",
|
dataIndex: "hbrvnm",
|
||||||
key: "baseName",
|
key: "hbrvnm",
|
||||||
dataIndexKey: "baseId",
|
dataIndexKey: "hbrvcd",
|
||||||
title: "流域",
|
title: "流域",
|
||||||
width: 140,
|
width: 140,
|
||||||
},
|
},
|
||||||
@ -350,17 +382,33 @@ const modalColumns = ref([
|
|||||||
|
|
||||||
// --- 初始化 ---
|
// --- 初始化 ---
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadBaseOptions();
|
// loadBaseOptions();
|
||||||
|
loadHbrvcdOptions();
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadBaseOptions = async () => {
|
// const loadBaseOptions = async () => {
|
||||||
|
// try {
|
||||||
|
// const res = await getBaseDropdown({});
|
||||||
|
// let list = res.data || [];
|
||||||
|
// if (list && list.length > 0) {
|
||||||
|
// list = list.filter((item: any) => item.baseid !== "all");
|
||||||
|
// }
|
||||||
|
// baseOptions.value = list;
|
||||||
|
// } catch (e) {
|
||||||
|
// console.error("Load base options failed", e);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
const loadHbrvcdOptions = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await getBaseDropdown({});
|
const res = await getSelectForDropdown({});
|
||||||
let list = res.data || [];
|
let list = res.data || [];
|
||||||
if (list.length > 0) list.shift();
|
if (list && list.length > 0) {
|
||||||
baseOptions.value = list;
|
list = list.filter((item: any) => item.hbrvcd !== "all");
|
||||||
|
}
|
||||||
|
hbrvcdOptions.value = list;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Load base options failed", e);
|
console.error("Load hbrvcd options failed", e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -370,6 +418,7 @@ const ensureRowState = (index: number) => {
|
|||||||
engOptions: [],
|
engOptions: [],
|
||||||
fpssOptions: [],
|
fpssOptions: [],
|
||||||
baseLoading: false,
|
baseLoading: false,
|
||||||
|
hbrvcdLoading: false,
|
||||||
engLoading: false,
|
engLoading: false,
|
||||||
fpssLoading: false,
|
fpssLoading: false,
|
||||||
};
|
};
|
||||||
@ -378,26 +427,61 @@ const ensureRowState = (index: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// --- 级联逻辑 (操作 editingData) ---
|
// --- 级联逻辑 (操作 editingData) ---
|
||||||
const handleBaseChange = async (
|
// const handleBaseChange = async (
|
||||||
baseId: string,
|
// hbrvcd: string,
|
||||||
|
// index: number,
|
||||||
|
// type: string = "start"
|
||||||
|
// ) => {
|
||||||
|
// const state = ensureRowState(index);
|
||||||
|
// editingData.value.baseName = hbrvcdOptions.value.find(
|
||||||
|
// (item: any) => item.hbrvcd == hbrvcd
|
||||||
|
// )?.basename;
|
||||||
|
// delWarning(hbrvcd, "hbrvcd");
|
||||||
|
// // 清空后续字段
|
||||||
|
// if (type != "start") {
|
||||||
|
// editingData.value.rstcd = undefined;
|
||||||
|
// editingData.value.stcd = undefined;
|
||||||
|
// editingData.value.ennm = undefined;
|
||||||
|
// editingData.value.stnm = undefined;
|
||||||
|
// state.engOptions = [];
|
||||||
|
// state.fpssOptions = [];
|
||||||
|
// }
|
||||||
|
// state.engLoading = true;
|
||||||
|
// try {
|
||||||
|
// const res = await getEngInfoDropdown({ hbrvcd });
|
||||||
|
// state.engOptions = res.data || [];
|
||||||
|
// } catch (e) {
|
||||||
|
// message.error("获取电站列表失败");
|
||||||
|
// } finally {
|
||||||
|
// state.engLoading = false;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
const handleHbrvcdChange = async (
|
||||||
|
hbrvcd: string,
|
||||||
index: number,
|
index: number,
|
||||||
type: string = "start"
|
type: string = "start"
|
||||||
) => {
|
) => {
|
||||||
const state = ensureRowState(index);
|
const state = ensureRowState(index);
|
||||||
editingData.value.baseName = baseOptions.value.find(
|
editingData.value.hbrvnm = hbrvcdOptions.value.find(
|
||||||
(item: any) => item.baseid == baseId
|
(item: any) => item.hbrvcd == hbrvcd
|
||||||
)?.basename;
|
)?.hbrvnm;
|
||||||
delWarning(baseId, "baseId");
|
delWarning(hbrvcd, "hbrvcd");
|
||||||
|
if (hbrvcd == null) {
|
||||||
|
delWarning(null, "hbrvcd");
|
||||||
|
delWarning(null, "stcd");
|
||||||
|
}
|
||||||
// 清空后续字段
|
// 清空后续字段
|
||||||
if (type != "start") {
|
if (type != "start") {
|
||||||
editingData.value.rstcd = undefined;
|
editingData.value.rstcd = undefined;
|
||||||
editingData.value.stcd = undefined;
|
editingData.value.stcd = undefined;
|
||||||
|
editingData.value.ennm = undefined;
|
||||||
|
editingData.value.stnm = undefined;
|
||||||
state.engOptions = [];
|
state.engOptions = [];
|
||||||
state.fpssOptions = [];
|
state.fpssOptions = [];
|
||||||
}
|
}
|
||||||
state.engLoading = true;
|
state.engLoading = true;
|
||||||
try {
|
try {
|
||||||
const res = await getEngInfoDropdown({ baseId });
|
const res = await getEngInfoDropdown({ hbrvcd });
|
||||||
state.engOptions = res.data || [];
|
state.engOptions = res.data || [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error("获取电站列表失败");
|
message.error("获取电站列表失败");
|
||||||
@ -408,17 +492,22 @@ const handleBaseChange = async (
|
|||||||
|
|
||||||
const handleEngChange = async (rstcd: string, index: number, type: string = "start") => {
|
const handleEngChange = async (rstcd: string, index: number, type: string = "start") => {
|
||||||
const state = ensureRowState(index);
|
const state = ensureRowState(index);
|
||||||
editingData.value.ennm = state.engOptions.find(
|
editingData.value.ennm = state.engOptions.find(
|
||||||
(item: any) => item.stcd === rstcd
|
(item: any) => item.stcd === rstcd
|
||||||
)?.ennm;
|
)?.ennm;
|
||||||
delWarning(rstcd, "rstcd");
|
delWarning(rstcd, "rstcd");
|
||||||
|
if (rstcd == null) {
|
||||||
|
delWarning(null, "stcd");
|
||||||
|
}
|
||||||
|
// 清空后续字段
|
||||||
if (type != "start") {
|
if (type != "start") {
|
||||||
editingData.value.stcd = undefined;
|
editingData.value.stcd = undefined;
|
||||||
|
editingData.value.stnm = undefined;
|
||||||
state.fpssOptions = [];
|
state.fpssOptions = [];
|
||||||
}
|
}
|
||||||
state.fpssLoading = true;
|
state.fpssLoading = true;
|
||||||
try {
|
try {
|
||||||
const res = await getFpssDropdown({ rstcd, baseId: editingData.value.baseId });
|
const res = await getFpssDropdown({ rstcd, hbrvcd: editingData.value.hbrvcd });
|
||||||
state.fpssOptions = res.data || [];
|
state.fpssOptions = res.data || [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error("获取设施列表失败");
|
message.error("获取设施列表失败");
|
||||||
@ -436,23 +525,23 @@ const handleFpssChange = (stcd: string, index: number) => {
|
|||||||
|
|
||||||
// 消除警告 / 添加警告
|
// 消除警告 / 添加警告
|
||||||
const delWarning = (val: any, key: string) => {
|
const delWarning = (val: any, key: string) => {
|
||||||
// 确保 _warnings 数组存在
|
// 确保 warnings 数组存在
|
||||||
if (!editingData.value._warnings) {
|
if (!editingData.value.warnings) {
|
||||||
editingData.value._warnings = [];
|
editingData.value.warnings = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const warnings = editingData.value._warnings;
|
const warnings = editingData.value.warnings;
|
||||||
const hasWarning = warnings.includes(key);
|
const hasWarning = warnings.includes(key);
|
||||||
|
|
||||||
if (val !== null && val !== undefined && val !== '') {
|
if (val !== null && val !== undefined && val !== "") {
|
||||||
// 1. 如果有值,且存在警告,则移除警告
|
// 1. 如果有值,且存在警告,则移除警告
|
||||||
if (hasWarning) {
|
if (hasWarning) {
|
||||||
editingData.value._warnings = warnings.filter((w: string) => w !== key);
|
editingData.value.warnings = warnings.filter((w: string) => w !== key);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 2. 如果值为空 (null/undefined/''),且不存在警告,则添加警告
|
// 2. 如果值为空 (null/undefined/''),且不存在警告,则添加警告
|
||||||
if (!hasWarning) {
|
if (!hasWarning) {
|
||||||
editingData.value._warnings.push(key);
|
editingData.value.warnings.push(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -462,24 +551,37 @@ const startEdit = (index: number) => {
|
|||||||
const originalRecord = props.fileTableData[index];
|
const originalRecord = props.fileTableData[index];
|
||||||
|
|
||||||
// 1. 深拷贝原始数据到临时编辑区
|
// 1. 深拷贝原始数据到临时编辑区
|
||||||
editingData.value = JSON.parse(JSON.stringify(originalRecord));
|
let copiedData = JSON.parse(JSON.stringify(originalRecord));
|
||||||
|
|
||||||
|
editingData.value = copiedData;
|
||||||
// 2. 预处理:将 fsz/fwet 字符串拆分为 Min/Max 供输入框使用
|
// 2. 预处理:将 fsz/fwet 字符串拆分为 Min/Max 供输入框使用
|
||||||
processStringToMinMax(editingData.value);
|
processStringToMinMax(editingData.value);
|
||||||
|
|
||||||
editingRowIndex.value = index;
|
editingRowIndex.value = index;
|
||||||
|
if (editingData.value.warnings.includes("hbrvcd")) {
|
||||||
|
editingData.value.hbrvcd = null;
|
||||||
|
editingData.value.hbrvnm = null;
|
||||||
|
editingData.value.rstcd = null;
|
||||||
|
editingData.value.stcd = null;
|
||||||
|
delWarning(null, "rstcd");
|
||||||
|
delWarning(null, "stcd");
|
||||||
|
}
|
||||||
|
if (editingData.value.warnings.includes("rstcd")) {
|
||||||
|
editingData.value.stcd = null;
|
||||||
|
delWarning(null, "stcd");
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 预加载下拉选项 (基于 editingData 的值)
|
// 3. 预加载下拉选项 (基于 editingData 的值)
|
||||||
if (editingData.value.baseId == "" || editingData.value.baseId == undefined) {
|
if (editingData.value.hbrvcd == "" || editingData.value.hbrvcd == undefined) {
|
||||||
if (editingData.value.rstcd) {
|
if (editingData.value.rstcd) {
|
||||||
handleBaseChange("", index, "start").then(() => {
|
handleHbrvcdChange("", index, "start").then(() => {
|
||||||
handleEngChange(editingData.value.rstcd, index, "start");
|
handleEngChange(editingData.value.rstcd, index, "start");
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
handleEngChange("", index, "start");
|
handleEngChange("", index, "start");
|
||||||
}
|
}
|
||||||
} else if (editingData.value.baseId != "" && editingData.value.baseId != undefined) {
|
} else if (editingData.value.hbrvcd != "" && editingData.value.hbrvcd != undefined) {
|
||||||
handleBaseChange(editingData.value.baseId, index, "start").then(() => {
|
handleHbrvcdChange(editingData.value.hbrvcd, index, "start").then(() => {
|
||||||
handleEngChange(editingData.value.rstcd, index, "start");
|
handleEngChange(editingData.value.rstcd, index, "start");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -536,24 +638,31 @@ const processMinMaxToString = (data: any) => {
|
|||||||
delete data.weightMax;
|
delete data.weightMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveEdit = (index: number) => {
|
const saveEdit = async (index: number) => {
|
||||||
// 1. 后处理:将 Min/Max 合并回 fsz/fwet
|
// 1. 后处理:将 Min/Max 合并回 fsz/fwet
|
||||||
processMinMaxToString(editingData.value);
|
processMinMaxToString(editingData.value);
|
||||||
|
|
||||||
// 2. 创建新数组,替换对应索引的数据
|
// 2. 创建新数组,替换对应索引的数据
|
||||||
const newData = [...props.fileTableData];
|
const newData = [...props.fileTableData];
|
||||||
newData[index] = { ...editingData.value };
|
newData[index] = { ...editingData.value };
|
||||||
|
emit("update:fileLoading", true);
|
||||||
// 3. 通知父组件更新
|
try {
|
||||||
emit("update:fileTableData", newData);
|
const res: any = await revalidateAndUpdateRow({
|
||||||
|
taskId: props.taskId,
|
||||||
// 4. 重置状态
|
data: newData[index],
|
||||||
editingRowIndex.value = null;
|
});
|
||||||
editingData.value = null;
|
if (res && res?.code == 0) {
|
||||||
console.log(newData)
|
message.success("保存成功");
|
||||||
console.log(props.taskId)
|
emit("update:fileTableData", newData);
|
||||||
// updateImportTask
|
editingRowIndex.value = null;
|
||||||
message.success("保存成功");
|
editingData.value = null;
|
||||||
|
emit("update:fileLoading", false);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
message.error("保存失败");
|
||||||
|
} finally {
|
||||||
|
emit("update:fileLoading", false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelEdit = () => {
|
const cancelEdit = () => {
|
||||||
|
|||||||
@ -32,13 +32,13 @@
|
|||||||
<template v-if="column.key === 'action' || column.dataIndex === 'action'">
|
<template v-if="column.key === 'action' || column.dataIndex === 'action'">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<a-button
|
<a-button
|
||||||
|
v-hasPerm="['sjtb:import-add']"
|
||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
@click="handleSubmit([record.id])"
|
@click="handleSubmit([record.id])"
|
||||||
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'"
|
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'"
|
||||||
>提交</a-button
|
>提交</a-button
|
||||||
>
|
>
|
||||||
|
|
||||||
<a-button
|
<a-button
|
||||||
v-hasPerm="['sjtb:import-add']"
|
v-hasPerm="['sjtb:import-add']"
|
||||||
type="link"
|
type="link"
|
||||||
@ -52,14 +52,11 @@
|
|||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
@click="handleEdit(record, 'edit')"
|
@click="handleEdit(record, 'edit')"
|
||||||
v-if="
|
v-if="record.status === 'PENDING'"
|
||||||
record.status === 'PENDING' ||
|
|
||||||
record.status === 'REJECTED' ||
|
|
||||||
record.status === 'PENDING'
|
|
||||||
"
|
|
||||||
>编辑</a-button
|
>编辑</a-button
|
||||||
>
|
>
|
||||||
<a-button
|
<a-button
|
||||||
|
v-hasPerm="['sjtb:import-add']"
|
||||||
type="link"
|
type="link"
|
||||||
danger
|
danger
|
||||||
size="small"
|
size="small"
|
||||||
@ -71,7 +68,12 @@
|
|||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
@click="handleEdit(record, 'view')"
|
@click="handleEdit(record, 'view')"
|
||||||
v-if="record.status === 'PENDING' || record.status === 'APPROVED'"
|
v-if="
|
||||||
|
(checkPerm(['sjtb:edit-review']) && record.status === 'DRAFT') ||
|
||||||
|
(checkPerm(['sjtb:import-add']) && record.status === 'PENDING') ||
|
||||||
|
(checkPerm(['sjtb:edit-review']) && record.status === 'REJECTED') ||
|
||||||
|
record.status === 'APPROVED'
|
||||||
|
"
|
||||||
>查看</a-button
|
>查看</a-button
|
||||||
>
|
>
|
||||||
<a-button
|
<a-button
|
||||||
@ -118,10 +120,10 @@
|
|||||||
<GuoYuSheShiShuJuTianBaoTable
|
<GuoYuSheShiShuJuTianBaoTable
|
||||||
ref="modalTableRef"
|
ref="modalTableRef"
|
||||||
:taskId="taskId"
|
:taskId="taskId"
|
||||||
:fileLoading="fileLoading"
|
|
||||||
:fileTableData="fileTableData"
|
:fileTableData="fileTableData"
|
||||||
:direction="direction"
|
:direction="direction"
|
||||||
@preview-click="handlePreviewClick"
|
@preview-click="handlePreviewClick"
|
||||||
|
v-model:file-loading="fileLoading"
|
||||||
@update:file-table-data="(val) => (fileTableData = val)"
|
@update:file-table-data="(val) => (fileTableData = val)"
|
||||||
/>
|
/>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -139,11 +141,11 @@
|
|||||||
|
|
||||||
<!-- 新增/编辑 Modal (对应 React 的 EditModal) -->
|
<!-- 新增/编辑 Modal (对应 React 的 EditModal) -->
|
||||||
<EditModal
|
<EditModal
|
||||||
|
ref="editModalRef"
|
||||||
v-model:visible="editModalVisible"
|
v-model:visible="editModalVisible"
|
||||||
:is-view="isView"
|
:is-view="isView"
|
||||||
:direction="direction"
|
:direction="direction"
|
||||||
:initial-values="currentRecord"
|
:initial-values="currentRecord"
|
||||||
:loading="submitLoading"
|
|
||||||
@cancel="editModalCancel"
|
@cancel="editModalCancel"
|
||||||
@ok="handleEditSubmit"
|
@ok="handleEditSubmit"
|
||||||
@preview-click="handlePreviewClick"
|
@preview-click="handlePreviewClick"
|
||||||
@ -274,15 +276,17 @@ import {
|
|||||||
importFishZip,
|
importFishZip,
|
||||||
cancelImportTask,
|
cancelImportTask,
|
||||||
checkImportStatus,
|
checkImportStatus,
|
||||||
batchSaveDraft,
|
importBatchSaveDraft,
|
||||||
getLastImportResult,
|
getLastImportResult,
|
||||||
markImportTaskSuccess,
|
markImportTaskSuccess,
|
||||||
|
deleteFile,
|
||||||
} from "@/api/guoYuSheShiShuJuTianBao";
|
} from "@/api/guoYuSheShiShuJuTianBao";
|
||||||
import { Tag } from "ant-design-vue"; // 确保导入 Tag
|
import { Tag } from "ant-design-vue"; // 确保导入 Tag
|
||||||
import { getDictItemsByCode } from "@/api/dict";
|
import { getDictItemsByCode } from "@/api/dict";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
||||||
|
const baseUrlPreview = import.meta.env.VITE_APP_BASE_URL;
|
||||||
// --- 类型定义 ---
|
// --- 类型定义 ---
|
||||||
interface FormData {
|
interface FormData {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@ -304,8 +308,8 @@ const guoyuStatus = ref<any>([]);
|
|||||||
// --- 基础配置 ---
|
// --- 基础配置 ---
|
||||||
const baseColumnsConfig: ColumnConfig[] = [
|
const baseColumnsConfig: ColumnConfig[] = [
|
||||||
{
|
{
|
||||||
dataIndex: "baseName",
|
dataIndex: "hbrvnm",
|
||||||
key: "baseName",
|
key: "hbrvnm",
|
||||||
title: "流域",
|
title: "流域",
|
||||||
width: 120,
|
width: 120,
|
||||||
fixed: "left",
|
fixed: "left",
|
||||||
@ -364,16 +368,17 @@ const baseColumnsConfig: ColumnConfig[] = [
|
|||||||
|
|
||||||
// --- 状态定义 ---
|
// --- 状态定义 ---
|
||||||
const visible = ref(false); // 导入预览 Modal
|
const visible = ref(false); // 导入预览 Modal
|
||||||
|
const editModalRef = ref<any>(null);
|
||||||
|
|
||||||
// 编辑相关状态
|
// 编辑相关状态
|
||||||
const editModalVisible = ref(false);
|
const editModalVisible = ref(false);
|
||||||
const isView = ref(false);
|
const isView = ref(false);
|
||||||
const currentRecord = ref<FormData | null>(null);
|
const currentRecord = ref<FormData | null>(null);
|
||||||
const submitLoading = ref(false);
|
|
||||||
|
|
||||||
const mediaPreviewVisible = ref(false);
|
const mediaPreviewVisible = ref(false);
|
||||||
const videoPreviewTitle = ref("视频预览");
|
const videoPreviewTitle = ref("视频预览");
|
||||||
interface MediaItem {
|
interface MediaItem {
|
||||||
|
id: string;
|
||||||
type: "image" | "video" | "formVideo" | "formImage";
|
type: "image" | "video" | "formVideo" | "formImage";
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
@ -387,7 +392,6 @@ const currentMediaItem = computed(() => previewList.value[currentMediaIndex.valu
|
|||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const fileTableData = ref<any[]>([]);
|
const fileTableData = ref<any[]>([]);
|
||||||
const orgFileTableData = ref<any[]>([]);
|
|
||||||
const batchData = ref<any[]>([]);
|
const batchData = ref<any[]>([]);
|
||||||
|
|
||||||
const modalTableRef = ref<any>(null);
|
const modalTableRef = ref<any>(null);
|
||||||
@ -589,7 +593,7 @@ const editModalCancel = () => {
|
|||||||
};
|
};
|
||||||
// 编辑/新增-按钮
|
// 编辑/新增-按钮
|
||||||
const handleEditSubmit = async (values: FormData) => {
|
const handleEditSubmit = async (values: FormData) => {
|
||||||
submitLoading.value = true;
|
editModalRef.value.localLoading = true;
|
||||||
if (currentRecord.value) {
|
if (currentRecord.value) {
|
||||||
// 编辑逻辑
|
// 编辑逻辑
|
||||||
let res: any = await editFishDraft({
|
let res: any = await editFishDraft({
|
||||||
@ -600,7 +604,7 @@ const handleEditSubmit = async (values: FormData) => {
|
|||||||
editModalVisible.value = false;
|
editModalVisible.value = false;
|
||||||
tableRef.value?.getList();
|
tableRef.value?.getList();
|
||||||
}
|
}
|
||||||
submitLoading.value = false;
|
editModalRef.value.localLoading = false;
|
||||||
} else {
|
} else {
|
||||||
// 新增逻辑
|
// 新增逻辑
|
||||||
let res: any = await addFishDraft({
|
let res: any = await addFishDraft({
|
||||||
@ -611,57 +615,9 @@ const handleEditSubmit = async (values: FormData) => {
|
|||||||
editModalVisible.value = false;
|
editModalVisible.value = false;
|
||||||
tableRef.value?.getList();
|
tableRef.value?.getList();
|
||||||
}
|
}
|
||||||
submitLoading.value = false;
|
editModalRef.value.localLoading = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const isRowDataEqual = (oldRow: any, newRow: any, fields: string[]): boolean => {
|
|
||||||
for (const field of fields) {
|
|
||||||
// 处理 undefined/null 的情况,确保比较的一致性
|
|
||||||
let oldVal = oldRow?.[field];
|
|
||||||
let newVal = newRow?.[field];
|
|
||||||
|
|
||||||
// 特殊处理:如果都是空值,视为相等
|
|
||||||
if (
|
|
||||||
(oldVal === undefined || oldVal === null || oldVal === "") &&
|
|
||||||
(newVal === undefined || newVal === null || newVal === "")
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 严格不相等
|
|
||||||
if (oldVal !== newVal) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkTableDataChanges = () => {
|
|
||||||
// 1. 定义需要比对的核心字段 (对应 Form 中的字段)
|
|
||||||
const oldData = orgFileTableData.value;
|
|
||||||
const newData = fileTableData.value;
|
|
||||||
|
|
||||||
// 2. 如果行数不同,肯定有变化
|
|
||||||
if (oldData.length !== newData.length) {
|
|
||||||
return { hasChanged: true, changedCount: newData.length };
|
|
||||||
}
|
|
||||||
|
|
||||||
let changedCount = 0;
|
|
||||||
|
|
||||||
// 3. 逐行比对
|
|
||||||
for (let i = 0; i < newData.length; i++) {
|
|
||||||
const oldRow = oldData[i];
|
|
||||||
const newRow = newData[i];
|
|
||||||
|
|
||||||
// 如果某一行数据不一致,计数+1
|
|
||||||
if (!isRowDataEqual(oldRow, newRow, ["baseId"])) {
|
|
||||||
changedCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { hasChanged: changedCount > 0, changedCount };
|
|
||||||
};
|
|
||||||
|
|
||||||
// 提交导入
|
// 提交导入
|
||||||
const handleModalOk = () => {
|
const handleModalOk = () => {
|
||||||
if (modalTableRef.value.editingData != undefined) {
|
if (modalTableRef.value.editingData != undefined) {
|
||||||
@ -669,36 +625,40 @@ const handleModalOk = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < fileTableData.value.length; i++) {
|
for (let i = 0; i < fileTableData.value.length; i++) {
|
||||||
if (fileTableData.value[i]._warnings?.length > 0) {
|
if (fileTableData.value[i].warnings?.length > 0) {
|
||||||
if (fileTableData.value[i]._warnings.includes("baseId")) {
|
// if (fileTableData.value[i].warnings.includes("baseId")) {
|
||||||
|
// message.warning("请检查流域,流域填写有误!");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
if (fileTableData.value[i].warnings.includes("hbrvcd")) {
|
||||||
message.warning("请检查流域,流域填写有误!");
|
message.warning("请检查流域,流域填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i]._warnings.includes("rstcd")) {
|
if (fileTableData.value[i].warnings.includes("rstcd")) {
|
||||||
message.warning("请检查电站,电站填写有误!");
|
message.warning("请检查电站,电站填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i]._warnings.includes("stcd")) {
|
if (fileTableData.value[i].warnings.includes("stcd")) {
|
||||||
message.warning("请检查过鱼设施,过鱼设施填写有误!");
|
message.warning("请检查过鱼设施,过鱼设施填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i]._warnings.includes("strdt")) {
|
if (fileTableData.value[i].warnings.includes("strdt")) {
|
||||||
message.warning("请检查过鱼时间,过鱼时间填写有误!");
|
message.warning("请检查过鱼时间,过鱼时间填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i]._warnings.includes("ftp")) {
|
if (fileTableData.value[i].warnings.includes("ftp")) {
|
||||||
message.warning("请检查鱼种类,鱼种类填写有误!");
|
message.warning("请检查鱼种类,鱼种类填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i]._warnings.includes("direction")) {
|
if (fileTableData.value[i].warnings.includes("direction")) {
|
||||||
message.warning("请检查游向,游向填写有误!");
|
message.warning("请检查游向,游向填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i]._warnings.includes("isfs")) {
|
if (fileTableData.value[i].warnings.includes("isfs")) {
|
||||||
message.warning("请检查是否鱼苗,是否鱼苗填写有误!");
|
message.warning("请检查是否鱼苗,是否鱼苗填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i]._warnings.includes("fcnt")) {
|
if (fileTableData.value[i].warnings.includes("fcnt")) {
|
||||||
message.warning("请检查过鱼数量,过鱼数量填写有误!");
|
message.warning("请检查过鱼数量,过鱼数量填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -715,17 +675,13 @@ const handleModalOk = () => {
|
|||||||
fileTableData.value.forEach((item) => {
|
fileTableData.value.forEach((item) => {
|
||||||
item.tm = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
item.tm = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||||
});
|
});
|
||||||
// const { hasChanged, changedCount } = checkTableDataChanges();
|
|
||||||
|
|
||||||
// // 3. 如果没有变化,直接返回,不执行后续操作
|
|
||||||
// if (!hasChanged) {
|
|
||||||
// message.info("数据未发生任何变化,无需提交");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: "是否提交导入数据?",
|
title: "是否提交导入数据?",
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
let res: any = await batchSaveDraft(fileTableData.value);
|
let res: any = await importBatchSaveDraft({
|
||||||
|
taskId: taskId.value,
|
||||||
|
fishDraftDataList: fileTableData.value,
|
||||||
|
});
|
||||||
if (res && res?.code == 0) {
|
if (res && res?.code == 0) {
|
||||||
message.success("导入成功");
|
message.success("导入成功");
|
||||||
tableRef.value?.getList();
|
tableRef.value?.getList();
|
||||||
@ -751,6 +707,8 @@ const handleCustomCancel = () => {
|
|||||||
message.success("取消成功");
|
message.success("取消成功");
|
||||||
tableRef.value?.getList();
|
tableRef.value?.getList();
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
|
} else {
|
||||||
|
message.error("取消失败");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -800,7 +758,11 @@ const fileChange = (file: File) => {
|
|||||||
message.error("导入失败");
|
message.error("导入失败");
|
||||||
} else {
|
} else {
|
||||||
taskId.value = res.data.taskId;
|
taskId.value = res.data.taskId;
|
||||||
message.success("导入成功");
|
if (res.data.summary) {
|
||||||
|
message.success(res.data.summary);
|
||||||
|
} else {
|
||||||
|
message.success("导入成功");
|
||||||
|
}
|
||||||
fileTableaAnalysis(res, "file");
|
fileTableaAnalysis(res, "file");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -847,9 +809,9 @@ const fileTableaAnalysis = (res: any, type: string) => {
|
|||||||
let data = [];
|
let data = [];
|
||||||
let list = [];
|
let list = [];
|
||||||
if (type == "file") {
|
if (type == "file") {
|
||||||
list = res.data.failedRows.concat(res.data.successRows);
|
list = res.data.rows;
|
||||||
} else {
|
} else {
|
||||||
list = res.data.result.failedRowDetails.concat(res.data.result.successRowDetails);
|
list = res.data.result.rows;
|
||||||
}
|
}
|
||||||
list.sort((a: any, b: any) => {
|
list.sort((a: any, b: any) => {
|
||||||
const keyA =
|
const keyA =
|
||||||
@ -866,11 +828,10 @@ const fileTableaAnalysis = (res: any, type: string) => {
|
|||||||
vdpthsWarnings: item.vdpthsWarnings,
|
vdpthsWarnings: item.vdpthsWarnings,
|
||||||
picpthList: item.picpthList,
|
picpthList: item.picpthList,
|
||||||
picpthsWarnings: item.picpthsWarnings,
|
picpthsWarnings: item.picpthsWarnings,
|
||||||
_warnings: item.warnings,
|
warnings: item.warnings,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
fileTableData.value = data || [];
|
fileTableData.value = data || [];
|
||||||
orgFileTableData.value = JSON.parse(JSON.stringify(fileTableData.value));
|
|
||||||
fileLoading.value = false;
|
fileLoading.value = false;
|
||||||
};
|
};
|
||||||
const handleReset = (values) => {
|
const handleReset = (values) => {
|
||||||
@ -937,12 +898,18 @@ const handleSearchFinish = (values: any) => {
|
|||||||
dataType: "string",
|
dataType: "string",
|
||||||
value: values.rstcd,
|
value: values.rstcd,
|
||||||
},
|
},
|
||||||
values.baseId !== "all" && {
|
values.hbrvcd !== "all" && {
|
||||||
field: "baseId",
|
field: "hbrvcd",
|
||||||
operator: "eq",
|
operator: "eq",
|
||||||
dataType: "string",
|
dataType: "string",
|
||||||
value: values.baseId,
|
value: values.hbrvcd,
|
||||||
},
|
},
|
||||||
|
// values.baseId !== "all" && {
|
||||||
|
// field: "baseId",
|
||||||
|
// operator: "eq",
|
||||||
|
// dataType: "string",
|
||||||
|
// value: values.baseId,
|
||||||
|
// },
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
@ -960,9 +927,16 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
|
|||||||
const nameList = record.picpthList;
|
const nameList = record.picpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
|
id: record.id,
|
||||||
type: "image",
|
type: "image",
|
||||||
name: item.name,
|
name: item.name,
|
||||||
url: item.value ? `${baseUrl}/?${item.value}` : "",
|
url:
|
||||||
|
baseUrlPreview +
|
||||||
|
"/data/fishDraft/previewFile?filename=" +
|
||||||
|
item.name +
|
||||||
|
"&taskId=" +
|
||||||
|
taskId.value +
|
||||||
|
"&type=1",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (type === "video") {
|
} else if (type === "video") {
|
||||||
@ -971,9 +945,16 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
|
|||||||
const nameList = record.vdpthList;
|
const nameList = record.vdpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
|
id: record.id,
|
||||||
type: "video",
|
type: "video",
|
||||||
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
||||||
url: item.value ? `${baseUrl}/?${item.value}` : "",
|
url:
|
||||||
|
baseUrlPreview +
|
||||||
|
"/data/fishDraft/previewFile?filename=" +
|
||||||
|
item.name +
|
||||||
|
"&taskId=" +
|
||||||
|
taskId.value +
|
||||||
|
"&type=2",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (type === "formImage") {
|
} else if (type === "formImage") {
|
||||||
@ -981,6 +962,7 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
|
|||||||
const nameList = JSON.parse(JSON.stringify(record)).picpthList;
|
const nameList = JSON.parse(JSON.stringify(record)).picpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
|
id: record.id,
|
||||||
type: "formImage",
|
type: "formImage",
|
||||||
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
||||||
url: item.url,
|
url: item.url,
|
||||||
@ -991,6 +973,7 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
|
|||||||
const nameList = JSON.parse(JSON.stringify(record)).vdpthList;
|
const nameList = JSON.parse(JSON.stringify(record)).vdpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
|
id: record.id,
|
||||||
type: "formVideo",
|
type: "formVideo",
|
||||||
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
||||||
url: item.url,
|
url: item.url,
|
||||||
@ -1011,7 +994,7 @@ const prevMedia = () => {
|
|||||||
currentMediaIndex.value--;
|
currentMediaIndex.value--;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// 【新增】统一下一逻辑
|
||||||
const nextMedia = () => {
|
const nextMedia = () => {
|
||||||
if (currentMediaIndex.value < previewList.value.length - 1) {
|
if (currentMediaIndex.value < previewList.value.length - 1) {
|
||||||
currentMediaIndex.value++;
|
currentMediaIndex.value++;
|
||||||
@ -1024,38 +1007,64 @@ const handleDeleteMedia = (item: any, index: number) => {
|
|||||||
title: "确认删除",
|
title: "确认删除",
|
||||||
content: "确定要从预览列表中移除该项吗?",
|
content: "确定要从预览列表中移除该项吗?",
|
||||||
zIndex: 2002,
|
zIndex: 2002,
|
||||||
onOk: () => {
|
onOk: async () => {
|
||||||
previewList.value.splice(index, 1);
|
return new Promise(async (resolve, reject) => {
|
||||||
if (videoPreviewTitle.value == "图片预览") {
|
const params = {
|
||||||
if (previewList.value.length == 0) {
|
id: item.id,
|
||||||
tablePreviewRecord.value.picpthList = [];
|
taskId: taskId.value,
|
||||||
tablePreviewRecord.value.picpthsWarnings = [];
|
type:
|
||||||
} else {
|
videoPreviewTitle.value == "图片预览"
|
||||||
tablePreviewRecord.value.picpthList.splice(index, 1);
|
? 1
|
||||||
tablePreviewRecord.value.picpthsWarnings = tablePreviewRecord.value.picpthsWarnings.filter(
|
: videoPreviewTitle.value == "视频预览"
|
||||||
(warningName: any) => warningName !== item.name
|
? 2
|
||||||
);
|
: 0,
|
||||||
}
|
filename: item.name,
|
||||||
} else {
|
};
|
||||||
if (previewList.value.length == 0) {
|
try {
|
||||||
tablePreviewRecord.value.vdpthList = [];
|
let res: any = await deleteFile(params);
|
||||||
tablePreviewRecord.value.vdpthsWarnings = [];
|
if (res && res?.code == 0) {
|
||||||
} else {
|
message.success("删除成功");
|
||||||
tablePreviewRecord.value.vdpthList.splice(index, 1);
|
previewList.value.splice(index, 1);
|
||||||
tablePreviewRecord.value.vdpthsWarnings = tablePreviewRecord.value.vdpthsWarnings.filter(
|
if (videoPreviewTitle.value == "图片预览") {
|
||||||
(warningName: any) => warningName !== item.name
|
if (previewList.value.length == 0) {
|
||||||
);
|
tablePreviewRecord.value.picpthList = [];
|
||||||
}
|
tablePreviewRecord.value.picpthsWarnings = [];
|
||||||
}
|
} else {
|
||||||
|
tablePreviewRecord.value.picpthList.splice(index, 1);
|
||||||
|
tablePreviewRecord.value.picpthsWarnings = tablePreviewRecord.value.picpthsWarnings.filter(
|
||||||
|
(warningName: any) => warningName !== item.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (previewList.value.length == 0) {
|
||||||
|
tablePreviewRecord.value.vdpthList = [];
|
||||||
|
tablePreviewRecord.value.vdpthsWarnings = [];
|
||||||
|
} else {
|
||||||
|
tablePreviewRecord.value.vdpthList.splice(index, 1);
|
||||||
|
tablePreviewRecord.value.vdpthsWarnings = tablePreviewRecord.value.vdpthsWarnings.filter(
|
||||||
|
(warningName: any) => warningName !== item.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (previewList.value.length === 0) {
|
if (previewList.value.length === 0) {
|
||||||
mediaPreviewVisible.value = false;
|
mediaPreviewVisible.value = false;
|
||||||
} else {
|
} else {
|
||||||
// 调整索引
|
// 调整索引
|
||||||
if (index <= currentMediaIndex.value) {
|
if (index <= currentMediaIndex.value) {
|
||||||
currentMediaIndex.value = Math.max(0, currentMediaIndex.value - 1);
|
currentMediaIndex.value = Math.max(0, currentMediaIndex.value - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
message.error("删除失败");
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
message.error("删除失败");
|
||||||
|
reject();
|
||||||
}
|
}
|
||||||
}
|
}).catch(() => console.log("Oops errors!"));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -1067,33 +1076,33 @@ const closeMediaPreview = () => {
|
|||||||
currentMediaIndex.value = 0;
|
currentMediaIndex.value = 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const tableContainerRef = ref<HTMLElement | null>(null)
|
const tableContainerRef = ref<HTMLElement | null>(null);
|
||||||
const tableScrollY = ref<number | undefined>(undefined)
|
const tableScrollY = ref<number | undefined>(undefined);
|
||||||
// 计算表格主体高度(减去表头、分页器、内边距等)
|
// 计算表格主体高度(减去表头、分页器、内边距等)
|
||||||
const calcTableScrollY = () => {
|
const calcTableScrollY = () => {
|
||||||
if (!tableContainerRef.value) return
|
if (!tableContainerRef.value) return;
|
||||||
// 获取容器高度
|
// 获取容器高度
|
||||||
const containerHeight = tableContainerRef.value.clientHeight
|
const containerHeight = tableContainerRef.value.clientHeight;
|
||||||
console.log(containerHeight)
|
console.log(containerHeight);
|
||||||
// 估算表头(约 55px) + 分页器(约 64px) + 上下内边距容差(10px) = 约 130px
|
// 估算表头(约 55px) + 分页器(约 64px) + 上下内边距容差(10px) = 约 130px
|
||||||
// 如果你有筛选栏等,需要额外减去
|
// 如果你有筛选栏等,需要额外减去
|
||||||
const otherHeight = 112
|
const otherHeight = 112;
|
||||||
const y = containerHeight - otherHeight
|
const y = containerHeight - otherHeight;
|
||||||
tableScrollY.value = y > 0 ? y : undefined
|
tableScrollY.value = y > 0 ? y : undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 监听容器大小变化(窗口 resize 或内容变化)
|
// 监听容器大小变化(窗口 resize 或内容变化)
|
||||||
const observer = new ResizeObserver(() => {
|
const observer = new ResizeObserver(() => {
|
||||||
calcTableScrollY()
|
calcTableScrollY();
|
||||||
})
|
});
|
||||||
// --- 生命周期 ---
|
// --- 生命周期 ---
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
calcTableScrollY()
|
calcTableScrollY();
|
||||||
if (tableContainerRef.value) {
|
if (tableContainerRef.value) {
|
||||||
observer.observe(tableContainerRef.value)
|
observer.observe(tableContainerRef.value);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
getDictItemsByCode({ dictCode: "direction" }).then((res) => {
|
getDictItemsByCode({ dictCode: "direction" }).then((res) => {
|
||||||
direction.value = res.data;
|
direction.value = res.data;
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user