f6ba09521a14a3a07b3f24f0753255a36d8f111d
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.statusPENDING/PREPROCESSING/EXTRACTING/QA_REVIEW/APPROVED
annotation_task.statusUNCLAIMED/IN_PROGRESS/SUBMITTED/APPROVED/REJECTED
training_dataset.statusPENDING_REVIEW/APPROVED/REJECTED
video_process_job.statusPENDING/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.enabledtrue时启用真实 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
- OpenAPI 文档路径,默认
springdoc.swagger-ui.path- Swagger UI 路径,默认
/swagger-ui.html
- Swagger UI 路径,默认
API接口
以下为当前主要接口分组。
1. 认证接口
POST /api/auth/login- 登录并返回 Bearer Token
POST /api/auth/logout- 登出并立即失效当前 Token
GET /api/auth/me- 获取当前登录用户信息
2. 公司管理
GET /api/companiesPOST /api/companiesPUT /api/companies/{id}PUT /api/companies/{id}/statusDELETE /api/companies/{id}
3. 用户管理
GET /api/usersPOST /api/usersPUT /api/users/{id}PUT /api/users/{id}/statusPUT /api/users/{id}/role
4. 资料管理
POST /api/source/uploadGET /api/source/listGET /api/source/{id}DELETE /api/source/{id}
5. 任务管理
GET /api/tasks/poolGET /api/tasks/mineGET /api/tasks/pending-reviewGET /api/tasksPOST /api/tasksGET /api/tasks/{id}POST /api/tasks/{id}/claimPOST /api/tasks/{id}/unclaimPOST /api/tasks/{id}/reclaimPUT /api/tasks/{id}/reassign
6. 提取标注
GET /api/extraction/{taskId}PUT /api/extraction/{taskId}POST /api/extraction/{taskId}/submitPOST /api/extraction/{taskId}/approvePOST /api/extraction/{taskId}/reject
7. 问答生成
GET /api/qa/{taskId}PUT /api/qa/{taskId}POST /api/qa/{taskId}/submitPOST /api/qa/{taskId}/approvePOST /api/qa/{taskId}/reject
8. 导出与微调
GET /api/training/samplesPOST /api/export/batchPOST /api/export/{batchId}/finetuneGET /api/export/{batchId}/statusGET /api/export/list
9. 系统配置
GET /api/configPUT /api/config/{key}
10. 视频处理
POST /api/video/processGET /api/video/jobs/{jobId}POST /api/video/jobs/{jobId}/resetPOST /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.ziptarget/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 复制启动脚本。
注意事项
- 开发模式下
auth.enabled=false- 此时会使用 mock 用户身份,不适合生产环境
- 生产部署前必须显式启用真实鉴权
- 多租户隔离仍依赖
CompanyContext+TenantLineInnerInterceptor- 租户表查询默认依赖租户拦截器
- 个别特殊场景通过显式
companyId参数校验
sys_config、sys_company、video_process_job属于特殊表- 其中部分表被排除出自动租户注入,需在服务层显式控制
- SQL 已迁移到
src/main/resources/sql- 仅作为源码级初始化文件保留
- 不会打进构建产物
- 集成测试依赖 Testcontainers
- 运行完整集成测试需要本机可用 Docker 环境
- 认证实现已移除 Shiro
- 当前使用自定义拦截器、注解与 Redis Token
- 用户上下文 ThreadLocal 已移除
- 当前只保留
CompanyContext - 用户主体通过请求属性中的
TokenPrincipal传递
- 当前只保留
开发规范
当前约束摘要:
- 统一扁平目录结构,避免再次引入按业务域分层的旧目录
- DTO 统一放在
dto/,不再拆分request/response - Service 统一放在
service/,不拆service/impl - 业务规则优先放在 Service,Controller 只负责 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、设计文档和部署说明必须同步更新
Description
Languages
Java
99.6%
Shell
0.3%
Dockerfile
0.1%