包含 s-file 后端、React 前端、MeshSafe 安全检测对接,以及内外网两套 compose/nginx/配置(仅前端 28180/28280 对外发布,其余端口不暴露)。 说明:deploy/config/application-iw.yml 与 application-ow.yml 按维护者 明确要求原样入库,其中含本机 Docker 用的库口令、RabbitMQ 口令与 JWT 密钥;上生产前需替换。
172 lines
8.2 KiB
Markdown
172 lines
8.2 KiB
Markdown
# 前端接口文档 —— 文件安全检测(MeshSafe 对接)
|
||
|
||
> 版本:v1.0(2026-11-01)
|
||
> 适用后端:s-file(alita-bjy-uygur)
|
||
> Swagger 分组:「文件安全检测」
|
||
|
||
## 功能说明
|
||
|
||
对接独立文件安全检测服务 **MeshSafe**:文件上传(网盘上传)与跨网传输接收解包后,自动提交 MeshSafe 检测,检测结论回写到本系统并标记在文件上。
|
||
|
||
核心规则:
|
||
|
||
- **检测不通过(误报可复核)**:文件**只能查看/下载/预览**,**禁止分享与跨网传输**;管理员可人工复核修改检测结果(需填写复核说明),复核通过后即可正常分享/传输;
|
||
- **文件夹部分文件不通过**:分享/传输弹窗内提示未通过的文件清单,用户确认后**仅分享/传输检测通过的内容**(请求带 `onlyPassed=true`,后端排除不通过/检测中的文件);不确认则整体拦截;
|
||
- **检测中**:禁止分享与传输(检测通常秒级完成,稍后重试即可);
|
||
- **检测失败**:默认不阻断业务(仅标记"检测失败",可重新检测);`meshsafe.fail-open=false` 时检测失败同样禁止分享/传输;
|
||
- **未检测**:不阻断(历史文件/开关未开启期间上传的文件);
|
||
- 同一文件允许多条检测记录(重新检测、人工复核均新增记录),**列表与校验均取最新一条**;
|
||
- 人工复核会尽力回写 MeshSafe 的人工复核接口(失败仅告警,不影响本地生效)。
|
||
|
||
检测状态(`securityStatus`)取值:
|
||
|
||
| 值 | 含义 | 能否分享/传输 |
|
||
|---|---|---|
|
||
| 空 | 未检测 | 能 |
|
||
| 1 | 检测中 | 否 |
|
||
| 2 | 通过 | 能 |
|
||
| 3 | 不通过 | 否 |
|
||
| 4 | 检测失败 | 默认能(fail-open=false 时否) |
|
||
|
||
## 通用约定
|
||
|
||
与既有接口一致:登录态调用;统一返回 `AlitaResult<T>`(`code="200"` 且 `success=true` 成功;业务失败 `success=false`,`msg` 为提示文案)。
|
||
|
||
**总开关**:`meshsafe.enabled=false` 时检测功能整体关闭——上传/解包不送检、分享/传输不拦截、预检返回空、复核与重新检测接口报"文件安全检测未开启";前端通过 `GET /file_security/enabled` 获取开关状态,关闭时列表隐藏"安全检测"列。
|
||
|
||
## 文件列表新增字段
|
||
|
||
`GET /user_file/page`、`GET /user_file/list`、`GET /user_file/record/page_by_phone` 等返回的文件记录新增以下字段(前端据此展示与禁用操作):
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| securityStatus | String | 安全检测状态:1检测中/2通过/3不通过/4检测失败,null 为未检测 |
|
||
| securityAction | String | MeshSafe 处置动作:pass/manual_review/reject |
|
||
| securityReason | String | 检测结论说明(可直接展示给用户,人工复核时为复核说明) |
|
||
| securityReviewComment | String | 人工复核说明(人工改判时有值) |
|
||
|
||
---
|
||
|
||
## 1. 查询文件最新检测结果
|
||
|
||
- **URL**:`GET /file_security/detail`
|
||
- **权限**:所有登录用户
|
||
- **参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| fileCode | String | 是 | 文件编码 |
|
||
|
||
- **返回**:`AlitaResult<FileSecurityDTO>`,无检测记录时 `data` 为 null
|
||
|
||
**FileSecurityDTO 字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| fileCode | String | 文件编码 |
|
||
| taskId | String | MeshSafe 检测任务 ID |
|
||
| scanStatus | String | 检测状态:1检测中/2通过/3不通过/4检测失败 |
|
||
| action | String | MeshSafe 处置动作:pass/manual_review/reject |
|
||
| reason | String | 检测结论说明 |
|
||
| resultJson | String | 检测完整结果 JSON(原始响应) |
|
||
| reviewComment | String | 人工复核说明(人工改判时有值) |
|
||
| createTime | String | 记录时间 yyyy-MM-dd HH:mm:ss |
|
||
|
||
## 2. 人工复核修改检测结果
|
||
|
||
- **URL**:`POST /file_security/review`
|
||
- **权限**:平台超管(全部)/ 机构管理员(仅本机构用户的文件)
|
||
- **Content-Type**:`application/json`
|
||
- **参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| fileCode | String | 是 | 文件编码 |
|
||
| decision | String | 是 | 复核结论:`pass` 通过 / `reject` 不通过 |
|
||
| comment | String | 是 | 复核说明(审计要求,必填),例如"经人工查验为误报" |
|
||
|
||
- **返回**:`AlitaResult<FileSecurityDTO>`(本次复核生成的最新检测记录)
|
||
- **行为**:新增一条检测记录留痕并立即生效;若该文件此前有 MeshSafe 任务 ID,会尽力回写 MeshSafe 人工复核接口(失败仅告警)
|
||
|
||
**错误提示**:无检测记录、复核结论不合法、无操作权限、非本机构文件时返回 `success=false` 并附 `msg`。
|
||
|
||
## 3. 分享/传输预检
|
||
|
||
- **URL**:`GET /file_security/share_check`
|
||
- **权限**:所有登录用户(校验本人文件)
|
||
- **参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| userFileId | Long | 是 | 用户文件ID(普通文件/文件夹) |
|
||
|
||
- **返回**:`AlitaResult<FileSecurityShareCheckDTO>`
|
||
|
||
**FileSecurityShareCheckDTO 字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| fileType | String | 1文件/2文件夹 |
|
||
| totalFileCount | Integer | 目录内文件总数(不含目录) |
|
||
| blockedCount | Integer | 检测不通过数量 |
|
||
| scanningCount | Integer | 检测中数量 |
|
||
| failedCount | Integer | 检测失败数量 |
|
||
| blockedFileNames | List<String> | 检测不通过文件名 |
|
||
| scanningFileNames | List<String> | 检测中文件名 |
|
||
| failedFileNames | List<String> | 检测失败文件名 |
|
||
| excludeFileIds | List<Long> | 确认跳过时需排除的用户文件ID |
|
||
|
||
**前端用法**:文件夹分享/传输前调用,`excludeFileIds` 非空时弹窗展示文件清单,用户确认后分享/传输请求带 `onlyPassed=true`。
|
||
|
||
## 4. 分享/传输的 onlyPassed 参数
|
||
|
||
`POST /share_user_file/create`、`POST /transfer_user_file/create` 请求体新增可选字段:
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| onlyPassed | Boolean | 文件夹内存在检测未通过文件且用户已确认跳过时传 `true`,仅复制/传输检测通过的内容;缺省或 `false` 时维持整体拦截 |
|
||
|
||
规则:单文件检测不通过 → 无论该参数一律拦截;文件夹 + `onlyPassed=true` → 排除不通过/检测中文件;文件夹内全部被拦截 → 报错「文件夹内没有检测通过的文件,无法分享/传输」。
|
||
|
||
## 5. 重新提交安全检测
|
||
|
||
- **URL**:`POST /file_security/rescan`
|
||
- **权限**:平台超管(全部)/ 机构管理员(仅本机构用户的文件)
|
||
- **参数**(query):
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| fileCode | String | 是 | 文件编码 |
|
||
|
||
- **返回**:`AlitaResult<Boolean>`,受理成功返回 `true`(异步执行,结果通过列表/详情查询获取)
|
||
- **行为**:新增一条"检测中"记录并异步提交 MeshSafe;该文件正在检测中时拒绝重复提交
|
||
|
||
---
|
||
|
||
## 后端对接配置(运维)
|
||
|
||
```yaml
|
||
meshsafe:
|
||
enabled: true # 总开关,false 时完全不送检、不校验
|
||
base-url: https://meshsafe.internal
|
||
client-id: s-file # MeshSafe 分配的调用方标识
|
||
secret: "***" # MeshSafe 分配的密钥(请勿泄露)
|
||
channel: default # 业务通道标识(仅用于 MeshSafe 日志追溯)
|
||
timeout-seconds: 120 # 单次请求超时
|
||
fail-open: true # 检测服务异常时是否放行(true仅标记检测失败)
|
||
poll-timeout-minutes: 60 # 检测中记录超时时长,超时标记检测失败
|
||
review-sync-to-meshsafe: true # 人工复核是否回写 MeshSafe
|
||
poll:
|
||
cron: "0 */30 * * * ?" # 轮询未完成检测任务的定时任务(默认30秒)
|
||
```
|
||
|
||
数据表:`x_file_security`(见 `db/upgrade-20261101-meshsafe-file-security.sql`)。
|
||
|
||
送检触发点:
|
||
|
||
1. **网盘上传**:`POST /normal_user_file/create` 落库后异步送检;
|
||
2. **跨网传输接收**:传输解包定时任务创建文件记录后逐个异步送检(保护"外传内"方向);
|
||
3. **手动重新检测**:上述 `/file_security/rescan`。
|
||
|
||
分享/传输入口强校验:`POST /share_user_file/create`、`POST /transfer_user_file/create` 均校验文件及子文件的最新检测状态,不通过/检测中直接拒绝,`msg` 会带上具体文件名与原因。
|