黑盒测试用例

This commit is contained in:
wh
2026-04-14 20:00:37 +08:00
parent 999856e110
commit b0e2b3c81a
5 changed files with 1724 additions and 594 deletions

576
README.md
View File

@@ -1,172 +1,404 @@
# 数据同步微服务
## 项目简介
数据同步微服务用于从第三方接口同步人员、项目和报告数据到MySQL数据库。支持定时任务自动同步和手动触发同步
## 功能特性
1. **数据同步**
- 从第三方接口同步人员数据
- 从第三方接口同步项目(工程)数据
- 从第三方接口同步报告数据
- 支持字段大小写兼容
2. **同步方式**
- 定时任务每晚12点自动执行全量同步
- 手动触发通过REST API手动触发同步
3. **同步策略**
- 先删除表中所有现有数据
- 再全量同步接口返回的数据
- 使用接口返回的ID作为主键
## 技术栈
- Java 21
- Spring Boot 3.1.5
- Spring Cloud 2022.0.4
- MyBatis Plus 3.5.3.1
- MySQL 8.2.0
- Nacos服务注册与发现
## 项目结构
```
src/main/java/com/zhonghe/datasync/
├── common/ # 公共类
├── exception/ # 异常处理
│ ├── Result.java # 统一响应结果
└── ResultCode.java # 响应码枚举
├── config/ # 配置类
├── controller/ # 控制器
├── dto/ # 数据传输对象
├── request/ # 请求DTO
└── response/ # 响应DTO
├── entity/ # 实体类
├── mapper/ # MyBatis映射器
├── scheduled/ # 定时任务
├── service/ # 业务服务
└── util/ # 工具类
```
## 数据库表结构
### employee人员表
- id: 主键VARCHAR
- name: 人员姓名
- phone_number: 人员手机号
- password: 密码(明文存储)
- created_at: 创建时间
- updated_at: 更新时间
### project项目表
- id: 主键BIGINT
- project_name: 工程名称
- created_at: 创建时间
- updated_at: 更新时间
### report报告表
- id: 主键BIGINT
- order_number: 委托编号
- sample_code: 样品编号
- bg_sample_code: 报告编号
- project_name: 工程名称
- project_id: 工程主键
- experiment_name: 试验人员
- real_experiment_date: 试验时间
- created_at: 创建时间
- updated_at: 更新时间
## 配置说明
### 环境变量
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| MYSQL_HOST | MySQL主机地址 | localhost |
| MYSQL_PORT | MySQL端口 | 3306 |
| MYSQL_DATABASE | MySQL数据库名 | datasync |
| MYSQL_USERNAME | MySQL用户名 | root |
| MYSQL_PASSWORD | MySQL密码 | root |
| NACOS_SERVER | Nacos服务器地址 | localhost:8848 |
| NACOS_USERNAME | Nacos用户名 | nacos |
| NACOS_PASSWORD | Nacos密码 | nacos |
| THIRD_PARTY_AUTH_URL | 第三方鉴权接口地址 | http://limspro.91jiance.net/api/LoginAPI/GetAdminUserCode |
| THIRD_PARTY_EMPLOYEE_URL | 第三方人员接口地址 | http://121.40.18.211:20016/api/EmployeeAPI/GetZHEmployeeList |
| THIRD_PARTY_PROJECT_URL | 第三方项目接口地址 | http://121.40.18.211:20030/API/GetZHProjectList |
| THIRD_PARTY_REPORT_URL | 第三方报告接口地址 | http://121.40.18.211:20030/API/GetZHSampleAllList |
| THIRD_PARTY_USER_NAME | 第三方接口用户名 | 13120251031 |
| THIRD_PARTY_PASS_WORD | 第三方接口密码 | whfst@1901 |
## API接口
### 1. 同步所有数据
- **URL**: `/api/v1/sync/all`
- **方法**: POST
- **说明**: 同步人员、项目和报告数据
### 2. 同步人员数据
- **URL**: `/api/v1/sync/employees`
- **方法**: POST
- **说明**: 仅同步人员数据
### 3. 同步项目数据
- **URL**: `/api/v1/sync/projects`
- **方法**: POST
- **说明**: 仅同步项目数据
### 4. 同步报告数据
- **URL**: `/api/v1/sync/reports`
- **方法**: POST
- **说明**: 仅同步报告数据
## 定时任务
定时任务配置在 `DataSyncScheduledTask` 类中,使用 cron 表达式:
- **执行时间**: 每晚12点0 0 0 * * ?
- **执行内容**: 同步所有数据(人员、项目、报告)
## 部署说明
### 1. 数据库初始化
执行 `src/main/resources/db/schema.sql` 创建数据库表。
### 2. 构建项目
```bash
mvn clean package
```
### 3. Docker部署
```bash
docker build -t data-sync-service:1.0.0 .
docker run -d -p 8080:8080 \
-e MYSQL_HOST=your-mysql-host \
-e MYSQL_USERNAME=your-username \
-e MYSQL_PASSWORD=your-password \
data-sync-service:1.0.0
```
## 注意事项
1. **字段大小写兼容**: 使用 `@JsonProperty` 注解处理接口返回字段的大小写差异
2. **ID使用**: 使用接口返回的ID作为数据库主键不自动生成
3. **同步策略**:
- 人员数据:增量同步(不删除现有数据),新增用户密码为手机号后六位,老用户密码保持不变
- 项目和报告数据:全量同步(先删除后插入)
4. **密码管理**:
- 新增用户:密码自动设置为手机号后六位
- 更新用户:密码字段不会被修改,保持原有密码
5. **事务管理**: 同步操作使用事务,失败时会回滚
6. **日志记录**: 所有同步操作都会记录详细日志
## 开发规范
本项目遵循《微服务开发规范文档.md》中的开发规范包括
- 代码风格规范
- 命名规范
- 异常处理规范
- 日志规范
# 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 兼容对象存储
## 项目结构
项目根目录结构:
```text
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 包结构:
```text
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](d:/workspace/label/label_backend/src/main/resources/sql/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](d:/workspace/label/label_backend/src/main/resources/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](d:/workspace/label/label_backend/src/main/resources/sql/init.sql)
说明:
- `src/main/resources/sql/init.sql` 会随源码保存,但**不会被打入 jar、target/classes 或分发包**
- `docker-compose.yml` 通过挂载该文件完成 PostgreSQL 初始化
### 2. 本地构建
```bash
mvn clean package -DskipTests
```
构建产物:
- `target/libs/`
- 薄 jar 与运行时依赖
- `target/label-backend-1.0.0-SNAPSHOT.zip`
- `target/label-backend-1.0.0-SNAPSHOT.tar.gz`
### 3. 分发包结构
分发包由 [distribution.xml](d:/workspace/label/label_backend/assembly/distribution.xml) 组装,解压后结构如下:
```text
label-backend-<version>/
├── bin/
│ └── start.sh
├── etc/
│ ├── application.yml
│ └── logback.xml
├── libs/
│ ├── label-backend-<version>.jar
│ └── *.jar
└── logs/
```
### 4. 启动脚本
启动脚本位于 [start.sh](d:/workspace/label/label_backend/scripts/start.sh)。
行为说明:
- 在 Docker 容器中检测到 `/.dockerenv` 时,前台 `exec java ...`
- 在宿主机环境中使用 `nohup` 后台启动
- 日志默认写入 `logs/startup.log`
### 5. Docker Compose 启动
```bash
docker compose up -d
```
当前 `docker-compose.yml` 会启动:
- PostgreSQL
- Redis
- RustFS当前使用 MinIO 作为 S3 兼容替代)
- backend
- ai-service 占位服务
- frontend 占位服务
### 6. Docker 镜像构建
```bash
docker build -t label-backend:latest .
```
`Dockerfile` 使用多阶段构建,并从项目根目录的 `scripts/start.sh` 复制启动脚本。
## 注意事项
1. 开发模式下 `auth.enabled=false`
- 此时会使用 mock 用户身份,不适合生产环境
- 生产部署前必须显式启用真实鉴权
2. 多租户隔离仍依赖 `CompanyContext` + `TenantLineInnerInterceptor`
- 租户表查询默认依赖租户拦截器
- 个别特殊场景通过显式 `companyId` 参数校验
3. `sys_config``sys_company``video_process_job` 属于特殊表
- 其中部分表被排除出自动租户注入,需在服务层显式控制
4. SQL 已迁移到 `src/main/resources/sql`
- 仅作为源码级初始化文件保留
- 不会打进构建产物
5. 集成测试依赖 Testcontainers
- 运行完整集成测试需要本机可用 Docker 环境
6. 认证实现已移除 Shiro
- 当前使用自定义拦截器、注解与 Redis Token
7. 用户上下文 ThreadLocal 已移除
- 当前只保留 `CompanyContext`
- 用户主体通过请求属性中的 `TokenPrincipal` 传递
## 开发规范
项目实现以以下文档为准:
- 总体设计
- [2026-04-09-label-backend-design.md](d:/workspace/label/label_backend/docs/superpowers/specs/2026-04-09-label-backend-design.md)
- 目录扁平化设计
- [2026-04-14-label-backend-directory-flattening-design.md](d:/workspace/label/label_backend/docs/superpowers/specs/2026-04-14-label-backend-directory-flattening-design.md)
当前约束摘要:
- 统一扁平目录结构,避免再次引入按业务域分层的旧目录
- DTO 统一放在 `dto/`,不再拆分 `request/response`
- Service 统一放在 `service/`,不拆 `service/impl`
- 业务规则优先放在 ServiceController 只负责 HTTP 协议层
- 新增接口需同步补齐 Swagger 注解与测试
- 目录、配置、打包方式变化后README、设计文档和部署说明必须同步更新