Merge remote-tracking branch 'origin/master'
This commit is contained in:
129
src/api/ai/aiHistory/index.ts
Normal file
129
src/api/ai/aiHistory/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type { ApiResult, PageResult } from '@/api';
|
||||
import type { AiHistory, AiHistoryParam } from './model';
|
||||
import { MODULES_API_URL } from '@/config/setting';
|
||||
|
||||
/**
|
||||
* 分页查询AI审计历史记录表
|
||||
*/
|
||||
export async function pageAiHistory(params: AiHistoryParam) {
|
||||
const res = await request.get<ApiResult<PageResult<AiHistory>>>(
|
||||
`${MODULES_API_URL}/ai/history/page`,
|
||||
{ params }
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询AI审计历史记录表列表
|
||||
*/
|
||||
export async function listAiHistory(params?: AiHistoryParam) {
|
||||
const res = await request.get<ApiResult<AiHistory[]>>(
|
||||
`${MODULES_API_URL}/ai/history`,
|
||||
{ params }
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询AI审计历史记录表
|
||||
*/
|
||||
export async function getAiHistory(id: number) {
|
||||
const res = await request.get<ApiResult<AiHistory>>(
|
||||
`${MODULES_API_URL}/ai/history/${id}`
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加AI审计历史记录表
|
||||
*/
|
||||
export async function addAiHistory(data: AiHistory) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
`${MODULES_API_URL}/ai/history`,
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改AI审计历史记录表
|
||||
*/
|
||||
export async function updateAiHistory(data: AiHistory) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
`${MODULES_API_URL}/ai/history`,
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除AI审计历史记录表
|
||||
*/
|
||||
export async function removeAiHistory(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
`${MODULES_API_URL}/ai/history/${id}`
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加AI审计历史记录表
|
||||
*/
|
||||
export async function addAiHistoryBatch(data: AiHistory[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
`${MODULES_API_URL}/ai/history/batch`,
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改AI审计历史记录表
|
||||
*/
|
||||
export async function updateAiHistoryBatch(data: { list: AiHistory[] }) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
`${MODULES_API_URL}/ai/history/batch`,
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除AI审计历史记录表
|
||||
*/
|
||||
export async function removeAiHistoryBatch(ids: number[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
`${MODULES_API_URL}/ai/history/batch`,
|
||||
{ data: ids }
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
41
src/api/ai/aiHistory/model/index.ts
Normal file
41
src/api/ai/aiHistory/model/index.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* AI审计历史记录表
|
||||
*/
|
||||
export interface AiHistory {
|
||||
// 主键ID
|
||||
id?: number;
|
||||
// 请求哈希值
|
||||
requestHash?: string;
|
||||
// 接口名称
|
||||
interfaceName?: string;
|
||||
// 用户ID
|
||||
userId?: number;
|
||||
// 用户名
|
||||
username?: string;
|
||||
// 状态, 0正常, 1冻结
|
||||
status?: number;
|
||||
// 是否删除, 0否, 1是
|
||||
deleted?: number;
|
||||
// 租户id
|
||||
tenantId?: number;
|
||||
// 创建时间
|
||||
createTime?: string;
|
||||
// 修改时间
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* AI审计历史记录表搜索条件
|
||||
*/
|
||||
export interface AiHistoryParam extends PageParam {
|
||||
id?: number;
|
||||
requestHash?: string;
|
||||
interfaceName?: string;
|
||||
userId?: number;
|
||||
username?: string;
|
||||
status?: number;
|
||||
deleted?: number;
|
||||
tenantId?: number;
|
||||
}
|
||||
@@ -1,271 +1,286 @@
|
||||
<!-- 编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="90%"
|
||||
width="85%"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
title="历史记录"
|
||||
:body-style="{ paddingBottom: '28px' }"
|
||||
:body-style="{ paddingBottom: '20px' }"
|
||||
@update:visible="updateVisible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-table
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:scroll="{ y: 500 }"
|
||||
:pagination="false"
|
||||
:datasource="datasource"
|
||||
:scroll="{ x: 1000 }"
|
||||
size="small"
|
||||
tool-class="ele-toolbar-form"
|
||||
class="compact-history-table"
|
||||
bordered
|
||||
:data-source="mockData"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<span>{{ toDateString(record.createTime, 'MM-DD HH:mm') }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'username'">
|
||||
<span>{{ record.username || '-' }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'interfaceName'">
|
||||
<a-tag :color="getInterfaceColor(record.interfaceName)" size="small">
|
||||
{{ getInterfaceName(record.interfaceName) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'dataCount'">
|
||||
<a-tag v-if="record.dataCount > 0" color="blue" size="small">
|
||||
{{ record.dataCount }}条
|
||||
</a-tag>
|
||||
<span v-else class="text-gray">无</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'processingTime'">
|
||||
<a-tag v-if="record.processingTime" color="green" size="small">
|
||||
{{ formatProcessingTime(record.processingTime) }}
|
||||
</a-tag>
|
||||
<span v-else class="text-gray">-</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'requestData'">
|
||||
<a-tooltip :title="getRequestDataPreview(record)">
|
||||
<a-button type="link" size="small" class="p-0 h-auto">
|
||||
查看
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<span>{{ record.createTime || '-' }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'testResult'">
|
||||
<span class="text-green-400" v-if="record.testResult === '通过'"
|
||||
>通过</span
|
||||
<a-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleSelect(record)"
|
||||
:disabled="!hasValidData(record)"
|
||||
>
|
||||
<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>
|
||||
选择
|
||||
</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</ele-pro-table>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
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;
|
||||
import { type EleProTable, toDateString } from 'ele-admin-pro';
|
||||
import type {
|
||||
ColumnItem,
|
||||
DatasourceFunction
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { pageAiHistory } from '@/api/ai/aiHistory';
|
||||
import type { AiHistoryParam } from '@/api/ai/aiHistory/model';
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
item: any;
|
||||
interfaceName?: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
(e: 'select', record: any): void;
|
||||
}>();
|
||||
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
const datasource: DatasourceFunction = async ({ page, limit, orders }) => {
|
||||
const params: AiHistoryParam = { page, limit };
|
||||
|
||||
const mockData = ref<any>([]);
|
||||
if (orders) {
|
||||
Object.assign(params, orders);
|
||||
}
|
||||
|
||||
const columns = ref<any>([]);
|
||||
// 使用传入的接口名称进行过滤
|
||||
if (props.interfaceName) {
|
||||
params.interfaceName = props.interfaceName;
|
||||
}
|
||||
|
||||
const createDefaultColumns = () => [
|
||||
try {
|
||||
const result = await pageAiHistory(params);
|
||||
|
||||
const processedList = result.list.map(record => {
|
||||
let dataCount = 0;
|
||||
let processingTime = '';
|
||||
|
||||
try {
|
||||
if (record.responseData) {
|
||||
const responseData = JSON.parse(record.responseData);
|
||||
if (responseData.data && Array.isArray(responseData.data)) {
|
||||
dataCount = responseData.data.length;
|
||||
} else if (responseData.data?.data && Array.isArray(responseData.data.data)) {
|
||||
dataCount = responseData.data.data.length;
|
||||
}
|
||||
processingTime = responseData.processing_time || responseData.generated_time || '';
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('解析响应数据失败:', error);
|
||||
}
|
||||
|
||||
return { ...record, dataCount, processingTime };
|
||||
});
|
||||
|
||||
return { total: result.total, list: processedList };
|
||||
} catch (error) {
|
||||
console.error('获取历史记录失败:', error);
|
||||
return { total: 0, list: [] };
|
||||
}
|
||||
};
|
||||
|
||||
// 监听 visible 变化,当弹窗显示时刷新表格
|
||||
watch(() => props.visible, (newVal) => {
|
||||
if (newVal && tableRef.value) {
|
||||
// 延迟一下确保表格已经渲染
|
||||
setTimeout(() => {
|
||||
tableRef.value?.reload();
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: '内容',
|
||||
key: 'content',
|
||||
dataIndex: 'content',
|
||||
title: '序号',
|
||||
key: 'index',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: '接口',
|
||||
key: 'interfaceName',
|
||||
width: 120,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '生成时间',
|
||||
key: 'action',
|
||||
dataIndex: 'createTime',
|
||||
title: '数据量',
|
||||
key: 'dataCount',
|
||||
width: 70,
|
||||
align: 'center'
|
||||
}
|
||||
];
|
||||
|
||||
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 || !props.item) {
|
||||
return;
|
||||
}
|
||||
const historyColumns = buildHistoryColumns(props.item.columns);
|
||||
columns.value = historyColumns;
|
||||
mockData.value = generateMockData(historyColumns);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
{
|
||||
title: '耗时',
|
||||
key: 'processingTime',
|
||||
width: 80,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户',
|
||||
dataIndex: 'username',
|
||||
key: 'username',
|
||||
width: 80,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '参数',
|
||||
key: 'requestData',
|
||||
width: 60,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
width: 110,
|
||||
align: 'center',
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
fixed: 'right'
|
||||
}
|
||||
]);
|
||||
|
||||
const getInterfaceName = (interfaceName: string) => {
|
||||
const nameMap: Record<string, string> = {
|
||||
'/api/ai/auditContent3/generateTripleOneTable': '三重一大',
|
||||
'/api/ai/auditContent3/generateDecisionTable': '重大经济决策调查表'
|
||||
};
|
||||
return nameMap[interfaceName] || interfaceName.split('/').pop() || interfaceName;
|
||||
};
|
||||
|
||||
const getInterfaceColor = (interfaceName: string) => {
|
||||
const colorMap: Record<string, string> = {
|
||||
'/api/ai/auditContent3/generateTripleOneTable': 'blue',
|
||||
'/api/ai/auditContent3/generateDecisionTable': 'green'
|
||||
};
|
||||
return colorMap[interfaceName] || 'default';
|
||||
};
|
||||
|
||||
const formatProcessingTime = (time: string) => {
|
||||
if (time.includes('ms')) {
|
||||
const ms = parseInt(time);
|
||||
if (!isNaN(ms)) return `${(ms / 1000).toFixed(1)}s`;
|
||||
}
|
||||
if (time.includes('CST')) {
|
||||
return new Date(time).toLocaleTimeString('zh-CN', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
}
|
||||
return time.length > 8 ? time.substring(0, 7) + '...' : time;
|
||||
};
|
||||
|
||||
const getRequestDataPreview = (record: any) => {
|
||||
try {
|
||||
if (record.requestData) {
|
||||
const requestData = JSON.parse(record.requestData);
|
||||
const preview: string[] = [];
|
||||
|
||||
if (requestData.kbIds) preview.push(`知识库: ${requestData.kbIds}`);
|
||||
if (requestData.libraryIds) preview.push(`项目库: ${requestData.libraryIds}`);
|
||||
if (requestData.suggestion) preview.push(`要求: ${requestData.suggestion.substring(0, 20)}...`);
|
||||
if (requestData.docList?.length > 0) preview.push(`文档: ${requestData.docList.length}个`);
|
||||
if (requestData.fileList?.length > 0) preview.push(`文件: ${requestData.fileList.length}个`);
|
||||
|
||||
return preview.join('\n') || '无参数';
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('解析请求数据失败:', error);
|
||||
}
|
||||
return '解析失败';
|
||||
};
|
||||
|
||||
const hasValidData = (record: any) => {
|
||||
try {
|
||||
if (record.responseData) {
|
||||
const responseData = JSON.parse(record.responseData);
|
||||
const hasData = (responseData.data && Array.isArray(responseData.data) && responseData.data.length > 0) ||
|
||||
(responseData.data?.data && Array.isArray(responseData.data.data) && responseData.data.data.length > 0);
|
||||
return hasData && responseData.success !== false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('检查数据有效性失败:', error);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleSelect = (record: any) => {
|
||||
if (!hasValidData(record)) return;
|
||||
emit('select', record);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text-gray {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.compact-history-table :deep(.ant-table-thead > tr > th) {
|
||||
padding: 8px 4px;
|
||||
}
|
||||
|
||||
.compact-history-table :deep(.ant-table-tbody > tr > td) {
|
||||
padding: 8px 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -237,13 +237,11 @@
|
||||
</template>
|
||||
<span class="ml-2"
|
||||
>共生成
|
||||
<span class="text-red-400 mx-1 font-bold">{{
|
||||
item.count
|
||||
}}</span>
|
||||
<span class="text-red-400 mx-1 font-bold">{{ item.data ? item.data.length : 0 }}</span>
|
||||
条数据</span
|
||||
>
|
||||
</div>
|
||||
<a @click="openHistory(item)" class="cursor-pointer">历史记录</a>
|
||||
<a @click="openHistory(index)" class="cursor-pointer">历史记录</a>
|
||||
</div>
|
||||
<a-table
|
||||
v-if="item.mode === 'table'"
|
||||
@@ -383,8 +381,8 @@
|
||||
<FileModal ref="fileModal" :current-company-id="currentCompanyId" />
|
||||
<HistoryModal
|
||||
v-model:visible="showHistory"
|
||||
:item="clickedItem"
|
||||
v-if="clickedItem"
|
||||
:interface-name="currentInterfaceName"
|
||||
@select="handleHistorySelect"
|
||||
/>
|
||||
|
||||
<!-- 文档选择弹窗 -->
|
||||
@@ -468,6 +466,9 @@
|
||||
// 文档管理相关变量
|
||||
const currentCompanyId = ref<number>();
|
||||
|
||||
// 历史记录接口相关变量
|
||||
const currentInterfaceName = ref('');
|
||||
|
||||
// 添加计算属性检查是否已生成三重一大数据
|
||||
const hasTripleOneData = computed(() => {
|
||||
const section = navigationItems.value[2];
|
||||
@@ -869,16 +870,7 @@
|
||||
console.log('三重一大接口返回结果:', result);
|
||||
|
||||
if (result.code === 0 && result.data && result.data.success) {
|
||||
const tableData = result.data.data.map((item, index) => ({
|
||||
key: index,
|
||||
category: item.category || '',
|
||||
policyContent: item.policyContent || '',
|
||||
groupSystem: item.groupSystem || '',
|
||||
companyFormulation: item.companyFormulation || '',
|
||||
checkEvidence: item.checkEvidence || '',
|
||||
testResult: item.testResult || '待检查',
|
||||
workPaperIndex: item.workPaperIndex || []
|
||||
}));
|
||||
const tableData = mapTripleOneData(result.data.data);
|
||||
|
||||
// 保存到三重一大数据
|
||||
tripleOneTableData.value = tableData;
|
||||
@@ -949,18 +941,7 @@
|
||||
console.log('重大经济决策调查表接口返回结果:', result);
|
||||
|
||||
if (result.code === 0 && result.data && result.data.success) {
|
||||
const tableData = result.data.data.map((item, index) => ({
|
||||
key: index,
|
||||
index: index + 1,
|
||||
name: item.decisionItem || '',
|
||||
meetingTime: item.meetingTime || '',
|
||||
decisionAmount: item.decisionAmount || '',
|
||||
procedure: item.procedure || '',
|
||||
executionStatus: item.executionStatus || '否',
|
||||
goods: item.executionEffect?.good || '否',
|
||||
normal: item.executionEffect?.normal || '否',
|
||||
bad: item.executionEffect?.bad || '否'
|
||||
}));
|
||||
const tableData = mapDecisionTableData(result.data.data);
|
||||
|
||||
console.log('生成的表格数据:', tableData);
|
||||
|
||||
@@ -1149,12 +1130,106 @@
|
||||
}
|
||||
);
|
||||
|
||||
// 数据映射工具函数
|
||||
const mapTripleOneData = (data: any[]) => {
|
||||
return data.map((item, index) => ({
|
||||
key: index,
|
||||
category: item.category || '',
|
||||
policyContent: item.policyContent || '',
|
||||
groupSystem: item.groupSystem || '',
|
||||
companyFormulation: item.companyFormulation || '',
|
||||
checkEvidence: item.checkEvidence || '',
|
||||
testResult: item.testResult || '待检查',
|
||||
workPaperIndex: item.workPaperIndex || []
|
||||
}));
|
||||
};
|
||||
|
||||
const mapDecisionTableData = (data: any[]) => {
|
||||
return data.map((item, index) => ({
|
||||
key: index,
|
||||
index: index + 1,
|
||||
name: item.decisionItem || item.name || '',
|
||||
meetingTime: item.meetingTime || '',
|
||||
decisionAmount: item.decisionAmount || '',
|
||||
procedure: item.procedure || '',
|
||||
executionStatus: item.executionStatus || '否',
|
||||
goods: item.executionEffect?.good || item.goods || '否',
|
||||
normal: item.executionEffect?.normal || item.normal || '否',
|
||||
bad: item.executionEffect?.bad || item.bad || '否'
|
||||
}));
|
||||
};
|
||||
|
||||
// 应用历史记录数据到指定章节
|
||||
const applyHistoryData = (sectionIndex: number, data: any[], dataType: 'tripleOne' | 'decisionTable') => {
|
||||
const section = navigationItems.value[sectionIndex];
|
||||
|
||||
if (dataType === 'tripleOne') {
|
||||
const tableData = mapTripleOneData(data);
|
||||
section.data = tableData;
|
||||
tripleOneTableData.value = tableData;
|
||||
|
||||
// 强制刷新当前显示的表格
|
||||
if (table3Title.value === '三重一大') {
|
||||
section.columns = table3Columns.columns0;
|
||||
section.data = [...tableData];
|
||||
}
|
||||
} else {
|
||||
const tableData = mapDecisionTableData(data);
|
||||
section.data = tableData;
|
||||
decisionTableData.value = tableData;
|
||||
|
||||
// 强制刷新当前显示的表格
|
||||
if (table3Title.value === '重大经济决策调查表') {
|
||||
section.columns = table3Columns.columns1;
|
||||
section.data = [...tableData];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const showHistory = ref(false);
|
||||
const clickedItem = ref();
|
||||
const openHistory = (item) => {
|
||||
clickedItem.value = item;
|
||||
const openHistory = (sectionIndex: number) => {
|
||||
// 重置接口名称
|
||||
currentInterfaceName.value = '';
|
||||
|
||||
// 根据当前章节和表格类型确定接口名称
|
||||
if (sectionIndex === 2) { // 审计内容3章节
|
||||
if (table3Title.value === '三重一大') {
|
||||
currentInterfaceName.value = '/api/ai/auditContent3/generateTripleOneTable';
|
||||
} else if (table3Title.value === '重大经济决策调查表') {
|
||||
currentInterfaceName.value = '/api/ai/auditContent3/generateDecisionTable';
|
||||
}
|
||||
}
|
||||
|
||||
showHistory.value = true;
|
||||
};
|
||||
|
||||
// 历史记录选择处理方法
|
||||
const handleHistorySelect = (record: any) => {
|
||||
// 关闭历史记录弹窗
|
||||
showHistory.value = false;
|
||||
|
||||
try {
|
||||
const responseData = JSON.parse(record.responseData);
|
||||
if (!responseData.success || !responseData.data) {
|
||||
throw new Error('历史记录数据格式错误');
|
||||
}
|
||||
|
||||
// 根据接口名称确定数据类型
|
||||
if (record.interfaceName === '/api/ai/auditContent3/generateTripleOneTable') {
|
||||
applyHistoryData(2, responseData.data, 'tripleOne');
|
||||
message.success('已应用选择的三重一大历史记录');
|
||||
} else if (record.interfaceName === '/api/ai/auditContent3/generateDecisionTable') {
|
||||
applyHistoryData(2, responseData.data, 'decisionTable');
|
||||
message.success('已应用选择的重大经济决策调查表历史记录');
|
||||
} else {
|
||||
message.warning('不支持的历史记录类型');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('解析历史记录数据失败:', error);
|
||||
message.error('历史记录数据解析失败');
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
Reference in New Issue
Block a user