/**
* 教师端 - 知识库管理页面
* 对应原始 index.html 的 knowledge-base section
* 复用原始HTML的知识库创建和管理逻辑
*/
import { useState, useEffect } from 'react';
import { Card, Form, Input, Upload, Button, Row, Col, message, Progress, Space, Modal, List, Tag } from 'antd';
import {
UploadOutlined,
DeleteOutlined,
FileTextOutlined,
FilePdfOutlined,
FileWordOutlined,
FileImageOutlined,
PlusOutlined,
ExclamationCircleOutlined,
} from '@ant-design/icons';
import { motion } from 'framer-motion';
import knowledgeService from '../../services/knowledgeService';
const { confirm } = Modal;
const KnowledgeBase = () => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const [knowledgeBases, setKnowledgeBases] = useState([]);
const [uploadProgress, setUploadProgress] = useState(0);
const [uploading, setUploading] = useState(false);
const [fileList, setFileList] = useState([]);
useEffect(() => {
loadKnowledgeBases();
}, []);
// 加载知识库列表
const loadKnowledgeBases = async () => {
try {
setLoading(true);
const res = await knowledgeService.getKnowledgeBases();
setKnowledgeBases(res.data || []);
} catch (error) {
console.error('加载知识库失败:', error);
message.error('加载知识库失败');
} finally {
setLoading(false);
}
};
// 创建知识库
const handleCreateKnowledgeBase = async (values) => {
if (fileList.length === 0) {
message.warning('请选择要上传的文件');
return;
}
try {
setUploading(true);
// 后端只支持单文件上传,所以需要逐个上传
const firstFile = fileList[0];
const formData = new FormData();
formData.append('name', values.name);
formData.append('file', firstFile.originFileObj); // 注意:使用 'file' 不是 'files'
const res = await knowledgeService.createKnowledgeBase(formData);
if (res.success) {
message.success('知识库创建成功!');
// 如果有taskId,轮询进度
if (res.data?.task_id) {
pollProgress(res.data.task_id);
}
// 如果还有其他文件,需要逐个添加到知识库
if (fileList.length > 1) {
message.info(`正在上传剩余 ${fileList.length - 1} 个文件...`);
// 获取创建的知识库ID
const kbId = `rag_${values.name}`;
// 上传剩余文件
for (let i = 1; i < fileList.length; i++) {
const additionalFormData = new FormData();
additionalFormData.append('file', fileList[i].originFileObj);
try {
const addRes = await knowledgeService.addFileToKnowledgeBase(kbId, additionalFormData);
if (addRes.success && addRes.data?.task_id) {
pollProgress(addRes.data.task_id);
}
} catch (error) {
console.error(`上传文件 ${fileList[i].name} 失败:`, error);
message.error(`文件 ${fileList[i].name} 上传失败`);
}
}
}
form.resetFields();
setFileList([]);
setUploadProgress(0);
loadKnowledgeBases();
}
} catch (error) {
message.error('创建知识库失败');
console.error('创建知识库失败:', error);
} finally {
setUploading(false);
}
};
// 轮询文件处理进度
const pollProgress = async (taskId) => {
const maxAttempts = 60; // 最多轮询60次(约1分钟)
let attempts = 0;
const poll = async () => {
try {
const res = await knowledgeService.getProgress(taskId);
if (res.data?.status === 'completed') {
setUploadProgress(100);
message.success('文件处理完成');
loadKnowledgeBases();
return;
}
if (res.data?.status === 'failed') {
message.error('文件处理失败');
return;
}
if (res.data?.progress) {
setUploadProgress(res.data.progress);
}
attempts++;
if (attempts < maxAttempts) {
setTimeout(poll, 1000); // 每秒轮询一次
}
} catch (error) {
console.error('获取进度失败:', error);
}
};
poll();
};
// 删除知识库
const handleDeleteKnowledgeBase = (kbId, kbName) => {
confirm({
title: '确认删除',
icon:
创建和管理您的教学资料知识库