1、新增生成条数

2、新增生成记录
This commit is contained in:
2025-11-17 14:09:08 +08:00
parent 8cd66a30ca
commit 93762473d6
2 changed files with 232 additions and 308 deletions

View File

@@ -1,7 +1,7 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
width="80%"
width="90%"
:visible="visible"
:maskClosable="false"
title="历史记录"
@@ -9,96 +9,84 @@
@update:visible="updateVisible"
:footer="null"
>
<ele-pro-table
ref="tableRef"
row-key="id"
<a-table
:columns="columns"
:datasource="datasource"
:customRow="customRow"
:scroll="{ x: 4000 }"
tool-class="ele-toolbar-form"
class="sys-org-table"
:scroll="{ y: 500 }"
:pagination="false"
bordered
:data-source="mockData"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">已完成</a-tag>
<a-tag v-if="record.status === 1" color="red">未完成</a-tag>
<template v-if="column.key === 'action'">
<span>{{ record.createTime || '-' }}</span>
</template>
<template v-if="column.key === 'draftUser'">
<a-space direction="vertical" v-if="record.draftUser">
<a-tag
v-for="(item, index) in JSON.parse(record.draftUser)"
:key="index"
>{{ item }}</a-tag
>
</a-space>
</template>
<template v-if="column.key === 'users'">
<a-space direction="vertical" v-if="record.users">
<a-tag
v-for="(item, index) in JSON.parse(record.users)"
:key="index"
>{{ item }}</a-tag
>
</a-space>
</template>
<template v-if="column.key === 'signUser'">
<a-space direction="vertical" v-if="record.signUser">
<a-tag
v-for="(item, index) in JSON.parse(record.signUser)"
:key="index"
>{{ item }}</a-tag
>
</a-space>
</template>
<template v-if="column.key === 'saleUser'">
<a-space direction="vertical" v-if="record.saleUser">
<a-tag
v-for="(item, index) in JSON.parse(record.saleUser)"
:key="index"
>{{ item }}</a-tag
>
</a-space>
</template>
<template v-if="column.key === 'electron'">
<span>电子</span>
<a-tag v-if="record.electron === 0" color="green">已完成</a-tag>
<a-tag v-else color="red">未完成</a-tag>
<span>纸质</span>
<a-tag v-if="record.paper === 0" color="green">已完成</a-tag>
<a-tag v-else color="red">未完成</a-tag>
</template>
<template v-if="column.key === 'createTime'">
<a-tooltip
:title="`创建于:${record.createTime}`"
class="flex flex-col"
<template v-if="column.key === 'testResult'">
<span class="text-green-400" v-if="record.testResult === '通过'"
>通过</span
>
<a-space>
<span>{{ toDateString(record.createTime, 'YYYY-MM-dd') }}</span>
<a-avatar :src="record.avatar" size="small" />
</a-space>
</a-tooltip>
<span class="text-red-400" v-else-if="record.testResult === '不通过'"
>不通过</span
>
<span class="text-gray-400" v-else>{{
record.testResult || '待检查'
}}</span>
</template>
<template v-if="column.key === 'workPaperIndex'">
<div
v-for="(fileItem, fileIndex) in record.workPaperIndex"
:key="fileIndex"
>
<img
src="@/assets/word.png"
style="width: 20px; height: 20px"
alt=""
/>
<span class="cursor-pointer text-wrap">{{ fileItem }}</span>
</div>
</template>
<template v-if="column.key === 'fileIndex'">
<div
v-for="(fileItem, fileIndex) in record.fileIndex"
:key="fileIndex"
>
<img
src="@/assets/word.png"
style="width: 20px; height: 20px"
alt=""
/>
<span class="cursor-pointer text-wrap">{{ fileItem }}</span>
</div>
</template>
<template v-if="column.key === 'goods'">
<span v-if="record.goods === '是'"></span>
<span v-else></span>
</template>
<template v-if="column.key === 'normal'">
<span v-if="record.normal === '是'"></span>
<span v-else></span>
</template>
<template v-if="column.key === 'bad'">
<span v-if="record.bad === '是'"></span>
<span v-else></span>
</template>
</template>
</ele-pro-table>
</a-table>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { type EleProTable, toDateString } from 'ele-admin-pro';
import Search from '@/views/pwl/pwlProject/components/search.vue';
import type {
ColumnItem,
DatasourceFunction
} from 'ele-admin-pro/es/ele-pro-table/types';
import { pagePwlProject } from '@/api/pwl/pwlProject';
import type { PwlProjectParam } from '@/api/pwl/pwlProject/model';
import { ref, watch } from 'vue';
import dayjs from 'dayjs';
import { cloneDeep } from 'lodash-es';
const MOCK_ROW_COUNT = 5;
const TEST_RESULT_OPTIONS = ['通过', '不通过', '待检查'];
const SCORE_COLUMN_ORDER = ['goods', 'normal', 'bad'] as const;
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
item: any;
}>();
const updateVisible = (value: boolean) => {
@@ -109,248 +97,174 @@
(e: 'update:visible', visible: boolean): void;
}>();
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
return pagePwlProject({
...where,
...orders,
page,
limit
});
};
const mockData = ref<any>([]);
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '序号',
key: 'index',
width: 48,
fixed: 'left',
align: 'center',
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
},
{
title: '被审计单位',
dataIndex: 'name',
key: 'name',
width: 240,
fixed: 'left',
align: 'center'
},
{
title: '项目名称',
dataIndex: 'code',
key: 'code',
width: 240,
sorter: true,
align: 'center'
},
{
title: '项目完成进度',
dataIndex: 'status',
key: 'status',
width: 120,
align: 'center'
},
{
title: '报告时间',
dataIndex: 'expirationTime',
key: 'expirationTime',
align: 'center',
width: 120
},
// {
// title: '类型',
// dataIndex: 'type',
// key: 'type',
// align: 'center',
// customRender: ({text}) => ['审字', '专审', '验证', '咨询'][text]
// },
{
title: '项目信息',
dataIndex: 'itemName',
key: 'itemName',
align: 'center',
children: [
{
title: '开票单位/汇款人',
dataIndex: 'itemName',
key: 'itemName',
align: 'center',
width: 180
},
{
title: '所属年度',
dataIndex: 'itemYear',
key: 'itemYear',
align: 'center'
},
{
title: '类型',
dataIndex: 'itemType',
key: 'itemType',
align: 'center'
},
{
title: '审计意见',
dataIndex: 'itemOpinion',
key: 'itemOpinion',
align: 'center'
}
]
},
{
title: '年末资产总额(万元)',
dataIndex: 'totalAssets',
key: 'totalAssets',
align: 'center',
width: 170
},
{
title: '合同金额',
dataIndex: 'contractPrice',
key: 'contractPrice',
align: 'center'
},
{
title: '实收金额',
dataIndex: 'payPrice',
key: 'payPrice',
align: 'center',
width: 120
},
{
title: '到账信息',
dataIndex: 'itemName',
key: 'itemName',
align: 'center',
children: [
{
title: '银行',
dataIndex: 'bankName',
key: 'bankName',
align: 'center',
width: 120
},
{
title: '日期',
dataIndex: 'bankPayTime',
key: 'bankPayTime',
align: 'center',
width: 120
},
{
title: '金额',
dataIndex: 'bankPrice',
key: 'bankPrice',
align: 'center',
width: 120
}
]
},
{
title: '开票信息',
dataIndex: 'invoice',
key: 'invoice',
align: 'center',
children: [
{
title: '日期',
dataIndex: 'invoiceTime',
key: 'invoiceTime',
align: 'center',
width: 120
},
{
title: '金额',
dataIndex: 'invoicePrice',
key: 'invoicePrice',
align: 'center',
width: 120
},
{
title: '发票类型',
dataIndex: 'invoiceType',
key: 'invoiceType',
align: 'center',
width: 120
}
]
},
const columns = ref<any>([]);
const createDefaultColumns = () => [
{
title: '报告份数',
dataIndex: 'reportNum',
key: 'reportNum',
align: 'center',
width: 90
},
{
title: '底稿人员',
dataIndex: 'draftUser',
key: 'draftUser',
align: 'center',
width: 90
},
{
title: '参与成员',
dataIndex: 'users',
key: 'users',
align: 'center',
width: 180
},
{
title: '签字注会',
dataIndex: 'signUser',
key: 'signUser',
align: 'center',
width: 90
},
{
title: '展业人员',
dataIndex: 'saleUser',
key: 'saleUser',
align: 'center',
width: 90
},
{
title: '底稿完成情况',
dataIndex: 'electron',
key: 'electron',
align: 'center',
width: 120
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
width: 180
title: '内容',
key: 'content',
dataIndex: 'content',
align: 'center'
},
{
title: '生成时间',
key: 'action',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
width: 180,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm')
align: 'center'
}
]);
];
/* 搜索 */
const reload = (where?: PwlProjectParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
const buildCreateTimeColumn = () => ({
title: '生成时间',
key: 'action',
dataIndex: 'createTime',
fixed: 'right',
align: 'center'
});
const ensureColumnIdentifiers = (cols: any[]) => {
let seed = 0;
const traverse = (columnList: any[]) => {
columnList.forEach((column) => {
if (column.children && column.children.length) {
traverse(column.children);
} else {
if (!column.key) {
column.key = `column_key_${seed++}`;
}
if (!column.dataIndex) {
column.dataIndex = column.key || `column_data_${seed++}`;
}
}
});
};
traverse(cols);
};
const applyCreateTimeColumn = (cols: any[]) => {
const actionColumn = buildCreateTimeColumn();
if (!cols.length) {
cols.push(actionColumn);
return;
}
const lastIndex = cols.length - 1;
if (cols[lastIndex]?.key === 'action') {
cols[lastIndex] = actionColumn;
} else {
cols.push(actionColumn);
}
};
const buildHistoryColumns = (sourceColumns?: any[]) => {
const parsedColumns =
sourceColumns && sourceColumns.length
? cloneDeep(sourceColumns)
: createDefaultColumns();
ensureColumnIdentifiers(parsedColumns);
applyCreateTimeColumn(parsedColumns);
return parsedColumns;
};
interface ColumnLeaf {
key: string;
dataIndex: string;
title?: string;
}
const flattenLeafColumns = (
columnList: any[],
collector: ColumnLeaf[] = []
) => {
columnList.forEach((column) => {
if (column.children && column.children.length) {
flattenLeafColumns(column.children, collector);
} else {
collector.push({
key: column.key,
dataIndex: column.dataIndex,
title: column.title
});
}
});
return collector;
};
const formatCreateTime = (offset: number) =>
dayjs().subtract(offset, 'hour').format('YYYY-MM-DD HH:mm:ss');
const buildFileList = (rowIndex: number, prefix: string) => {
const count = (rowIndex % 2) + 1;
return Array.from({ length: count }, (_, fileIndex) => {
return `${prefix}${rowIndex + 1}-${fileIndex + 1}.docx`;
});
};
const getScoreFlag = (columnKey: string, rowIndex: number) => {
const targetIndex = SCORE_COLUMN_ORDER.indexOf(
columnKey as (typeof SCORE_COLUMN_ORDER)[number]
);
if (targetIndex === -1) {
return '否';
}
return rowIndex % SCORE_COLUMN_ORDER.length === targetIndex ? '是' : '否';
};
const buildMockCellValue = (
column: ColumnLeaf,
rowIndex: number,
columnIndex: number
) => {
const columnKey = column.key || column.dataIndex;
if (columnKey === 'index') {
return rowIndex + 1;
}
if (columnKey === 'testResult') {
return TEST_RESULT_OPTIONS[rowIndex % TEST_RESULT_OPTIONS.length];
}
if (columnKey === 'workPaperIndex') {
return buildFileList(rowIndex, '工作底稿');
}
if (columnKey === 'fileIndex') {
return buildFileList(rowIndex, '附件');
}
if (['goods', 'normal', 'bad'].includes(columnKey)) {
return getScoreFlag(columnKey, rowIndex);
}
const label = column.title || columnKey || `字段${columnIndex + 1}`;
return `${label || '字段'}示例${rowIndex + 1}`;
};
const generateMockData = (columnDefs: any[]) => {
const leafColumns = flattenLeafColumns(columnDefs).filter(
(column) => column.key !== 'action'
);
return Array.from({ length: MOCK_ROW_COUNT }, (_, rowIndex) => {
const record: Record<string, any> = {
key: `row-${rowIndex + 1}`,
createTime: formatCreateTime(rowIndex)
};
leafColumns.forEach((column, columnIndex) => {
record[column.dataIndex] = buildMockCellValue(
column,
rowIndex,
columnIndex
);
});
return record;
});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
} else {
if (!visible || !props.item) {
return;
}
const historyColumns = buildHistoryColumns(props.item.columns);
columns.value = historyColumns;
mockData.value = generateMockData(historyColumns);
},
{ immediate: true }
);

View File

@@ -235,11 +235,15 @@
/>
</div>
</template>
<span class="ml-2 ">共生成
<span class="text-red-400 mx-1 font-bold">{{ item.count }}</span>
条数据</span>
<span class="ml-2"
>共生成
<span class="text-red-400 mx-1 font-bold">{{
item.count
}}</span>
条数据</span
>
</div>
<a @click="openHistory" class="cursor-pointer">历史记录</a>
<a @click="openHistory(item)" class="cursor-pointer">历史记录</a>
</div>
<a-table
v-if="item.mode === 'table'"
@@ -377,7 +381,11 @@
<!-- 返回顶部按钮 -->
<a-back-top :target="getScrollContainer" />
<FileModal ref="fileModal" :current-company-id="currentCompanyId" />
<HistoryModal v-model:visible="showHistory"/>
<HistoryModal
v-model:visible="showHistory"
:item="clickedItem"
v-if="clickedItem"
/>
<!-- 文档选择弹窗 -->
</a-drawer>
@@ -1138,7 +1146,9 @@
);
const showHistory = ref(false);
const openHistory = () => {
const clickedItem = ref();
const openHistory = (item) => {
clickedItem.value = item;
showHistory.value = true;
};
</script>