2025-03-08 07:05:33 +08:00
|
|
|
// Mock API service for development without backend
|
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
|
|
|
|
// Mock data for knowledge bases
|
|
|
|
const mockKnowledgeBases = [
|
|
|
|
{
|
|
|
|
id: 'kb-001',
|
|
|
|
name: 'Frontend Development',
|
|
|
|
description: 'Resources and guides for frontend development including React, Vue, and Angular',
|
|
|
|
created_at: '2023-10-15T08:30:00Z',
|
|
|
|
updated_at: '2023-12-20T14:45:00Z',
|
|
|
|
create_time: '2023-10-15T08:30:00Z',
|
|
|
|
update_time: '2023-12-20T14:45:00Z',
|
|
|
|
type: 'private',
|
2025-03-13 09:14:25 +08:00
|
|
|
department: '研发部',
|
|
|
|
group: '前端开发组',
|
2025-03-08 07:05:33 +08:00
|
|
|
owner: {
|
|
|
|
id: 'user-001',
|
|
|
|
username: 'johndoe',
|
|
|
|
email: 'john@example.com',
|
2025-03-13 09:14:25 +08:00
|
|
|
department: '研发部',
|
|
|
|
group: '前端开发组',
|
2025-03-08 07:05:33 +08:00
|
|
|
},
|
|
|
|
document_count: 15,
|
|
|
|
tags: ['react', 'javascript', 'frontend'],
|
|
|
|
permissions: {
|
|
|
|
can_edit: true,
|
|
|
|
can_read: true,
|
|
|
|
},
|
|
|
|
documents: [
|
|
|
|
{
|
|
|
|
id: 'doc-001',
|
|
|
|
name: 'React Best Practices.pdf',
|
|
|
|
description: 'A guide to React best practices and patterns',
|
|
|
|
size: '1.2MB',
|
|
|
|
create_time: '2023-10-20T09:15:00Z',
|
|
|
|
update_time: '2023-10-20T09:15:00Z',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'doc-002',
|
|
|
|
name: 'Vue.js Tutorial.docx',
|
|
|
|
description: 'Step-by-step tutorial for Vue.js beginners',
|
|
|
|
size: '850KB',
|
|
|
|
create_time: '2023-11-05T14:30:00Z',
|
|
|
|
update_time: '2023-11-05T14:30:00Z',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'doc-003',
|
|
|
|
name: 'JavaScript ES6 Features.pdf',
|
|
|
|
description: 'Overview of ES6 features and examples',
|
|
|
|
size: '1.5MB',
|
|
|
|
create_time: '2023-11-15T11:45:00Z',
|
|
|
|
update_time: '2023-11-15T11:45:00Z',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'kb-002',
|
|
|
|
name: 'Backend Technologies',
|
|
|
|
description: 'Information about backend frameworks, databases, and server configurations',
|
|
|
|
created_at: '2023-09-05T10:15:00Z',
|
|
|
|
updated_at: '2024-01-10T09:20:00Z',
|
|
|
|
create_time: '2023-09-05T10:15:00Z',
|
|
|
|
update_time: '2024-01-10T09:20:00Z',
|
|
|
|
type: 'private',
|
|
|
|
owner: {
|
|
|
|
id: 'user-001',
|
|
|
|
username: 'johndoe',
|
|
|
|
email: 'john@example.com',
|
|
|
|
},
|
|
|
|
document_count: 23,
|
|
|
|
tags: ['nodejs', 'python', 'databases'],
|
|
|
|
permissions: {
|
|
|
|
can_edit: true,
|
|
|
|
can_read: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
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];
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2025-03-13 09:14:25 +08:00
|
|
|
// 导入聊天历史模拟数据和方法
|
|
|
|
import {
|
|
|
|
mockChatHistory,
|
|
|
|
mockGetChatHistory,
|
|
|
|
mockCreateChat,
|
|
|
|
mockUpdateChat,
|
|
|
|
mockDeleteChat,
|
|
|
|
} from '../store/chatHistory/chatHistory.mock';
|
|
|
|
|
|
|
|
// 模拟聊天消息数据
|
|
|
|
const chatMessages = {};
|
|
|
|
|
2025-03-08 07:05:33 +08:00
|
|
|
// Mock API functions
|
2025-03-13 09:14:25 +08:00
|
|
|
export const mockGet = async (url, config = {}) => {
|
|
|
|
console.log(`[MOCK API] GET ${url}`, config);
|
2025-03-08 07:05:33 +08:00
|
|
|
|
|
|
|
// Simulate network delay
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
|
|
|
2025-03-13 09:14:25 +08:00
|
|
|
// Get knowledge bases
|
2025-03-08 07:05:33 +08:00
|
|
|
if (url === '/knowledge-bases/') {
|
2025-03-13 09:14:25 +08:00
|
|
|
return {
|
|
|
|
data: {
|
|
|
|
items: knowledgeBases,
|
|
|
|
total: knowledgeBases.length,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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: knowledgeBase };
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get chat history
|
|
|
|
if (url === '/chat-history/') {
|
|
|
|
const params = config.params || { page: 1, page_size: 10 };
|
|
|
|
return { data: mockGetChatHistory(params) };
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
data: {
|
|
|
|
code: 200,
|
|
|
|
message: '获取成功',
|
|
|
|
data: {
|
|
|
|
messages: chatMessages[chatId] || [],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
2025-03-08 07:05:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Knowledge base search
|
|
|
|
if (url === '/knowledge-bases/search/') {
|
2025-03-13 09:14:25 +08:00
|
|
|
const { keyword = '', page = 1, page_size = 10 } = config.params || {};
|
2025-03-08 07:05:33 +08:00
|
|
|
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()))
|
|
|
|
);
|
|
|
|
return paginate(filtered, page_size, page);
|
|
|
|
}
|
|
|
|
|
|
|
|
throw { response: { status: 404, data: { message: 'Not found' } } };
|
|
|
|
};
|
|
|
|
|
|
|
|
export const mockPost = async (url, data) => {
|
|
|
|
console.log(`[MOCK API] POST ${url}`, data);
|
|
|
|
|
|
|
|
// Simulate network delay
|
2025-03-13 09:14:25 +08:00
|
|
|
await new Promise((resolve) => setTimeout(resolve, 800));
|
2025-03-08 07:05:33 +08:00
|
|
|
|
|
|
|
// 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',
|
2025-03-13 09:14:25 +08:00
|
|
|
department: data.department || null,
|
|
|
|
group: data.group || null,
|
2025-03-08 07:05:33 +08:00
|
|
|
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);
|
2025-03-13 09:14:25 +08:00
|
|
|
|
|
|
|
// 模拟后端返回格式
|
|
|
|
return {
|
|
|
|
code: 200,
|
|
|
|
message: '知识库创建成功',
|
|
|
|
data: {
|
|
|
|
knowledge_base: newKnowledgeBase,
|
|
|
|
external_id: uuidv4(),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create new chat
|
|
|
|
if (url === '/chat-history/') {
|
|
|
|
return { data: mockCreateChat(data) };
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
data: {
|
|
|
|
code: 200,
|
|
|
|
message: '发送成功',
|
|
|
|
data: {
|
|
|
|
user_message: userMessage,
|
|
|
|
bot_message: botMessage,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
2025-03-08 07:05:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2025-03-13 09:14:25 +08:00
|
|
|
|
|
|
|
// 返回与 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) };
|
2025-03-08 07:05:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
throw { response: { status: 404, data: { message: 'Not found' } } };
|
|
|
|
};
|
|
|
|
|
|
|
|
export const mockDel = 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 };
|
|
|
|
}
|
|
|
|
|
2025-03-13 09:14:25 +08:00
|
|
|
// Delete chat
|
|
|
|
if (url.match(/^\/chat-history\/[^/]+\/$/)) {
|
|
|
|
const id = url.split('/')[2];
|
|
|
|
return { data: mockDeleteChat(id) };
|
|
|
|
}
|
|
|
|
|
2025-03-08 07:05:33 +08:00
|
|
|
throw { response: { status: 404, data: { message: 'Not found' } } };
|
|
|
|
};
|
|
|
|
|
|
|
|
// Reset mock data to initial state (useful for testing)
|
|
|
|
export const resetMockData = () => {
|
|
|
|
knowledgeBases = [...mockKnowledgeBases];
|
|
|
|
};
|