feat(pkb): Replace Dify with self-developed pgvector RAG engine
Major milestone: Successfully replaced Dify external service with PostgreSQL + pgvector RAG engine Backend changes: - Refactor ragService.ts: Remove dual-track mode, keep only pgvector - Refactor knowledgeBaseService.ts: Remove Dify creation logic - Refactor documentService.ts: Remove Dify upload/polling logic - DifyClient.ts: Convert to deprecated stub file (for legacy compatibility) - common/rag/index.ts: Update exports - common/rag/types.ts: Remove Dify types, keep generic RAG types - config/env.ts: Remove Dify configuration Frontend changes: - DashboardPage.tsx: Add delete knowledge base dropdown menu - KnowledgeBaseList.tsx: Enhance quota warning display - CreateKBDialog.tsx: Add quota exceeded modal with guidance - knowledgeBaseApi.ts: Add auth interceptor Documentation: - Update PKB module status guide (v2.3) - Update system status guide (v4.0) Performance metrics: - Single query latency: 2.5s - Single query cost: 0.0025 CNY - Cross-language accuracy improvement: +20.5% Remaining tasks: - OSS storage integration - pg_bigm extension installation Tested: End-to-end test passed (create KB -> upload doc -> vector search)
This commit is contained in:
@@ -3,13 +3,39 @@ import axios from 'axios';
|
||||
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3001';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: `${API_BASE_URL}/api/v1`,
|
||||
baseURL: `${API_BASE_URL}/api/v1/pkb/knowledge`,
|
||||
timeout: 30000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
// 请求拦截器 - 添加认证token
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token && config.headers) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器 - 处理401未授权
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401) {
|
||||
localStorage.removeItem('token');
|
||||
window.location.href = '/login';
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 知识库类型定义
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Modal, Form, Input, message } from 'antd';
|
||||
import { Modal, Form, Input, message, Alert } from 'antd';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
@@ -32,7 +33,35 @@ const CreateKBDialog: React.FC<CreateKBDialogProps> = ({
|
||||
// 表单验证错误
|
||||
return;
|
||||
}
|
||||
message.error(error.message || '创建失败');
|
||||
|
||||
// 检查是否是配额超限错误
|
||||
const errorMsg = error.message || '创建失败';
|
||||
if (errorMsg.includes('已达上限') || errorMsg.includes('配额')) {
|
||||
Modal.warning({
|
||||
title: '知识库数量已达上限',
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
content: (
|
||||
<div>
|
||||
<p style={{ marginBottom: 12 }}>{errorMsg}</p>
|
||||
<Alert
|
||||
type="info"
|
||||
showIcon
|
||||
message="如何释放配额?"
|
||||
description={
|
||||
<ul style={{ margin: 0, paddingLeft: 16 }}>
|
||||
<li>返回知识库列表</li>
|
||||
<li>删除不再需要的知识库</li>
|
||||
<li>然后再创建新的知识库</li>
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
okText: '我知道了',
|
||||
});
|
||||
} else {
|
||||
message.error(errorMsg);
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Card, Button, Empty, Tag, Popconfirm, Space, Typography } from 'antd';
|
||||
import { Card, Button, Empty, Popconfirm, Space, Typography } from 'antd';
|
||||
import {
|
||||
PlusOutlined,
|
||||
FolderOutlined,
|
||||
@@ -65,10 +65,26 @@ const KnowledgeBaseList: React.FC<KnowledgeBaseListProps> = ({
|
||||
|
||||
{/* 配额提示 */}
|
||||
{!canCreateMore && (
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<Tag color="warning">
|
||||
已达到知识库数量上限(3个)
|
||||
</Tag>
|
||||
<div style={{
|
||||
marginBottom: 16,
|
||||
padding: '12px 16px',
|
||||
background: '#fffbe6',
|
||||
border: '1px solid #ffe58f',
|
||||
borderRadius: 6,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 8
|
||||
}}>
|
||||
<span style={{ fontSize: 16 }}>⚠️</span>
|
||||
<div>
|
||||
<Text strong style={{ color: '#d48806' }}>
|
||||
已达到知识库数量上限(3个)
|
||||
</Text>
|
||||
<br />
|
||||
<Text type="secondary" style={{ fontSize: 13 }}>
|
||||
如需创建新知识库,请先删除不需要的知识库
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user