// Mock API service for development without backend import { v4 as uuidv4 } from 'uuid'; // Mock data for knowledge bases const mockKnowledgeBases = [ { id: uuidv4(), user_id: 'user-001', name: 'Frontend Development', desc: 'Resources and guides for frontend development including React, Vue, and Angular', type: 'private', department: '研发部', group: '前端开发组', documents: [], char_length: 0, document_count: 0, external_id: uuidv4(), create_time: '2024-02-26T08:30:00Z', update_time: '2024-02-26T14:45:00Z', permissions: { can_read: true, can_edit: true, can_delete: false, }, }, { id: uuidv4(), user_id: 'user-001', name: 'Backend Technologies', desc: 'Information about backend frameworks, databases, and server configurations', type: 'private', department: '研发部', group: '后端开发组', documents: [], char_length: 0, document_count: 0, external_id: uuidv4(), create_time: '2024-02-25T10:15:00Z', update_time: '2024-02-26T09:20:00Z', permissions: { can_read: true, can_edit: true, can_delete: false, }, }, { id: 'kb-003', name: 'DevOps Practices', description: 'Best practices for CI/CD, containerization, and cloud deployment', created_at: '2023-11-12T15:45:00Z', updated_at: '2024-02-05T11:30:00Z', create_time: '2023-11-12T15:45:00Z', update_time: '2024-02-05T11:30:00Z', type: 'public', owner: { id: 'user-002', username: 'janedoe', email: 'jane@example.com', }, document_count: 18, tags: ['docker', 'kubernetes', 'aws'], permissions: { can_edit: false, can_read: true, }, }, { id: 'kb-004', name: 'Machine Learning Fundamentals', description: 'Introduction to machine learning concepts, algorithms, and frameworks', created_at: '2023-08-20T09:00:00Z', updated_at: '2024-01-25T16:15:00Z', create_time: '2023-08-20T09:00:00Z', update_time: '2024-01-25T16:15:00Z', type: 'public', owner: { id: 'user-003', username: 'alexsmith', email: 'alex@example.com', }, document_count: 30, tags: ['ml', 'python', 'tensorflow'], permissions: { can_edit: false, can_read: true, }, }, { id: 'kb-005', name: 'UI/UX Design Principles', description: 'Guidelines for creating effective and user-friendly interfaces', created_at: '2023-12-01T13:20:00Z', updated_at: '2024-02-15T10:45:00Z', create_time: '2023-12-01T13:20:00Z', update_time: '2024-02-15T10:45:00Z', type: 'private', owner: { id: 'user-002', username: 'janedoe', email: 'jane@example.com', }, document_count: 12, tags: ['design', 'ui', 'ux'], permissions: { can_edit: true, can_read: true, }, }, { id: 'kb-006', name: 'Mobile App Development', description: 'Resources for iOS, Android, and cross-platform mobile development', created_at: '2023-10-25T11:10:00Z', updated_at: '2024-01-30T14:00:00Z', create_time: '2023-10-25T11:10:00Z', update_time: '2024-01-30T14:00:00Z', type: 'private', owner: { id: 'user-001', username: 'johndoe', email: 'john@example.com', }, document_count: 20, tags: ['mobile', 'react-native', 'flutter'], permissions: { can_edit: true, can_read: true, }, }, { id: 'kb-007', name: 'Cybersecurity Best Practices', description: 'Guidelines for securing applications, networks, and data', created_at: '2023-09-18T14:30:00Z', updated_at: '2024-02-10T09:15:00Z', create_time: '2023-09-18T14:30:00Z', update_time: '2024-02-10T09:15:00Z', type: 'private', owner: { id: 'user-004', username: 'sarahwilson', email: 'sarah@example.com', }, document_count: 25, tags: ['security', 'encryption', 'authentication'], permissions: { can_edit: false, can_read: false, }, }, { id: 'kb-008', name: 'Data Science Toolkit', description: 'Tools and techniques for data analysis, visualization, and modeling', created_at: '2023-11-05T10:00:00Z', updated_at: '2024-01-20T15:30:00Z', create_time: '2023-11-05T10:00:00Z', update_time: '2024-01-20T15:30:00Z', type: 'public', owner: { id: 'user-003', username: 'alexsmith', email: 'alex@example.com', }, document_count: 28, tags: ['data-science', 'python', 'visualization'], permissions: { can_edit: false, can_read: true, }, }, ]; // In-memory store for CRUD operations let knowledgeBases = [...mockKnowledgeBases]; // Mock user data for authentication const mockUsers = [ { id: 'user-001', username: 'leader2', password: 'leader123', // 在实际应用中不应该存储明文密码 email: 'admin@example.com', name: '管理员', department: '研发部', group: '前端开发组', role: 'admin', avatar: null, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z', }, { id: 'user-002', username: 'user', password: 'user123', // 在实际应用中不应该存储明文密码 email: 'user@example.com', name: '普通用户', department: '市场部', group: '市场组', role: 'user', avatar: null, created_at: '2024-01-02T00:00:00Z', updated_at: '2024-01-02T00:00:00Z', }, ]; // Helper function for pagination const paginate = (array, page_size, page) => { const startIndex = (page - 1) * page_size; const endIndex = startIndex + page_size; const items = array.slice(startIndex, endIndex); return { items, total: array.length, page, page_size, }; }; // Mock chat history data const mockChatHistory = [ { id: 'chat-001', title: '关于React组件开发的问题', knowledge_base_id: 'kb-001', knowledge_base_name: 'Frontend Development', message_count: 5, created_at: '2024-03-15T10:30:00Z', updated_at: '2024-03-15T11:45:00Z', }, { id: 'chat-002', title: 'Vue.js性能优化讨论', knowledge_base_id: 'kb-001', knowledge_base_name: 'Frontend Development', message_count: 3, created_at: '2024-03-14T15:20:00Z', updated_at: '2024-03-14T16:10:00Z', }, { id: 'chat-003', title: '后端API集成问题', knowledge_base_id: 'kb-002', knowledge_base_name: 'Backend Technologies', message_count: 4, created_at: '2024-03-13T09:15:00Z', updated_at: '2024-03-13T10:30:00Z', }, ]; // Mock chat history functions const mockGetChatHistory = (params) => { const { page = 1, page_size = 10 } = params; return paginate(mockChatHistory, page_size, page); }; const mockCreateChat = (data) => { const newChat = { id: `chat-${uuidv4().slice(0, 8)}`, title: data.title || '新对话', knowledge_base_id: data.knowledge_base_id, knowledge_base_name: data.knowledge_base_name, message_count: 0, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), }; mockChatHistory.unshift(newChat); return newChat; }; const mockUpdateChat = (id, data) => { const index = mockChatHistory.findIndex((chat) => chat.id === id); if (index === -1) { throw new Error('Chat not found'); } const updatedChat = { ...mockChatHistory[index], ...data, updated_at: new Date().toISOString(), }; mockChatHistory[index] = updatedChat; return updatedChat; }; const mockDeleteChat = (id) => { const index = mockChatHistory.findIndex((chat) => chat.id === id); if (index === -1) { throw new Error('Chat not found'); } mockChatHistory.splice(index, 1); return { success: true }; }; // 模拟聊天消息数据 const chatMessages = {}; // 权限申请列表的 mock 数据 const mockPendingRequests = [ { id: 1, knowledge_base: 'f13c4bdb-eb03-4ce2-b83c-30917351fb72', applicant: 'f2799611-7a3d-436d-b3fa-3789bdd877e2', permissions: { can_edit: false, can_read: true, can_delete: false, }, status: 'pending', reason: '需要访问知识库进行学习', response_message: null, expires_at: '2025-03-19T00:17:43.781000Z', created_at: '2025-03-12T00:17:44.044351Z', updated_at: '2025-03-12T00:17:44.044369Z', }, { id: 2, knowledge_base: 'f13c4bdb-eb03-4ce2-b83c-30917351fb73', applicant: 'f2799611-7a3d-436d-b3fa-3789bdd877e3', permissions: { can_edit: true, can_read: true, can_delete: false, }, status: 'pending', reason: '需要编辑和更新文档', response_message: null, expires_at: '2025-03-20T00:17:43.781000Z', created_at: '2025-03-12T00:17:44.044351Z', updated_at: '2025-03-12T00:17:44.044369Z', }, ]; // 用户权限列表的 mock 数据 const mockUserPermissions = [ { id: 'perm-001', user: { id: 'user-001', username: 'johndoe', name: 'John Doe', email: 'john@example.com', department: '研发部', group: '前端开发组', }, knowledge_base: { id: 'kb-001', name: 'Frontend Development Guide', }, permissions: { can_read: true, can_edit: true, can_delete: true, can_manage: true, }, granted_at: '2024-01-15T10:00:00Z', granted_by: { id: 'user-admin', username: 'admin', name: 'System Admin', }, }, { id: 'perm-002', user: { id: 'user-002', username: 'janedoe', name: 'Jane Doe', email: 'jane@example.com', department: '研发部', group: '前端开发组', }, knowledge_base: { id: 'kb-001', name: 'Frontend Development Guide', }, permissions: { can_read: true, can_edit: true, can_delete: false, can_manage: false, }, granted_at: '2024-01-20T14:30:00Z', granted_by: { id: 'user-001', username: 'johndoe', name: 'John Doe', }, }, { id: 'perm-003', user: { id: 'user-003', username: 'alexsmith', name: 'Alex Smith', email: 'alex@example.com', department: '研发部', group: '后端开发组', }, knowledge_base: { id: 'kb-001', name: 'Frontend Development Guide', }, permissions: { can_read: true, can_edit: false, can_delete: false, can_manage: false, }, granted_at: '2024-02-01T09:15:00Z', granted_by: { id: 'user-001', username: 'johndoe', name: 'John Doe', }, }, ]; // Mock API handlers for permissions const mockPermissionApi = { // 获取待处理的权限申请列表 getPendingRequests: () => { return { code: 200, message: 'success', data: { items: mockPendingRequests, total: mockPendingRequests.length, }, }; }, // 获取用户权限列表 getUserPermissions: (knowledgeBaseId) => { const permissions = mockUserPermissions.filter((perm) => perm.knowledge_base.id === knowledgeBaseId); return { code: 200, message: 'success', data: { items: permissions, total: permissions.length, }, }; }, // 处理权限申请 handlePermissionRequest: (requestId, action) => { const request = mockPendingRequests.find((req) => req.id === requestId); if (!request) { return { code: 404, message: 'Permission request not found', }; } request.status = action === 'approve' ? 'approved' : 'rejected'; if (action === 'approve') { // 如果批准,添加新的权限记录 const newPermission = { id: `perm-${Date.now()}`, user: request.user, knowledge_base: request.knowledge_base, permissions: { can_read: true, can_edit: request.request_type === 'edit', can_delete: false, can_manage: false, }, granted_at: new Date().toISOString(), granted_by: mockCurrentUser, }; mockUserPermissions.push(newPermission); } return { code: 200, message: 'success', data: request, }; }, // 更新用户权限 updateUserPermission: (permissionId, permissions) => { const permission = mockUserPermissions.find((perm) => perm.id === permissionId); if (!permission) { return { code: 404, message: 'Permission not found', }; } permission.permissions = { ...permission.permissions, ...permissions, }; return { code: 200, message: 'success', data: permission, }; }, // 删除用户权限 deleteUserPermission: (permissionId) => { const index = mockUserPermissions.findIndex((perm) => perm.id === permissionId); if (index === -1) { return { code: 404, message: 'Permission not found', }; } mockUserPermissions.splice(index, 1); return { code: 200, message: 'success', }; }, }; // Mock API functions export const mockGet = async (url, config = {}) => { console.log(`[MOCK API] GET ${url}`, config); // Simulate network delay await new Promise((resolve) => setTimeout(resolve, 500)); // Get current user if (url === '/users/me/') { return { user: mockUsers[0], // 默认返回第一个用户 }; } // Get knowledge bases if (url === '/knowledge-bases/') { const params = config.params || { page: 1, page_size: 10 }; const result = paginate(knowledgeBases, params.page_size, params.page); return { data: { code: 200, message: '获取知识库列表成功', data: { total: result.total, page: result.page, page_size: result.page_size, items: result.items, }, }, }; } // Get knowledge base details if (url.match(/^\/knowledge-bases\/[^/]+\/$/)) { const id = url.split('/')[2]; const knowledgeBase = knowledgeBases.find((kb) => kb.id === id); if (!knowledgeBase) { throw { response: { status: 404, data: { message: 'Knowledge base not found' } } }; } return { data: { code: 200, message: 'success', data: { knowledge_base: knowledgeBase, }, }, }; } // Get chat history if (url === '/chat-history/') { const params = config.params || { page: 1, page_size: 10 }; const result = mockGetChatHistory(params); return { data: { code: 200, message: 'success', data: result, }, }; } // Get chat messages if (url.match(/^\/chat-history\/[^/]+\/messages\/$/)) { const chatId = url.split('/')[2]; // 如果没有该聊天的消息记录,创建一个空数组 if (!chatMessages[chatId]) { chatMessages[chatId] = []; // 添加一条欢迎消息 const chat = mockChatHistory.find((chat) => chat.id === chatId); if (chat) { chatMessages[chatId].push({ id: uuidv4(), chat_id: chatId, sender: 'bot', content: `欢迎使用 ${chat.knowledge_base_name},有什么可以帮助您的?`, type: 'text', created_at: new Date().toISOString(), }); } } return { code: 200, message: '获取成功', data: { messages: chatMessages[chatId] || [], }, }; } // Knowledge base search if (url === '/knowledge-bases/search/') { const { keyword = '', page = 1, page_size = 10 } = config.params || {}; const filtered = knowledgeBases.filter( (kb) => kb.name.toLowerCase().includes(keyword.toLowerCase()) || kb.description.toLowerCase().includes(keyword.toLowerCase()) || kb.tags.some((tag) => tag.toLowerCase().includes(keyword.toLowerCase())) ); const result = paginate(filtered, page_size, page); return { code: 200, message: 'success', data: result, }; } // 用户权限管理 - 获取用户列表 if (url === '/users/permissions/') { return { code: 200, message: 'success', data: { users: mockUsers, }, }; } // 用户权限管理 - 获取待处理申请 if (url === '/permissions/pending/') { return { code: 200, message: 'success', data: { items: mockPendingRequests, total: mockPendingRequests.length, }, }; } // 用户权限管理 - 获取用户权限详情 if (url.match(/\/users\/(.+)\/permissions\//)) { const userId = url.match(/\/users\/(.+)\/permissions\//)[1]; return { code: 200, message: 'success', data: { permissions: mockUserPermissions[userId] || [], }, }; } throw { response: { status: 404, data: { message: 'Not found' } } }; }; export const mockPost = async (url, data) => { console.log(`[MOCK API] POST ${url}`, data); // Simulate network delay await new Promise((resolve) => setTimeout(resolve, 800)); // Login if (url === '/auth/login/') { const { username, password } = data; const user = mockUsers.find((u) => u.username === username && u.password === password); if (!user) { throw { response: { status: 401, data: { code: 401, message: '用户名或密码错误', }, }, }; } // 在实际应用中,这里应该生成 JWT token const token = `mock-jwt-token-${uuidv4()}`; return { code: 200, message: '登录成功', data: { token, id: user.id, username: user.username, email: user.email, name: user.name, department: user.department, group: user.group, role: user.role, avatar: user.avatar, }, }; } // Create knowledge base if (url === '/knowledge-bases/') { const newKnowledgeBase = { id: `kb-${uuidv4().slice(0, 8)}`, name: data.name, description: data.description || '', desc: data.desc || data.description || '', created_at: new Date().toISOString(), updated_at: new Date().toISOString(), create_time: new Date().toISOString(), update_time: new Date().toISOString(), type: data.type || 'private', department: data.department || null, group: data.group || null, owner: { id: 'user-001', username: 'johndoe', email: 'john@example.com', }, document_count: 0, tags: data.tags || [], permissions: { can_edit: true, can_read: true, }, documents: [], }; knowledgeBases.push(newKnowledgeBase); return { code: 200, message: '知识库创建成功', data: { knowledge_base: newKnowledgeBase, external_id: uuidv4(), }, }; } // Create new chat if (url === '/chat-history/') { const newChat = mockCreateChat(data); return { code: 200, message: 'success', data: { chat: newChat, }, }; } // Send chat message if (url.match(/^\/chat-history\/[^/]+\/messages\/$/)) { const chatId = url.split('/')[2]; // 如果没有该聊天的消息记录,创建一个空数组 if (!chatMessages[chatId]) { chatMessages[chatId] = []; } // 创建用户消息 const userMessage = { id: uuidv4(), chat_id: chatId, sender: 'user', content: data.content, type: data.type || 'text', created_at: new Date().toISOString(), }; // 添加用户消息 chatMessages[chatId].push(userMessage); // 创建机器人回复 const botMessage = { id: uuidv4(), chat_id: chatId, sender: 'bot', content: `这是对您问题的回复:${data.content}`, type: 'text', created_at: new Date(Date.now() + 1000).toISOString(), }; // 添加机器人回复 chatMessages[chatId].push(botMessage); // 更新聊天的最后一条消息和时间 const chatIndex = mockChatHistory.findIndex((chat) => chat.id === chatId); if (chatIndex !== -1) { mockChatHistory[chatIndex].message_count = (mockChatHistory[chatIndex].message_count || 0) + 2; mockChatHistory[chatIndex].updated_at = new Date().toISOString(); } return { code: 200, message: '发送成功', data: { user_message: userMessage, bot_message: botMessage, }, }; } // 批准权限申请 if (url === '/permissions/approve/') { const { id, responseMessage } = data; // 从待处理列表中移除该申请 mockPendingRequests = mockPendingRequests.filter((request) => request.id !== id); return { code: 200, message: 'Permission approved successfully', data: { id: id, status: 'approved', response_message: responseMessage, }, }; } // 拒绝权限申请 if (url === '/permissions/reject/') { const { id, responseMessage } = data; // 从待处理列表中移除该申请 mockPendingRequests = mockPendingRequests.filter((request) => request.id !== id); return { code: 200, message: 'Permission rejected successfully', data: { id: id, status: 'rejected', response_message: responseMessage, }, }; } throw { response: { status: 404, data: { message: 'Not found' } } }; }; export const mockPut = async (url, data) => { console.log(`[MOCK API] PUT ${url}`, data); // Simulate network delay await new Promise((resolve) => setTimeout(resolve, 600)); // Update knowledge base if (url.match(/^\/knowledge-bases\/[^/]+\/$/)) { const id = url.split('/')[2]; const index = knowledgeBases.findIndex((kb) => kb.id === id); if (index === -1) { throw { response: { status: 404, data: { message: 'Knowledge base not found' } } }; } const updatedKnowledgeBase = { ...knowledgeBases[index], ...data, updated_at: new Date().toISOString(), update_time: new Date().toISOString(), }; knowledgeBases[index] = updatedKnowledgeBase; // 返回与 mockPost 类似的格式 return { code: 200, message: '知识库更新成功', data: { knowledge_base: updatedKnowledgeBase, external_id: knowledgeBases[index].id, }, }; } // Update chat if (url.match(/^\/chat-history\/[^/]+\/$/)) { const id = url.split('/')[2]; return { data: mockUpdateChat(id, data) }; } // 更新用户权限 if (url.match(/\/users\/(.+)\/permissions\//)) { const userId = url.match(/\/users\/(.+)\/permissions\//)[1]; const { permissions } = data; // 将权限更新应用到模拟数据 if (mockUserPermissions[userId]) { // 遍历permissions对象,更新对应知识库的权限 Object.entries(permissions).forEach(([knowledgeBaseId, permissionType]) => { // 查找该用户的该知识库权限 const permissionIndex = mockUserPermissions[userId].findIndex( (p) => p.knowledge_base.id === knowledgeBaseId ); if (permissionIndex !== -1) { // 根据权限类型设置具体权限 const permission = { can_read: permissionType === 'read' || permissionType === 'edit' || permissionType === 'admin', can_edit: permissionType === 'edit' || permissionType === 'admin', can_admin: permissionType === 'admin', }; // 更新权限 mockUserPermissions[userId][permissionIndex].permission = permission; } }); } return { code: 200, message: 'Permissions updated successfully', data: { permissions: permissions, }, }; } throw { response: { status: 404, data: { message: 'Not found' } } }; }; export const mockDelete = async (url) => { console.log(`[MOCK API] DELETE ${url}`); // Simulate network delay await new Promise((resolve) => setTimeout(resolve, 800)); // Delete knowledge base if (url.match(/^\/knowledge-bases\/[^/]+\/$/)) { const id = url.split('/')[2]; const index = knowledgeBases.findIndex((kb) => kb.id === id); if (index === -1) { throw { response: { status: 404, data: { message: 'Knowledge base not found' } } }; } knowledgeBases.splice(index, 1); return { success: true }; } // Delete chat if (url.match(/^\/chat-history\/[^/]+\/$/)) { const id = url.split('/')[2]; return { data: mockDeleteChat(id) }; } throw { response: { status: 404, data: { message: 'Not found' } } }; }; // Reset mock data to initial state (useful for testing) export const resetMockData = () => { knowledgeBases = [...mockKnowledgeBases]; }; // 添加权限相关的 API 处理 export const mockApi = { // ... existing api handlers ... // 权限管理相关的 API 'GET /api/permissions/pending': () => mockPermissionApi.getPendingRequests(), 'GET /api/permissions/users/:knowledgeBaseId': (params) => mockPermissionApi.getUserPermissions(params.knowledgeBaseId), 'POST /api/permissions/handle/:requestId': (params, body) => mockPermissionApi.handlePermissionRequest(params.requestId, body.action), 'PUT /api/permissions/:permissionId': (params, body) => mockPermissionApi.updateUserPermission(params.permissionId, body.permissions), 'DELETE /api/permissions/:permissionId': (params) => mockPermissionApi.deleteUserPermission(params.permissionId), };