diff --git a/README.md b/README.md index f29f02f6..93a56e81 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,7 @@ agent_manager.init_all_agents() ### 品牌信息配置 -在主页和登录页面的很多信息,比如 Logo,组织名称,版权信息等,都可以复制 [src/static/info.template.yaml](src/static/info.template.yaml),并新建一个 `src/static/info.local.yaml`,在这个文件中配置。在项目启动时,会加载这个文件,然后根据文件中的配置,渲染到前端页面中。如果 `src/static/info.local.yaml` 不存在,会使用 [src/static/info.template.yaml](src/static/info.template.yaml) 中的配置。 +在主页和登录页面的很多信息,比如 Logo,组织名称,版权信息等,都可以复制 [src/static/info.template.yaml](src/static/info.template.yaml),并新建一个 `src/static/info.local.yaml`(或者在 .env 文件中配置 `YUXI_BRAND_FILE_PATH` 指向这个文件),在这个文件中配置。在项目启动时,会加载这个文件,然后根据文件中的配置,渲染到前端页面中。如果 `src/static/info.local.yaml` 不存在,会默认使用 [src/static/info.template.yaml](src/static/info.template.yaml) 中的配置。 系统的配色方面,主要保存在 [web/src/assets/css/base.css](web/src/assets/css/base.css) 中。只要替换其中的 `--main-*` 相关的变量,就可以改变系统的配色。 diff --git a/web/src/apis/auth_api.js b/web/src/apis/agent.js similarity index 62% rename from web/src/apis/auth_api.js rename to web/src/apis/agent.js index 9310bfe9..7168963f 100644 --- a/web/src/apis/auth_api.js +++ b/web/src/apis/agent.js @@ -1,15 +1,19 @@ -import { apiGet, apiPost, apiDelete, apiPut } from './base' +import { apiGet, apiPost, apiDelete, apiPut, apiAdminGet, apiAdminPost } from './base' import { useUserStore } from '@/stores/user' /** - * 需要用户认证的API模块 - * 用户必须登录才能访问的API + * 智能体API模块 + * 包含智能体管理、聊天、配置等功能 * 权限要求: 任何已登录用户(普通用户、管理员、超级管理员) */ -// 聊天相关API -export const chatApi = { + +// ============================================================================= +// === 智能体聊天分组 === +// ============================================================================= + +export const agentApi = { /** * 发送聊天消息到指定智能体(流式响应) * @param {string} agentId - 智能体ID @@ -32,26 +36,26 @@ export const chatApi = { * @param {string} query - 查询内容 * @returns {Promise} - 聊天响应 */ - simpleCall: (query) => apiPost('/api/chat/call', { query }, {}, true), + simpleCall: (query) => apiPost('/api/chat/call', { query }), /** * 获取默认智能体 * @returns {Promise} - 默认智能体信息 */ - getDefaultAgent: () => apiGet('/api/chat/default_agent', {}, true), + getDefaultAgent: () => apiGet('/api/chat/default_agent'), /** * 获取智能体列表 * @returns {Promise} - 智能体列表 */ - getAgents: () => apiGet('/api/chat/agent', {}, true), + getAgents: () => apiGet('/api/chat/agent'), /** * 获取单个智能体详情 * @param {string} agentId - 智能体ID * @returns {Promise} - 智能体详情 */ - getAgentDetail: (agentId) => apiGet(`/api/chat/agent/${agentId}`, {}, true), + getAgentDetail: (agentId) => apiGet(`/api/chat/agent/${agentId}`), /** * 获取智能体历史消息 @@ -59,20 +63,14 @@ export const chatApi = { * @param {string} threadId - 会话ID * @returns {Promise} - 历史消息 */ - getAgentHistory: (agentId, threadId) => apiGet(`/api/chat/agent/${agentId}/history?thread_id=${threadId}`, {}, true), - - /** - * 获取可用工具列表 - * @returns {Promise} - 工具列表 - */ - getTools: () => apiGet('/api/chat/tools', {}, true), + getAgentHistory: (agentId, threadId) => apiGet(`/api/chat/agent/${agentId}/history?thread_id=${threadId}`), /** * 获取模型提供商的模型列表 * @param {string} provider - 模型提供商 * @returns {Promise} - 模型列表 */ - getProviderModels: (provider) => apiGet(`/api/chat/models?model_provider=${provider}`, {}, true), + getProviderModels: (provider) => apiGet(`/api/chat/models?model_provider=${provider}`), /** * 更新模型提供商的模型列表 @@ -80,26 +78,48 @@ export const chatApi = { * @param {Array} models - 选中的模型列表 * @returns {Promise} - 更新结果 */ - updateProviderModels: (provider, models) => apiPost(`/api/chat/models/update?model_provider=${provider}`, models, {}, true) -} - -// 用户设置API -export const userSettingsApi = { - /** - * 获取用户设置 - * @returns {Promise} - 用户设置 - */ - getSettings: () => apiGet('/api/user/settings', {}, true), + updateProviderModels: (provider, models) => apiPost(`/api/chat/models/update?model_provider=${provider}`, models), /** - * 更新用户设置 - * @param {Object} settings - 新设置 - * @returns {Promise} - 更新结果 + * 获取智能体配置 + * @param {string} agentName - 智能体名称 + * @returns {Promise} - 智能体配置 */ - updateSettings: (settings) => apiPost('/api/user/settings', settings, {}, true), + getAgentConfig: async (agentName) => { + return apiAdminGet(`/api/chat/agent/${agentName}/config`) + }, + + /** + * 保存智能体配置 + * @param {string} agentName - 智能体名称 + * @param {Object} config - 配置对象 + * @returns {Promise} - 保存结果 + */ + saveAgentConfig: async (agentName, config) => { + return apiAdminPost(`/api/chat/agent/${agentName}/config`, config) + }, + + /** + * 设置默认智能体 + * @param {string} agentId - 智能体ID + * @returns {Promise} - 设置结果 + */ + setDefaultAgent: async (agentId) => { + return apiAdminPost('/api/chat/set_default_agent', { agent_id: agentId }) + }, + + /** + * 获取所有可用工具的信息 + * @returns {Promise} - 工具信息列表 + */ + getTools: () => apiGet('/api/tool/tools') } -// 对话线程相关API + +// ============================================================================= +// === 对话线程分组 === +// ============================================================================= + export const threadApi = { /** * 获取对话线程列表 @@ -108,7 +128,7 @@ export const threadApi = { */ getThreads: (agentId) => { const url = agentId ? `/api/chat/threads?agent_id=${agentId}` : '/api/chat/threads'; - return apiGet(url, {}, true); + return apiGet(url); }, /** @@ -122,7 +142,7 @@ export const threadApi = { agent_id: agentId, title: title || '新的对话', metadata: metadata || {} - }, {}, true), + }), /** * 更新对话线程 @@ -134,14 +154,12 @@ export const threadApi = { updateThread: (threadId, title, description) => apiPut(`/api/chat/thread/${threadId}`, { title, description - }, {}, true), + }), /** * 删除对话线程 * @param {string} threadId - 对话线程ID * @returns {Promise} - 删除结果 */ - deleteThread: (threadId) => apiDelete(`/api/chat/thread/${threadId}`, {}, true) -}; - -// 其他需要用户认证的API可以继续添加到这里 \ No newline at end of file + deleteThread: (threadId) => apiDelete(`/api/chat/thread/${threadId}`) +}; \ No newline at end of file diff --git a/web/src/apis/base.js b/web/src/apis/base.js index dde8ea66..81732927 100644 --- a/web/src/apis/base.js +++ b/web/src/apis/base.js @@ -1,4 +1,4 @@ -import { useUserStore } from '@/stores/user' +import { useUserStore, checkAdminPermission, checkSuperAdminPermission } from '@/stores/user' import { message } from 'ant-design-vue' /** @@ -13,7 +13,7 @@ import { message } from 'ant-design-vue' * @param {boolean} requiresAuth - 是否需要认证头 * @returns {Promise} - 请求结果 */ -export async function apiRequest(url, options = {}, requiresAuth = false) { +export async function apiRequest(url, options = {}, requiresAuth = true) { try { // 默认请求配置 const requestOptions = { @@ -100,10 +100,20 @@ export async function apiRequest(url, options = {}, requiresAuth = false) { * @param {boolean} requiresAuth - 是否需要认证 * @returns {Promise} - 请求结果 */ -export function apiGet(url, options = {}, requiresAuth = false) { +export function apiGet(url, options = {}, requiresAuth = true) { return apiRequest(url, { method: 'GET', ...options }, requiresAuth) } +export function apiAdminGet(url, options = {}) { + checkAdminPermission() + return apiGet(url, options, true) +} + +export function apiSuperAdminGet(url, options = {}) { + checkSuperAdminPermission() + return apiGet(url, options, true) +} + /** * 发送POST请求 * @param {string} url - API端点 @@ -112,7 +122,7 @@ export function apiGet(url, options = {}, requiresAuth = false) { * @param {boolean} requiresAuth - 是否需要认证 * @returns {Promise} - 请求结果 */ -export function apiPost(url, data = {}, options = {}, requiresAuth = false) { +export function apiPost(url, data = {}, options = {}, requiresAuth = true) { return apiRequest( url, { @@ -124,6 +134,16 @@ export function apiPost(url, data = {}, options = {}, requiresAuth = false) { ) } +export function apiAdminPost(url, data = {}, options = {}) { + checkAdminPermission() + return apiPost(url, data, options, true) +} + +export function apiSuperAdminPost(url, data = {}, options = {}) { + checkSuperAdminPermission() + return apiPost(url, data, options, true) +} + /** * 发送PUT请求 * @param {string} url - API端点 @@ -132,7 +152,7 @@ export function apiPost(url, data = {}, options = {}, requiresAuth = false) { * @param {boolean} requiresAuth - 是否需要认证 * @returns {Promise} - 请求结果 */ -export function apiPut(url, data = {}, options = {}, requiresAuth = false) { +export function apiPut(url, data = {}, options = {}, requiresAuth = true) { return apiRequest( url, { @@ -144,6 +164,16 @@ export function apiPut(url, data = {}, options = {}, requiresAuth = false) { ) } +export function apiAdminPut(url, data = {}, options = {}) { + checkAdminPermission() + return apiPut(url, data, options, true) +} + +export function apiSuperAdminPut(url, data = {}, options = {}) { + checkSuperAdminPermission() + return apiPut(url, data, options, true) +} + /** * 发送DELETE请求 * @param {string} url - API端点 @@ -155,3 +185,12 @@ export function apiDelete(url, options = {}, requiresAuth = false) { return apiRequest(url, { method: 'DELETE', ...options }, requiresAuth) } +export function apiAdminDelete(url, options = {}) { + checkAdminPermission() + return apiDelete(url, options, true) +} + +export function apiSuperAdminDelete(url, options = {}) { + checkSuperAdminPermission() + return apiDelete(url, options, true) +} diff --git a/web/src/apis/index.js b/web/src/apis/index.js index 4ec3b5b4..c63e4866 100644 --- a/web/src/apis/index.js +++ b/web/src/apis/index.js @@ -9,9 +9,12 @@ export * from './knowledge_api' // 知识库管理API export * from './auth_api' // 认证API export * from './graph_api' // 图谱API export * from './tools.js' // 工具API +export * from './agent.js' // 智能体API // 导出基础工具函数 -export { apiRequest, apiGet, apiPost, apiPut, apiDelete } from './base' +export { apiGet, apiPost, apiPut, apiDelete, + apiAdminGet, apiAdminPost, apiAdminPut, apiAdminDelete, + apiSuperAdminGet, apiSuperAdminPost, apiSuperAdminPut, apiSuperAdminDelete } from './base' /** * API模块说明: @@ -33,5 +36,8 @@ export { apiRequest, apiGet, apiPost, apiPut, apiDelete } from './base' * 5. tools.js: 工具API * - 工具信息获取 * + * 6. agent.js: 智能体API + * - 智能体管理、聊天、配置等功能 + * * 注意:API模块已处理权限验证和请求头,使用时无需再手动添加认证头 */ \ No newline at end of file diff --git a/web/src/apis/knowledge_api.js b/web/src/apis/knowledge_api.js index 44fdfd24..e718197b 100644 --- a/web/src/apis/knowledge_api.js +++ b/web/src/apis/knowledge_api.js @@ -1,20 +1,10 @@ -import { apiGet, apiPost, apiPut, apiDelete } from './base' -import { useUserStore } from '@/stores/user' +import { apiAdminGet, apiAdminPost, apiAdminPut, apiAdminDelete } from './base' /** * 知识库管理API模块 * 包含数据库管理、文档管理、查询接口等功能 */ -// 检查当前用户是否有管理员权限 -const checkAdminPermission = () => { - const userStore = useUserStore() - if (!userStore.isAdmin) { - throw new Error('需要管理员权限') - } - return true -} - // ============================================================================= // === 数据库管理分组 === // ============================================================================= @@ -25,8 +15,7 @@ export const databaseApi = { * @returns {Promise} - 知识库列表 */ getDatabases: async () => { - checkAdminPermission() - return apiGet('/api/knowledge/databases', {}, true) + return apiAdminGet('/api/knowledge/databases') }, /** @@ -35,8 +24,7 @@ export const databaseApi = { * @returns {Promise} - 创建结果 */ createDatabase: async (databaseData) => { - checkAdminPermission() - return apiPost('/api/knowledge/databases', databaseData, {}, true) + return apiAdminPost('/api/knowledge/databases', databaseData) }, /** @@ -45,8 +33,7 @@ export const databaseApi = { * @returns {Promise} - 知识库信息 */ getDatabaseInfo: async (dbId) => { - checkAdminPermission() - return apiGet(`/api/knowledge/databases/${dbId}`, {}, true) + return apiAdminGet(`/api/knowledge/databases/${dbId}`) }, /** @@ -56,8 +43,7 @@ export const databaseApi = { * @returns {Promise} - 更新结果 */ updateDatabase: async (dbId, updateData) => { - checkAdminPermission() - return apiPut(`/api/knowledge/databases/${dbId}`, updateData, {}, true) + return apiAdminPut(`/api/knowledge/databases/${dbId}`, updateData) }, /** @@ -66,8 +52,7 @@ export const databaseApi = { * @returns {Promise} - 删除结果 */ deleteDatabase: async (dbId) => { - checkAdminPermission() - return apiDelete(`/api/knowledge/databases/${dbId}`, {}, true) + return apiAdminDelete(`/api/knowledge/databases/${dbId}`) } } @@ -84,11 +69,10 @@ export const documentApi = { * @returns {Promise} - 添加结果 */ addDocuments: async (dbId, items, params = {}) => { - checkAdminPermission() - return apiPost(`/api/knowledge/databases/${dbId}/documents`, { + return apiAdminPost(`/api/knowledge/databases/${dbId}/documents`, { items, params - }, {}, true) + }) }, /** @@ -98,8 +82,7 @@ export const documentApi = { * @returns {Promise} - 文档信息 */ getDocumentInfo: async (dbId, docId) => { - checkAdminPermission() - return apiGet(`/api/knowledge/databases/${dbId}/documents/${docId}`, {}, true) + return apiAdminGet(`/api/knowledge/databases/${dbId}/documents/${docId}`) }, /** @@ -109,8 +92,7 @@ export const documentApi = { * @returns {Promise} - 删除结果 */ deleteDocument: async (dbId, docId) => { - checkAdminPermission() - return apiDelete(`/api/knowledge/databases/${dbId}/documents/${docId}`, {}, true) + return apiAdminDelete(`/api/knowledge/databases/${dbId}/documents/${docId}`) } } @@ -127,11 +109,10 @@ export const queryApi = { * @returns {Promise} - 查询结果 */ queryKnowledgeBase: async (dbId, query, meta = {}) => { - checkAdminPermission() - return apiPost(`/api/knowledge/databases/${dbId}/query`, { + return apiAdminPost(`/api/knowledge/databases/${dbId}/query`, { query, meta - }, {}, true) + }) }, /** @@ -142,11 +123,10 @@ export const queryApi = { * @returns {Promise} - 测试结果 */ queryTest: async (dbId, query, meta = {}) => { - checkAdminPermission() - return apiPost(`/api/knowledge/databases/${dbId}/query-test`, { + return apiAdminPost(`/api/knowledge/databases/${dbId}/query-test`, { query, meta - }, {}, true) + }) }, /** @@ -155,8 +135,7 @@ export const queryApi = { * @returns {Promise} - 查询参数 */ getKnowledgeBaseQueryParams: async (dbId) => { - checkAdminPermission() - return apiGet(`/api/knowledge/databases/${dbId}/query-params`, {}, true) + return apiAdminGet(`/api/knowledge/databases/${dbId}/query-params`) } } @@ -172,8 +151,6 @@ export const fileApi = { * @returns {Promise} - 上传结果 */ uploadFile: async (file, dbId = null) => { - checkAdminPermission() - const formData = new FormData() formData.append('file', file) @@ -181,11 +158,11 @@ export const fileApi = { ? `/api/knowledge/files/upload?db_id=${dbId}` : '/api/knowledge/files/upload' - return apiPost(url, formData, { + return apiAdminPost(url, formData, { headers: { 'Content-Type': 'multipart/form-data' } - }, true) + }) } } @@ -199,8 +176,7 @@ export const typeApi = { * @returns {Promise} - 知识库类型列表 */ getKnowledgeBaseTypes: async () => { - checkAdminPermission() - return apiGet('/api/knowledge/types', {}, true) + return apiAdminGet('/api/knowledge/types') }, /** @@ -208,8 +184,7 @@ export const typeApi = { * @returns {Promise} - 统计信息 */ getStatistics: async () => { - checkAdminPermission() - return apiGet('/api/knowledge/stats', {}, true) + return apiAdminGet('/api/knowledge/stats') } } diff --git a/web/src/apis/system_api.js b/web/src/apis/system_api.js index a3530934..b9ecd401 100644 --- a/web/src/apis/system_api.js +++ b/web/src/apis/system_api.js @@ -1,28 +1,11 @@ -import { apiGet, apiPost } from './base' -import { useUserStore } from '@/stores/user' +import { apiGet, apiPost, apiAdminGet, apiAdminPost, apiSuperAdminPost } from './base' /** * 系统管理API模块 * 包含系统配置、健康检查、信息管理等功能 */ -// 检查当前用户是否有管理员权限 -const checkAdminPermission = () => { - const userStore = useUserStore() - if (!userStore.isAdmin) { - throw new Error('需要管理员权限') - } - return true -} -// 检查当前用户是否有超级管理员权限 -const checkSuperAdminPermission = () => { - const userStore = useUserStore() - if (!userStore.isSuperAdmin) { - throw new Error('需要超级管理员权限') - } - return true -} // ============================================================================= // === 健康检查分组 === @@ -33,16 +16,13 @@ export const healthApi = { * 系统健康检查(公开接口) * @returns {Promise} - 健康检查结果 */ - checkHealth: () => apiGet('/api/system/health'), + checkHealth: () => apiGet('/api/system/health', {}, false), /** * OCR服务健康检查 * @returns {Promise} - OCR服务健康状态 */ - checkOcrHealth: async () => { - checkAdminPermission() - return apiGet('/api/system/health/ocr', {}, true) - } + checkOcrHealth: async () => apiAdminGet('/api/system/health/ocr') } // ============================================================================= @@ -54,10 +34,7 @@ export const configApi = { * 获取系统配置 * @returns {Promise} - 系统配置 */ - getConfig: async () => { - checkAdminPermission() - return apiGet('/api/system/config', {}, true) - }, + getConfig: async () => apiAdminGet('/api/system/config'), /** * 更新单个配置项 @@ -65,59 +42,44 @@ export const configApi = { * @param {any} value - 配置值 * @returns {Promise} - 更新结果 */ - updateConfig: async (key, value) => { - checkAdminPermission() - return apiPost('/api/system/config', { key, value }, {}, true) - }, + updateConfig: async (key, value) => apiAdminPost('/api/system/config', { key, value }), /** * 批量更新配置项 * @param {Object} items - 配置项对象 * @returns {Promise} - 更新结果 */ - updateConfigBatch: async (items) => { - checkAdminPermission() - return apiPost('/api/system/config/update', items, {}, true) - }, + updateConfigBatch: async (items) => apiAdminPost('/api/system/config/update', items), /** * 重启系统(仅超级管理员) * @returns {Promise} - 重启结果 */ - restartSystem: async () => { - checkSuperAdminPermission() - return apiPost('/api/system/restart', {}, {}, true) - }, + restartSystem: async () => apiSuperAdminPost('/api/system/restart', {}), /** * 获取系统日志 * @returns {Promise} - 系统日志 */ - getLogs: async () => { - checkAdminPermission() - return apiGet('/api/system/logs', {}, true) - } + getLogs: async () => apiAdminGet('/api/system/logs') } // ============================================================================= // === 信息管理分组 === // ============================================================================= -export const infoApi = { +export const brandAPi = { /** * 获取系统信息配置(公开接口) * @returns {Promise} - 系统信息配置 */ - getInfoConfig: () => apiGet('/api/system/info'), + getInfoConfig: () => apiGet('/api/system/info', {}, false), /** * 重新加载信息配置 * @returns {Promise} - 重新加载结果 */ - reloadInfoConfig: async () => { - checkAdminPermission() - return apiPost('/api/system/info/reload', {}, {}, true) - } + reloadInfoConfig: async () => apiPost('/api/system/info/reload', {}, {}, false) } // ============================================================================= @@ -129,55 +91,14 @@ export const ocrApi = { * 获取OCR服务统计信息 * @returns {Promise} - OCR统计信息 */ - getStats: async () => { - checkAdminPermission() - return apiGet('/api/system/ocr/stats', {}, true) - }, + getStats: async () => apiAdminGet('/api/system/ocr/stats'), /** * 获取OCR服务健康状态 * @returns {Promise} - OCR健康状态 */ - getHealth: async () => { - checkAdminPermission() - return apiGet('/api/system/ocr/health', {}, true) - } + getHealth: async () => apiAdminGet('/api/system/ocr/health') } -// ============================================================================= -// === 智能体配置分组 === -// ============================================================================= -export const agentConfigApi = { - /** - * 获取智能体配置 - * @param {string} agentName - 智能体名称 - * @returns {Promise} - 智能体配置 - */ - getAgentConfig: async (agentName) => { - checkAdminPermission() - return apiGet(`/api/chat/agent/${agentName}/config`, {}, true) - }, - - /** - * 保存智能体配置 - * @param {string} agentName - 智能体名称 - * @param {Object} config - 配置对象 - * @returns {Promise} - 保存结果 - */ - saveAgentConfig: async (agentName, config) => { - checkAdminPermission() - return apiPost(`/api/chat/agent/${agentName}/config`, config, {}, true) - }, - - /** - * 设置默认智能体 - * @param {string} agentId - 智能体ID - * @returns {Promise} - 设置结果 - */ - setDefaultAgent: async (agentId) => { - checkAdminPermission() - return apiPost('/api/chat/set_default_agent', { agent_id: agentId }, {}, true) - } -} diff --git a/web/src/apis/tools.js b/web/src/apis/tools.js deleted file mode 100644 index 9ec8377f..00000000 --- a/web/src/apis/tools.js +++ /dev/null @@ -1,18 +0,0 @@ -import { apiGet } from './base' - -/** - * 工具管理API模块 - * 包含工具信息获取等功能 - */ - -// ============================================================================= -// === 工具信息分组 === -// ============================================================================= - -export const toolsApi = { - /** - * 获取所有可用工具的信息 - * @returns {Promise} - 工具信息列表 - */ - getTools: () => apiGet('/api/tool/tools', {}, true) -} \ No newline at end of file diff --git a/web/src/components/AgentChatComponent.vue b/web/src/components/AgentChatComponent.vue index 7198e3f8..e7a0a282 100644 --- a/web/src/components/AgentChatComponent.vue +++ b/web/src/components/AgentChatComponent.vue @@ -147,7 +147,7 @@ import MessageInputComponent from '@/components/MessageInputComponent.vue' import AgentMessageComponent from '@/components/AgentMessageComponent.vue' import ChatSidebarComponent from '@/components/ChatSidebarComponent.vue' import RefsComponent from '@/components/RefsComponent.vue' -import { chatApi, threadApi } from '@/apis/auth_api' +import { agentApi, threadApi } from '@/apis/agent' import { PanelLeftOpen, MessageSquarePlus } from 'lucide-vue-next'; // 新增props属性,允许父组件传入agentId @@ -950,7 +950,7 @@ const sendMessageToServer = async (text) => { try { state.waitingServerResponse = true; - const response = await chatApi.sendAgentMessage(currentAgent.value.id, requestData); + const response = await agentApi.sendAgentMessage(currentAgent.value.id, requestData); if (!response.ok) { throw new Error('请求失败'); } @@ -1067,7 +1067,7 @@ const initAll = async () => { // 获取智能体列表 const fetchAgents = async () => { try { - const data = await chatApi.getAgents(); + const data = await agentApi.getAgents(); // 将数组转换为对象 agents.value = data.agents.reduce((acc, agent) => { acc[agent.id] = agent; @@ -1113,7 +1113,7 @@ const getAgentHistory = async () => { try { console.debug(`正在获取智能体[${props.agentId}]的历史记录,对话ID: ${currentChatId.value}`); - const response = await chatApi.getAgentHistory(props.agentId, currentChatId.value); + const response = await agentApi.getAgentHistory(props.agentId, currentChatId.value); console.debug('智能体历史记录:', response); // 如果成功获取历史记录并且是数组 @@ -1836,7 +1836,7 @@ const mergeMessageChunk = (chunks) => { } .chat-header { - padding: 0.5rem 1rem !important; + padding: 0.5rem 0 !important; .nav-btn { font-size: 14px !important; diff --git a/web/src/components/AgentConfigSidebar.vue b/web/src/components/AgentConfigSidebar.vue index 8bae4a13..93a7235a 100644 --- a/web/src/components/AgentConfigSidebar.vue +++ b/web/src/components/AgentConfigSidebar.vue @@ -279,8 +279,7 @@ import { } from '@ant-design/icons-vue'; import { message } from 'ant-design-vue'; import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue'; -import { agentConfigApi } from '@/apis/system_api'; -import { toolsApi } from '@/apis/tools'; +import { agentApi } from '@/apis/agent'; // Props const props = defineProps({ @@ -422,7 +421,7 @@ const getToolNameById = (toolId) => { const loadAvailableTools = async () => { try { - const response = await toolsApi.getTools(); + const response = await agentApi.getTools(); availableTools.value = Object.values(response.tools || {}); } catch (error) { console.error('加载工具列表失败:', error); @@ -482,7 +481,7 @@ const saveConfig = async () => { } try { - await agentConfigApi.saveAgentConfig(props.selectedAgentId, props.agentConfig); + await agentApi.saveAgentConfig(props.selectedAgentId, props.agentConfig); message.success('配置已保存到服务器'); emit('config-saved'); } catch (error) { @@ -498,7 +497,7 @@ const resetConfig = async () => { } try { - await agentConfigApi.saveAgentConfig(props.selectedAgentId, {}); + await agentApi.saveAgentConfig(props.selectedAgentId, {}); emit('config-reset'); message.info('配置已重置'); } catch (error) { @@ -1067,7 +1066,7 @@ watch(() => props.isOpen, (newVal) => { // 响应式适配 @media (max-width: 768px) { - .agent-config-sidebar { + .agent-config-sidebar.open { width: 100vw; } } diff --git a/web/src/components/DebugComponent.vue b/web/src/components/DebugComponent.vue index 3f8b96fd..55eed505 100644 --- a/web/src/components/DebugComponent.vue +++ b/web/src/components/DebugComponent.vue @@ -114,22 +114,15 @@ import { RobotOutlined } from '@ant-design/icons-vue'; import dayjs from 'dayjs'; -import { configApi, agentConfigApi } from '@/apis/system_api'; -import { chatApi } from '@/apis/auth_api'; +import { configApi } from '@/apis/system_api'; +import { agentApi } from '@/apis/agent'; +import { checkAdminPermission } from '@/stores/user'; const configStore = useConfigStore() const userStore = useUserStore(); const databaseStore = useDatabaseStore(); const config = configStore.config; -// 权限检查 -const checkAdminPermission = () => { - if (!userStore.isAdmin) { - message.error('需要管理员权限才能查看日志'); - return false; - } - return true; -}; // 定义日志级别 const logLevels = [ @@ -386,17 +379,17 @@ const printAgentConfig = async () => { console.log('=== 智能体配置 ==='); // 获取智能体列表 - const agentsData = await chatApi.getAgents(); + const agentsData = await agentApi.getAgents(); console.log('智能体列表:', JSON.stringify(agentsData.agents, null, 2)); // 获取默认智能体 - const defaultAgent = await chatApi.getDefaultAgent(); + const defaultAgent = await agentApi.getDefaultAgent(); console.log('默认智能体:', JSON.stringify(defaultAgent, null, 2)); // 获取每个智能体的配置 for (const agent of agentsData.agents) { try { - const agentConfig = await agentConfigApi.getAgentConfig(agent.id); + const agentConfig = await agentApi.getAgentConfig(agent.id); console.log(`智能体 "${agent.name}" 配置:`, JSON.stringify(agentConfig, null, 2)); } catch (err) { console.log(`智能体 "${agent.name}" 配置获取失败:`, err.message); diff --git a/web/src/components/KnowledgeGraphSection.vue b/web/src/components/KnowledgeGraphSection.vue index 0f137d08..500f6dd6 100644 --- a/web/src/components/KnowledgeGraphSection.vue +++ b/web/src/components/KnowledgeGraphSection.vue @@ -235,51 +235,51 @@ const applySettings = () => { // 设置已通过props传递给子组件,不需要额外操作 }; -const handleExport = async () => { - const dbId = store.databaseId; - if (!dbId) { - message.error('请先选择一个知识库'); - return; - } - try { - const response = await fetch(`/api/knowledge/databases/${dbId}/export?format=${exportOptions.value.format}`, { - headers: { - ...userStore.getAuthHeaders() - } - }); +// const handleExport = async () => { +// const dbId = store.databaseId; +// if (!dbId) { +// message.error('请先选择一个知识库'); +// return; +// } +// try { +// const response = await fetch(`/api/knowledge/databases/${dbId}/export?format=${exportOptions.value.format}`, { +// headers: { +// ...userStore.getAuthHeaders() +// } +// }); - if (!response.ok) { - const errorData = await response.json(); - throw new Error(errorData.detail || `导出失败: ${response.statusText}`); - } +// if (!response.ok) { +// const errorData = await response.json(); +// throw new Error(errorData.detail || `导出失败: ${response.statusText}`); +// } - const blob = await response.blob(); - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.style.display = 'none'; - a.href = url; +// const blob = await response.blob(); +// const url = window.URL.createObjectURL(blob); +// const a = document.createElement('a'); +// a.style.display = 'none'; +// a.href = url; - const disposition = response.headers.get('content-disposition'); - let filename = `export_${dbId}.zip`; - if (disposition) { - const filenameMatch = disposition.match(/filename="([^"]+)"/); - if (filenameMatch && filenameMatch[1]) { - filename = filenameMatch[1]; - } - } - a.download = filename; - document.body.appendChild(a); - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); +// const disposition = response.headers.get('content-disposition'); +// let filename = `export_${dbId}.zip`; +// if (disposition) { +// const filenameMatch = disposition.match(/filename="([^"]+)"/); +// if (filenameMatch && filenameMatch[1]) { +// filename = filenameMatch[1]; +// } +// } +// a.download = filename; +// document.body.appendChild(a); +// a.click(); +// window.URL.revokeObjectURL(url); +// document.body.removeChild(a); - message.success('导出任务已开始'); - showExportModal.value = false; - } catch (error) { - console.error('导出图谱失败:', error); - message.error(error.message || '导出图谱失败'); - } -}; +// message.success('导出任务已开始'); +// showExportModal.value = false; +// } catch (error) { +// console.error('导出图谱失败:', error); +// message.error(error.message || '导出图谱失败'); +// } +// }; watch(isGraphSupported, (supported) => { if (supported) { diff --git a/web/src/components/ModelProvidersComponent.vue b/web/src/components/ModelProvidersComponent.vue index 86fd8506..74424798 100644 --- a/web/src/components/ModelProvidersComponent.vue +++ b/web/src/components/ModelProvidersComponent.vue @@ -202,7 +202,7 @@ import { } from '@ant-design/icons-vue'; import { useConfigStore } from '@/stores/config'; import { modelIcons } from '@/utils/modelIcon'; -import { chatApi } from '@/apis/auth_api'; +import { agentApi } from '@/apis/agent'; const configStore = useConfigStore(); @@ -373,7 +373,7 @@ const openProviderConfig = (provider) => { // 获取模型提供商的模型列表 const fetchProviderModels = (provider) => { providerConfig.loading = true; - chatApi.getProviderModels(provider) + agentApi.getProviderModels(provider) .then(data => { console.log(`${provider} 模型列表:`, data); @@ -415,7 +415,7 @@ const saveProviderConfig = async () => { try { // 发送选择的模型列表到后端 - const data = await chatApi.updateProviderModels(providerConfig.provider, providerConfig.selectedModels); + const data = await agentApi.updateProviderModels(providerConfig.provider, providerConfig.selectedModels); console.log('更新后的模型列表:', data.models); message.success({ content: '模型配置已保存!', key: 'save-config', duration: 2 }); diff --git a/web/src/components/ToolCallingResult/KnowledgeGraphResult.vue b/web/src/components/ToolCallingResult/KnowledgeGraphResult.vue index 67663561..512fc050 100644 --- a/web/src/components/ToolCallingResult/KnowledgeGraphResult.vue +++ b/web/src/components/ToolCallingResult/KnowledgeGraphResult.vue @@ -8,7 +8,7 @@ -
+
diff --git a/web/src/router/index.js b/web/src/router/index.js index 8e2ab8d7..e50c112b 100644 --- a/web/src/router/index.js +++ b/web/src/router/index.js @@ -2,6 +2,7 @@ import { createRouter, createWebHistory } from 'vue-router' import AppLayout from '@/layouts/AppLayout.vue'; import BlankLayout from '@/layouts/BlankLayout.vue'; import { useUserStore } from '@/stores/user'; +import { agentApi } from '@/apis/agent'; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), @@ -121,26 +122,18 @@ router.beforeEach(async (to, from, next) => { // 如果是普通用户,跳转到默认智能体页面 try { // 先尝试获取默认智能体 - const response = await fetch('/api/chat/default_agent'); - if (response.ok) { - const data = await response.json(); - if (data.default_agent_id) { - // 如果存在默认智能体,直接跳转 - next(`/agent/${data.default_agent_id}`); - return; - } + const data = await agentApi.getDefaultAgent(); + if (data && data.default_agent_id) { + // 如果存在默认智能体,直接跳转 + next(`/agent/${data.default_agent_id}`); + return; } // 如果没有默认智能体,则获取第一个可用智能体 - const agentResponse = await fetch('/api/chat/agent'); - if (agentResponse.ok) { - const agentData = await agentResponse.json(); - if (agentData.agents && agentData.agents.length > 0) { - const firstAgentId = agentData.agents[0].name; - next(`/agent/${firstAgentId}`); - } else { - next('/'); - } + const agentData = await agentApi.getAgents(); + if (agentData && agentData.agents && agentData.agents.length > 0) { + const firstAgentId = agentData.agents[0].name; + next(`/agent/${firstAgentId}`); } else { next('/'); } diff --git a/web/src/stores/info.js b/web/src/stores/info.js index 77a49400..f647ce9b 100644 --- a/web/src/stores/info.js +++ b/web/src/stores/info.js @@ -1,6 +1,6 @@ import { ref, computed } from 'vue' import { defineStore } from 'pinia' -import { infoApi } from '@/apis/system_api' +import { brandAPi } from '@/apis/system_api' export const useInfoStore = defineStore('info', () => { // 状态 @@ -49,7 +49,7 @@ export const useInfoStore = defineStore('info', () => { try { isLoading.value = true - const response = await infoApi.getInfoConfig() + const response = await brandAPi.getInfoConfig() if (response.success && response.data) { setInfoConfig(response.data) @@ -70,7 +70,7 @@ export const useInfoStore = defineStore('info', () => { async function reloadInfoConfig() { try { isLoading.value = true - const response = await infoApi.reloadInfoConfig() + const response = await brandAPi.reloadInfoConfig() if (response.success && response.data) { setInfoConfig(response.data) diff --git a/web/src/stores/user.js b/web/src/stores/user.js index 1dfa0204..57faaf64 100644 --- a/web/src/stores/user.js +++ b/web/src/stores/user.js @@ -229,4 +229,22 @@ export const useUserStore = defineStore('user', () => { updateUser, deleteUser } -}) \ No newline at end of file +}) + +// 检查当前用户是否有管理员权限 +export const checkAdminPermission = () => { + const userStore = useUserStore() + if (!userStore.isAdmin) { + throw new Error('需要管理员权限') + } + return true +} + +// 检查当前用户是否有超级管理员权限 +export const checkSuperAdminPermission = () => { + const userStore = useUserStore() + if (!userStore.isSuperAdmin) { + throw new Error('需要超级管理员权限') + } + return true +} \ No newline at end of file diff --git a/web/src/views/AgentView.vue b/web/src/views/AgentView.vue index c73033c0..60462011 100644 --- a/web/src/views/AgentView.vue +++ b/web/src/views/AgentView.vue @@ -106,8 +106,7 @@ import AgentChatComponent from '@/components/AgentChatComponent.vue'; import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue'; import AgentConfigSidebar from '@/components/AgentConfigSidebar.vue'; import { useUserStore } from '@/stores/user'; -import { chatApi } from '@/apis/auth_api'; -import { agentConfigApi } from '@/apis/system_api'; +import { agentApi } from '@/apis/agent'; // 路由 const router = useRouter(); @@ -157,7 +156,7 @@ const setAsDefaultAgent = async () => { if (!selectedAgentId.value || !userStore.isAdmin) return; try { - await agentConfigApi.setDefaultAgent(selectedAgentId.value); + await agentApi.setDefaultAgent(selectedAgentId.value); defaultAgentId.value = selectedAgentId.value; message.success('已将当前智能体设为默认'); } catch (error) { @@ -173,7 +172,7 @@ const setAsDefaultAgent = async () => { // 获取默认智能体ID const fetchDefaultAgent = async () => { try { - const data = await chatApi.getDefaultAgent(); + const data = await agentApi.getDefaultAgent(); defaultAgentId.value = data.default_agent_id; console.debug("Default agent ID:", defaultAgentId.value); } catch (error) { @@ -184,7 +183,7 @@ const fetchDefaultAgent = async () => { // 获取智能体列表 const fetchAgents = async () => { try { - const data = await chatApi.getAgents(); + const data = await agentApi.getAgents(); // 将数组转换为对象 agents.value = data.agents.reduce((acc, agent) => { acc[agent.id] = agent; @@ -243,7 +242,7 @@ const loadAgentConfig = async () => { try { // 从服务器加载配置 - const response = await agentConfigApi.getAgentConfig(selectedAgentId.value); + const response = await agentApi.getAgentConfig(selectedAgentId.value); if (response.success && response.config) { // 合并服务器配置 Object.keys(response.config).forEach(key => { @@ -277,7 +276,7 @@ const saveConfig = async () => { try { // 保存配置到服务器 - await agentConfigApi.saveAgentConfig(selectedAgentId.value, agentConfig.value); + await agentApi.saveAgentConfig(selectedAgentId.value, agentConfig.value); // 提示保存成功 message.success('配置已保存到服务器'); console.log("保存配置:", agentConfig.value); @@ -296,7 +295,7 @@ const resetConfig = async () => { try { // 保存空配置到服务器,相当于重置 - await agentConfigApi.saveAgentConfig(selectedAgentId.value, {}); + await agentApi.saveAgentConfig(selectedAgentId.value, {}); // 重新加载默认配置 await loadAgentConfig(); message.info('配置已重置'); diff --git a/web/src/views/HomeView.vue b/web/src/views/HomeView.vue index b2ef1543..5b13a31d 100644 --- a/web/src/views/HomeView.vue +++ b/web/src/views/HomeView.vue @@ -64,7 +64,7 @@ import { ref, onMounted } from 'vue' import { useRouter } from 'vue-router' import { useUserStore } from '@/stores/user' import { useInfoStore } from '@/stores/info' -import { chatApi } from '@/apis/auth_api' +import { agentApi } from '@/apis/agent' import UserInfoComponent from '@/components/UserInfoComponent.vue' const router = useRouter() @@ -90,13 +90,13 @@ const goToChat = async () => { // 普通用户跳转到默认智能体 try { // 获取默认智能体 - const data = await chatApi.getDefaultAgent(); + const data = await agentApi.getDefaultAgent(); if (data.default_agent_id) { // 使用后端设置的默认智能体 router.push(`/agent/${data.default_agent_id}`); } else { // 如果没有设置默认智能体,则获取智能体列表选择第一个 - const agentData = await chatApi.getAgents(); + const agentData = await agentApi.getAgents(); if (agentData.agents && agentData.agents.length > 0) { router.push(`/agent/${agentData.agents[0].id}`); } else { diff --git a/web/src/views/LoginView.vue b/web/src/views/LoginView.vue index f87dbfba..f4722fc5 100644 --- a/web/src/views/LoginView.vue +++ b/web/src/views/LoginView.vue @@ -34,7 +34,6 @@