From 58774d320d98f7f94f868142b31dabc703f71218 Mon Sep 17 00:00:00 2001 From: xs Date: Fri, 29 Aug 2025 17:11:26 +0800 Subject: [PATCH] =?UTF-8?q?1.5.1=E5=89=8D=E7=AB=AF=201=E3=80=81AI=E7=9F=A5?= =?UTF-8?q?=E8=AF=86=E5=BA=93=E7=9A=84=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5?= =?UTF-8?q?=202=E3=80=81AI=E7=9F=A5=E8=AF=86=E5=BA=93=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E7=9A=84=E4=B8=8A=E4=BC=A0=E3=80=81=E8=A7=A3=E6=9E=90=E3=80=81?= =?UTF-8?q?=E5=90=91=E9=87=8F=E5=8C=96=E3=80=81=E9=A2=84=E8=A7=88=E3=80=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=203=E3=80=81=E6=A3=80=E7=B4=A2=E7=9F=A5?= =?UTF-8?q?=E8=AF=86=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/ai/base/aiApp/index.ts | 178 +++++ src/api/ai/skill/aiKnowledgeBase/index.ts | 143 ++++ src/api/ai/skill/aiKnowledgeBase/types.ts | 232 +++++++ src/api/ai/skill/aiKnowledgeContent/index.ts | 77 +++ src/api/ai/skill/aiKnowledgeContent/types.ts | 206 ++++++ src/assets/PDF.png | Bin 0 -> 9479 bytes src/assets/document.png | Bin 0 -> 2697 bytes src/assets/docx.png | Bin 0 -> 8331 bytes src/assets/icons/svg/knowledge-base.svg | 1 + src/assets/knowledge-base.png | Bin 0 -> 2864 bytes src/router/index.ts | 58 +- src/views/ai/base/aiApp/aiAppConfig.vue | 522 +++++++++++++++ src/views/ai/record/tokenUsage/index.vue | 621 ++++++++++++++++++ src/views/ai/record/usageRecord/index.vue | 383 +++++++++++ src/views/ai/skill/aiChat/index.vue | 289 ++++---- src/views/ai/skill/aiForm/index.vue | 157 +++++ src/views/ai/skill/aiKnowledge/index.vue | 618 +++++++++++++++++ .../skill/aiKnowledge/knowledgeBaseCreate.vue | 116 ++++ .../ai/skill/aiKnowledge/knowledgeContent.vue | 496 ++++++++++++++ .../aiKnowledge/knowledgeContentPreview.vue | 319 +++++++++ .../aiKnowledge/knowledgeContentUpload.vue | 436 ++++++++++++ src/views/ai/skill/aiSql/index.vue | 341 ++++++++++ 22 files changed, 4998 insertions(+), 195 deletions(-) create mode 100644 src/api/ai/base/aiApp/index.ts create mode 100644 src/api/ai/skill/aiKnowledgeBase/index.ts create mode 100644 src/api/ai/skill/aiKnowledgeBase/types.ts create mode 100644 src/api/ai/skill/aiKnowledgeContent/index.ts create mode 100644 src/api/ai/skill/aiKnowledgeContent/types.ts create mode 100644 src/assets/PDF.png create mode 100644 src/assets/document.png create mode 100644 src/assets/docx.png create mode 100644 src/assets/icons/svg/knowledge-base.svg create mode 100644 src/assets/knowledge-base.png create mode 100644 src/views/ai/base/aiApp/aiAppConfig.vue create mode 100644 src/views/ai/record/tokenUsage/index.vue create mode 100644 src/views/ai/record/usageRecord/index.vue create mode 100644 src/views/ai/skill/aiForm/index.vue create mode 100644 src/views/ai/skill/aiKnowledge/index.vue create mode 100644 src/views/ai/skill/aiKnowledge/knowledgeBaseCreate.vue create mode 100644 src/views/ai/skill/aiKnowledge/knowledgeContent.vue create mode 100644 src/views/ai/skill/aiKnowledge/knowledgeContentPreview.vue create mode 100644 src/views/ai/skill/aiKnowledge/knowledgeContentUpload.vue create mode 100644 src/views/ai/skill/aiSql/index.vue diff --git a/src/api/ai/base/aiApp/index.ts b/src/api/ai/base/aiApp/index.ts new file mode 100644 index 0000000..42e0fa9 --- /dev/null +++ b/src/api/ai/base/aiApp/index.ts @@ -0,0 +1,178 @@ +import request from '@/utils/request' + +// AI聊天消息接口 +export interface ChatMessage { + role: 'user' | 'assistant' | 'system' + content: string + timestamp?: number +} + +// AI聊天请求参数 +export interface ChatRequest { + messages: ChatMessage[] + model: string + temperature?: number + top_p?: number + max_tokens?: number + stream?: boolean + api_key?: string + api_endpoint?: string +} + +// AI聊天响应 +export interface ChatResponse { + id: string + object: string + created: number + model: string + choices: Array<{ + index: number + message: ChatMessage + finish_reason: string + }> + usage?: { + prompt_tokens: number + completion_tokens: number + total_tokens: number + } +} + +// 流式响应数据 +export interface StreamChunk { + id: string + object: string + created: number + model: string + choices: Array<{ + index: number + delta: { + content?: string + role?: string + } + finish_reason: string | null + }> +} + +// 发送聊天消息(非流式) +export function sendChatMessage(data: ChatRequest) { + return request({ + url: '/ai/chat', + method: 'post', + data + }) +} + +// 发送聊天消息(流式) +export function sendChatMessageStream(data: ChatRequest): ReadableStream { + return new ReadableStream({ + start(controller) { + const eventSource = new EventSource(`/ai/chat/stream?${new URLSearchParams({ + messages: JSON.stringify(data.messages), + model: data.model, + temperature: data.temperature?.toString() || '0.7', + top_p: data.top_p?.toString() || '1', + max_tokens: data.max_tokens?.toString() || '2048', + api_key: data.api_key || '', + api_endpoint: data.api_endpoint || '' + })}`) + + eventSource.onmessage = (event) => { + try { + if (event.data === '[DONE]') { + controller.close() + eventSource.close() + return + } + + const chunk: StreamChunk = JSON.parse(event.data) + controller.enqueue(chunk) + } catch (error) { + console.error('解析流式数据失败:', error) + } + } + + eventSource.onerror = (error) => { + console.error('流式请求错误:', error) + controller.error(error) + eventSource.close() + } + } + }) +} + +// 获取聊天历史 +export function getChatHistory(params?: { + page?: number + size?: number + chatId?: string +}) { + return request<{ + total: number + list: Array<{ + id: string + title: string + messages: ChatMessage[] + createdAt: string + updatedAt: string + }> + }>({ + url: '/ai/chat/history', + method: 'get', + params + }) +} + +// 保存聊天记录 +export function saveChat(data: { + title: string + messages: ChatMessage[] +}) { + return request<{ id: string }>({ + url: '/ai/chat/save', + method: 'post', + data + }) +} + +// 删除聊天记录 +export function deleteChat(chatId: string) { + return request({ + url: `/ai/chat/${chatId}`, + method: 'delete' + }) +} + +// 更新聊天标题 +export function updateChatTitle(chatId: string, title: string) { + return request({ + url: `/ai/chat/${chatId}/title`, + method: 'put', + data: { title } + }) +} + +// AI问答设置接口 +export interface AiChatSettings { + welcomeIcon: string + welcomeTitle: string + welcomeMessage: string + presetQuestions: string[] + historyCount: number +} + +// 获取AI问答设置 +export function getAiChatSettings() { + return request({ + url: '/ai/chat/settings', + method: 'get' + }) +} + +// 保存AI问答设置 +export function saveAiChatSettings(data: AiChatSettings) { + return request({ + url: '/ai/chat/settings', + method: 'post', + data + }) +} diff --git a/src/api/ai/skill/aiKnowledgeBase/index.ts b/src/api/ai/skill/aiKnowledgeBase/index.ts new file mode 100644 index 0000000..1bfcc0b --- /dev/null +++ b/src/api/ai/skill/aiKnowledgeBase/index.ts @@ -0,0 +1,143 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { AiKnowledgeBaseVO, AiKnowledgeBaseForm, AiKnowledgeBaseQuery } from '@/api/ai/skill/aiKnowledgeBase/types'; + +/** + * 查询AI知识库列表 + * @param query + * @returns {*} + */ + +export const listAiKnowledgeBase = (query?: AiKnowledgeBaseQuery): AxiosPromise => { + return request({ + url: '/ai/aiKnowledgeBase/list', + method: 'get', + params: query + }); +}; + +/** + * 查询AI知识库详细 + * @param knowledgeBaseId + */ +export const getAiKnowledgeBase = (knowledgeBaseId: string | number): AxiosPromise => { + return request({ + url: '/ai/aiKnowledgeBase/' + knowledgeBaseId, + method: 'get' + }); +}; + +/** + * 新增AI知识库 + * @param data + */ +export const addAiKnowledgeBase = (data: AiKnowledgeBaseForm) => { + return request({ + url: '/ai/aiKnowledgeBase', + method: 'post', + data: data + }); +}; + +/** + * 修改AI知识库 + * @param data + */ +export const updateAiKnowledgeBase = (data: AiKnowledgeBaseForm) => { + return request({ + url: '/ai/aiKnowledgeBase', + method: 'put', + data: data + }); +}; + +/** + * 删除AI知识库 + * @param knowledgeBaseId + */ +export const delAiKnowledgeBase = (knowledgeBaseId: string | number | Array) => { + return request({ + url: '/ai/aiKnowledgeBase/' + knowledgeBaseId, + method: 'delete' + }); +}; + + +/** + * 下拉框查询AI知识库列表 + * @param query + * @returns {*} + */ +export function getAiKnowledgeBaseList (query) { + return request({ + url: '/ai/aiKnowledgeBase/getAiKnowledgeBaseList', + method: 'get', + params: query + }); +}; + + + + +/** + * 知识库文件上传切分后向量化 + * @param data 知识库切片内容 + */ +export const vectorizeKnowledgeContent = (data: FormData) => { + return request({ + url: '/ai/aiKnowledgeBase/vectorizeKnowledgeContent', + method: 'post', + data: data + }); +}; + +/** + * 获取AI知识库内容列表 + * @param query + * @returns {*} + */ +export function listAiKnowledgeContent (query) { + return request({ + url: '/ai/aiKnowledgeBase/listAiKnowledgeContent', + method: 'get', + params: query + }); +}; + + +/** + * 删除AI知识库内容,连同向量库内容一同删除 + * @param knowledgeBaseId + * @param knowledgeContentId + */ +export const delAiKnowledgeContent = (knowledgeBaseId: string | number ,knowledgeContentId: string | number | Array) => { + return request({ + url: '/ai/aiKnowledgeBase/deleteKnowledgeContent/' + knowledgeBaseId + '/' + knowledgeContentId, + method: 'post' + }); +}; + + +/** + * 删除知识库内容文件 + * @param knowledgeContentId + */ +export const removeContentFile = (knowledgeContentId: string | number) => { + return request({ + url: '/ai/aiKnowledgeBase/removeContentFile/' + knowledgeContentId, + method: 'post' + }); +}; + +/** + * 获取AI知识库内容分段列表 + * @param query + * @returns {*} + */ +export function getKnowledgeContentFragmentList (query) { + return request({ + url: '/ai/aiKnowledgeBase/getKnowledgeContentFragmentList', + method: 'get', + params: query + }); +}; diff --git a/src/api/ai/skill/aiKnowledgeBase/types.ts b/src/api/ai/skill/aiKnowledgeBase/types.ts new file mode 100644 index 0000000..9210314 --- /dev/null +++ b/src/api/ai/skill/aiKnowledgeBase/types.ts @@ -0,0 +1,232 @@ +export interface AiKnowledgeBaseVO { + /** + * 主键 + */ + knowledgeBaseId: string | number; + + /** + * 知识库名称 + */ + knowledgeBaseName: string; + + /** + * 知识库图标 + */ + knowledgeBaseIcon: string; + + + /** + * AI模型ID,关联ai_model + */ + modelId: string | number; + + /** + * 知识库类型ID,关联ai_knowledge_base_type + */ + knowledgeBaseTypeId: string | number; + + /** + * 分隔符 + */ + knowledgeBaseSeparator: string; + + /** + * 知识库中检索的条数 + */ + retrieveLimit: number; + + /** + * 文本块大小 + */ + textBlockSize: number; + + /** + * 重叠字符数 + */ + overlapCharacter: number; + + /** + * 提问分隔符 + */ + questionSeparator: string; + + /** + * 知识库描述 + */ + knowledgeBaseDesc: string; + + /** + * 状态(1启用,0禁用) + */ + knowledgeBaseStatus: string; + + /** + * 向量库(milvus) + */ + vector: string; + + /** + * 是否公开(1是,0否) + */ + openFlag: string; + + /** + * AI模型名称 + */ + modelName: string; + + /** + * AI知识库类型名称 + */ + knowledgeBaseTypeName: string; + +} + +export interface AiKnowledgeBaseForm extends BaseEntity { + /** + * 主键 + */ + knowledgeBaseId?: string | number; + + /** + * 知识库名称 + */ + knowledgeBaseName?: string; + + /** + * 知识库图标 + */ + knowledgeBaseIcon?: string; + + /** + * AI模型ID,关联ai_model + */ + modelId?: string | number; + + /** + * 知识库类型ID,关联ai_knowledge_base_type + */ + knowledgeBaseTypeId?: string | number; + + /** + * 分隔符 + */ + knowledgeBaseSeparator?: string; + + /** + * 知识库中检索的条数 + */ + retrieveLimit?: number; + + /** + * 文本块大小 + */ + textBlockSize?: number; + + /** + * 重叠字符数 + */ + overlapCharacter?: number; + + /** + * 提问分隔符 + */ + questionSeparator?: string; + + /** + * 知识库描述 + */ + knowledgeBaseDesc?: string; + + /** + * 状态(1启用,0禁用) + */ + knowledgeBaseStatus?: string; + + /** + * 向量库(milvus) + */ + vector?: string; + + /** + * 是否公开(1是,0否) + */ + openFlag?: string; + +} + +export interface AiKnowledgeBaseQuery extends PageQuery { + + /** + * 主键 + */ + knowledgeBaseId?: string | number; + + /** + * 知识库名称 + */ + knowledgeBaseName?: string; + + /** + * AI模型ID,关联ai_model + */ + modelId?: string | number; + + /** + * 知识库类型ID,关联ai_knowledge_base_type + */ + knowledgeBaseTypeId?: string | number; + + /** + * 分隔符 + */ + knowledgeBaseSeparator?: string; + + /** + * 知识库中检索的条数 + */ + retrieveLimit?: number; + + /** + * 文本块大小 + */ + textBlockSize?: number; + + /** + * 重叠字符数 + */ + overlapCharacter?: number; + + /** + * 提问分隔符 + */ + questionSeparator?: string; + + /** + * 知识库描述 + */ + knowledgeBaseDesc?: string; + + /** + * 状态(1启用,0禁用) + */ + knowledgeBaseStatus?: string; + + /** + * 向量库(milvus) + */ + vector?: string; + + /** + * 是否公开(1是,0否) + */ + openFlag?: string; + + /** + * 日期范围参数 + */ + params?: any; +} + + + diff --git a/src/api/ai/skill/aiKnowledgeContent/index.ts b/src/api/ai/skill/aiKnowledgeContent/index.ts new file mode 100644 index 0000000..ecf6e0c --- /dev/null +++ b/src/api/ai/skill/aiKnowledgeContent/index.ts @@ -0,0 +1,77 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { AiKnowledgeContentVO, AiKnowledgeContentForm, AiKnowledgeContentQuery } from '@/api/ai/aiKnowledgeContent/types'; + +/** + * 查询AI知识库内容列表 + * @param query + * @returns {*} + */ + +export const listAiKnowledgeContent = (query?: AiKnowledgeContentQuery): AxiosPromise => { + return request({ + url: '/ai/aiKnowledgeContent/list', + method: 'get', + params: query + }); +}; + +/** + * 查询AI知识库内容详细 + * @param knowledgeContentId + */ +export const getAiKnowledgeContent = (knowledgeContentId: string | number): AxiosPromise => { + return request({ + url: '/ai/aiKnowledgeContent/' + knowledgeContentId, + method: 'get' + }); +}; + +/** + * 新增AI知识库内容 + * @param data + */ +export const addAiKnowledgeContent = (data: AiKnowledgeContentForm) => { + return request({ + url: '/ai/aiKnowledgeContent', + method: 'post', + data: data + }); +}; + +/** + * 修改AI知识库内容 + * @param data + */ +export const updateAiKnowledgeContent = (data: AiKnowledgeContentForm) => { + return request({ + url: '/ai/aiKnowledgeContent', + method: 'put', + data: data + }); +}; + +/** + * 删除AI知识库内容 + * @param knowledgeContentId + */ +export const delAiKnowledgeContent = (knowledgeContentId: string | number | Array) => { + return request({ + url: '/ai/aiKnowledgeContent/' + knowledgeContentId, + method: 'delete' + }); +}; + + +/** + * 下拉框查询AI知识库内容列表 + * @param query + * @returns {*} + */ +export function getAiKnowledgeContentList (query) { + return request({ + url: '/ai/aiKnowledgeContent/getAiKnowledgeContentList', + method: 'get', + params: query + }); +}; diff --git a/src/api/ai/skill/aiKnowledgeContent/types.ts b/src/api/ai/skill/aiKnowledgeContent/types.ts new file mode 100644 index 0000000..15827b3 --- /dev/null +++ b/src/api/ai/skill/aiKnowledgeContent/types.ts @@ -0,0 +1,206 @@ +export interface AiKnowledgeContentVO { + /** + * 主键 + */ + knowledgeContentId: string | number; + + /** + * 知识库ID,关联ai_knowledge_base + */ + knowledgeBaseId: string | number; + + /** + * 标题 + */ + contentTitle: string; + + /** + * 内容方式(1上传文件,2手动录入) + */ + contentWay: string; + + /** + * 内容(暂时不存,只存内容片段) + */ + description: string; + + /** + * 文件名称 + */ + fileName: string; + + /** + * 文件路径 + */ + filePath: string; + + /** + * 文件类型 + */ + fileType: string; + + /** + * 文件大小(byte) + */ + fileSize: number; + + /** + * 内容状态(1已完成,2失败(解析或向量失败等),3待解析) + */ + contentStatus: string; + + /** + * 重叠字符数 + */ + overlapCharacter: number; + + /** + * 总共片段 + */ + totalChunk: number; + + /** + * 创建时间 + */ + createTime: string; + + /** + * 更新时间 + */ + updateTime: string; + +} + +export interface AiKnowledgeContentForm extends BaseEntity { + /** + * 主键 + */ + knowledgeContentId?: string | number; + + /** + * 知识库ID,关联ai_knowledge_base + */ + knowledgeBaseId?: string | number; + + /** + * 标题 + */ + contentTitle?: string; + + /** + * 内容方式(1上传文件,2手动录入) + */ + contentWay?: string; + + /** + * 内容(暂时不存,只存内容片段) + */ + description?: string; + + /** + * 文件名称 + */ + fileName?: string; + + /** + * 文件路径 + */ + filePath?: string; + + /** + * 文件类型 + */ + fileType?: string; + + /** + * 文件大小(byte) + */ + fileSize?: number; + + /** + * 内容状态(1已完成,2失败(解析或向量失败等),3待解析) + */ + contentStatus?: string; + + /** + * 重叠字符数 + */ + overlapCharacter?: number; + + /** + * 总共片段 + */ + totalChunk?: number; + +} + +export interface AiKnowledgeContentQuery extends PageQuery { + + /** + * 主键 + */ + knowledgeContentId?: string | number; + + /** + * 知识库ID,关联ai_knowledge_base + */ + knowledgeBaseId?: string | number; + + /** + * 标题 + */ + contentTitle?: string; + + /** + * 内容方式(1上传文件,2手动录入) + */ + contentWay?: string; + + /** + * 内容(暂时不存,只存内容片段) + */ + description?: string; + + /** + * 文件名称 + */ + fileName?: string; + + /** + * 文件路径 + */ + filePath?: string; + + /** + * 文件类型 + */ + fileType?: string; + + /** + * 文件大小(byte) + */ + fileSize?: number; + + /** + * 内容状态(1已完成,2失败(解析或向量失败等),3待解析) + */ + contentStatus?: string; + + /** + * 重叠字符数 + */ + overlapCharacter?: number; + + /** + * 总共片段 + */ + totalChunk?: number; + + /** + * 日期范围参数 + */ + params?: any; +} + + + diff --git a/src/assets/PDF.png b/src/assets/PDF.png new file mode 100644 index 0000000000000000000000000000000000000000..ee947e32371faa153cee16c55fa29885f1915875 GIT binary patch literal 9479 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 Z|36yli^%Ovk+}c>002ovPDHLkV1f#gxz_*y literal 0 HcmV?d00001 diff --git a/src/assets/document.png b/src/assets/document.png new file mode 100644 index 0000000000000000000000000000000000000000..53cf297228a55ad6577cfd1e89cab59691340f10 GIT binary patch literal 2697 zcmdT`dpK0<8lSRgjZH>w&BV5vCR1)jAx;_-!wk73W5{IN9c7ykBPvNOw#%SBMx&Bj zDMH32_ek2v=%S&BNUqbxr4S0W*R-GKob%WD=j`X4=lrqO`@FyRd*Ai@e((Ez&q{D| zu#uO=$)Zpwc^cKq8L@4W2b4kH#cqNu#HJSQ`!S(y|} zoX-JeigJswtMYzjMMa90m9jm>N|BQCie^8YpEu|i(ELUGWBMzHcSa{Z)zesgB}T~tlP9%WjIqG9O05R(%UR?kp@>wh zNx96%NGN(|y5U0*`X9MFRYp4<>NOr!wO2W~s;m|Ts87W;Xdf#c!h_|p_K)?^v^2aW zcf$8z7eFw*T?Urt&3d}1@^-`WWR8|^aw>N;Y8>B&>j(?-rLr|OU}Z;9IuS2?<^{OV znx5px5x`+wjv{Z(#TX^;n2ihFyGjv6BWwT68a_a_#(uzstlg4u0TN9>R(B5M_V9b+ z^F2SfEq@bccZF-7cMqSO8`NVvupQ4$*4L+&XsnpL_|zU^Uf1u%YeTaaj@B41VZc3J z!GD`7w&HF|j{7Wa11Me?x}{g*!i^%3F~C;h_IorK8XFPOj}D>P9gmEezuu}vIHaGC z;MoBQB0;QI^`i;6h-Z`rkeR6>M|J`fXJYxHKbhoSG5Bc0fMIk@8x7awUCSPICabFW zO|@$3IS_>-0#3KnIv~j2iX{AztVOFDQBciG9Yr(f$FwBNuV#CfK#8`VFU}7>$UT?3 z`)#3LGD4__Fqg`-B_%2hyo9B-r|fSephVa`dN~kDHt)obIC!;UqX3 z!SkTRLjB3+xh){I$f$NC_HWs>!N zB%vN~*>m8_<_P6!dtUwUHBo^CXOV=(fN4a?``^z5@kZ%tDQh>AF$|j}TENye_G6b-8vhBRF2e)~=(Wwg>kbGfsncfa68G6in5V7~7NE8{g@w$;tjjA$jvlXh za{@2f>kCKrHbkzvPl7|29C#*&V$8V66lhEkYl-AMMzx^jq$SrT4PK1L6O$FMZE{tQyS{20VUt!77GzuHRucl>ctY{<2-Nl<1Fu?k#c`cthbaHzXn%31|TE% zvdK>;L>f?p`F$?K$Th}Idg~O;-;cX$2j2XYp`)5x@4Oo1MR~}(TKmSZ;YA-5d0Fnc ztJ8Z^hHfQVX>c3tz0>K>V9QJg3SPt(7Uy&a3*1;rT6cc}gumqAZY6bsW1O+L$GY*%?mk^+Z)ZdSnuJ8BOX*k4+VP$c9=u}TeXH(k(4 zJ12u_?r`##uFMKy4Bc;XP<-~)K3SHz<~*meR-?pYdr!Vu zfxOShh}=nyskkHA*8ECc*!wjL{R7z$_bY@g)s8h*_3kkH3|4WdV)w$~HNI67r_mWH zC2knB0} zH9jO2a(N1!X2I27Fa8N2kNbpoD`Bq7FHGd)smA5nXwX@DWH}LPTTU`1_iY!eBOUYj>xzHbnr|7OP7)QrEmTta-AU{BY@7btrLbVhAM`lZJIkArUrL=@ z=Qg^ChNv=@-$kp7i9Fb0N?t$4UuVIU>;F?LrRKjvNHOPz@z29c6mF7CVN?5-WG8{! zSF8nwWLc^5EbNJjo&Wvjg+vG|@A7?6m}Sd5BB6*_mX2g#()wZ&rqvLkZ_4Q8?%Z2@ z`13y|=5s0IR?8K}11}GjRQKV=jeV;$bGjnK5v8xZOfe~Om^3}Ul!|Dt4nG?+eaQk1 zH}nOo1?Ym=`!Dr{?$MNJUxPHF#nzulq-qz`1%b{N#ePK_+x&hxbN6r%e7#D8>`Z%} zJo3*5WkCK+sj>SKPj5;Axp z_SfzSW5tKYDLnOkdOHo?x#glw`sITiaV!3wd6n|30O4!F_q|=jAg6!`{vVx?f7@97 zlP#R4fSdBtODn%w#D|)@eTmDrz8!tXPlWtiqG%KcE5Tkb_z!Nl#ex6; literal 0 HcmV?d00001 diff --git a/src/assets/docx.png b/src/assets/docx.png new file mode 100644 index 0000000000000000000000000000000000000000..23af3a1133a7146eeed88ea0199a3b18b5e5670e GIT binary patch literal 8331 zcmcJV^;=Xy+s7AJ1XQ|97NikDTDq1F1$LK`1_?=#ZjdhN2A2|+k`Sb&1O$O41(uGb zyTfT!;BpSE5tNm{ zxupYC+al{Bjrb}g`Z%M>02$mRE|7QF{MyuZ*H(f`>^oj{gOp!bBTv{;uw3dVKBYF|yJKNba}1>ue=II8`AS3D z1KYWHFfRyTaJHWrGypc!1S5hkSt?7U#0+AS$$FS7(m#n!16psa`gRw2vD-ocQV%&^ zY7wW{llMw8%iRWThO8L*a@f(Afn_5BEfG73PW0Li#vzw-Z-O~Vn(J1mf)^BmUQU>+ z#!+5o0J$QLxO)5y4y^5;e#5s?2#V6G#NA&va&T5iRHJE2pq;jPZ`tq+yDbJlx?oD! zdhjmq2Nf`ru_Aw2e4p2BccR5^wx1W9mJ}q($Z^z~x?F#w%==D`#1stsQ#K#FWY_=) zximl*25;8u1gHTYIwkh!##`wQ1`@*ddO2ak`EJVnrIGkoLfR8Ng8-B8ea zfpkKo({ueK5ylu<8(_v&q@jMZbqYv55}h+NRRISVnBnuETs71Pb^P;%01R>K$Nzg) z5P!ZfwNd5_uhl{Rh%fuA)dyZ|uwtkA1)(0ayOb6 zS_SAd%d1zwDiwlb9Dp*VkX&{exPTVu#A@1$z{>j*ONnqG+ zBr7VwaTp)O!%|Q5bE$_ujK-Mc@TN*qi7{TUmTW62C@`iFq6$qOCXCnPA7h4G|H}py z7~vm3&ge+NwPepy?UblRd+2W}@&C2zqG5PzX)wdeT=X~pKAjWoGEa8VfqOE|`Y_un z>YlQbM{sN7%LFe_buQ{jCC-5_a^8 zOp1%RpU2=$bA0SizTmPQC8RS=$l$>RTbMgAHA7+3daCm(^?!F8B-qDIo5>1LEm*G# zX(9uV>0EB4p2H)w;#_0jFCER@%@7LB)(4G>+(KAh(J^D*3f8_ z!P(sBpF^7yUC6gZ?YI2b>`lH451OMv!0R?$H=AdsvfApwyok#u*asYwJ3+UahTfW* z>Nn=6uld_&gJc}W!7xjQV9#73JDJF8 zz|qfQAIEeKX&7GdN!HPvO#cllLp9LSP|(A$ME#Ug)AJk=kaZ7RDP)+~B>i+*XtJWf zJ@)~KwW`DDQ>sdSgcqI=v1-gV>Chp`R1VqtZF6^RUjH~2C#zwc%)hJg!;-(O{T%EJ z49Mk~bSU<_APqxvh`aPUmhn8A?jVS7Nh08LWHZzJ!`|#1u_#gJ+@3NeYK<4f)RT|n z3ag-em#scEkcR$??PXLqvsSj~4^*v-`7<4(CTs@}pg|GzG3&H>43Mw#OpdBIz7q0> zgrN1={Yvc=cwa0%DWc>}&e$jRN(iG{WEyAlsZ85b3n3XZnCztF3%@E4z>?O+%pkX9dnr>t9WRn9} z&33OwjQRd(G7;e4OD>kt(Yrvzl*%NfYny`q5-u^F)TT!;Vz-+>7F>0VP~sm@mB1^@ z*kylcdAcMU)^*TT-~v~kh`(@#XA-(W^<3G|+j(Rh#uiI0aAKAxlKlmx6o>6{{I*QEG`o7lFvZ7U;teCZ$C@h1O8LZDsEK5337`0fWp;S`3RUamB^Q zL^nRN=Xd%~Dwq@rqC}m(2_=xOqBIhD>W{TPg)Bv!;hGsfn{;UKOZ!+iU?DEHwAHQU zCX>-(Rmi?r3b9)pSXsC}NadG~$V^u`n`K^X05Xr>LDu)5;(jKZBDO4so5^)m_zzI z7&+@nxF}_@gtg4Xa}tg-1u;3ig~{YWVW&&9c%|ej&g;9-?z-e2T7j=9ds>gA%!Xj; zG3W&M#ta49A_~ZS8%5^1Xs@EJ0x0{kZ19+) z%}zXk)I}ZQt(@^-1%du^#@Af^#ve<{p^Ds;$fX2FzeJin*>dTZ@OqSJOj`Hlla+nc zM-&Q(B^yQz!8tHWCLEm#yny&q$}-+VG|A11Lv?J){szZf3BRV03Fe&De96`DQ$0iFK*;zHR<}(k zPBY5NY!i4E$_Q^+YHEK1T5Yp^j~&of=h}R+&K_V064a=YC~QttYyom}OXvQeZUp7c zYj{Y>0Rmp(EyNO@6^Kkl3bZya!zdMrE7$Xf{q*-7h1w*1y7|$T!t2pQidW|Dcr+1o zUCE6ZQ-cVVxDs+QK+jLN;()AA2UsCRTSsz+sfsNMqD~t;Qus^O!+?p{D)%=9aJU1_ zC4W%0{kp%#N()(^I?_NUN-Ln&Jqo(d!FKMK>Qoy$PFoFAJ)Py9BL^~<;7*QGR@Yyb z*KIzEbg>XVj9vW2!`;ru+t*nziD^iC{w==`2hF1M1>wYD`e%GFTV%XN7qK{5b*G&( ziJ};}P*xzgcT;f2YfLjJJD5|7y5;w?@s-Cv{nAm3k_^g);SIAu9fuh4}bI`r+)X*lTg?FOTEQT(K% z7bfkIjfI;lrtWJ}>0A?^5gK?C#4B~Oem~f~OSE@J?<&gf@#TKAv%GFIjketQ1ZqjA>pdcrt#At^^vyB;5&1qc zm_s}t6?JW9P(GT{eQDYAY_@K4|7fQYR-sgX`ie>7<~gC=xNkFoE#n`x;nTV^ZHb$T zd+te1i+AsgN-ujWt#4*fT815s72Cw5wtVCrFZ(OvrdnE1{?d1H77lfP#G?$At$a5L zlB5&xKwfxeE9z?bN9Onb&}+g?niBmUCN{fgU%q0`|fNq{_$_QbPNnWZ=6_8J$>O24y7S#Ar7TA9=|Fnaq; zC%s~U1^ zHIJ|Z>7$_g8G13T-#yY?jd-Im=O>{_fxyhp`cia*Mw0JBZJSb}(BIXDV?_zrFRTM4 zinmoI&#`hds2~cSoq9iEN3?*z06%Z%fmn+0N~V&d_`w$^!wog=MT*rj`i*!J z3vEMhjPKkKVLtI7MR#jqm%1EZtwu-(M4-UHs<@YSkh?iID3E3ZmPWknM$?vUIKP@8 z7mArKbkS*$Q*&%LuAFr1ceUu#CvvjHfA@(KhHra|TVl57pdn}h_DDogzihGc^~|3+ zckX7_fPmH0D$(G4TdU@2FCX9ikGIIpzYL`jL-&SM9p8mWJ1Xf?_64R@M)H+SZ9;6x zOL_u$tbF4^T=*Kd#0>>0RN^A-w;*vkpsNwCC0-nrTT@AiB;2k^Rq20ur&@rX^ZRgq4u{DCvsu19%rT$TrbWZOoKTw~@6MG3Iyt5QW_ zK7}{s0eG^N;(Djp@9VXBbDn1|XmSvF2==d18+yZ6T&#PgnW<7W1R@KW4sa)6T)P@U1+rClM3qBV>L@8hO;`oCe$~n zfY^QB>cngm$vwBYy58*KZB$Kgt@Z$tH;=k*H2i4>?+kgg6`L``5j|dc6KIJpbm;L( z0|69oa_^5RqL9%?-5dC+y!y^n8uLDa(3;!hM+bRotfuxmRcl?JMNBk`BC3z zx`E62C+7=8v$VCT^J*lh&afO}%A>;Sg;kJ&*i%F>$2Rs3;#wO(1~X>j6Y*G~Z3wm_RDFetcRvBS3_3UbOx9`X2&=_YC@_0i?} zt^BP7$+uq{E`q#WsuSvj8vbvYP7loB9iCA$mG5NI3%P}POR6u!FY$)LI4 z!xyG$XHMpDU5DW8G>CA!AH?+Gs9fK}Rf2~O4@9H8UHyphtL*NsY zcU4D5tS$JmmDrT#^mzJ~aJ}P)s=!P0tbhl=h z^$0m|Vn$BFp$xvsCaTF68J@v!1Q!h7!bDz7(S6xsiMio+G%lCzMBFudl77Om-`N zQAEon_POhYQ}vkNa@kN#b}%x^*qG=&QtuN~prriE6WWn7eff4^8g`bC!|IeU9Ck5* z?VR1^vASOSRm^x+KSdF-?`@u3nu|>eG_B@75F-$4U-4JYYEqd{vbuUzsg|^bYHi_) z@|?VuJB5%)bE~Cw?wGoGQV3HLZod~zVQhx1m8ySyq(BnH6t_HVSjLHBbMU(|zXfK1 z9~nHpE$`cR!smMNA*FXD>|0dcM6d+(>vz{lf!tqjE0CXeeM{lnIFAMFjqRgNOV=JM zCieNJH6cyG;6;lioFptze;%~Gyn_(*`V&E&mzDO{JLzEwjk)J04mQ4e(b9<28@s6Z z(~6iLj~43~Fv%!crSaG&LsPIFWm5f8-4z%k)APP+X*oQf>-nicJtcqf?4*;Pw=g1O zm|7*%%Y>Jcw&Qtm?=smj^2r%5PdxKLqro2w(lFO_B5Nt(!I-N_iry_Qg>jx^W6uQZ zM+06;gT#f_W(;QAo%-=L#&`?Cea9F(B_H;T`>?Iooii#u^P8*6D!O;Yg?t(IECjG) z5&yROaVd)LyPcJku+?}=9p%BU&aJ*W)e!z!2I>urTY$Z(=JvM$CWt88rFd`Jn~pPo zbbp$3l&=QFO3Z;n^1r-lC`#iE#d9dPGIpyYQ{)hks|OnkG$Emn;{L2#2MWwEPX%QWZs3|Gn=;(C_*M>w@0@VE#+&zdz(VK zhez*C*!(F-)f1T9jR(b3>&s^Ns9hSn^$k|(1;o1R%G_xE(EIX~Lzi>hw4ITpLnT=> z)z27j|2h4&5e>E0A*9)77!G$Xadl29RBmtsKXRj_%pY7*=Qvle`xKe3ZgCWPZ2-Df zf2tGZmOe<82#RZFI;aR=C=zxSWg<_`Ek)LGw6EX}$kJ!N z3QC`^uJ{&$b0I&T@lVPTE~S=;w}D_PA%I)UN;UY#`GZN(B+l{!kBgPPp;FJeX-!pQ z#0>1UxGTR?J|%~iO{M-sI#fZZ+2_01ydnWr5{O>wYo#{4$=GNjT?8T8?nha?$Qvje z-<8mC9INVCv(iDYWO-46mRb;-;l=&iNWA|T|n*vf)v3E8mkOO@l2!TLJAh$u(K0DR!4&tS+B3EecYLkYZKQ6 zVJ(+=SBv{nu|HQVpDB1wsNs{=!Ef3MSWXy}Mq*g?Ke4yfyilp6jRgL6CA8|xwSOAp z*vsO1H$iYfND&hYHF{LaC+(}V1=;J;Ov zg|c@5c9sqBxv|lHGX}k9p@_(CuGW`Dxy~O)V+rJq@ZsG~D;_b4w3yqAANq}Fdl%VT z8cMSGx{B$(og1uly_px~&DVC&(7ZJFW6zLjR5dX+5t1fea%{KMxbti=9?J*GCgqgi z-LU`htY7EHta_k~#guzQ{R2qehrqgdNut9al!G_gx+ph&nUsuunooaop?P1LaxgNy zXl+j8?kvlAnLxfX5Sn@+H_-WRL07?WteY6FE=!Wy|EWi$?AgC8S6`blkywIf^v;p9 zZcEQ)wLQA+tq#*u?6?(|wGvETN%Mn`X4NH-`I@p$P?^W4&)tRF{8Y}yPcZeMo5{3Y z@2=7nWh(P!kr2KS)1CRCrGepun=wrhynYMvVX5r=U7$Uga+5w?scONg=Gs(tONi`$ zb4@|>$Lm52P?-vQ(FVK0^Y%#UQ7AdCOnT4Y`5QBKPUDi|Wt~fEnyK}6#_iG7z)PU+ zl}QTEExFa2#7dW;J{hIxA>{N~2H%wVfS+$v^a$YcB)5YUJw!+-!zU0|NYxEKRC544? zsltK2F15Art$7H!+I9X7E;o_ry6IPdqKmO9@hijlK6LpPv`6?2S0%cX{o&o_N&G(=~Tv_%|; zbP3=W{L8*2=SIBBu@_KwPtz7IcmKbx}B$P;~dp1ri#Gtp1DIAw8D< zRi^=7K2zB~O*2-Umd~x|TEcbA4)~Jn#?8Q_{d3c|FJE%X65x~(b=CS$@l{MDG@R4) zoU}Rx8KWJH9IulzY(MV0bUAr*7WtltnAEShq=5>7SpHSz^Yf;mm<0LbnlHld7ex1F z&e0T=#;-}+23F{}h+sHg8&d%HGO9Fd*C%L~$16a$pbzZ55vRu9r?S8r)bg#ff`Hm@7rZ;5(8POFC3 ze;=BceAm$5=V<61v1#7&rFVIkXKD(cKYr}9r+=O3FxHRjHVe0L(+Q{jlGB`DuHN2a zd&@Q_y!NhQ>WPjdOEDN(_-B_;mk3TC>0({yVOTj5n=m0?y~W~z(Sp%jeLoY7a$yp? z+P$y}3fS1ogrf)Wz24>81yb7RLB~D&A~ECZdiUD!u^1oSWDt;D>$ZIRmtT{eOfO$% zd{Lj->#yIm=2?Nwfs8rF_Fz7%Gt;#dmvc&o$G}K*to@Qn&Rw`2#9_07RI`M`fwrxo zfrUDv4oLe5Yxy(W(J7-qIzMXGguzLGF80FH!sHd9Ivnm+_)UZ=LLIrs)?#zEi15)p zp>$ZamBQWFWtvfR#sYC8r{+YssTAClm}>pEoG1ailHKIm}S%kxIZ>H*CCha_R3UVakKs zXv2SDV_*vCBoe(*6*u+3hSXLNd&p0b_ZbQa>hE`$`T&S`de1PG3of81Z8G6G$PlX0 z{4eR<-|n+@)SwFXU`ga>5}-&+bCOH^RN4;##5=#`pGpT8{32;G_o z3j0TnTUZI{!@;0H;Ea@Ug!`OVI0vgrC~N4M0NEy8kmrbuxWgFBC>Id@T5Q18r$8^8 zGengD35qi85M9bMFAb6q&X{ukjc-iYLv1I#_hVp}j?`+Rzu#ho%cIv{K!0zsg(7%| zeB+lgHI}9Y1;%Ffa>-k9z#PQzU_&%ptX6<3I36T>3ZQ8elxUomZwAvTu!qe34E~Kd z81VAnS%7!@MYXo5JO+sfoZoo>j|aAIgG?M)>5pJHw*bcFSY37 literal 0 HcmV?d00001 diff --git a/src/assets/icons/svg/knowledge-base.svg b/src/assets/icons/svg/knowledge-base.svg new file mode 100644 index 0000000..7e62cf0 --- /dev/null +++ b/src/assets/icons/svg/knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/src/assets/knowledge-base.png b/src/assets/knowledge-base.png new file mode 100644 index 0000000000000000000000000000000000000000..bb0608229fb6bc5296e684ceefd96f87260ce24b GIT binary patch literal 2864 zcmeHJ`#aN%AK#3*P6#KLQ=cy9tJ6U-88v(ka+@TgMCpsO7LAT&qYNt!iR_D`Mv+pU z5z;U-EOJ?kb#lMWR@2;8l3TWwuk(DL=ll=f=jn&{`~5uc_w#!H@OobF%MD*2cZ7zq z1_S~@czU?{ZAR|jrUu{iRi~@%RAJS&1ljkp;~mB!wfD6M)f#Ee}W}ejdFN$nBoIH9lSkJqN#+Xj#6LMoFvHT76G;R9D z$EU2uBeFQb6rYq3vsjoZmxzdIDx7xn5W`ubY0+_58`+;3;B=)`?ABdwtFo5|wOGtE?Dr?ZltBIp zbxl<>bhe>Lm?L~XO5$pH#L27X(OQD7*RrR+>P+ls!(AzNlR#97(V_Ru%ZILR6bQC* z6rMClf^e12T)pzm0m(+!h$hT@U_7v(#Lkp?_I=mXC5J91Y2)NvCMCihWY@}rbg8wqXDSUX6IO#I4faG|{_AqeGf2?4g38Z)*6L(;m@Q)$ zFt|9joxrxhf_y%cVhy!ognP1E+j?A{6!^jD(Hy+XjK#N(-k}bSZq_==*BX#uL+?bP z9Dk^!4}fm}di*hVDW_Ybi`8l4YYRw{K3j*LLLmv=NGoFuqU_LFc_phVTQ?JVGwS|j zu)y(VV=}Hfz)9y}{Ryx_+#fD^+q#Wn#~6Y0)H=|Ya{~#%S&}{|?a2qmIcAqy2d&fA z*9*XMFk{)M4xFU{_05f0m$vrR|6#l|I&z7-2Mb;g6DwRQxAt$LrIAV&E+ugi5%~t( z_QJuaTT)@1^?aAV65SyTYr@cek~;D4z$@N%27V zS!jWf2MwNd^!MU-622?p|8yLFQ?X8*8+de&f4jK1$@>`LT-<}z3>w~>U@?qC`T7B7 zdBpIeSy-sv!$G~0AU`0->_gX}Rivs%Rv;!3YfnjK=Mk5}|4A588pnrNf#UIhGU^o5 zzn4;Xg(*;5Xfexr1batx>5DYY3_yWl2ZQ?v82D6cncxf9Qvuau2=t22>;jfvlowBq z%qFe~t)k!_Jw!}A(KAJn7>{clv#*=Zsr?1+A^ihGY<1LeLMP5~4u>fQ6d^GNpqH&^ zm`kGeHoex>`-e%2y@U^Qid6MM!LIb3fV94CGsC0A%gy zummH}hSI}MUq4%89b+Kx?X-3qoR&7sxd$-b->aOd0oI0#mg0Xp0&Qqz)1@O#B;3TkfWWQzT3Xi!1 z-6(fD;&5Q?5#?87u0cjnGv_dx>#}s(c!o&{+2q`P`gHbH8KQf$^9(#zCG5}A%3Rub z$zEA0%L%bO4(?7qT*Pot32)8h=_G;#Ou!~38{C9-Drg0USzt^egkhSjII5D=zvkZQ=)COJ`eEul8`Vcr=R z;tWf(p=xmB#Pt>iOx6B9+B-vp_wf8ORzVaFSb+OMjZEarb7=vUK99BJx61_aM|n}K zEO;y)FrYq49lSBS8~g95in=!KpBULDerH}Cv7v^;=$kitAX*zsss`psf^=d}ee_1Z z24Cc7oG}JQ0)sEdg3U+7MrHEU0K?>`#FZPN3qsBYON%d7Gv+>_41fik-U^Gai{psYEB{iM{P9%jZ-n_*a zGUK#A$_YK#K;?*^N4TyZd{AtAtOx%w<#yzA@=U#zQ+M???#!3v`RnOBibfAjx*6}i zPkHFcuKjt4d{S!@GZXP)_s$VPt#hm;qB#V%GgTlMm57p;={cv7&}Rw?S@sJ1Hjg}! zcl$4J2(ibLZB@8ZikbcmKDA!6XG`k2g&Vs0$P1#MOfJdseUZ&pZZ0&Xpl^RUl52u9 zWWun{z1NVh#=!%J-{4Vae-x`*tH#QHdC5!WZ5IdGFDc=HI}QVQRCV@Z{PC2#Zq|09XS#LZ} z0Q;5UURlgr$YU_|B!5yv(t$t|79>HJH?>?pq*>I9XVA_V%$M4&?ZN@6$;rhuWMv=u{XoTR~40wWOVCZ}XS{4No+D+n!^d3Wsv e*;Q%z`VNE|&G!nh$7S;chIk(FajkYfckRDod-IzB literal 0 HcmV?d00001 diff --git a/src/router/index.ts b/src/router/index.ts index b36eacd..22df47a 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -518,35 +518,35 @@ export const dynamicRoutes: RouteRecordRaw[] = [ ] }, - // { - // path: '/ai/skill/knowledgeBaseDocs', - // component: Layout, - // hidden: true, - // permissions: ['ai:aiKnowledgeBaseDocs:list'], - // children: [ - // { - // path: 'index', - // component: () => import('@/views/ai/skill/aiKnowledge/knowledgeBaseDocs.vue'), - // name: 'KnowledgeBaseDocs', - // meta: { title: '知识库详情', activeMenu: '/ai/skill/aiKnowledge', noCache: true } - // } - // ] - // }, - // - // { - // path: '/ai/skill/knowledgeBaseQA', - // component: Layout, - // hidden: true, - // permissions: ['ai:aiKnowledgeBaseDocs:qa'], - // children: [ - // { - // path: 'index', - // component: () => import('@/views/ai/skill/aiChat/index.vue'), - // name: 'KnowledgeBaseQA', - // meta: { title: '知识库问答', activeMenu: '/ai/skill/aiKnowledge', noCache: true } - // } - // ] - // }, + { + path: '/ai/skill/knowledgeContent', + component: Layout, + hidden: true, + permissions: ['ai:aiKnowledgeContent:list'], + children: [ + { + path: 'index/:knowledgeBaseId/:modelId/:knowledgeBaseName', + component: () => import('@/views/ai/skill/aiKnowledge/knowledgeContent.vue'), + name: 'KnowledgeContent', + meta: { title: '知识库内容', activeMenu: '/ai/skill/aiKnowledge', noCache: true } + } + ] + }, + + { + path: '/ai/skill/knowledgeBaseQA', + component: Layout, + hidden: true, + permissions: ['ai:aiKnowledgeBaseDocs:qa'], + children: [ + { + path: 'index/:knowledgeBaseId', + component: () => import('@/views/ai/skill/aiChat/index.vue'), + name: 'KnowledgeBaseQA', + meta: { title: '知识库问答', activeMenu: '/ai/skill/aiChat', noCache: true } + } + ] + }, // { // path: '/knowledge-base-preview', diff --git a/src/views/ai/base/aiApp/aiAppConfig.vue b/src/views/ai/base/aiApp/aiAppConfig.vue new file mode 100644 index 0000000..f661095 --- /dev/null +++ b/src/views/ai/base/aiApp/aiAppConfig.vue @@ -0,0 +1,522 @@ + + + + + diff --git a/src/views/ai/record/tokenUsage/index.vue b/src/views/ai/record/tokenUsage/index.vue new file mode 100644 index 0000000..ec78dba --- /dev/null +++ b/src/views/ai/record/tokenUsage/index.vue @@ -0,0 +1,621 @@ + + + + + diff --git a/src/views/ai/record/usageRecord/index.vue b/src/views/ai/record/usageRecord/index.vue new file mode 100644 index 0000000..973388a --- /dev/null +++ b/src/views/ai/record/usageRecord/index.vue @@ -0,0 +1,383 @@ + + + + + diff --git a/src/views/ai/skill/aiChat/index.vue b/src/views/ai/skill/aiChat/index.vue index c3fa5fa..3baf040 100644 --- a/src/views/ai/skill/aiChat/index.vue +++ b/src/views/ai/skill/aiChat/index.vue @@ -1,10 +1,10 @@