数据填报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_PORT = 3000
VITE_APP_BASE_API = '/dev-api' VITE_APP_BASE_API = '/dev-api'
## 开发环境API地址 ## 开发环境API地址
# VITE_APP_BASE_URL = 'http://localhost:8093'
VITE_APP_BASE_URL = 'http://10.84.121.21: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' 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' VITE_APP_BASE_API = '/prod-api'
## 生产环境API地址 ## 生产环境API地址
VITE_APP_BASE_URL = 'http://localhost:8093' 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' 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({ return request({
url: '/data/fishDraft/importBatchSaveDraft', url: '/data/fishDraft/batchSaveDraft',
method: 'post',
data
});
}
// 标记导入任务为成功
export function markImportTaskSuccess(data:any) {
return request({
url: '/data/importTask/markSuccess',
method: 'post', method: 'post',
data data
}); });

View File

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

View File

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

View File

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

View File

@ -80,7 +80,6 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
fpssLoading.value = true; fpssLoading.value = true;
const param = hbrvcd === 'all' ? {} : { hbrvcd }; const param = hbrvcd === 'all' ? {} : { hbrvcd };
const res = await getFpssDropdown({...param, rstcd: rstcd}); 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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@
<!-- 审批操作日志弹框 --> <!-- 审批操作日志弹框 -->
<a-modal v-model:open="approvalLogVisible" title="审批操作日志" width="1600px" :footer="null" <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"> <div class="approval-log-modal-content">
<ApprovalLogSearch :action-type-dict="actionTypeDict" @search-finish="handleApprovalLogSearch" <ApprovalLogSearch :action-type-dict="actionTypeDict" @search-finish="handleApprovalLogSearch"
@reset="handleApprovalLogReset" /> @reset="handleApprovalLogReset" />
@ -42,7 +42,7 @@
</a-modal> </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"> <div class="change-log-modal-content">
<ChangeLogSearch :operation-type-dict="operationTypeDict" @search-finish="handleChangeLogSearch" <ChangeLogSearch :operation-type-dict="operationTypeDict" @search-finish="handleChangeLogSearch"
@reset="handleChangeLogReset" /> @reset="handleChangeLogReset" />
@ -64,14 +64,14 @@
</a-modal> </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"> <div class="detail-modal-content">
<!-- 搜索组件 --> <!-- 搜索组件 -->
<ApprovalDetailSearch :guoyu-status="guoyuStatus" :direction="direction" <ApprovalDetailSearch :guoyu-status="guoyuStatus" :direction="direction"
@search-finish="handleDetailSearchFinish" @reset="handleDetailReset" /> @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"> :scroll-y="'500px'" :transform-data="customTransform">
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'isfs'"> <template v-if="column.dataIndex === 'isfs'">
@ -196,6 +196,7 @@ import ApprovalDetailSearch from "./approvalDetailSearch.vue";
import EditModal from "@/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue"; import EditModal from "@/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue";
import { getDictItemsByCode } from '@/api/dict'; import { getDictItemsByCode } from '@/api/dict';
import { getFishDraftPage } from "@/api/guoYuSheShiShuJuTianBao"; import { getFishDraftPage } from "@/api/guoYuSheShiShuJuTianBao";
import { set } from 'lodash';
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; const baseUrlPreview = import.meta.env.VITE_APP_BASE_URL;
@ -208,7 +209,31 @@ let columns = ref([
width: 120, width: 120,
fixed: "left", 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: '审批批次号', title: '审批批次号',
dataIndex: 'approvalNo', dataIndex: 'approvalNo',
@ -554,42 +579,9 @@ const handleDetailReset = (values: any) => {
// //
const approvalId = ref(''); const approvalId = ref('');
const handleShowDetail = (record: any) => { const handleShowDetail = (record: any) => {
detailVisible.value = true;
// BasicTable approvalNo:record.approvalNo
setTimeout(() => {
approvalId.value = record.id; approvalId.value = record.id;
setTimeout(() => {
detailVisible.value = true;
// 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();
}, 300); }, 300);
}; };
@ -940,10 +932,6 @@ const handleBatchRejectConfirm = async () => {
message.success('批量驳回成功'); message.success('批量驳回成功');
batchRejectVisible.value = false; batchRejectVisible.value = false;
batchRejectForm.value.rejectReason = ''; batchRejectForm.value.rejectReason = '';
//
tableRef.value?.clearSelection();
//
handleSearchFinish(searchData.value);
} }
} catch (error) { } 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 :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current" @pagination="init()">
</Page> </Page>
</div> </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" <el-table v-loading="loading" :data="Logdata"
style="width: 100%; height: calc(50vh - 266px);margin-bottom: 20px;" border style="width: 100%; height: calc(50vh - 266px);margin-bottom: 20px;" border
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"> :header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }">

View File

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

View File

@ -452,7 +452,7 @@ onMounted(() => {
<el-button type="primary" @click="organizesubmit"> </el-button> <el-button type="primary" @click="organizesubmit"> </el-button>
</span> </span>
</el-dialog> </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 <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" /> :default-expanded-keys="DefaultDeployment" :props="defaultProps" @check="currentChecked" />
<span class="dialog-footer" <span class="dialog-footer"