Files
label_backend/README.md
2026-04-15 15:28:11 +08:00

12 KiB
Raw Permalink Blame History

label-backend

项目简介

label-backend 是知识图谱智能标注平台的后端服务,负责资料上传、任务分发、提取标注、问答生成、训练样本导出、系统配置和视频预处理等核心流程。

系统采用 Spring Boot 3 + MyBatis-Plus + PostgreSQL + Redis 的技术组合,面向多租户标注场景设计,支持:

  • 公司级数据隔离
  • 基于 Redis Token 的认证鉴权
  • 提取与问答两阶段标注流程
  • 导出训练数据并对接微调任务
  • 视频预处理与异步回调
  • 审计日志与任务状态追踪

代码结构已按扁平标准目录整理,主包位于 src/main/java/com/label

功能特性

  • 认证鉴权
    • 使用 UUID Bearer Token + Redis 会话存储
    • 自定义 @RequireAuth@RequireRole
    • 角色分级:ADMIN > REVIEWER > ANNOTATOR > UPLOADER
  • 多租户隔离
    • 基于 CompanyContext + TenantLineInnerInterceptor
    • 对租户表自动追加 company_id 条件
    • 特殊表通过显式 companyId 参数校验
  • 公司与用户管理
    • 公司 CRUD
    • 公司内用户创建、状态变更、角色变更
    • 角色变更和禁用后即时刷新或失效 Redis Token
  • 资料管理
    • 支持文本、图片、视频三类原始资料
    • 上传到 RustFS数据库保存元数据
    • 支持按角色查看、查询详情、删除
  • 任务管理
    • 任务池、我的任务、待审批队列、管理员全量视图
    • Redis 分布式锁 + 数据库原子更新保证任务领取并发安全
  • 提取标注
    • AI 预标注
    • 标注结果整体覆盖更新
    • 提交、审批通过、驳回
  • 问答生成
    • 基于提取审批通过事件生成候选问答对
    • 支持编辑、提交、审批、驳回
  • 训练数据导出
    • 查询已审批样本
    • 创建导出批次
    • 触发微调任务并查询状态
  • 系统配置
    • 支持公司专属配置覆盖全局默认配置
    • 配置项存储于 sys_config
  • 视频处理
    • 支持触发视频预处理任务
    • 支持异步回调、失败重试、管理员重置

技术栈

  • Java 21
  • Spring Boot 3.1.5
  • Spring MVC
  • MyBatis-Plus 3.5.3.1
  • PostgreSQL
  • Redis
  • Spring AOP
  • springdoc-openapi
  • Testcontainers
  • RustFS / S3 兼容对象存储

项目结构

项目根目录结构:

label_backend/
├── assembly/                      # 分发包描述与占位目录
├── docs/                          # 设计、计划、规范文档
├── scripts/                       # 启动脚本
├── src/
│   ├── main/
│   │   ├── java/com/label/        # 主代码
│   │   └── resources/
│   │       ├── application.yml
│   │       ├── logback.xml
│   │       └── sql/               # 初始化 SQL不打入构建产物
│   └── test/
│       ├── java/                  # 单元测试与集成测试
│       └── resources/db/init.sql  # Testcontainers 测试初始化 SQL
├── docker-compose.yml
├── Dockerfile
├── pom.xml
└── README.md

Java 包结构:

com.label
├── annotation     # 自定义注解,如 RequireAuth / RequireRole / OperationLog
├── aspect         # AOP 审计切面
├── common         # 通用能力auth、context、exception、result、storage、ai、statemachine
├── config         # Spring 配置、MyBatis-Plus 配置、认证拦截器注册
├── controller     # 所有 REST 接口
├── dto            # DTO
├── entity         # 实体
├── event          # 领域事件
├── interceptor    # 认证拦截器
├── listener       # 事件监听器
├── mapper         # MyBatis Mapper
├── service        # 业务服务
└── util           # 工具类

数据库表结构

初始化脚本位于 init.sql,包含 11 张核心表:

  • sys_company
    • 租户公司表
  • sys_user
    • 公司用户表,包含角色与状态
  • source_data
    • 原始资料元数据,支持 TEXT / IMAGE / VIDEO
  • annotation_task
    • 标注任务表,支持 EXTRACTION / QA_GENERATION
  • annotation_result
    • 提取阶段 JSON 结果
  • training_dataset
    • 训练样本数据,存储 GLM 格式 JSON
  • export_batch
    • 导出批次与微调任务状态
  • sys_config
    • 全局与公司级配置
  • sys_operation_log
    • 审计日志,只追加不更新
  • annotation_task_history
    • 任务状态变更历史
  • video_process_job
    • 视频预处理任务与回调状态

当前主要状态机:

  • source_data.status
    • PENDING / PREPROCESSING / EXTRACTING / QA_REVIEW / APPROVED
  • annotation_task.status
    • UNCLAIMED / IN_PROGRESS / SUBMITTED / APPROVED / REJECTED
  • training_dataset.status
    • PENDING_REVIEW / APPROVED / REJECTED
  • video_process_job.status
    • PENDING / RETRYING / SUCCESS / FAILED

配置说明

主配置文件位于 application.yml

环境变量

变量名 说明
SPRING_DATASOURCE_URL PostgreSQL JDBC 地址
SPRING_DATASOURCE_USERNAME PostgreSQL 用户名
SPRING_DATASOURCE_PASSWORD PostgreSQL 密码
SPRING_DATA_REDIS_HOST Redis 主机
SPRING_DATA_REDIS_PORT Redis 端口
SPRING_DATA_REDIS_PASSWORD Redis 密码
RUSTFS_ENDPOINT RustFS / S3 兼容服务地址
RUSTFS_ACCESS_KEY RustFS Access Key
RUSTFS_SECRET_KEY RustFS Secret Key
AI_SERVICE_BASE_URL AI 服务地址
VIDEO_CALLBACK_SECRET 视频处理回调共享密钥

关键配置项

  • auth.enabled
    • true 时启用真实 Token 鉴权
    • false 时使用 mock 身份,便于本地开发
  • auth.mock-company-id
    • 开发模式下的模拟公司 ID
  • auth.mock-user-id
    • 开发模式下的模拟用户 ID
  • auth.mock-role
    • 开发模式下的模拟角色
  • token.ttl-seconds
    • Token 有效期,默认 7200 秒
  • springdoc.api-docs.path
    • OpenAPI 文档路径,默认 /v3/api-docs
  • springdoc.swagger-ui.path
    • Swagger UI 路径,默认 /swagger-ui.html

API接口

以下为当前主要接口分组。

1. 认证接口

  • POST /api/auth/login
    • 登录并返回 Bearer Token
  • POST /api/auth/logout
    • 登出并立即失效当前 Token
  • GET /api/auth/me
    • 获取当前登录用户信息

2. 公司管理

  • GET /api/companies
  • POST /api/companies
  • PUT /api/companies/{id}
  • PUT /api/companies/{id}/status
  • DELETE /api/companies/{id}

3. 用户管理

  • GET /api/users
  • POST /api/users
  • PUT /api/users/{id}
  • PUT /api/users/{id}/status
  • PUT /api/users/{id}/role

4. 资料管理

  • POST /api/source/upload
  • GET /api/source/list
  • GET /api/source/{id}
  • DELETE /api/source/{id}

5. 任务管理

  • GET /api/tasks/pool
  • GET /api/tasks/mine
  • GET /api/tasks/pending-review
  • GET /api/tasks
  • POST /api/tasks
  • GET /api/tasks/{id}
  • POST /api/tasks/{id}/claim
  • POST /api/tasks/{id}/unclaim
  • POST /api/tasks/{id}/reclaim
  • PUT /api/tasks/{id}/reassign

6. 提取标注

  • GET /api/extraction/{taskId}
  • PUT /api/extraction/{taskId}
  • POST /api/extraction/{taskId}/submit
  • POST /api/extraction/{taskId}/approve
  • POST /api/extraction/{taskId}/reject

7. 问答生成

  • GET /api/qa/{taskId}
  • PUT /api/qa/{taskId}
  • POST /api/qa/{taskId}/submit
  • POST /api/qa/{taskId}/approve
  • POST /api/qa/{taskId}/reject

8. 导出与微调

  • GET /api/training/samples
  • POST /api/export/batch
  • POST /api/export/{batchId}/finetune
  • GET /api/export/{batchId}/status
  • GET /api/export/list

9. 系统配置

  • GET /api/config
  • PUT /api/config/{key}

10. 视频处理

  • POST /api/video/process
  • GET /api/video/jobs/{jobId}
  • POST /api/video/jobs/{jobId}/reset
  • POST /api/video/callback

定时任务

当前项目中没有启用 Spring @Scheduled 定时同步任务

现有异步能力主要通过以下方式完成:

  • 事务提交后事件监听
    • 提取审批通过后触发问答生成
  • 外部 AI 服务异步回调
    • 视频处理完成后回调 /api/video/callback
  • Redis 分布式锁
    • 用于任务领取并发控制

如果后续需要周期性任务,建议单独引入明确的调度场景,不要复用当前业务链路中的事件机制。

部署说明

1. 数据库初始化

初始化 SQL 位于:

说明:

  • src/main/resources/sql/init.sql 会随源码保存,但不会被打入 jar、target/classes 或分发包
  • docker-compose.yml 通过挂载该文件完成 PostgreSQL 初始化

2. 本地构建

mvn clean package -DskipTests

构建产物: ...

  • target/label-backend-1.0.0-SNAPSHOT.zip
  • target/label-backend-1.0.0-SNAPSHOT.tar.gz

3. 分发包结构

分发包由 distribution.xml 组装,解压后结构如下:

label-backend-<version>/
├── bin/
│   └── start.sh
├── etc/
│   ├── application.yml
│   └── logback.xml
├── libs/
│   ├── label-backend-<version>.jar
│   └── *.jar
└── logs/

4. 启动脚本

启动脚本位于 start.sh

行为说明:

  • 在 Docker 容器中检测到 /.dockerenv 时,前台 exec java ...
  • 在宿主机环境中使用 nohup 后台启动
  • 日志默认写入 logs/startup.log

5. Docker Compose 启动

docker compose up -d

当前 docker-compose.yml 会启动:

  • PostgreSQL
  • Redis
  • RustFS当前使用 MinIO 作为 S3 兼容替代)
  • backend
  • ai-service 占位服务
  • frontend 占位服务

6. Docker 镜像构建

docker build -t label-backend:latest .

Dockerfile 使用多阶段构建,并从项目根目录的 scripts/start.sh 复制启动脚本。

注意事项

  1. 开发模式下 auth.enabled=false
    • 此时会使用 mock 用户身份,不适合生产环境
    • 生产部署前必须显式启用真实鉴权
  2. 多租户隔离仍依赖 CompanyContext + TenantLineInnerInterceptor
    • 租户表查询默认依赖租户拦截器
    • 个别特殊场景通过显式 companyId 参数校验
  3. sys_configsys_companyvideo_process_job 属于特殊表
    • 其中部分表被排除出自动租户注入,需在服务层显式控制
  4. SQL 已迁移到 src/main/resources/sql
    • 仅作为源码级初始化文件保留
    • 不会打进构建产物
  5. 集成测试依赖 Testcontainers
    • 运行完整集成测试需要本机可用 Docker 环境
  6. 认证实现已移除 Shiro
    • 当前使用自定义拦截器、注解与 Redis Token
  7. 用户上下文 ThreadLocal 已移除
    • 当前只保留 CompanyContext
    • 用户主体通过请求属性中的 TokenPrincipal 传递

开发规范

当前约束摘要:

  • 统一扁平目录结构,避免再次引入按业务域分层的旧目录
  • DTO 统一放在 dto/,不再拆分 request/response
  • Service 统一放在 service/,不拆 service/impl
  • 业务规则优先放在 ServiceController 只负责 HTTP 协议层
  • 新增接口需同步补齐 Swagger 注解与测试
  • 所有对外接口参数必须在 Swagger 中明确体现名称、类型和含义
  • 固定结构请求体禁止继续使用匿名 Map<String, Object>Map<String, String>,必须定义 DTO 并补齐 @Schema 字段说明
  • 固定结构响应应优先使用明确 DTO或至少为 Swagger 暴露对象补齐字段级 @Schema 注解
  • 路径参数、查询参数、请求体、分页包装和通用返回体都必须维护可读的 OpenAPI 文档说明
  • 需要保持历史兼容的原始 JSON 字符串请求体可以继续使用 String,但必须在 Swagger @RequestBody 中说明完整 JSON body 的提交方式和兼容原因
  • 修改 Controller 参数、请求 DTO、响应 DTO 或对外实体后,必须运行 mvn -Dtest=OpenApiAnnotationTest test,确保 Swagger 参数名称、类型和含义没有回退
  • 目录、配置、打包方式变化后README、设计文档和部署说明必须同步更新