数据填报bug修改

This commit is contained in:
扈兆增 2026-05-07 15:40:18 +08:00
parent 0c3b314861
commit f1a1f808c7
18 changed files with 430 additions and 219 deletions

View File

@ -7,6 +7,8 @@ VITE_APP_TITLE = '水电水利建设项目全过程环境管理信息平台'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/dev-api'
## 开发环境API地址
# VITE_APP_BASE_URL = 'http://localhost:8093'
VITE_APP_BASE_URL = 'http://10.84.121.21:8093'
VITE_APP_BASE_API_URL = 'https://211.99.26.225:12130/prod-api'
## 开发环境预览 图片视频地址
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'

View File

@ -6,5 +6,7 @@ VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/prod-api'
## 生产环境API地址
VITE_APP_BASE_URL = 'http://localhost:8093'
## 生产环境导入预览地址
VITE_APP_BASE_API_URL = 'https://211.99.26.225:12130/prod-api'
## 生产环境预览 图片视频地址
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'

View File

@ -103,18 +103,9 @@ export function deleteFile(params:any) {
});
}
// 批量保存草稿
export function importBatchSaveDraft(data:any) {
export function batchSaveDraft(data:any) {
return request({
url: '/data/fishDraft/importBatchSaveDraft',
method: 'post',
data
});
}
// 标记导入任务为成功
export function markImportTaskSuccess(data:any) {
return request({
url: '/data/importTask/markSuccess',
url: '/data/fishDraft/batchSaveDraft',
method: 'post',
data
});

View File

@ -32,6 +32,15 @@ export function revalidateAndUpdateRow(data:any) {
data
});
}
// 删除 行数据
export function deleteRowById(data:any) {
return request({
url: '/data/fishDraft/deleteRowById',
method: 'post',
data
});
}
//过鱼设施下拉列表
export function getFpssDropdown(params:any) {
return request({

View File

@ -170,7 +170,7 @@ interface Props {
initialValues?: any;
showSearch?: boolean;
showReset?: boolean;
zhujianfujian: any;
zhujianfujian?: string;
}
const props = withDefaults(defineProps<Props>(), {

View File

@ -33,6 +33,8 @@ interface Props {
rowKey?: string;
// /
searchParams?: Record<string, any>;
// false
isOneLoad?: boolean;
//
defaultPageSize?: number;
getCheckboxProps?: (record: any) => any;
@ -42,6 +44,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), {
enableRowSelection: false,
rowKey: "id",
isOneLoad: true,
searchParams: () => ({}),
defaultPageSize: 20,
getCheckboxProps: undefined,
@ -103,6 +106,8 @@ const paginationConfig = computed(() => ({
*/
const getList = async (filter?: Record<string, any>) => {
loading.value = true;
tableData.value = [];
total.value = 0;
// filter
if (filter !== undefined) {
lastFilter.value = filter;
@ -178,11 +183,17 @@ const refresh = () => {
getList();
};
const clearSelection = () => {
selectedRowKeys.value = [];
selectedRows.value = [];
}
// --- Expose Methods to Parent ---
defineExpose({
getList,
reset,
refresh,
tableData,
clearSelection,
//
getSelected: () => ({
keys: selectedRowKeys.value,

View File

@ -80,7 +80,6 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
fpssLoading.value = true;
const param = hbrvcd === 'all' ? {} : { hbrvcd };
const res = await getFpssDropdown({...param, rstcd: rstcd});
console.log(res.data);
fpssOption.value = res.data;
} catch (error) {
console.log(error);

View File

@ -6,7 +6,7 @@ import { useUserStoreHook } from '@/store/modules/user';
// 创建 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 50000,
timeout: 100000,
headers: { 'Content-Type': 'application/json;charset=utf-8' }
});

View File

@ -84,7 +84,7 @@
<!-- 用户名/账号/手机号输入框 -->
<a-form-item label="" name="username">
<a-input ref="username" v-model:value="loginData.username" clearable type="text"
placeholder="请输入用户账号/身份证号/手机号" size="large">
placeholder="请输入用户账号/手机号" size="large">
<template #prefix>
<UserOutlined />
</template>

View File

@ -110,7 +110,7 @@
v-model:value="loginData.username"
clearable
type="text"
placeholder="请输入用户账号/身份证号/手机号"
placeholder="请输入用户账号/手机号"
size="large"
>
<template #prefix>

View File

@ -53,13 +53,13 @@
<!-- 手机号 -->
<a-form-item name="phone" label="手 机 号">
<a-row :gutter="8">
<a-row class="w-full" :gutter="8">
<a-col :span="16">
<a-input v-model:value="registerData.phone" placeholder="请输入11位手机号" />
</a-col>
<a-col :span="8">
<a-button type="primary" :disabled="smsCountdown > 0" @click="handleSendSms"
style="width: 100%">
>
{{ smsCountdown > 0 ? `${smsCountdown}s` : '获取验证码' }}
</a-button>
</a-col>
@ -655,6 +655,7 @@ const filterOption = (inputValue: string, option: any) => {
max-height: 90vh; // 90%
border-radius: 8px; //
padding: clamp(15px, 2vw, 24px) clamp(15px, 2vw, 24px); //
padding-top: 0 !important;
background-color: rgba(255, 255, 255, 0.98); //
overflow-y: auto;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); //
@ -686,6 +687,7 @@ const filterOption = (inputValue: string, option: any) => {
font-size: clamp(13px, 1.2vw, 15px); //
font-weight: 600;
color: #333;
padding-left: 10px;
margin-bottom: clamp(8px, 1vh, 12px);
padding-bottom: clamp(6px, 0.8vh, 10px);
border-bottom: 1px solid #e8e8e8;
@ -698,6 +700,7 @@ const filterOption = (inputValue: string, option: any) => {
:deep(.ant-form-item-label) {
text-align: right !important;
line-height: 32px;
>label {
font-size: clamp(12px, 1vw, 14px); //

View File

@ -9,6 +9,10 @@
row-key="id"
>
<template #bodyCell="{ column, record, index }">
<!--
<template v-if="column.key === 'index' || column.dataIndex === 'index'">
{{ index + 1 }}
</template> -->
<!-- 1. 操作列 -->
<template v-if="column.key === 'action' || column.dataIndex === 'action'">
<div class="flex">
@ -281,20 +285,21 @@ import {
getEngInfoDropdown,
getFpssDropdown,
revalidateAndUpdateRow,
deleteRowById,
} from "@/api/select";
const props: any = defineProps({
taskId: { type: String, default: "" },
getFileList: { type: Function, default: () => {} },
fileTableData: { type: Array, default: () => [] },
fileLoading: { type: Boolean, default: false },
direction: { type: Array, default: () => [] },
});
const emit = defineEmits(["update:fileTableData", "preview-click", "update:fileLoading"]);
const emit = defineEmits(["preview-click", "update:fileLoading"]);
// --- ---
const editingRowIndex = ref<number | null>(null);
const baseOptions = ref<any[]>([]);
const hbrvcdOptions = ref<any[]>([]);
const rowStates = reactive<Record<number, any>>({});
@ -302,6 +307,7 @@ const rowStates = reactive<Record<number, any>>({});
const editingData = ref<any>(null);
const modalColumns = ref([
{ dataIndex: "rowIndex", key: "rowIndex", title: "序号", width: 60, dataIndexKey: "rowIndex",align: "center",fixed: "left" },
{
dataIndex: "hbrvnm",
key: "hbrvnm",
@ -654,10 +660,9 @@ const saveEdit = async (index: number) => {
});
if (res && res?.code == 0) {
message.success("保存成功");
emit("update:fileTableData", newData);
props.getFileList();
editingRowIndex.value = null;
editingData.value = null;
emit("update:fileLoading", false);
}
} catch (e) {
message.error("保存失败");
@ -671,19 +676,27 @@ const cancelEdit = () => {
editingData.value = null;
// props.fileTableData退
};
const handlePreviewDelete = (index: number) => {
//
const handlePreviewDelete = async (index: number) => {
const newData = [...props.fileTableData];
newData.splice(index, 1);
emit("update:fileTableData", newData);
emit("update:fileLoading", true);
try {
const res: any = await deleteRowById({
taskId: props.taskId,
data: newData[index],
});
if (res && res?.code == 0) {
message.success("删除成功");
if (editingRowIndex.value === index) {
props.getFileList();
editingRowIndex.value = null;
editingData.value = null;
} else if (editingRowIndex.value !== null && editingRowIndex.value > index) {
editingRowIndex.value--;
}
message.success("删除成功");
} catch (e) {
message.error("删除失败");
} finally {
emit("update:fileLoading", false);
}
};
//
const handleFtpChange = (val: any, opt: any) => {

View File

@ -1,50 +1,113 @@
<template>
<div class="guoYuSheShiShuJuTianBao-page">
<GuoYuSheShiShuJuTianBaoSearch ref="searchRef" class="search-container" :guoyuStatus="guoyuStatus"
:direction="direction" :handle-add="handleAdd" :batchData="batchData" :importBtn="importBtn"
:batchDelBtn="batchDelBtn" :submitBtn="submitBtn" :allSubmitBtn="allSubmitBtn" :successBtn="successBtn"
@reset="handleReset" @search-finish="handleSearchFinish" />
<GuoYuSheShiShuJuTianBaoSearch
ref="searchRef"
class="search-container"
:guoyuStatus="guoyuStatus"
:direction="direction"
:handle-add="handleAdd"
:batchData="batchData"
:importBtn="importBtn"
:batchDelBtn="batchDelBtn"
:submitBtn="submitBtn"
:allSubmitBtn="allSubmitBtn"
:successBtn="successBtn"
@reset="handleReset"
@search-finish="handleSearchFinish"
/>
<!-- 主表格 -->
<div class="table-container" ref="tableContainerRef">
<BasicTable ref="tableRef" :columns="columns" :scroll-y="tableScrollY" :list-url="getFishDraftPage"
:search-params="{}" :enable-row-selection="true" :get-checkbox-props="getCheckboxProps"
:transform-data="customTransform" @selection-change="handleSelectionChange">
<BasicTable
ref="tableRef"
:columns="columns"
:scroll-y="tableScrollY"
:list-url="getFishDraftPage"
:search-params="{}"
:enable-row-selection="true"
:get-checkbox-props="getCheckboxProps"
:transform-data="customTransform"
@selection-change="handleSelectionChange"
>
<!-- 使用 bodyCell 插槽自定义单元格渲染 -->
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action' || column.dataIndex === 'action'">
<div class="flex">
<a-button v-hasPerm="['sjtb:import-add']" type="link" size="small" @click="handleSubmit([record.id])"
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'">提交</a-button>
<a-button v-hasPerm="['sjtb:import-add']" type="link" size="small" @click="handleEdit(record, 'edit')"
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'">编辑</a-button>
<a-button v-hasPerm="['sjtb:edit-review']" type="link" size="small" @click="handleEdit(record, 'edit')"
v-if="record.status === 'PENDING'">编辑</a-button>
<a-button v-hasPerm="['sjtb:import-add']" type="link" danger size="small"
<a-button
v-hasPerm="['sjtb:import-add']"
type="link"
size="small"
@click="handleSubmit([record.id])"
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'"
>提交</a-button
>
<a-button
v-hasPerm="['sjtb:import-add']"
type="link"
size="small"
@click="handleEdit(record, 'edit')"
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'"
>编辑</a-button
>
<a-button
v-hasPerm="['sjtb:edit-review']"
type="link"
size="small"
@click="handleEdit(record, 'edit')"
v-if="record.status === 'PENDING'"
>编辑</a-button
>
<a-button
v-hasPerm="['sjtb:import-add']"
type="link"
danger
size="small"
@click="handleDelete([record.id])"
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'">删除</a-button>
<a-button type="link" size="small" @click="handleEdit(record, 'view')" v-if="
v-if="record.status === 'DRAFT' || record.status === 'REJECTED'"
>删除</a-button
>
<a-button
type="link"
size="small"
@click="handleEdit(record, 'view')"
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 v-hasPerm="['sjtb:edit-review']" type="link" size="small" @click="handleSuccess([record.id])"
v-if="record.status === 'PENDING'">审批</a-button>
<a-button v-hasPerm="['sjtb:edit-review']" type="link" danger size="small"
@click="handleReject(record.id)" v-if="record.status === 'PENDING'">驳回</a-button>
"
>查看</a-button
>
<a-button
v-hasPerm="['sjtb:edit-review']"
type="link"
size="small"
@click="handleSuccess([record.id])"
v-if="record.status === 'PENDING'"
>审批</a-button
>
<a-button
v-hasPerm="['sjtb:edit-review']"
type="link"
danger
size="small"
@click="handleReject(record.id)"
v-if="record.status === 'PENDING'"
>驳回</a-button
>
</div>
</template>
</template>
</BasicTable>
</div>
<div class="buttonStyle">
<div class="button">
<a-tooltip title="提交数据">
<a-button v-hasPerm="['sjtb:import-add']" @click="submitBtn" :disabled="batchData.length === 0" size="large">
<template #icon>
<SaveOutlined />
</template>
<a-button
v-hasPerm="['sjtb:import-add']"
@click="submitBtn"
:disabled="batchData.length === 0"
size="large"
>
提交数据
</a-button>
</a-tooltip>
@ -52,101 +115,192 @@
<div class="button">
<a-tooltip title="全部提交">
<a-button v-hasPerm="['sjtb:import-add']" @click="allSubmitBtn" size="large">
<template #icon>
<SaveOutlined />
</template>
全部提交
</a-button>
</a-tooltip>
</div>
<div class="button">
<a-tooltip title="批量删除">
<a-button v-hasPerm="['sjtb:import-add']" @click="batchDelBtn" :disabled="batchData.length === 0" size="large">
<a-button
v-hasPerm="['sjtb:import-add']"
@click="batchDelBtn"
:disabled="batchData.length === 0"
size="large"
>
批量删除
</a-button>
</a-tooltip>
</div>
</div>
<!-- 隐藏的文件输入框 -->
<input ref="fileInputRef" type="file" accept=".zip,application/zip,application/x-zip-compressed"
style="display: none" @change="handleFileSelect" />
<input
ref="fileInputRef"
type="file"
accept=".zip,application/zip,application/x-zip-compressed"
style="display: none"
@change="handleFileSelect"
/>
<!-- 导入预览 Modal -->
<a-modal title="导入数据预览" ok-text="提交导入" cancel-text="取消导入" :width="1500" v-model:open="visible" :maskClosable="false"
:confirm-loading="fileLoading" @cancel="taskId = ''">
<GuoYuSheShiShuJuTianBaoTable ref="modalTableRef" :taskId="taskId" :fileTableData="fileTableData"
:direction="direction" @preview-click="handlePreviewClick" v-model:file-loading="fileLoading"
@update:file-table-data="(val) => (fileTableData = val)" />
<a-modal
title="导入数据预览"
ok-text="提交导入"
cancel-text="取消导入"
:width="1500"
v-model:open="visible"
:maskClosable="false"
:confirm-loading="fileLoading"
@cancel="taskId = ''"
>
<GuoYuSheShiShuJuTianBaoTable
ref="modalTableRef"
:taskId="taskId"
:fileTableData="fileTableData"
:getFileList="getFileList"
:direction="direction"
@preview-click="handlePreviewClick"
v-model:file-loading="fileLoading"
@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
key="submit"
type="primary"
:loading="fileLoading"
@click="handleModalOk"
>
提交导入
</a-button>
</template>
</a-modal>
<!-- 新增/编辑 Modal (对应 React EditModal) -->
<EditModal ref="editModalRef" v-model:visible="editModalVisible" :is-view="isView" :direction="direction"
:initial-values="currentRecord" @cancel="editModalCancel" @ok="handleEditSubmit"
@preview-click="handlePreviewClick" />
<EditModal
ref="editModalRef"
v-model:visible="editModalVisible"
:is-view="isView"
:direction="direction"
:initial-values="currentRecord"
@cancel="editModalCancel"
@ok="handleEditSubmit"
@preview-click="handlePreviewClick"
/>
<!-- 媒体预览 Modal -->
<a-modal v-model:open="mediaPreviewVisible" :title="videoPreviewTitle" :footer="null" width="900px"
@cancel="closeMediaPreview" :zIndex="2000">
<a-modal
v-model:open="mediaPreviewVisible"
:title="videoPreviewTitle"
:footer="null"
width="900px"
@cancel="closeMediaPreview"
:zIndex="2000"
>
<div class="flex h-[60vh] gap-4">
<!-- 左侧混合列表 (图片+视频) -->
<div class="w-1/4 overflow-y-auto border-r pr-2 media-list-container">
<div v-for="(item, index) in previewList" :key="index" class="mb-2 cursor-pointer list-item"
:class="{ select: index === currentMediaIndex }" @click="currentMediaIndex = index">
<div
v-for="(item, index) in previewList"
:key="index"
class="mb-2 cursor-pointer list-item"
:class="{ select: index === currentMediaIndex }"
@click="currentMediaIndex = index"
>
<span class="file-name">{{ item.name }}</span>
<!-- 删除按钮 -->
<div class="list-item-delete" v-if="item.type != 'formVideo' && item.type != 'formImage'"
@click.stop="handleDeleteMedia(item, index)">
<div
class="list-item-delete"
v-if="item.type != 'formVideo' && item.type != 'formImage'"
@click.stop="handleDeleteMedia(item, index)"
>
<CloseCircleOutlined />
</div>
</div>
</div>
<!-- 右侧动态预览区域 -->
<div class="w-3/4 flex flex-col items-center justify-center bg-gray-100 relative p-4">
<div
class="w-3/4 flex flex-col items-center justify-center bg-gray-100 relative p-4"
>
<a-spin v-if="imageLoading" tip="图片加载中..." size="large" />
<!-- 图片预览 -->
<a-image v-if="
<div
v-if="
currentMediaItem &&
currentMediaItem.url != '' &&
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
" :src="currentMediaItem.url" class="max-w-full max-h-full object-contain" />
<div v-else-if="
"
>
<img
v-show="!imageLoading && !imageLoadError"
:src="currentMediaItem.url"
alt="preview"
class="max-w-full max-h-[50vh] object-contain"
@load="onImageLoad"
@error="onImageError"
/>
<!-- 3. 加载失败提示 -->
<div
v-if="!imageLoading && imageLoadError"
class="text-gray-400 flex flex-col items-center"
>
<ExclamationCircleOutlined style="font-size: 24px; margin-bottom: 8px" />
<span>图片加载失败</span>
</div>
</div>
<div
v-else-if="
currentMediaItem &&
currentMediaItem.url == '' &&
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
" class="text-gray-400">
"
class="text-gray-400"
>
暂无图片预览
</div>
<!-- 视频预览 -->
<video v-else-if="
<video
v-else-if="
currentMediaItem &&
currentMediaItem.url != '' &&
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
" :src="currentMediaItem.url" controls autoplay class="max-w-full max-h-[50vh]">
"
:src="currentMediaItem.url"
controls
autoplay
class="max-w-full max-h-[50vh]"
>
您的浏览器不支持视频播放
</video>
<div v-else-if="
<div
v-else-if="
currentMediaItem &&
currentMediaItem.url == '' &&
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
" class="text-gray-400">
"
class="text-gray-400"
>
暂无视频预览
</div>
<!-- 底部切换控制 -->
<div class="absolute bottom-4 flex gap-4 z-10">
<a-button shape="circle" :icon="h(LeftOutlined)" @click="prevMedia" :disabled="currentMediaIndex === 0" />
<a-button
shape="circle"
:icon="h(LeftOutlined)"
@click="prevMedia"
:disabled="currentMediaIndex === 0"
/>
<span class="self-center text-gray-600 bg-white px-2 rounded shadow-sm">
{{ currentMediaIndex + 1 }} / {{ previewList.length }}
</span>
<a-button shape="circle" :icon="h(RightOutlined)" @click="nextMedia"
:disabled="currentMediaIndex === previewList.length - 1" />
<a-button
shape="circle"
:icon="h(RightOutlined)"
@click="nextMedia"
:disabled="currentMediaIndex === previewList.length - 1"
/>
</div>
</div>
</div>
@ -155,9 +309,9 @@
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, h, nextTick } from "vue";
import { ref, computed, onMounted, h, nextTick, watch } from "vue";
import { message, Modal } from "ant-design-vue"; // 使 ant-design-vue
import { LeftOutlined, RightOutlined, CloseCircleOutlined } from "@ant-design/icons-vue"; //
import { LeftOutlined, RightOutlined, CloseCircleOutlined, ExclamationCircleOutlined } from "@ant-design/icons-vue"; //
import BasicTable from "@/components/BasicTable/index.vue";
import GuoYuSheShiShuJuTianBaoSearch from "./guoYuSheShiShuJuTianBaoSearch.vue";
import GuoYuSheShiShuJuTianBaoTable from "./guoYuSheShiShuJuTianBaoTable.vue";
@ -174,18 +328,17 @@ import {
importFishZip,
cancelImportTask,
checkImportStatus,
importBatchSaveDraft,
batchSaveDraft,
getLastImportResult,
markImportTaskSuccess,
deleteFile,
batchApproveAll
batchApproveAll,
} from "@/api/guoYuSheShiShuJuTianBao";
import { Tag } from "ant-design-vue"; // Tag
import { getDictItemsByCode } from "@/api/dict";
import dayjs from "dayjs";
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
const baseUrlPreview = import.meta.env.VITE_APP_BASE_URL;
const baseUrlApi = import.meta.env.VITE_APP_BASE_API_URL;
// --- ---
interface FormData {
[key: string]: any;
@ -201,7 +354,9 @@ interface ColumnConfig {
}
const fileInputRef = ref<any>(null);
const tableRef = ref<any>(null);
const searchRef = ref<any>(null);
//
const imageLoading = ref(false);
const imageLoadError = ref(false);
//
const direction = ref<any>([]);
const guoyuStatus = ref<any>([]);
@ -388,6 +543,10 @@ const submitBtn = async () => {
};
//
const allSubmitBtn = async () => {
if (tableRef.value.tableData.length === 0) {
message.warning("请先添加数据!");
return;
}
Modal.confirm({
title: "是否 提交 全部数据吗?",
onOk: async () => {
@ -585,21 +744,18 @@ const handleModalOk = () => {
return;
}
}
fileTableData.value.forEach((item) => {
item.tm = dayjs().format("YYYY-MM-DD HH:mm:ss");
});
Modal.confirm({
title: "是否提交导入数据?",
onOk: async () => {
let res: any = await importBatchSaveDraft({
taskId: taskId.value,
fishDraftDataList: fileTableData.value,
let res: any = await batchSaveDraft({
taskId: taskId.value
});
if (res && res?.code == 0) {
message.success("导入成功");
fileTableData.value = [];
taskId.value = "";
tableRef.value?.refresh();
visible.value = false;
await markImportTaskSuccess({ id: taskId.value });
message.success("导入成功");
} else {
message.error("导入失败,请检查数据是否正确");
}
@ -617,6 +773,8 @@ const handleCustomCancel = () => {
//
let res: any = await cancelImportTask({ taskId: taskId.value });
if (res && res?.code == 0) {
fileTableData.value = [];
taskId.value = "";
message.success("取消成功");
tableRef.value?.refresh();
visible.value = false;
@ -626,7 +784,6 @@ const handleCustomCancel = () => {
},
});
};
// -
const importBtn = async () => {
let res: any = await checkImportStatus();
taskId.value = "";
@ -637,18 +794,21 @@ const importBtn = async () => {
}
if (hasImportingTask) {
visible.value = true;
fileLoading.value = true;
if (currentTask.status == "UPLOADED") {
if (visible.value) message.warning(currentTask.statusText);
} else if (currentTask.status == "VALIDATED") {
nextTick(async () => {
try {
fileLoading.value = true;
modalTableRef.value.editingRowIndex = null;
let res1: any = await getLastImportResult();
fileTableaAnalysis(res1, "get");
getFileList();
} catch (error) {
message.error("导入失败");
} finally {
fileLoading.value = false;
}
});
}
} else {
fileInputRef.value?.click();
}
@ -656,6 +816,10 @@ const importBtn = async () => {
message.error("导入查询失败");
}
};
const getFileList = async () => {
let res: any = await getLastImportResult();
fileTableaAnalysis(res, "get");
}
//
const fileChange = (file: File) => {
try {
@ -667,6 +831,7 @@ const fileChange = (file: File) => {
formData.append("file", file);
let res: any = await importFishZip(formData);
const { code } = res.data || {};
try {
if (code == 1) {
message.error("导入失败");
} else {
@ -678,6 +843,9 @@ const fileChange = (file: File) => {
}
fileTableaAnalysis(res, "file");
}
} catch (error) {
message.error("导入失败");
}
});
} catch (error) {
} finally {
@ -737,6 +905,7 @@ const fileTableaAnalysis = (res: any, type: string) => {
list.forEach((item) => {
data.push({
...item.data,
rowIndex: item.rowIndex,
vdpthList: item.vdpthList,
vdpthsWarnings: item.vdpthsWarnings,
picpthList: item.picpthList,
@ -779,13 +948,13 @@ const handleSearchFinish = (values: any) => {
field: "strdt",
operator: "gte",
dataType: "date",
value: values.strdt[0] + ' 00:00:00',
value: values.strdt[0] + " 00:00:00",
},
{
field: "strdt",
operator: "lte",
dataType: "date",
value: values.strdt[1] + ' 23:59:59',
value: values.strdt[1] + " 23:59:59",
},
values.direction && {
field: "direction",
@ -836,6 +1005,8 @@ const handleSearchFinish = (values: any) => {
const handlePreviewClick = (record: any, type: string, index: number) => {
const mixedList: MediaItem[] = [];
if (type === "image") {
imageLoading.value = true;
imageLoadError.value = false;
tablePreviewRecord.value = record;
videoPreviewTitle.value = "图片预览";
const nameList = record.picpthList;
@ -845,7 +1016,7 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
type: "image",
name: item.name,
url:
baseUrlPreview +
baseUrlApi +
"/data/fishDraft/previewFile?filename=" +
item.name +
"&taskId=" +
@ -863,7 +1034,7 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
type: "video",
name: item.name, //
url:
baseUrlPreview +
baseUrlApi +
"/data/fishDraft/previewFile?filename=" +
item.name +
"&taskId=" +
@ -872,6 +1043,8 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
});
});
} else if (type === "formImage") {
imageLoading.value = true;
imageLoadError.value = false;
videoPreviewTitle.value = "图片预览";
const nameList = JSON.parse(JSON.stringify(record)).picpthList;
nameList.forEach((item: any) => {
@ -997,7 +1170,6 @@ const calcTableScrollY = () => {
if (!tableContainerRef.value) return;
//
const containerHeight = tableContainerRef.value.clientHeight;
console.log(containerHeight);
// 55px + 64px + 10px = 130px
//
const otherHeight = 112;
@ -1009,6 +1181,29 @@ const calcTableScrollY = () => {
const observer = new ResizeObserver(() => {
calcTableScrollY();
});
//
const onImageLoad = () => {
imageLoading.value = false;
imageLoadError.value = false;
};
//
const onImageError = () => {
imageLoading.value = false;
imageLoadError.value = true;
};
watch(currentMediaIndex, (newIndex) => {
const item = previewList.value[newIndex];
if (item && (item.type === "image" || item.type === "formImage")) {
imageLoading.value = true;
imageLoadError.value = false;
} else {
imageLoading.value = false;
imageLoadError.value = false;
}
});
// --- ---
onMounted(() => {
nextTick(() => {
@ -1018,13 +1213,12 @@ onMounted(() => {
}
});
getDictItemsByCode({ dictCode: "direction" }).then((res) => {
direction.value = res.data
direction.value = res.data;
});
getDictItemsByCode({ dictCode: "approvalStatus" }).then((res) => {
guoyuStatus.value.length = 0
guoyuStatus.value.length = 0;
res.data.forEach((item: any) => {
if(item.itemCode != "APPROVED" ){
if (item.itemCode != "APPROVED") {
guoyuStatus.value.push(item);
}
});

View File

@ -26,7 +26,7 @@
<!-- 审批操作日志弹框 -->
<a-modal v-model:open="approvalLogVisible" title="审批操作日志" width="1600px" :footer="null"
destroy-on-close="false">
:destroy-on-close="false">
<div class="approval-log-modal-content">
<ApprovalLogSearch :action-type-dict="actionTypeDict" @search-finish="handleApprovalLogSearch"
@reset="handleApprovalLogReset" />
@ -42,7 +42,7 @@
</a-modal>
<!-- 数据变更记录弹框 -->
<a-modal v-model:open="changeLogVisible" title="数据变更记录" width="1600px" :footer="null" destroy-on-close="false">
<a-modal v-model:open="changeLogVisible" title="数据变更记录" width="1600px" :footer="null" :destroy-on-close="false">
<div class="change-log-modal-content">
<ChangeLogSearch :operation-type-dict="operationTypeDict" @search-finish="handleChangeLogSearch"
@reset="handleChangeLogReset" />
@ -64,14 +64,14 @@
</a-modal>
<!-- 详情信息弹框 -->
<a-modal v-model:open="detailVisible" title="详情信息" width="1800px" :footer="null" destroy-on-close="false">
<a-modal v-model:open="detailVisible" title="详情信息" width="1800px" :footer="null" :destroy-on-close="false">
<div class="detail-modal-content">
<!-- 搜索组件 -->
<ApprovalDetailSearch :guoyu-status="guoyuStatus" :direction="direction"
@search-finish="handleDetailSearchFinish" @reset="handleDetailReset" />
<!-- 表格组件 -->
<BasicTable ref="detailTableRef" :columns="detailColumns" :list-url="getFishDraftPage"
<BasicTable ref="detailTableRef" :columns="detailColumns" :isOneLoad="false" :list-url="getFishDraftPage"
:scroll-y="'500px'" :transform-data="customTransform">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'isfs'">
@ -196,6 +196,7 @@ import ApprovalDetailSearch from "./approvalDetailSearch.vue";
import EditModal from "@/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue";
import { getDictItemsByCode } from '@/api/dict';
import { getFishDraftPage } from "@/api/guoYuSheShiShuJuTianBao";
import { set } from 'lodash';
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
const baseUrlPreview = import.meta.env.VITE_APP_BASE_URL;
@ -208,7 +209,31 @@ let columns = ref([
width: 120,
fixed: "left",
},
{ dataIndex: "ennm", key: "ennm", title: "电站名称", width: 120, fixed: "left" },
{ dataIndex: "ennm", key: "ennm", title: "电站名称", width: 120, fixed: "left",
customRender: ({ text }: any) => {
if (!text) return "-";
const str = String(text);
//
const items = str.split(/[,]/);
// 66
let displayText = "";
if (items.length > 6) {
displayText = items.slice(0, 6).join("") + " ...";
} else {
displayText = str;
}
// span title
return h('span', {
title: str,
style: {
cursor: 'default'
}
}, displayText);
},
},
{
title: '审批批次号',
dataIndex: 'approvalNo',
@ -554,42 +579,9 @@ const handleDetailReset = (values: any) => {
//
const approvalId = ref('');
const handleShowDetail = (record: any) => {
detailVisible.value = true;
// BasicTable approvalNo:record.approvalNo
setTimeout(() => {
approvalId.value = record.id;
// approvalNo
const filters = [
{
field: "strdt",
operator: "gte",
dataType: "date",
value: dayjs().subtract(1, "month").startOf("month").format("YYYY-MM-DD HH:mm:ss"),
},
{
field: "strdt",
operator: "lte",
dataType: "date",
value: dayjs().endOf("day").format("YYYY-MM-DD HH:mm:ss"),
},
approvalId.value && {
field: "approvalId", //
operator: "eq", //
dataType: "string", //
value: approvalId.value // record
}
].filter(Boolean);
const filter = {
logic: "and",
filters: filters,
};
detailTableRef.value?.getList(filter);
// detailTableRef.value?.getList();
setTimeout(() => {
detailVisible.value = true;
}, 300);
};
@ -940,10 +932,6 @@ const handleBatchRejectConfirm = async () => {
message.success('批量驳回成功');
batchRejectVisible.value = false;
batchRejectForm.value.rejectReason = '';
//
tableRef.value?.clearSelection();
//
handleSearchFinish(searchData.value);
}
} catch (error) {

View File

@ -170,7 +170,7 @@ function handleClose(){
<Page :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current" @pagination="init()">
</Page>
</div>
<el-dialog title="日志详情" v-model="LogDetails" width="90%" :before-close="handleClose" top="30px" draggable destroy-on-close>
<el-dialog title="日志详情" v-model="LogDetails" width="90%" :before-close="handleClose" top="30px" draggable :destroy-on-close="false">
<el-table v-loading="loading" :data="Logdata"
style="width: 100%; height: calc(50vh - 266px);margin-bottom: 20px;" border
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }">

View File

@ -25,7 +25,6 @@ import {
import { ElMessageBox, ElMessage } from "element-plus";
import Page from '@/components/Pagination/page.vue'
import { Search } from '@element-plus/icons-vue'
import { p } from "vue-router/dist/router-CWoNjPRp.mjs";
//
const loading = ref(false);
//
@ -981,20 +980,20 @@ function handleClearSelection() {
:v-loading="dialog" @selection-change="handleSelectionChange"
:header-cell-style="{ background: 'rgb(250 250 250)', color: ' #383838', height: '50px' }">
<!-- <el-table-column type="selection" width="50" align="center" /> -->
<el-table-column type="index" label="序号" width="70" align="center" />
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="nickname" label="用户姓名" width="140"></el-table-column>
<!-- <el-table-column prop="avatar" label="头像"></el-table-column> -->
<el-table-column prop="email" label="邮箱"></el-table-column>
<el-table-column prop="phone" label="手机号" min-width="90"></el-table-column>
<el-table-column prop="username" label="登录账号" width="120"></el-table-column>
<!-- <el-table-column prop="email" label="邮箱"></el-table-column> -->
<el-table-column prop="phone" label="手机号" width="160"></el-table-column>
<el-table-column prop="username" label="登录账号" ></el-table-column>
<!-- <el-table-column prop="custom1" label="登录账号"></el-table-column> -->
<el-table-column prop="rolename" label="所属角色" width="120">
<el-table-column prop="rolename" label="所属角色" >
<template #default="scope">
<span v-for="(item, index) in scope.row.roles" :key="index">{{ item.rolename }} <span></span>
</span>
</template>
</el-table-column>
<el-table-column prop="regStatus" label="审核状态" width="120" align="center">
<el-table-column prop="regStatus" label="审核状态" width="90" align="center">
<template #default="scope">
<el-tag :type="getRegStatusColor(scope.row.regStatus)" size="small">
{{ getName(regStatusArr, scope.row.regStatus) }}
@ -1002,7 +1001,7 @@ function handleClearSelection() {
</template>
</el-table-column>
<el-table-column prop="lastmodifier" label="最近修改者" width="120"></el-table-column>
<el-table-column prop="lastmodifydate" label="最近修改日期" width="205">
<el-table-column prop="lastmodifydate" label="最近修改日期" width="160">
<template #default="scope">
{{ dateFormat(scope.row.lastmodifydate) }}
</template>

View File

@ -452,7 +452,7 @@ onMounted(() => {
<el-button type="primary" @click="organizesubmit"> </el-button>
</span>
</el-dialog>
<el-dialog title="权限分配" v-model="accessVisible" width="500px" :before-close="handleClose" destroy-on-close draggable style="max-height: 640px;" >
<el-dialog title="权限分配" v-model="accessVisible" width="500px" :before-close="handleClose" :destroy-on-close="false" draggable style="max-height: 640px;" >
<el-tree ref="tree" style="max-height: 400px;overflow:auto" :data="accessdata" show-checkbox node-key="id" accordion
:default-expanded-keys="DefaultDeployment" :props="defaultProps" @check="currentChecked" />
<span class="dialog-footer"