diff --git a/index.html b/index.html index 2d795ce..0155d7b 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ diff --git a/src/renderer/api/SessionsApi.ts b/src/renderer/api/SessionsApi.ts new file mode 100644 index 0000000..9ccc5a2 --- /dev/null +++ b/src/renderer/api/SessionsApi.ts @@ -0,0 +1,122 @@ +import { getRequest, postRequest, patchRequest, deleteRequest, ResponseModel } from '@utils/request' + +// 创建会话 的请求参数和响应数据结构 +export interface CreateSessionRequest { + title?: string + tenant_id_query?: string +} + +export interface CreateSessionResponse { + session_id: string + user_id: string + tenant_id: string + title: string +} + +export const createSession = async (params: CreateSessionRequest) => { + const res: ResponseModel = await postRequest('/nianxx/api/sessions', params) + return res.data as CreateSessionResponse +} + + +// 获取会话列表 的请求参数和响应数据结构 +export interface SessionListRequest { + tenant_id_query?: string + limit?: number + offset?: number +} + +export interface SessionListResponse { + sessions: Array + total: number +} + +export interface SessionListRecords { + session_id: string + user_id: string + tenant_id: string + title: string + status: string + created_at: string + updated_at: string +} + +export const getSessionList = async (params: SessionListRequest) => { + const res: ResponseModel = await getRequest('/nianxx/api/sessions', params) + return res.data as SessionListResponse +} + + + +/// 获取会话消息历史 的请求参数和响应数据结构 +export interface SessionMessagesRequest { + user_id_query?: string + tenant_id_query?: number + limit?: number + offset?: number + session_id: string +} + +export interface SessionMessagesResponse { + messages: Array + total: number +} + +export interface SessionMessageRecords { + id: number + session_id: string + role: string + content: string + source: string + message_id: string | null + created_at: string + timestamp?: number +} + +// 获取会话消息历史 的函数实现 +export const getSessionMessages = async (params: SessionMessagesRequest) => { + const res: ResponseModel = await getRequest(`/nianxx/api/sessions/${params.session_id}/messages`, { + limit: params.limit, + offset: params.offset, + user_id_query: params.user_id_query, + tenant_id_query: params.tenant_id_query, + }) + return res.data as SessionMessagesResponse +} + + + +/// /api/sessions/{session_id} 的请求参数和响应数据结构 +export interface UpdateSessionRequest { + session_id: string + title: string +} + +export interface UpdateSessionResponse { + success: boolean +} + +// 更新会话信息 的函数实现 +export const updateSession = async (params: UpdateSessionRequest) => { + const res: ResponseModel = await postRequest(`/nianxx/api/sessions/${params.session_id}/rename`, { + title: params.title, + }) + return res.data as UpdateSessionResponse +} + + + +/// /api/sessions/{session_id} 的请求参数和响应数据结构 +export interface DeleteSessionRequest { + session_id: string +} + +export interface DeleteSessionResponse { + success: boolean +} + +// 删除会话 的函数实现 +export const deleteSession = async (params: DeleteSessionRequest) => { + const res: ResponseModel = await postRequest(`/nianxx/api/sessions/${params.session_id}/delete`, {}) + return res.data as DeleteSessionResponse +} \ No newline at end of file diff --git a/src/renderer/utils/request.ts b/src/renderer/utils/request.ts index 43799b4..a0709f2 100644 --- a/src/renderer/utils/request.ts +++ b/src/renderer/utils/request.ts @@ -77,6 +77,7 @@ instance.interceptors.request.use( } } + console.log(`🚀 ~ request: \n url:${config.url} \n params:${JSON.stringify(config.data)} \n`) return config }, (error) => { @@ -87,7 +88,7 @@ instance.interceptors.request.use( // 添加响应拦截器 instance.interceptors.response.use( (res) => { - console.log(`🚀 ~ response: \n url:${res.config.url} \n params:${JSON.stringify(res.config.params)} \n data:\n ${JSON.stringify(res.data)}`) + console.log(`🚀 ~ response: \n url:${res.config.url} \n params:${JSON.stringify(res.config.data)} \n data:\n ${JSON.stringify(res.data)}`) // 未设置状态码则默认成功状态 const code = res.data.code || 200 // 获取错误信息 @@ -143,7 +144,7 @@ instance.interceptors.response.use( export const postRequest = (url: string, data?: any, options?: any): Promise => { return instance.request({ url, - method: 'POST', + method: 'post', headers: { 'Content-Type': 'application/json', }, @@ -156,12 +157,38 @@ export const postRequest = (url: string, data?: any, options?: an export const getRequest = (url: string, params?: any, options?: any): Promise => { return instance.request({ url, - method: 'GET', + method: 'get', params, ...(options || {}), }) as Promise } +// 封装基于 request 的 PATCH 请求 +export const patchRequest = (url: string, data?: any, options?: any): Promise => { + return instance.request({ + url, + method: 'patch', + headers: { + 'Content-Type': 'application/json', + }, + data, + ...(options || {}), + }) as Promise +} + +// 封装基于 request 的 DELETE 请求 +export const deleteRequest = (url: string, data?: any, options?: any): Promise => { + return instance.request({ + url, + method: 'delete', + headers: { + 'Content-Type': 'application/json', + }, + data, + ...(options || {}), + }) as Promise +} + export default instance /// 响应模型 diff --git a/src/renderer/views/home/ChatBox.vue b/src/renderer/views/home/ChatBox.vue index 948e0f3..1b745c1 100644 --- a/src/renderer/views/home/ChatBox.vue +++ b/src/renderer/views/home/ChatBox.vue @@ -23,7 +23,7 @@ @@ -31,7 +31,7 @@ diff --git a/src/renderer/views/home/components/ChatNameTime.vue b/src/renderer/views/home/components/ChatNameTime.vue index 3b28e25..dd848ac 100644 --- a/src/renderer/views/home/components/ChatNameTime.vue +++ b/src/renderer/views/home/components/ChatNameTime.vue @@ -1,17 +1,65 @@ \ No newline at end of file diff --git a/src/renderer/views/home/components/ChatRoleAI.vue b/src/renderer/views/home/components/ChatRoleAI.vue index 3ddac92..964db8d 100644 --- a/src/renderer/views/home/components/ChatRoleAI.vue +++ b/src/renderer/views/home/components/ChatRoleAI.vue @@ -1,10 +1,17 @@ @@ -23,6 +30,9 @@ interface Props { const { msg } = defineProps() const md = new MarkdownIt({ + html: true, + linkify: true, + typographer: true, highlight: function (str: string, lang: string) { if (lang && hljs.getLanguage(lang)) { try { @@ -33,6 +43,18 @@ const md = new MarkdownIt({ return hljs.highlightAuto(str).value; } }); + const compiledMarkdown = computed(() => md.render(msg.messageContent)) +const compiledList = computed(() => { + return (msg.messageContentList || []).map((m: string) => md.render(m || '')) +}) + +const compiledAt = (index: number): string => { + const list: string[] = (compiledList as any).value || [] + if (list[index]) return list[index] + const raw = msg?.messageContentList?.[index] || '' + return md.render(raw || '') +} + \ No newline at end of file diff --git a/src/renderer/views/home/index.vue b/src/renderer/views/home/index.vue index 67a674d..24796d2 100644 --- a/src/renderer/views/home/index.vue +++ b/src/renderer/views/home/index.vue @@ -1,43 +1,35 @@ diff --git a/src/renderer/views/home/model/ChatModel.ts b/src/renderer/views/home/model/ChatModel.ts index 1c12a40..3354c76 100644 --- a/src/renderer/views/home/model/ChatModel.ts +++ b/src/renderer/views/home/model/ChatModel.ts @@ -16,6 +16,8 @@ export class ChatMessage { messageRole: MessageRole; // 消息内容 messageContent: string; + // 消息内容列表(用于流式更新) + messageContentList: string[]; // 是否加载中 isLoading?: boolean; // 是否完成 @@ -24,22 +26,28 @@ export class ChatMessage { toolCall?: any; // 问题信息 question?: string; + // 时间戳 + timestamp?: number; constructor( messageId: string, messageRole: MessageRole, messageContent: string, + messageContentList: string[] = [], isLoading: boolean = false, finished: boolean = false, toolCall?: any, - question?: any + question?: any, + timestamp?: number ) { this.messageId = messageId; this.messageRole = messageRole; this.messageContent = messageContent; + this.messageContentList = messageContentList; this.isLoading = isLoading; this.finished = finished; this.toolCall = toolCall; this.question = question; + this.timestamp = timestamp || Date.now(); } }