功能修改

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="description" content="qgc-buji-web" />
<meta name="keywords" content="qgc-buji-web" />
<title>水电水利建设项目全过程环境管理信息平台</title>
<title>水电水利建设项目全过程数据填报系统</title>
</head>
<body>
<div id="app"></div>

View File

@ -65,14 +65,6 @@ export function importFishZip(data:FormData) {
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) {
return request({
@ -105,3 +97,12 @@ export function batchSaveDraft(data:any) {
data
});
}
// 标记导入任务为成功
export function markImportTaskSuccess(data:any) {
return request({
url: '/data/importTask/markSuccess',
method: 'post',
data
});
}

View File

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

View File

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

View File

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

View File

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