chat log soft delete (#6110)

* chat log soft delete

* perf: history api

* add history test

* Update packages/web/i18n/en/app.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* zod parse error

* fix: ts

---------

Co-authored-by: archer <545436317@qq.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
heheer
2025-12-18 10:17:10 +08:00
committed by GitHub
parent 463b02d127
commit 09b9fa517b
48 changed files with 1830 additions and 251 deletions
@@ -105,11 +105,11 @@ export const UpdateUserFeedbackBodySchema = z.object({
example: 'data123',
description: '消息数据 ID'
}),
userGoodFeedback: z.string().optional().nullable().meta({
userGoodFeedback: z.string().nullish().meta({
example: '回答很好',
description: '用户好评反馈内容'
}),
userBadFeedback: z.string().optional().nullable().meta({
userBadFeedback: z.string().nullish().meta({
example: '回答不准确',
description: '用户差评反馈内容'
})
@@ -0,0 +1,73 @@
import z from 'zod';
import { ObjectIdSchema } from '../../../../common/type/mongo';
import { OutLinkChatAuthSchema } from '../../../../support/permission/chat';
import { ChatSourceEnum } from '../../../../core/chat/constants';
import { PaginationSchema, PaginationResponseSchema } from '../../../api';
// Get chat histories schema
export const GetHistoriesBodySchema = PaginationSchema.and(
OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.optional().describe('应用ID'),
source: z.enum(ChatSourceEnum).optional().describe('对话来源'),
startCreateTime: z.string().optional().describe('创建时间开始'),
endCreateTime: z.string().optional().describe('创建时间结束'),
startUpdateTime: z.string().optional().describe('更新时间开始'),
endUpdateTime: z.string().optional().describe('更新时间结束')
})
)
);
export type GetHistoriesBodyType = z.infer<typeof GetHistoriesBodySchema>;
export const GetHistoriesResponseSchema = PaginationResponseSchema(
z.object({
chatId: z.string(),
updateTime: z.date(),
appId: z.string(),
customTitle: z.string().optional(),
title: z.string(),
top: z.boolean().optional()
})
);
export type GetHistoriesResponseType = z.infer<typeof GetHistoriesResponseSchema>;
// Update chat history schema
export const UpdateHistoryBodySchema = OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.describe('应用ID'),
chatId: z.string().min(1).describe('对话ID'),
title: z.string().optional().describe('标题'),
customTitle: z.string().optional().describe('自定义标题'),
top: z.boolean().optional().describe('是否置顶')
})
);
export type UpdateHistoryBodyType = z.infer<typeof UpdateHistoryBodySchema>;
// Delete single chat history schema
export const DelChatHistorySchema = OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.describe('应用ID'),
chatId: z.string().min(1).describe('对话ID')
})
);
export type DelChatHistoryType = z.infer<typeof DelChatHistorySchema>;
// Clear all chat histories schema
export const ClearChatHistoriesSchema = OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.describe('应用ID')
})
);
export type ClearChatHistoriesType = z.infer<typeof ClearChatHistoriesSchema>;
// Batch delete chat histories schema (for log manager)
export const ChatBatchDeleteBodySchema = z.object({
appId: ObjectIdSchema,
chatIds: z
.array(z.string().min(1))
.min(1)
.meta({
description: '对话ID列表',
example: ['chat_123456', 'chat_789012']
})
});
export type ChatBatchDeleteBodyType = z.infer<typeof ChatBatchDeleteBodySchema>;
@@ -0,0 +1,109 @@
import type { OpenAPIPath } from '../../../type';
import { TagsMap } from '../../../tag';
import {
GetHistoriesBodySchema,
GetHistoriesResponseSchema,
UpdateHistoryBodySchema,
ChatBatchDeleteBodySchema,
DelChatHistorySchema,
ClearChatHistoriesSchema
} from './api';
export const ChatHistoryPath: OpenAPIPath = {
'/core/chat/history/getHistories': {
post: {
summary: '获取对话历史列表',
description: '分页获取指定应用的对话历史记录',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: GetHistoriesBodySchema
}
}
},
responses: {
200: {
description: '成功获取对话历史列表',
content: {
'application/json': {
schema: GetHistoriesResponseSchema
}
}
}
}
}
},
'/core/chat/history/updateHistory': {
put: {
summary: '修改对话历史',
description: '修改对话历史的标题、自定义标题或置顶状态',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: UpdateHistoryBodySchema
}
}
},
responses: {
200: {
description: '成功修改对话历史'
}
}
}
},
'/core/chat/history/delHistory': {
delete: {
summary: '删除单个对话历史',
description: '软删除指定的单个对话记录',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: DelChatHistorySchema
}
}
},
responses: {
200: {
description: '成功删除对话'
}
}
}
},
'/core/chat/history/clearHistories': {
delete: {
summary: '清空应用对话历史',
description: '清空指定应用的所有对话记录(软删除)',
tags: [TagsMap.chatHistory],
requestParams: {
query: ClearChatHistoriesSchema
},
responses: {
200: {
description: '成功清空对话历史'
}
}
}
},
'/core/chat/history/batchDelete': {
post: {
summary: '批量删除对话历史',
description: '批量删除指定应用的多个对话记录(真实删除),需应用日志权限。',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: ChatBatchDeleteBodySchema
}
}
},
responses: {
200: {
description: '成功删除对话'
}
}
}
}
};
@@ -2,6 +2,7 @@ import type { OpenAPIPath } from '../../type';
import { ChatSettingPath } from './setting';
import { ChatFavouriteAppPath } from './favourite/index';
import { ChatFeedbackPath } from './feedback/index';
import { ChatHistoryPath } from './history/index';
import { z } from 'zod';
import { CreatePostPresignedUrlResultSchema } from '../../../../service/common/s3/type';
import { PresignChatFileGetUrlSchema, PresignChatFilePostUrlSchema } from '../../../core/chat/api';
@@ -11,6 +12,7 @@ export const ChatPath: OpenAPIPath = {
...ChatSettingPath,
...ChatFavouriteAppPath,
...ChatFeedbackPath,
...ChatHistoryPath,
'/core/chat/presignChatFileGetUrl': {
post: {