文件上传与处理功能重构文档
📋 修改概述
将文件上传、向量化、出题三个功能解耦，实现分步式独立控制，支持灵活的业务场景组合。

🔧 核心改动
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 格式，前端需注意序列化/反序列化

    🚀 后续优化方向
    增加批量标签更新接口
    支持按标签筛选文件
    增加软删除数据的恢复接口
    增加删除操作的回滚机制
    优化大批量题目软删除的性能

  

  