bug修改,鱼种类修改,流域基地逻辑修改

This commit is contained in:
扈兆增 2026-04-30 18:07:19 +08:00
parent 86f1030b03
commit 2342a3555e
10 changed files with 583 additions and 300 deletions

View File

@ -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
}); });

View File

@ -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
}); });

View File

@ -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);
}; };

View File

@ -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"
> >
<!-- <!--
@ -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 {

View File

@ -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,

View File

@ -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;
}

View File

@ -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"
@ -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 {

View File

@ -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;
} }

View File

@ -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("获取电站列表失败");
@ -412,13 +496,18 @@ const handleEngChange = async (rstcd: string, index: number, type: string = "sta
(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 {
const res: any = await revalidateAndUpdateRow({
taskId: props.taskId,
data: newData[index],
});
if (res && res?.code == 0) {
message.success("保存成功");
emit("update:fileTableData", newData); emit("update:fileTableData", newData);
// 4.
editingRowIndex.value = null; editingRowIndex.value = null;
editingData.value = null; editingData.value = null;
console.log(newData) emit("update:fileLoading", false);
console.log(props.taskId) }
// updateImportTask } catch (e) {
message.success("保存成功"); message.error("保存失败");
} finally {
emit("update:fileLoading", false);
}
}; };
const cancelEdit = () => { const cancelEdit = () => {

View File

@ -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;
if (res.data.summary) {
message.success(res.data.summary);
} else {
message.success("导入成功"); 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,7 +1007,23 @@ const handleDeleteMedia = (item: any, index: number) => {
title: "确认删除", title: "确认删除",
content: "确定要从预览列表中移除该项吗?", content: "确定要从预览列表中移除该项吗?",
zIndex: 2002, zIndex: 2002,
onOk: () => { onOk: async () => {
return new Promise(async (resolve, reject) => {
const params = {
id: item.id,
taskId: taskId.value,
type:
videoPreviewTitle.value == "图片预览"
? 1
: videoPreviewTitle.value == "视频预览"
? 2
: 0,
filename: item.name,
};
try {
let res: any = await deleteFile(params);
if (res && res?.code == 0) {
message.success("删除成功");
previewList.value.splice(index, 1); previewList.value.splice(index, 1);
if (videoPreviewTitle.value == "图片预览") { if (videoPreviewTitle.value == "图片预览") {
if (previewList.value.length == 0) { if (previewList.value.length == 0) {
@ -1056,6 +1055,16 @@ const handleDeleteMedia = (item: any, index: number) => {
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;
}); });