功能修改

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
扈兆增 2026-04-27 11:58:47 +08:00
parent 0817d15258
commit 7ccaeffd39
6 changed files with 126 additions and 114 deletions

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="qgc-buji-web" /> <meta name="description" content="qgc-buji-web" />
<meta name="keywords" content="qgc-buji-web" /> <meta name="keywords" content="qgc-buji-web" />
<title>水电水利建设项目全过程环境管理信息平台</title> <title>水电水利建设项目全过程数据填报系统</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -65,14 +65,6 @@ export function importFishZip(data:FormData) {
headers: { 'Content-Type': 'multipart/form-data' } headers: { 'Content-Type': 'multipart/form-data' }
}); });
} }
// 提交导入任务
export function submitImportTask(data:any) {
return request({
url: '/data/fishDraft/submitDrafts',
method: 'post',
data
});
}
// 取消导入任务 // 取消导入任务
export function cancelImportTask(data:any) { export function cancelImportTask(data:any) {
return request({ return request({
@ -105,3 +97,12 @@ export function batchSaveDraft(data:any) {
data data
}); });
} }
// 标记导入任务为成功
export function markImportTaskSuccess(data:any) {
return request({
url: '/data/importTask/markSuccess',
method: 'post',
data
});
}

View File

@ -159,6 +159,11 @@
> >
<span>登录</span> <span>登录</span>
</a-button> </a-button>
<div class="flex justify-center items-center mt-[10px]">
<a-button type="link" size="small">
<span>注册</span>
</a-button>
</div>
<!-- <a-button <!-- <a-button
type="link" type="link"
size="mini" size="mini"
@ -245,7 +250,7 @@ import loginImg from "@/assets/images/logo.png";
import { UserOutlined, LockOutlined, MobileOutlined } from "@ant-design/icons-vue"; import { UserOutlined, LockOutlined, MobileOutlined } from "@ant-design/icons-vue";
import { getCaptcha } from "@/api/auth"; import { getCaptcha } from "@/api/auth";
import { message } from "ant-design-vue"; import { message } from "ant-design-vue";
import { setPath } from '@/utils/auth'; import { setPath } from "@/utils/auth";
// //
import router from "@/router"; import router from "@/router";
@ -322,11 +327,12 @@ const forgotPasswordRules = ref({
], ],
}); });
const { loginData, loginRules, loading, const {
// passwordType, capslockTooltipDisabled loginData,
} = toRefs( loginRules,
state loading,
); // passwordType, capslockTooltipDisabled
} = toRefs(state);
// function checkCapslock(e: any) { // function checkCapslock(e: any) {
// const { key } = e; // const { key } = e;
@ -364,7 +370,7 @@ function onFinish() {
.login(user) .login(user)
.then(() => { .then(() => {
Cookies.set("username", user.username); Cookies.set("username", user.username);
setPath('/login-sjtb') setPath("/login-sjtb");
router.push({ path: "/" }); router.push({ path: "/" });
state.loading = false; state.loading = false;
}) })

View File

@ -13,25 +13,39 @@
</template> </template>
<template #actions> <template #actions>
<a-tooltip title="新增"> <a-tooltip title="新增">
<a-button @click="props.handleAdd"> 新增 </a-button> <a-button v-hasPerm="['sjtb:import-add']" @click="props.handleAdd">
新增
</a-button>
</a-tooltip> </a-tooltip>
<a-tooltip title="导入zip"> <a-tooltip title="导入zip">
<a-button v-hasPerm="['sjtb:import-zip']" @click="props.importBtn"> <a-button v-hasPerm="['sjtb:import-add']" @click="props.importBtn">
导入zip 导入zip
</a-button> </a-button>
</a-tooltip> </a-tooltip>
<a-button @click="props.batchDelBtn" :disabled="batchData.length === 0"> <a-button
v-hasPerm="['sjtb:import-add']"
@click="props.batchDelBtn"
:disabled="batchData.length === 0"
>
批量删除 批量删除
</a-button> </a-button>
<a-tooltip title="提交数据"> <a-tooltip title="提交数据">
<a-button @click="props.submitBtn" :disabled="batchData.length === 0"> <a-button
v-hasPerm="['sjtb:import-add']"
@click="props.submitBtn"
:disabled="batchData.length === 0"
>
<template #icon><SaveOutlined /></template> <template #icon><SaveOutlined /></template>
提交数据 提交数据
</a-button> </a-button>
</a-tooltip> </a-tooltip>
<a-tooltip title="批量审批"> <a-tooltip title="批量审批">
<a-button @click="props.successBtn" :disabled="batchData.length === 0"> <a-button
v-hasPerm="['sjtb:edit-review']"
@click="props.successBtn"
:disabled="batchData.length === 0"
>
<template #icon><CheckSquareOutlined /></template> <template #icon><CheckSquareOutlined /></template>
批量审批 批量审批
</a-button> </a-button>
@ -51,7 +65,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, onMounted, watch } from "vue"; import { ref, computed, onMounted, watch } from "vue";
import { message } from "ant-design-vue";
import { import {
SaveOutlined, SaveOutlined,
CheckSquareOutlined, CheckSquareOutlined,
@ -137,7 +150,7 @@ const searchList: any = computed(() => [
allowClear: true, allowClear: true,
}, },
}, },
checkPerm(["sjtb:edit-ztcx"]) && { {
width: 120, width: 120,
type: "Select", type: "Select",
name: "status", name: "status",
@ -147,7 +160,6 @@ const searchList: any = computed(() => [
}, },
options: props.guoyuStatus, options: props.guoyuStatus,
}, },
{ {
span: 12, span: 12,
type: "RangePicker", type: "RangePicker",

View File

@ -4,8 +4,8 @@
:loading="fileLoading" :loading="fileLoading"
:data-source="fileTableData" :data-source="fileTableData"
:columns="modalColumns" :columns="modalColumns"
height="500" :scroll="{ y: '100%', x: '100%' }"
:scroll="{ y: 500, x: '100%' }" pagination="false"
:row-key="(record, index) => index" :row-key="(record, index) => index"
> >
<template #bodyCell="{ column, record, index }"> <template #bodyCell="{ column, record, index }">
@ -29,13 +29,13 @@
<template <template
v-else-if=" v-else-if="
!isEditing(index) && !isEditing(index) &&
column.dataIndex && column.dataIndexKey &&
record._warnings && record._warnings &&
record._warnings.includes(column.dataIndex) record._warnings.includes(column.dataIndexKey)
" "
> >
<div style="color: red; display: flex; align-items: center"> <div style="color: red; display: flex; align-items: center">
<span>{{ getDisplayValue(column.dataIndex, record) }}</span> <span>{{record[column.dataIndex] }}</span>
<exclamation-circle-outlined style="margin-left: 4px" /> <exclamation-circle-outlined style="margin-left: 4px" />
</div> </div>
</template> </template>
@ -236,9 +236,9 @@ const rowStates = reactive<Record<number, any>>({});
const editingData = ref<any>(null); const editingData = ref<any>(null);
const modalColumns = ref([ const modalColumns = ref([
{ dataIndex: "baseName", key: "baseName", title: "流域", width: 140 }, { dataIndex: "baseName", key: "baseName", dataIndexKey: "baseId", title: "流域", width: 140 },
{ dataIndex: "ennm", key: "ennm", title: "电站名称", width: 140 }, { dataIndex: "ennm", key: "ennm", dataIndexKey: "rstcd", title: "电站名称", width: 140 },
{ dataIndex: "stnm", key: "stnm", title: "过鱼设施名称", width: 150 }, { dataIndex: "stnm", key: "stnm", dataIndexKey: "stcd", title: "过鱼设施名称", width: 150 },
{ dataIndex: "strdt", key: "strdt", title: "过鱼时间", width: 190 }, { dataIndex: "strdt", key: "strdt", title: "过鱼时间", width: 190 },
{ dataIndex: "ftpName", key: "ftpName", title: "鱼种类", width: 120 }, { dataIndex: "ftpName", key: "ftpName", title: "鱼种类", width: 120 },
{ {
@ -258,8 +258,10 @@ const modalColumns = ref([
key: "direction", key: "direction",
title: "游向", title: "游向",
width: 120, width: 120,
customRender: ({ text }: any) => customRender: ({ text }: any) => {
props.direction.find((item: any) => item.itemCode === text)?.dictName || "-", console.log(props.direction)
return props.direction.find((item: any) => item.itemCode === text)?.dictName || "-"
}
}, },
{ dataIndex: "fcnt", key: "fcnt", title: "过鱼数量(尾)", width: 120 }, { dataIndex: "fcnt", key: "fcnt", title: "过鱼数量(尾)", width: 120 },
{ dataIndex: "fsz", key: "fsz", title: "体长(cm)", width: 160 }, { dataIndex: "fsz", key: "fsz", title: "体长(cm)", width: 160 },

View File

@ -57,7 +57,7 @@
type="link" type="link"
size="small" size="small"
@click="handleEdit(record, 'view')" @click="handleEdit(record, 'view')"
v-if="record.status === 'SUBMITTED'" v-if="record.status === 'SUBMITTED' || record.status === 'APPROVED'"
>查看</a-button >查看</a-button
> >
<a-button <a-button
@ -97,6 +97,7 @@
maskClosable="false" maskClosable="false"
:confirm-loading="fileLoading" :confirm-loading="fileLoading"
> >
<div class="w-full h-[500px]">
<GuoYuSheShiShuJuTianBaoTable <GuoYuSheShiShuJuTianBaoTable
ref="modalTableRef" ref="modalTableRef"
:fileLoading="fileLoading" :fileLoading="fileLoading"
@ -104,6 +105,7 @@
:direction="direction" :direction="direction"
@update:file-table-data="(val) => fileTableData = val" @update:file-table-data="(val) => fileTableData = val"
/> />
</div>
<template #footer> <template #footer>
<a-button key="back" @click="handleCustomCancel">取消导入</a-button> <a-button key="back" @click="handleCustomCancel">取消导入</a-button>
<a-button <a-button
@ -166,15 +168,14 @@ import {
successFishDraft, successFishDraft,
rejectFishDraft, rejectFishDraft,
importFishZip, importFishZip,
submitImportTask,
cancelImportTask, cancelImportTask,
checkImportStatus, checkImportStatus,
batchSaveDraft, batchSaveDraft,
getLastImportResult, getLastImportResult,
markImportTaskSuccess
} 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 { m } from "vue-router/dist/router-CWoNjPRp.mjs";
// import { FileImageOutlined, VideoCameraOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue' // import { FileImageOutlined, VideoCameraOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
// --- --- // --- ---
@ -274,24 +275,10 @@ const currentVideoUrl = ref<string>("");
// //
const fileTableData = ref<any[]>([]); const fileTableData = ref<any[]>([]);
const orgFileTableData = ref<any[]>([]); const orgFileTableData = ref<any[]>([]);
const warnings = ref<any[]>([]);
const batchData = ref<any[]>([]); const batchData = ref<any[]>([]);
const modalTableRef = ref<any>(null); const modalTableRef = ref<any>(null);
const fileLoading = ref(false); const fileLoading = ref(false);
// Key ()
const editingKey = ref<string | number>("");
// --- ---
// Zip Blob URL
// 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>(""); const taskId = ref<string>("");
// Columns // Columns
@ -429,7 +416,6 @@ const successBtn = async () => {
// //
const handleReject = (id: any) => { const handleReject = (id: any) => {
let rejectReason = ""; let rejectReason = "";
Modal.confirm({ Modal.confirm({
title: "是否确认 驳回 选中数据?", title: "是否确认 驳回 选中数据?",
// 使 h // 使 h
@ -576,22 +562,20 @@ const handleModalOk = () => {
return; return;
} }
console.log(123) console.log(123)
// Modal.confirm({ Modal.confirm({
// title: "?", title: "是否提交导入数据?",
// onOk: async () => { onOk: async () => {
// // tableData.value = [...fileTableData.value]; let res: any = await batchSaveDraft(fileTableData.value);
// let ids = fileTableData.value.map((item: any) => item.id); if (res && res?.code == 0) {
// visible.value = false; message.success("导入成功");
// editingKey.value = ""; visible.value = false;
// let res: any = await submitImportTask(ids); tableRef.value?.getList();
// if (res && res?.code == 0) { await markImportTaskSuccess({id: taskId.value});
// message.success(""); } else {
// tableRef.value?.getList(); message.error("导入失败,请检查数据是否正确");
// } else { }
// message.error(","); },
// } });
// },
// });
}; };
// //
@ -601,18 +585,69 @@ const handleCustomCancel = () => {
content: "未提交的数据将丢失", content: "未提交的数据将丢失",
okText: "确定", okText: "确定",
onOk: async () => { onOk: async () => {
visible.value = false;
editingKey.value = "";
// //
let res: any = await cancelImportTask({taskId: taskId.value}); let res: any = await cancelImportTask({taskId: taskId.value});
if (res && res?.code == 0) { if (res && res?.code == 0) {
message.success("取消成功"); message.success("取消成功");
tableRef.value?.getList(); tableRef.value?.getList();
visible.value = false;
} }
}, },
}); });
}; };
// -
const importBtn = async () => {
let res: any = await checkImportStatus();
taskId.value = "";
if (res?.code == 0) {
const { hasImportingTask, currentTask} = res?.data || {};
if (currentTask) {
taskId.value = currentTask.id;
}
if (hasImportingTask) {
visible.value = true;
nextTick(async () => {
try {
fileLoading.value = true;
modalTableRef.value.editingRowIndex = null;
let res1: any = await getLastImportResult();
fileTableaAnalysis(res1, "get");
} catch (error) {
message.error("导入失败");
} finally {
fileLoading.value = false;
}
});
} else {
fileInputRef.value?.click();
}
} else {
message.error("导入查询失败");
}
};
//
const fileChange = async (file: File) => {
try {
visible.value = true;
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 {
taskId.value = res.data.taskId;
message.success("导入成功");
fileTableaAnalysis(res, "file");
}
} catch (error) {
} finally {
fileLoading.value = false;
}
};
//
const handleFileSelect = (e: Event) => { const handleFileSelect = (e: Event) => {
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
const file = target.files?.[0]; const file = target.files?.[0];
@ -646,51 +681,8 @@ const resetFileInput = () => {
fileInputRef.value.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 () => {
let res: any = await checkImportStatus();
taskId.value = "";
if (res?.code == 0) {
const { hasImportingTask, currentTask} = res?.data || {};
if (currentTask) {
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("导入查询失败");
}
// editingKey.value = "";
};
const fileTableaAnalysis = (res: any, type: string) => { const fileTableaAnalysis = (res: any, type: string) => {
let data = []; let data = [];
// let warningsList = [];
let list = []; let list = [];
if (type == "file") { if (type == "file") {
list = res.data.failedRows; list = res.data.failedRows;
@ -706,7 +698,6 @@ const fileTableaAnalysis = (res: any, type: string) => {
}); });
fileTableData.value = data || []; fileTableData.value = data || [];
orgFileTableData.value = JSON.parse(JSON.stringify(fileTableData.value)); orgFileTableData.value = JSON.parse(JSON.stringify(fileTableData.value));
// warnings.value = warningsList || [];
fileLoading.value = false; fileLoading.value = false;
}; };
const handleReset = (values) => { const handleReset = (values) => {