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>
|
<template>
|
||||||
<ele-modal
|
<ele-modal
|
||||||
width="90%"
|
width="85%"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
title="历史记录"
|
title="历史记录"
|
||||||
:body-style="{ paddingBottom: '28px' }"
|
:body-style="{ paddingBottom: '20px' }"
|
||||||
@update:visible="updateVisible"
|
@update:visible="updateVisible"
|
||||||
:footer="null"
|
:footer="null"
|
||||||
>
|
>
|
||||||
<a-table
|
<ele-pro-table
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="id"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:scroll="{ y: 500 }"
|
:datasource="datasource"
|
||||||
:pagination="false"
|
:scroll="{ x: 1000 }"
|
||||||
|
size="small"
|
||||||
|
tool-class="ele-toolbar-form"
|
||||||
|
class="compact-history-table"
|
||||||
bordered
|
bordered
|
||||||
:data-source="mockData"
|
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, record }">
|
<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'">
|
<template v-if="column.key === 'action'">
|
||||||
<span>{{ record.createTime || '-' }}</span>
|
<a-button
|
||||||
</template>
|
type="primary"
|
||||||
<template v-if="column.key === 'testResult'">
|
size="small"
|
||||||
<span class="text-green-400" v-if="record.testResult === '通过'"
|
@click="handleSelect(record)"
|
||||||
>通过</span
|
:disabled="!hasValidData(record)"
|
||||||
>
|
>
|
||||||
<span class="text-red-400" v-else-if="record.testResult === '不通过'"
|
选择
|
||||||
>不通过</span
|
</a-button>
|
||||||
>
|
|
||||||
<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>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</ele-pro-table>
|
||||||
</ele-modal>
|
</ele-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import dayjs from 'dayjs';
|
import { type EleProTable, toDateString } from 'ele-admin-pro';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import type {
|
||||||
|
ColumnItem,
|
||||||
const MOCK_ROW_COUNT = 5;
|
DatasourceFunction
|
||||||
const TEST_RESULT_OPTIONS = ['通过', '不通过', '待检查'];
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
const SCORE_COLUMN_ORDER = ['goods', 'normal', 'bad'] as const;
|
import { pageAiHistory } from '@/api/ai/aiHistory';
|
||||||
|
import type { AiHistoryParam } from '@/api/ai/aiHistory/model';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
// 弹窗是否打开
|
|
||||||
visible: boolean;
|
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) => {
|
const updateVisible = (value: boolean) => {
|
||||||
emit('update:visible', value);
|
emit('update:visible', value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const datasource: DatasourceFunction = async ({ page, limit, orders }) => {
|
||||||
(e: 'update:visible', visible: boolean): void;
|
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: '内容',
|
title: '序号',
|
||||||
key: 'content',
|
key: 'index',
|
||||||
dataIndex: 'content',
|
width: 50,
|
||||||
|
align: 'center',
|
||||||
|
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '接口',
|
||||||
|
key: 'interfaceName',
|
||||||
|
width: 120,
|
||||||
align: 'center'
|
align: 'center'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '生成时间',
|
title: '数据量',
|
||||||
key: 'action',
|
key: 'dataCount',
|
||||||
dataIndex: 'createTime',
|
width: 70,
|
||||||
align: 'center'
|
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>
|
</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>
|
</template>
|
||||||
<span class="ml-2"
|
<span class="ml-2"
|
||||||
>共生成
|
>共生成
|
||||||
<span class="text-red-400 mx-1 font-bold">{{
|
<span class="text-red-400 mx-1 font-bold">{{ item.data ? item.data.length : 0 }}</span>
|
||||||
item.count
|
|
||||||
}}</span>
|
|
||||||
条数据</span
|
条数据</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<a @click="openHistory(item)" class="cursor-pointer">历史记录</a>
|
<a @click="openHistory(index)" class="cursor-pointer">历史记录</a>
|
||||||
</div>
|
</div>
|
||||||
<a-table
|
<a-table
|
||||||
v-if="item.mode === 'table'"
|
v-if="item.mode === 'table'"
|
||||||
@@ -383,8 +381,8 @@
|
|||||||
<FileModal ref="fileModal" :current-company-id="currentCompanyId" />
|
<FileModal ref="fileModal" :current-company-id="currentCompanyId" />
|
||||||
<HistoryModal
|
<HistoryModal
|
||||||
v-model:visible="showHistory"
|
v-model:visible="showHistory"
|
||||||
:item="clickedItem"
|
:interface-name="currentInterfaceName"
|
||||||
v-if="clickedItem"
|
@select="handleHistorySelect"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 文档选择弹窗 -->
|
<!-- 文档选择弹窗 -->
|
||||||
@@ -468,6 +466,9 @@
|
|||||||
// 文档管理相关变量
|
// 文档管理相关变量
|
||||||
const currentCompanyId = ref<number>();
|
const currentCompanyId = ref<number>();
|
||||||
|
|
||||||
|
// 历史记录接口相关变量
|
||||||
|
const currentInterfaceName = ref('');
|
||||||
|
|
||||||
// 添加计算属性检查是否已生成三重一大数据
|
// 添加计算属性检查是否已生成三重一大数据
|
||||||
const hasTripleOneData = computed(() => {
|
const hasTripleOneData = computed(() => {
|
||||||
const section = navigationItems.value[2];
|
const section = navigationItems.value[2];
|
||||||
@@ -869,16 +870,7 @@
|
|||||||
console.log('三重一大接口返回结果:', result);
|
console.log('三重一大接口返回结果:', result);
|
||||||
|
|
||||||
if (result.code === 0 && result.data && result.data.success) {
|
if (result.code === 0 && result.data && result.data.success) {
|
||||||
const tableData = result.data.data.map((item, index) => ({
|
const tableData = mapTripleOneData(result.data.data);
|
||||||
key: index,
|
|
||||||
category: item.category || '',
|
|
||||||
policyContent: item.policyContent || '',
|
|
||||||
groupSystem: item.groupSystem || '',
|
|
||||||
companyFormulation: item.companyFormulation || '',
|
|
||||||
checkEvidence: item.checkEvidence || '',
|
|
||||||
testResult: item.testResult || '待检查',
|
|
||||||
workPaperIndex: item.workPaperIndex || []
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 保存到三重一大数据
|
// 保存到三重一大数据
|
||||||
tripleOneTableData.value = tableData;
|
tripleOneTableData.value = tableData;
|
||||||
@@ -949,18 +941,7 @@
|
|||||||
console.log('重大经济决策调查表接口返回结果:', result);
|
console.log('重大经济决策调查表接口返回结果:', result);
|
||||||
|
|
||||||
if (result.code === 0 && result.data && result.data.success) {
|
if (result.code === 0 && result.data && result.data.success) {
|
||||||
const tableData = result.data.data.map((item, index) => ({
|
const tableData = mapDecisionTableData(result.data.data);
|
||||||
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 || '否'
|
|
||||||
}));
|
|
||||||
|
|
||||||
console.log('生成的表格数据:', tableData);
|
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 showHistory = ref(false);
|
||||||
const clickedItem = ref();
|
const openHistory = (sectionIndex: number) => {
|
||||||
const openHistory = (item) => {
|
// 重置接口名称
|
||||||
clickedItem.value = item;
|
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;
|
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>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
Reference in New Issue
Block a user