WholeProcessPlatform/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/index.vue

798 lines
21 KiB
Vue
Raw Normal View History

<template>
2026-04-20 16:57:54 +08:00
<div class="guoYuSheShiShuJuTianBao-page">
<GuoYuSheShiShuJuTianBaoSearch
2026-04-24 15:31:32 +08:00
ref="searchRef"
:guoyuStatus="guoyuStatus"
:direction="direction"
2026-04-20 16:57:54 +08:00
:handle-add="handleAdd"
2026-04-22 17:53:20 +08:00
:batchData="batchData"
2026-04-24 15:31:32 +08:00
:importBtn="importBtn"
:batchDelBtn="batchDelBtn"
:submitBtn="submitBtn"
:successBtn="successBtn"
@reset="handleReset"
2026-04-20 16:57:54 +08:00
@search-finish="handleSearchFinish"
/>
<!-- 主表格 -->
2026-04-22 17:53:20 +08:00
<BasicTable
ref="tableRef"
2026-04-20 16:57:54 +08:00
:columns="columns"
2026-04-22 17:53:20 +08:00
:list-url="getFishDraftPage"
:search-params="{}"
:enable-row-selection="true"
@selection-change="handleSelectionChange"
2026-04-20 16:57:54 +08:00
>
2026-04-22 17:53:20 +08:00
<!-- 使用 bodyCell 插槽自定义单元格渲染 -->
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action' || column.dataIndex === 'action'">
<div class="flex">
2026-04-24 15:31:32 +08:00
<a-button
type="link"
size="small"
@click="handleSubmit([record.id])"
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'"
>提交</a-button
>
<a-button
type="link"
size="small"
@click="handleEdit(record, 'edit')"
v-if="
record.status === 'DRAFT' ||
record.status === 'REJECTED' ||
record.status === 'SUBMITTED'
"
2026-04-24 15:31:32 +08:00
>编辑</a-button
>
<a-button
type="link"
danger
size="small"
@click="handleDelete([record.id])"
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'"
2026-04-22 17:53:20 +08:00
>删除</a-button
>
2026-04-24 15:31:32 +08:00
<a-button
type="link"
size="small"
@click="handleEdit(record, 'view')"
v-if="record.status === 'SUBMITTED'"
>查看</a-button
>
<a-button
type="link"
size="small"
@click="handleSuccess([record.id])"
v-if="record.status === 'SUBMITTED'"
>审批</a-button
>
<a-button
type="link"
danger
size="small"
@click="handleReject(record.id)"
v-if="record.status === 'SUBMITTED'"
>驳回</a-button
>
2026-04-22 17:53:20 +08:00
</div>
</template>
</template>
</BasicTable>
2026-04-24 15:31:32 +08:00
<!-- 隐藏的文件输入框 -->
<input
ref="fileInputRef"
type="file"
accept=".zip,application/zip,application/x-zip-compressed"
style="display: none"
@change="handleFileSelect"
/>
2026-04-20 16:57:54 +08:00
<!-- 导入预览 Modal -->
<a-modal
title="导入数据预览"
ok-text="提交导入"
2026-04-24 15:31:32 +08:00
cancel-text="取消导入"
2026-04-20 16:57:54 +08:00
:width="1500"
2026-04-22 17:53:20 +08:00
v-model:open="visible"
maskClosable="false"
@cancel="handleCancel"
2026-04-20 16:57:54 +08:00
:confirm-loading="fileLoading"
>
<GuoYuSheShiShuJuTianBaoTable
ref="modalTableRef"
:fileLoading="fileLoading"
:fileTableData="fileTableData"
:direction="direction"
@update:file-table-data="(val) => fileTableData = val"
/>
<template #footer>
<a-button key="back" @click="handleCustomCancel">取消导入</a-button>
<a-button
key="submit"
type="primary"
:loading="fileLoading"
@click="handleModalOk"
>
提交导入
</a-button>
</template>
2026-04-20 16:57:54 +08:00
</a-modal>
<!-- 新增/编辑 Modal (对应 React EditModal) -->
<!-- 假设已创建对应的 Vue 组件 GuoYuSheShiShuJuTianBaoForm -->
<EditModal
2026-04-22 17:53:20 +08:00
v-model:visible="editModalVisible"
2026-04-24 15:31:32 +08:00
:is-view="isView"
:direction="direction"
2026-04-20 16:57:54 +08:00
:initial-values="currentRecord"
:loading="submitLoading"
@cancel="editModalCancel"
@ok="handleEditSubmit"
/>
<!-- 视频预览 Modal -->
<a-modal
title="视频预览"
2026-04-22 17:53:20 +08:00
v-model:open="videoPreviewVisible"
2026-04-20 16:57:54 +08:00
:footer="null"
width="800px"
@cancel="closeVideoPreview"
>
2026-04-22 17:53:20 +08:00
<video
v-if="currentVideoUrl"
controls
autoplay
style="width: 100%"
:src="currentVideoUrl"
>
2026-04-20 16:57:54 +08:00
您的浏览器不支持视频播放
</video>
</a-modal>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, h, nextTick } from "vue";
2026-04-22 17:53:20 +08:00
import { message, Modal } from "ant-design-vue"; // 假设使用 ant-design-vue
import BasicTable from "@/components/BasicTable/index.vue";
import GuoYuSheShiShuJuTianBaoSearch from "./guoYuSheShiShuJuTianBaoSearch.vue";
import GuoYuSheShiShuJuTianBaoTable from "./guoYuSheShiShuJuTianBaoTable.vue";
2026-04-22 17:53:20 +08:00
import EditModal from "./guoYuSheShiShuJuTianBaoForm.vue";
import {
getFishDraftPage,
addFishDraft,
editFishDraft,
delFishDraft,
2026-04-24 15:31:32 +08:00
submitFishDraft,
successFishDraft,
rejectFishDraft,
importFishZip,
submitImportTask,
cancelImportTask,
checkImportStatus,
batchSaveDraft,
getLastImportResult,
2026-04-22 17:53:20 +08:00
} from "@/api/guoYuSheShiShuJuTianBao";
2026-04-24 15:31:32 +08:00
import { Tag } from "ant-design-vue"; // 确保导入 Tag
import { getDictItemsByCode } from "@/api/dict";
import { m } from "vue-router/dist/router-CWoNjPRp.mjs";
2026-04-20 16:57:54 +08:00
// import { FileImageOutlined, VideoCameraOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
// --- 类型定义 ---
interface FormData {
2026-04-22 17:53:20 +08:00
[key: string]: any;
2026-04-20 16:57:54 +08:00
}
interface ColumnConfig {
2026-04-22 17:53:20 +08:00
dataIndex: string;
key: string;
title: string;
width?: number;
2026-04-24 15:31:32 +08:00
fixed?: string;
2026-04-22 17:53:20 +08:00
customRender?: (text: any, record: any) => any;
2026-04-20 16:57:54 +08:00
}
2026-04-24 15:31:32 +08:00
const fileInputRef = ref<any>(null);
2026-04-22 17:53:20 +08:00
const tableRef = ref<any>(null);
2026-04-24 15:31:32 +08:00
// 字典项
const direction = ref<any>([]);
const guoyuStatus = ref<any>([]);
2026-04-20 16:57:54 +08:00
// --- 基础配置 ---
const baseColumnsConfig: ColumnConfig[] = [
2026-04-24 15:31:32 +08:00
{
dataIndex: "baseName",
key: "baseName",
title: "流域",
2026-04-24 15:31:32 +08:00
width: 120,
fixed: "left",
},
{ dataIndex: "ennm", key: "ennm", title: "电站名称", width: 120, fixed: "left" },
{ dataIndex: "stnm", key: "stnm", title: "过鱼设施名称", width: 150, fixed: "left" },
2026-04-22 17:53:20 +08:00
{ dataIndex: "strdt", key: "strdt", title: "过鱼时间", width: 150 },
2026-04-24 15:31:32 +08:00
{ dataIndex: "ftpName", key: "ftpName", title: "鱼种类", width: 120 },
2026-04-22 17:53:20 +08:00
{
dataIndex: "isfs",
key: "isfs",
title: "是否鱼苗",
width: 74,
customRender: ({ text }: any) => {
2026-04-24 15:31:32 +08:00
const isYes = text === 1 || text === "1";
return h(
Tag,
{
color: isYes ? "success" : "error", // Antdv Tag 的颜色预设
style: { margin: 0 }, // 去除默认 margin使其在表格中对齐更好
},
() => (isYes ? "是" : "否")
);
},
2026-04-22 17:53:20 +08:00
},
2026-04-24 15:31:32 +08:00
{
dataIndex: "direction",
key: "direction",
title: "游向",
width: 80,
customRender: ({ text }: any) =>
direction.value.find((item: any) => item.itemCode === text)?.dictName || "-",
2026-04-22 17:53:20 +08:00
},
{ dataIndex: "fcnt", key: "fcnt", title: "过鱼数量(尾)", width: 120 },
{ dataIndex: "fsz", key: "fsz", title: "体长(cm)", width: 110 },
{ dataIndex: "fwet", key: "fwet", title: "平均体重(g)", width: 110 },
{ dataIndex: "wt", key: "wt", title: "水温(℃)", width: 80 },
{ dataIndex: "picpth", key: "level5", title: "图片", width: 100 },
{ dataIndex: "vdpth", key: "level6", title: "视频", width: 100 },
{ dataIndex: "tm", key: "tm", title: "填报时间", width: 150 },
2026-04-24 15:31:32 +08:00
{
dataIndex: "status",
key: "status",
title: "状态",
width: 100,
customRender: ({ text }: any) => {
let data = guoyuStatus.value.find((item: any) => item.itemCode === text);
return h(
Tag,
{
color: data?.custom1 || "error", // Antdv Tag 的颜色预设
},
() => data?.dictName || "-"
);
},
},
2026-04-22 17:53:20 +08:00
];
2026-04-20 16:57:54 +08:00
// --- 状态定义 ---
2026-04-22 17:53:20 +08:00
const visible = ref(false); // 导入预览 Modal
2026-04-20 16:57:54 +08:00
// 编辑相关状态
2026-04-22 17:53:20 +08:00
const editModalVisible = ref(false);
2026-04-24 15:31:32 +08:00
const isView = ref(false);
2026-04-22 17:53:20 +08:00
const currentRecord = ref<FormData | null>(null);
const submitLoading = ref(false);
2026-04-20 16:57:54 +08:00
// 视频预览相关状态
2026-04-22 17:53:20 +08:00
const videoPreviewVisible = ref(false);
const currentVideoUrl = ref<string>("");
2026-04-20 16:57:54 +08:00
// 表格数据
2026-04-22 17:53:20 +08:00
const fileTableData = ref<any[]>([]);
const orgFileTableData = ref<any[]>([]);
const warnings = ref<any[]>([]);
2026-04-22 17:53:20 +08:00
const batchData = ref<any[]>([]);
2026-04-20 16:57:54 +08:00
const modalTableRef = ref<any>(null);
2026-04-22 17:53:20 +08:00
const fileLoading = ref(false);
2026-04-20 16:57:54 +08:00
// 行内编辑 Key (用于导入预览表格)
2026-04-22 17:53:20 +08:00
const editingKey = ref<string | number>("");
2026-04-20 16:57:54 +08:00
// --- 辅助函数 ---
// 从 Zip 获取 Blob URL
2026-04-22 17:53:20 +08:00
// const getBlobUrlFromZip = async (zip: JSZip, fileName: string): Promise<string> => {
// try {
// const file = zip.file(fileName);
// if (!file) return "";
// const blob = await file.async("blob");
// return URL.createObjectURL(blob);
const taskId = ref<string>("");
2026-04-20 16:57:54 +08:00
// 主表格 Columns
const columns = computed(() => {
return [
...baseColumnsConfig.map((col) => {
2026-04-22 17:53:20 +08:00
if (col.dataIndex === "level5") {
2026-04-20 16:57:54 +08:00
return {
...col,
customRender: ({ text }: any) => {
2026-04-22 17:53:20 +08:00
if (!text) return "-";
// 实际应渲染 Icon 和点击事件,此处简化
return `<span style="color:#52c41a; cursor:pointer">查看图片</span>`;
},
};
2026-04-20 16:57:54 +08:00
}
2026-04-22 17:53:20 +08:00
if (col.dataIndex === "level6") {
2026-04-20 16:57:54 +08:00
return {
...col,
customRender: ({ text }: any) => {
2026-04-22 17:53:20 +08:00
if (!text) return "-";
return `<span style="color:#1890ff; cursor:pointer">播放视频</span>`;
},
};
2026-04-20 16:57:54 +08:00
}
2026-04-22 17:53:20 +08:00
return { ...col, visible: true };
2026-04-20 16:57:54 +08:00
}),
{
2026-04-22 17:53:20 +08:00
title: "操作",
key: "action",
dataIndex: "action",
fixed: "right",
2026-04-24 15:31:32 +08:00
width: 200,
2026-04-22 17:53:20 +08:00
align: "center",
},
];
});
2026-04-20 16:57:54 +08:00
// --- 业务逻辑方法 ---
const handleAdd = () => {
2026-04-22 17:53:20 +08:00
currentRecord.value = null;
editModalVisible.value = true;
};
2026-04-24 15:31:32 +08:00
// 修改
const handleEdit = (record: any, type: string) => {
if (type == "view") {
isView.value = true;
} else {
isView.value = false;
}
2026-04-22 17:53:20 +08:00
currentRecord.value = { ...record };
editModalVisible.value = true;
};
2026-04-20 16:57:54 +08:00
2026-04-24 15:31:32 +08:00
// 单个/批量 删除过鱼数据
2026-04-22 17:53:20 +08:00
const handleDelete = (ids: any[]) => {
2026-04-20 16:57:54 +08:00
Modal.confirm({
2026-04-24 15:31:32 +08:00
title: "是否确认 删除 选中数据吗?",
2026-04-22 17:53:20 +08:00
onOk: async () => {
let res: any = await delFishDraft(ids);
if (res && res?.code == 0) {
message.success("删除成功");
tableRef.value?.getList();
}
},
});
};
2026-04-24 15:31:32 +08:00
// 批量删除 - 按钮
const batchDelBtn = () => {
2026-04-22 17:53:20 +08:00
handleDelete(batchData.value);
};
2026-04-24 15:31:32 +08:00
//单个/ 批量提交过鱼数据
const handleSubmit = (ids: any[]) => {
Modal.confirm({
title: "是否 提交 选中数据吗?",
onOk: async () => {
let res: any = await submitFishDraft(ids);
if (res && res?.code == 0) {
message.success("提交成功");
tableRef.value?.getList();
}
},
});
};
// 批量提交-按钮
const submitBtn = async () => {
handleSubmit(batchData.value);
};
// 单个/ 批量审批过鱼数据
const handleSuccess = (ids: any[]) => {
let rejectReason = "";
Modal.confirm({
title: "是否确认 审批通过 选中数据?",
// 使用 h 函数创建内容
content: h("div", { style: "margin-top: 10px;" }, [
h("div", { style: "margin-bottom: 8px;" }, [
h("span", { style: "color: red;" }, "* "),
h("span", "审批原因:"),
]),
h("textarea", {
class: "ant-input", // 使用 antdv 的样式类,使其看起来像 Antdv 输入框
placeholder: "请输入审批原因",
rows: 4,
style: {
width: "100%",
resize: "none",
border: "1px solid #d9d9d9",
padding: "8px",
borderRadius: "4px",
},
// 监听输入事件,更新局部变量
onInput: (e: Event) => {
rejectReason = (e.target as HTMLTextAreaElement).value;
},
}),
]),
okText: "确认审批",
cancelText: "取消",
onOk: async () => {
let res: any = await successFishDraft({ ids: ids, approveComment: rejectReason });
if (res && res?.code == 0) {
message.success("审批成功");
tableRef.value?.getList();
}
},
});
};
// 批量审批-按钮
const successBtn = async () => {
handleSuccess(batchData.value);
};
// 批量驳回过鱼数据
const handleReject = (id: any) => {
let rejectReason = "";
Modal.confirm({
title: "是否确认 驳回 选中数据?",
// 使用 h 函数创建内容
content: h("div", { style: "margin-top: 10px;" }, [
h("div", { style: "margin-bottom: 8px;" }, [
h("span", { style: "color: red;" }, "* "),
h("span", "驳回原因:"),
]),
h("textarea", {
class: "ant-input", // 使用 antdv 的样式类,使其看起来像 Antdv 输入框
placeholder: "请输入驳回原因",
rows: 4,
style: {
width: "100%",
resize: "none",
border: "1px solid #d9d9d9",
padding: "8px",
borderRadius: "4px",
},
// 监听输入事件,更新局部变量
onInput: (e: Event) => {
rejectReason = (e.target as HTMLTextAreaElement).value;
},
}),
]),
okText: "确认驳回",
cancelText: "取消",
onOk: async () => {
// 校验驳回原因不能为空
if (!rejectReason || rejectReason.trim() === "") {
message.warning("请输入驳回原因");
return Promise.reject(); // 阻止 Modal 关闭
}
let res: any = await rejectFishDraft({ id: id, rejectReason: rejectReason });
if (res && res?.code == 0) {
message.success("驳回成功");
tableRef.value?.getList();
}
},
});
};
2026-04-22 17:53:20 +08:00
// 多选
2026-04-24 15:31:32 +08:00
const handleSelectionChange = (keys: any) => {
2026-04-22 17:53:20 +08:00
batchData.value = keys;
};
2026-04-20 16:57:54 +08:00
const editModalCancel = () => {
2026-04-22 17:53:20 +08:00
editModalVisible.value = false;
};
2026-04-24 15:31:32 +08:00
// 编辑/新增-按钮
2026-04-20 16:57:54 +08:00
const handleEditSubmit = async (values: FormData) => {
2026-04-22 17:53:20 +08:00
submitLoading.value = true;
if (currentRecord.value) {
// 编辑逻辑
let res: any = await editFishDraft({
2026-04-24 15:31:32 +08:00
...values,
2026-04-22 17:53:20 +08:00
});
if (res && res?.code == 0) {
message.success("编辑成功");
editModalVisible.value = false;
tableRef.value?.getList();
2026-04-20 16:57:54 +08:00
}
2026-04-22 17:53:20 +08:00
submitLoading.value = false;
} else {
// 新增逻辑
let res: any = await addFishDraft({
...values,
});
if (res && res?.code == 0) {
message.success("新增成功");
editModalVisible.value = false;
tableRef.value?.getList();
}
submitLoading.value = 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 };
};
2026-04-20 16:57:54 +08:00
// 提交导入
2026-04-20 16:57:54 +08:00
const handleModalOk = () => {
console.log(orgFileTableData.value)
console.log(fileTableData.value)
console.log(
modalTableRef.value.editingData)
if (modalTableRef.value.editingData != undefined) {
message.warning("请点击保存后提交数据!");
return
}
const { hasChanged, changedCount } = checkTableDataChanges();
// 3. 如果没有变化,直接返回,不执行后续操作
if (!hasChanged) {
message.info("数据未发生任何变化,无需提交");
return;
}
console.log(123)
// if (warnings.value.length > 0) {
// message.warning("请先修复数据");
// return;
// }
// Modal.confirm({
// title: "是否提交导入数据?",
// onOk: async () => {
// // tableData.value = [...fileTableData.value];
// let ids = fileTableData.value.map((item: any) => item.id);
// visible.value = false;
// editingKey.value = "";
// let res: any = await submitImportTask(ids);
// if (res && res?.code == 0) {
// message.success("导入成功");
// tableRef.value?.getList();
// } else {
// message.error("导入失败,请检查数据是否正确");
// }
// },
// });
2026-04-22 17:53:20 +08:00
};
2026-04-20 16:57:54 +08:00
// 关闭导入弹窗
const handleCustomCancel = () => {
2026-04-24 15:31:32 +08:00
Modal.confirm({
title: "是否取消导入数据?",
content: "未提交的数据将丢失",
okText: "确定",
2026-04-24 15:31:32 +08:00
onOk: async () => {
visible.value = false;
editingKey.value = "";
// 可选:调用取消接口
let res: any = await cancelImportTask({taskId: taskId.value});
if (res && res?.code == 0) {
message.success("取消成功");
tableRef.value?.getList();
}
2026-04-24 15:31:32 +08:00
},
});
2026-04-22 17:53:20 +08:00
};
2026-04-20 16:57:54 +08:00
2026-04-24 15:31:32 +08:00
const handleFileSelect = (e: Event) => {
const target = e.target as HTMLInputElement;
const file = target.files?.[0];
if (!file) return;
2026-04-20 16:57:54 +08:00
2026-04-24 15:31:32 +08:00
// 校验文件大小 (50MB)
const maxSize = 50 * 1024 * 1024;
if (file.size > maxSize) {
message.error("文件大小不能超过50MB");
resetFileInput();
return;
}
2026-04-20 16:57:54 +08:00
2026-04-24 15:31:32 +08:00
// 校验文件类型
const isZip =
file.name.toLowerCase().endsWith(".zip") ||
file.type === "application/zip" ||
file.type === "application/x-zip-compressed";
if (!isZip) {
message.error("请选择.zip格式的压缩包");
resetFileInput();
return;
2026-04-20 16:57:54 +08:00
}
fileChange(file);
2026-04-24 15:31:32 +08:00
resetFileInput();
2026-04-22 17:53:20 +08:00
};
2026-04-20 16:57:54 +08:00
2026-04-24 15:31:32 +08:00
const resetFileInput = () => {
if (fileInputRef.value) {
fileInputRef.value.value = "";
}
};
const fileChange = async (file: File) => {
try {
fileLoading.value = true;
const formData = new FormData();
formData.append("file", file);
let res: any = await importFishZip(formData);
const { code } = res.data || {};
if (code == 1) {
message.error("导入失败");
} else {
message.success("导入成功");
fileTableaAnalysis(res, "file");
}
} catch (error) {
} finally {
}
};
// 导入-按钮
const importBtn = async () => {
2026-04-24 15:31:32 +08:00
let res: any = await checkImportStatus();
taskId.value = "";
if (res?.code == 0) {
const { hasImportingTask ,currentTask} = res?.data || {};
taskId.value = currentTask.id;
if (hasImportingTask) {
visible.value = true;
nextTick(async () => {
fileLoading.value = true;
modalTableRef.value.editingRowIndex = null;
let res1: any = await getLastImportResult();
fileTableaAnalysis(res1, "get");
});
} else {
fileInputRef.value?.click();
}
} else {
message.error("导入查询失败");
}
2026-04-24 15:31:32 +08:00
// editingKey.value = "";
};
const fileTableaAnalysis = (res: any, type: string) => {
let data = [];
// let warningsList = [];
let list = [];
if (type == "file") {
list = res.data.failedRows;
} else {
list = res.data.result.failedRowDetails;
}
console.log(list);
list.forEach((item) => {
data.push({
...item.data,
_warnings: item.warnings,
});
});
fileTableData.value = data || [];
orgFileTableData.value = JSON.parse(JSON.stringify(fileTableData.value));
// warnings.value = warningsList || [];
fileLoading.value = false;
2026-04-24 15:31:32 +08:00
};
const handleReset = (values) => {
handleSearchFinish(values);
};
// 搜索-按钮
2026-04-22 17:53:20 +08:00
const handleSearchFinish = (values: any) => {
2026-04-24 15:31:32 +08:00
const filters = [
values.ftp && {
field: "ftp",
operator: "eq",
dataType: "string",
value: values.ftp,
},
{
field: "TM",
operator: "gte",
dataType: "date",
value: values.strdt[0],
},
{
field: "TM",
operator: "lte",
dataType: "date",
value: values.strdt[1],
},
values.direction && {
field: "direction",
operator: "eq",
dataType: "string",
value: values.direction,
},
values.status && {
field: "status",
operator: "eq",
dataType: "string",
value: values.status,
},
values.stcd && {
field: "stcd",
operator: "eq",
dataType: "string",
value: values.stcd,
},
values.rstcd && {
field: "rstcd",
operator: "eq",
dataType: "string",
value: values.rstcd,
},
values.baseId !== "all" && {
field: "baseId",
operator: "eq",
dataType: "string",
value: values.baseId,
},
].filter(Boolean);
const filter = {
logic: "and",
filters: filters,
};
tableRef.value?.getList(filter);
2026-04-22 17:53:20 +08:00
};
2026-04-20 16:57:54 +08:00
const closeVideoPreview = () => {
2026-04-22 17:53:20 +08:00
videoPreviewVisible.value = false;
currentVideoUrl.value = "";
};
2026-04-20 16:57:54 +08:00
// --- 生命周期 ---
2026-04-24 15:31:32 +08:00
onMounted(() => {
getDictItemsByCode({ dictCode: "direction" }).then((res) => {
direction.value = res.data;
});
getDictItemsByCode({ dictCode: "guoyuStatus" }).then((res) => {
guoyuStatus.value = res.data;
});
});
</script>
2026-04-20 16:57:54 +08:00
<style lang="scss" scoped>
.guoYuSheShiShuJuTianBao-page {
2026-04-22 17:53:20 +08:00
width: 100%;
height: 100%;
background-color: #ffffff;
padding: 20px;
2026-04-20 16:57:54 +08:00
}
</style>