1.修复创建多个向量库2.查看试卷没有用户答案3.向量化自动出题
This commit is contained in:
343
docs/文件上传与处理功能重构文档.md
Normal file
343
docs/文件上传与处理功能重构文档.md
Normal file
@@ -0,0 +1,343 @@
|
||||
文件上传与处理功能重构文档
|
||||
📋 修改概述
|
||||
将文件上传、向量化、出题三个功能解耦,实现分步式独立控制,支持灵活的业务场景组合。
|
||||
|
||||
🔧 核心改动
|
||||
1. 数据库表结构变更
|
||||
1.1 File 表新增字段
|
||||
tags (JSON类型):存储文件自定义标签,如版本信息、分类标识等元数据
|
||||
1.2 Question 表新增字段
|
||||
is_deleted (INT类型,默认0):软删除标志,0表示正常,1表示已删除
|
||||
|
||||
2. 实体类修改
|
||||
2.1 File 实体
|
||||
新增 tags 字段(JSON格式),支持存储任意自定义标签
|
||||
2.2 Question 实体
|
||||
新增 isDeleted 字段,实现题目软删除功能
|
||||
|
||||
3. DTO 修改
|
||||
FileUpdateRequest
|
||||
新增 tags 字段(Map类型),支持通过更新接口设置文件标签
|
||||
|
||||
4. Service 层功能增强
|
||||
4.1 QuestionService 新增方法
|
||||
软删除题目相关:
|
||||
softDeleteByFileId(Long fileId):根据文件ID软删除该文件关联的所有题目
|
||||
softDeleteByDocumentName(String documentName):根据文档名软删除所有关联题目
|
||||
实现逻辑:
|
||||
查询指定文件/文档名的所有未删除题目
|
||||
将题目的 isDeleted 字段设置为 1
|
||||
更新 updatedAt 时间戳
|
||||
返回实际删除的题目数量
|
||||
4.2 FileService 接口调整
|
||||
uploadFile 方法签名变更:
|
||||
新增参数 autoVectorize(Boolean类型)
|
||||
控制上传后是否自动触发了向量化流程
|
||||
实现逻辑:
|
||||
autoVectorize = false:仅上传文件,不向量化
|
||||
autoVectorize = true:上传后自动触发向量化(需无需审核)
|
||||
需要审核的文件无论参数如何都暂不向量化
|
||||
|
||||
5. Controller 层接口调整
|
||||
5.1 FileController 修改
|
||||
5.1.1 文件上传接口 (POST /file/upload)
|
||||
新增参数:
|
||||
autoVectorize:是否自动向量化(默认 false)
|
||||
功能说明:
|
||||
用户上传文件到服务器
|
||||
根据 autoVectorize 参数决定是否自动触发了向量化
|
||||
需要审核的文件暂存待审核区,不向量化
|
||||
5.1.2 文件删除接口 (DELETE /file/{id})
|
||||
返回值变更:
|
||||
从 Result<Void> 改为 Result<Map<String, Object>>
|
||||
功能增强:
|
||||
改为软删除(标记 status=0,不物理删除)
|
||||
自动级联软删除该文件对应的所有题目
|
||||
返回删除的题目数量统计
|
||||
返回数据:
|
||||
|
||||
{
|
||||
"success": true,
|
||||
"message": "文件和题目已成功软删除",
|
||||
"fileId": 123,
|
||||
"fileName": "document.pdf",
|
||||
"deletedQuestionCount": 15
|
||||
}
|
||||
|
||||
5.1.3 文件更新接口 (PUT /file/{id})
|
||||
新增功能:
|
||||
支持更新文件的 tags 字段
|
||||
用户可自定义存储各种元数据(版本、分类、自定义字段等)
|
||||
|
||||
5.2 CollectionController 新增接口
|
||||
5.2.1 级联软删除接口 (POST /collection/cascade-delete/{fileId})
|
||||
功能说明:
|
||||
软删除指定文件并自动软删除其关联的所有题目
|
||||
与 FileController 的删除接口功能类似,提供统一入口
|
||||
前置条件:
|
||||
用户已登录
|
||||
文件存在且未被软删除
|
||||
返回数据:{
|
||||
"success": true,
|
||||
"message": "文件和题目已成功软删除",
|
||||
"fileId": 123,
|
||||
"fileName": "document.pdf",
|
||||
"deletedQuestionCount": 15
|
||||
}
|
||||
|
||||
5.2.2 删除向量化数据接口 (POST /collection/{name}/devectorize?fileId=xxx)
|
||||
功能说明:
|
||||
删除文件的向量化数据(从 RAG 服务中移除)
|
||||
如果存在关联题目,先自动软删除题目
|
||||
清理本地数据库的文档关联记录
|
||||
触发 AI 端同步
|
||||
执行流程:
|
||||
验证文件是否存在且有向量化数据
|
||||
调用 questionService.softDeleteByFileId() 软删除关联题目
|
||||
调用 RAG 服务删除向量化文档
|
||||
清空文件的 vectorDbAddress 字段
|
||||
重置文件状态为 PENDING
|
||||
删除 collection_file 关联记录
|
||||
触发同步
|
||||
返回数据:{
|
||||
"success": true,
|
||||
"message": "向量化数据已删除",
|
||||
"fileId": 123,
|
||||
"fileName": "document.pdf",
|
||||
"deletedQuestionCount": 10
|
||||
}
|
||||
|
||||
5.2.3 文件生成题目接口 (POST /collection/{name}/generate-exam)
|
||||
功能说明:
|
||||
对已向量化完成的文件生成考试题目
|
||||
异步执行,立即返回任务提交状态
|
||||
请求参数:
|
||||
fileId(必填):文件ID
|
||||
questionTypes(可选):题目类型,逗号分隔,如 "single,multiple",默认 "single"
|
||||
difficulty(可选):难度等级 1-5,默认 3
|
||||
questionCount(可选):题目数量,默认 10
|
||||
前置条件:
|
||||
文件必须已完成向量化(vectorDbAddress 不为空)
|
||||
执行流程:
|
||||
验证文件存在且已完成向量化
|
||||
更新文件状态为 "GENERATING_EXAM"
|
||||
异步调用 examService.generateQuestionsWithFileId()
|
||||
根据结果更新文件状态和题目生成状态
|
||||
返回数据:
|
||||
|
||||
{
|
||||
"success": true,
|
||||
"message": "题目生成任务已提交,正在后台处理中",
|
||||
"fileId": 123,
|
||||
"fileName": "document.pdf",
|
||||
"collection": "public_kb",
|
||||
"requestId": "EXAM_1234567890_123",
|
||||
"status": "GENERATING"
|
||||
}
|
||||
|
||||
🎯 业务场景支持
|
||||
场景 1:只上传,不向量化
|
||||
适用情况: 临时存储文件,后续再决定是否处理
|
||||
操作流程:POST /file/upload?autoVectorize=false
|
||||
|
||||
结果:
|
||||
文件保存到服务器
|
||||
数据库记录创建
|
||||
不触发了向量化
|
||||
|
||||
场景 2:上传并自动向量化
|
||||
适用情况: 标准流程,上传后立即建立向量索引
|
||||
操作流程:POST /file/upload?autoVectorize=true
|
||||
|
||||
结果:
|
||||
文件保存到服务器
|
||||
自动触发了异步向量化
|
||||
向量化完成后自动更新状态
|
||||
|
||||
场景 3:手动触发了向量化
|
||||
适用情况: 之前上传时未向量化,现在需要补充
|
||||
操作流程:POST /collection/{name}/vectorize?fileId=123
|
||||
|
||||
结果:
|
||||
对指定文件进行向量化处理
|
||||
异步执行,返回任务提交状态
|
||||
|
||||
场景 4:向量化后生成题目
|
||||
适用情况: 文件已向量化,需要基于内容生成考试题目
|
||||
操作流程:POST /collection/{name}/generate-exam?fileId=123&questionTypes=single,multiple&difficulty=3&questionCount=10
|
||||
|
||||
结果:
|
||||
异步生成题目
|
||||
题目保存到数据库
|
||||
更新文件出题状态
|
||||
|
||||
场景 5:新文件替换旧文件
|
||||
适用情况: 上传新版本文件,需要清理旧文件及其衍生数据
|
||||
操作流程:1. 上传新文件
|
||||
|
||||
POST /file/upload?autoVectorize=true
|
||||
|
||||
2. 级联删除旧文件(包括题目)
|
||||
|
||||
POST /collection/cascade-delete/{oldFileId}
|
||||
|
||||
结果:
|
||||
旧文件标记为删除(status=0)
|
||||
旧文件关联的所有题目标记为删除(is_deleted=1)
|
||||
新文件正常处理
|
||||
|
||||
场景 6:删除向量化但保留文件
|
||||
适用情况: 需要重新向量化或不再需要向量检索
|
||||
操作流程:POST /collection/{name}/devectorize?fileId=123
|
||||
|
||||
结果:
|
||||
先软删除关联题目(避免脏数据)
|
||||
从 RAG 服务删除向量化数据
|
||||
清空文件的向量化地址
|
||||
重置文件状态为待处理
|
||||
|
||||
场景 7:删除文件及所有关联数据
|
||||
适用情况: 完全移除文件及其所有衍生数据
|
||||
操作流程:DELETE /file/{id}
|
||||
|
||||
结果:
|
||||
文件软删除(status=0)
|
||||
关联题目全部软删除(is_deleted=1)
|
||||
数据保留在数据库中,可通过恢复操作还原
|
||||
|
||||
场景 8:给文件添加自定义标签
|
||||
适用情况: 为文件添加版本、分类等元数据
|
||||
操作流程:PUT /file/{id}
|
||||
{
|
||||
"tags": {
|
||||
"version": "v2",
|
||||
"category": "important",
|
||||
"custom_field": "any_value"
|
||||
}
|
||||
}
|
||||
|
||||
结果:
|
||||
文件的 tags 字段更新为指定的 JSON 对象
|
||||
支持任意自定义字段
|
||||
|
||||
📊 状态流转
|
||||
文件状态 (processStatus)
|
||||
PENDING:待处理(上传完成但未向量化)
|
||||
VECTORIZING:正在向量化
|
||||
INDEXED:向量化完成
|
||||
GENERATING_EXAM:正在生成题目
|
||||
EXAM_GENERATED:题目生成成功
|
||||
EXAM_FAILED:题目生成失败
|
||||
DELETED:已软删除
|
||||
文件步骤状态 (processStepStatus)
|
||||
UPLOADED:已上传
|
||||
VECTORIZING:向量化中
|
||||
VECTORIZED:已向量化
|
||||
VECTORIZE_FAILED:向量化失败
|
||||
DELETED:已删除
|
||||
题目状态 (examStatus in File)
|
||||
UNGENERATED:未生成题目
|
||||
GENERATED:已生成题目
|
||||
FAILED:生成失败
|
||||
题目软删除 (isDeleted in Question)
|
||||
0:正常
|
||||
1:已删除(软删除)
|
||||
文件软删除 (status in File)
|
||||
1:正常
|
||||
0:已删除(软删除)
|
||||
|
||||
⚙️ 技术特性
|
||||
1. 软删除机制
|
||||
文件软删除:标记 status=0,不物理删除文件和数据
|
||||
题目软删除:标记 is_deleted=1,保留历史记录
|
||||
优势:数据可追溯、可恢复、符合审计要求
|
||||
|
||||
2. 级联删除
|
||||
删除文件时自动软删除关联题目
|
||||
删除向量化时先软删除题目再清理向量数据
|
||||
保证数据一致性,避免孤儿数据
|
||||
|
||||
3. 异步处理
|
||||
向量化操作异步执行,不阻塞接口响应
|
||||
题目生成异步执行,支持大批量处理
|
||||
通过状态字段追踪进度
|
||||
|
||||
4. 标签系统
|
||||
JSON 格式存储,灵活扩展
|
||||
支持任意自定义字段
|
||||
便于后续筛选和分类
|
||||
|
||||
5. 权限控制
|
||||
所有接口都需要用户登录验证
|
||||
文件删除遵循原有权限规则
|
||||
管理员可操作本部门文件
|
||||
|
||||
6. 日志记录
|
||||
完整记录关键操作流程
|
||||
包含文件ID、文件名、操作结果等信息
|
||||
便于问题排查和审计
|
||||
|
||||
7. 🔄 接口依赖关系
|
||||
|
||||
文件上传 (POST /file/upload)
|
||||
├─ autoVectorize=false → 仅上传
|
||||
└─ autoVectorize=true → 上传 + 自动向量化
|
||||
|
||||
向量化 (POST /collection/{name}/vectorize)
|
||||
└─ 前提:文件已上传且路径有效
|
||||
|
||||
批量向量化 (POST /collection/{name}/vectorize/batch)
|
||||
└─ 前提:所有文件已上传且路径有效
|
||||
|
||||
生成题目 (POST /collection/{name}/generate-exam)
|
||||
└─ 前提:文件已完成向量化
|
||||
|
||||
删除向量化 (POST /collection/{name}/devectorize)
|
||||
├─ 先软删除关联题目
|
||||
├─ 再删除 RAG 中的向量数据
|
||||
└─ 最后清理本地关联记录
|
||||
|
||||
级联删除 (POST /collection/cascade-delete/{fileId})
|
||||
├─ 软删除文件
|
||||
└─ 软删除关联题目
|
||||
|
||||
删除文件 (DELETE /file/{id})
|
||||
├─ 软删除文件
|
||||
└─ 软删除关联题目
|
||||
|
||||
更新标签 (PUT /file/{id})
|
||||
└─ 更新 tags 字段
|
||||
|
||||
✅ 测试建议
|
||||
单元测试
|
||||
测试 softDeleteByFileId 方法的正确性
|
||||
测试 softDeleteByDocumentName 方法的正确性
|
||||
测试上传接口不同 autoVectorize 参数的行为
|
||||
集成测试
|
||||
测试完整的上传→向量化→出题流程
|
||||
测试级联删除的数据一致性
|
||||
测试删除向量化后的状态重置
|
||||
测试标签的读写功能
|
||||
边界测试
|
||||
文件不存在时的错误处理
|
||||
重复删除的处理
|
||||
未完成向量化时尝试出题的处理
|
||||
空标签、null 值的处理
|
||||
|
||||
📝 注意事项
|
||||
数据库迁移:部署前需执行 SQL 脚本添加新字段
|
||||
兼容性:旧的上传接口调用需要添加 autoVectorize 参数
|
||||
性能考虑:级联删除可能涉及大量题目,注意监控执行时间
|
||||
数据恢复:软删除的数据可通过手动更新状态恢复
|
||||
标签格式:tags 字段为 JSON 格式,前端需注意序列化/反序列化
|
||||
|
||||
🚀 后续优化方向
|
||||
增加批量标签更新接口
|
||||
支持按标签筛选文件
|
||||
增加软删除数据的恢复接口
|
||||
增加删除操作的回滚机制
|
||||
优化大批量题目软删除的性能
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user