diff --git a/src/api/review/ai.ts b/src/api/review/ai.ts new file mode 100644 index 000000000..596715e28 --- /dev/null +++ b/src/api/review/ai.ts @@ -0,0 +1,99 @@ +import request from '@/config/axios' +import { fetchEventSource } from '@microsoft/fetch-event-source' +import { getAccessToken } from '@/utils/auth' +import { config } from '@/config/axios/config' + +// ============================================================ +// 类型定义 +// ============================================================ + +export const AI_SUMMARY_STATUS = { + NOT_BUILT: 0, + BUILDING: 1, + SUCCESS: 2, + FAILED: 3 +} as const + +export interface ReviewAiSummaryVO { + reviewMeetingProjectId: number + status: number + statusName: string + updatedTime: string | null + summaryMarkdown: string | null + sourceFileIds: number[] + errorMessage: string | null + summary: { + projectOverview: string + businessGoal: string + constructionScope: string + implementationPlan: string + budgetInfo: string + keyEntities: string[] + readingGuide: string[] + sourceFiles: string[] + } | null +} + +export interface ReviewAiConversationVO { + conversationId: number + title: string + knowledgeId: number +} + +// ============================================================ +// API 调用 +// ============================================================ + +/** 获取评审项目 AI 摘要 */ +export const getProjectAiSummary = (reviewMeetingProjectId: number): Promise => + request.get({ url: `/project/review-ai/project/${reviewMeetingProjectId}/summary` }) + +/** 触发重建 AI 摘要(管理端) */ +export const rebuildProjectAiSummary = (reviewMeetingProjectId: number) => + request.post({ url: `/project/review-ai/project/${reviewMeetingProjectId}/rebuild` }) + +/** 打开 / 获取当前项目共享会话 */ +export const openProjectAiConversation = ( + reviewMeetingProjectId: number +): Promise => + request.post({ url: `/project/review-ai/project/${reviewMeetingProjectId}/conversation/open` }) + +/** 清空当前项目共享会话消息 */ +export const clearProjectAiMessages = (reviewMeetingProjectId: number) => + request.delete({ url: `/project/review-ai/project/${reviewMeetingProjectId}/chat/messages` }) + +/** + * 流式发送评审项目 AI 消息 + * 使用 fetchEventSource(axios 不支持 SSE) + */ +export const sendProjectAiChatStream = ( + reviewMeetingProjectId: number, + conversationId: number, + content: string, + ctrl: AbortController, + onMessage: (event: any) => void, + onError: (error: any) => void, + onClose: () => void +) => { + const token = getAccessToken() + return fetchEventSource( + `${config.base_url}/project/review-ai/project/${reviewMeetingProjectId}/chat/send-stream`, + { + method: 'post', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + openWhenHidden: true, + body: JSON.stringify({ + conversationId, + content, + useContext: true + }), + onmessage: onMessage, + onerror: onError, + onclose: onClose, + signal: ctrl.signal + } + ) +} diff --git a/src/views/review/tablet/index.vue b/src/views/review/tablet/index.vue index 4440a04c1..284f2280c 100644 --- a/src/views/review/tablet/index.vue +++ b/src/views/review/tablet/index.vue @@ -1,5 +1,6 @@