refactor(api): 重构API模块结构,合并智能体相关功能

feat(api): 新增权限检查函数和分级API请求方法
refactor(api): 将工具API合并到智能体API模块
refactor(api): 重命名系统信息API为品牌API
refactor: 更新前端组件使用新的API路径
fix: 修复知识图谱空数据时的显示问题
docs: 更新README中的品牌配置说明
This commit is contained in:
Wenjie Zhang 2025-08-24 22:32:37 +08:00
parent 51c0af517b
commit 861474d3b8
19 changed files with 247 additions and 305 deletions

View File

@ -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-*` 相关的变量,就可以改变系统的配色。

View File

@ -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可以继续添加到这里
deleteThread: (threadId) => apiDelete(`/api/chat/thread/${threadId}`)
};

View File

@ -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)
}

View File

@ -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模块已处理权限验证和请求头使用时无需再手动添加认证头
*/

View File

@ -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')
}
}

View File

@ -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)
}
}

View File

@ -1,18 +0,0 @@
import { apiGet } from './base'
/**
* 工具管理API模块
* 包含工具信息获取等功能
*/
// =============================================================================
// === 工具信息分组 ===
// =============================================================================
export const toolsApi = {
/**
* 获取所有可用工具的信息
* @returns {Promise} - 工具信息列表
*/
getTools: () => apiGet('/api/tool/tools', {}, true)
}

View File

@ -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';
// propsagentId
@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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 });

View File

@ -8,7 +8,7 @@
</div>
<!-- 图谱可视化容器 -->
<div class="graph-visualization" ref="graphContainerRef">
<div class="graph-visualization" ref="graphContainerRef" v-if="totalNodes > 0 || totalRelations > 0">
<GraphContainer :graph-data="graphData" ref="graphContainer" />
</div>

View File

@ -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('/');
}

View File

@ -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)

View File

@ -229,4 +229,22 @@ export const useUserStore = defineStore('user', () => {
updateUser,
deleteUser
}
})
})
// 检查当前用户是否有管理员权限
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
}

View File

@ -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('配置已重置');

View File

@ -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 {

View File

@ -34,7 +34,6 @@
<div class="login-form-section">
<div class="login-container">
<div class="login-logo">
<!-- <img src="@/assets/logo.svg" alt="Logo" v-if="false" /> -->
<h1>欢迎登录 {{ infoStore.branding.name }}</h1>
</div>
@ -172,7 +171,7 @@ import { useRouter } from 'vue-router';
import { useUserStore } from '@/stores/user';
import { useInfoStore } from '@/stores/info';
import { message } from 'ant-design-vue';
import { chatApi } from '@/apis/auth_api';
import { agentApi } from '@/apis/agent';
import { healthApi } from '@/apis/system_api';
import { UserOutlined, LockOutlined, WechatOutlined, QrcodeOutlined, ThunderboltOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
const router = useRouter();
@ -250,7 +249,7 @@ const handleLogin = async () => {
//
try {
//
const data = await chatApi.getDefaultAgent();
const data = await agentApi.getDefaultAgent();
if (data.default_agent_id) {
//
router.push(`/agent/${data.default_agent_id}`);
@ -258,7 +257,7 @@ const handleLogin = async () => {
}
//
const agentData = await chatApi.getAgents();
const agentData = await agentApi.getAgents();
if (agentData.agents && agentData.agents.length > 0) {
router.push(`/agent/${agentData.agents[0].id}`);
return;