Files
baiyue-firstleg/docs/企业资质文件迁移说明.md
2026-07-31 18:10:32 +08:00

86 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 企业资质文件迁移说明
## 统一接口边界
企业资质的唯一真实上传入口是:
```http
POST /api/merchant/v1/files/qualifications
Content-Type: multipart/form-data
```
表单字段为 `file`,可选字段为 `certificateNo`。File 服务先校验并保存真实图片,再通过内部接口通知 IAM 创建资质和审核记录。IAM 的商户资质接口只负责查询,不再提供 JSON 上传入口。
有效的商户预览地址格式为:
```text
/api/merchant/v1/files/qualifications/{uuid}.jpg
/api/merchant/v1/files/qualifications/{uuid}.png
```
数据库中的 URL 不是文件本身。禁止只生成 UUID 并修改 `document_url`,也禁止用空文件或任意图片冒充营业执照。
## 历史数据盘点
发布前先以只读方式盘点历史路径:
```sql
SELECT id, tenant_id, qualification_type, document_url, status
FROM baiyue_iam.iam_tenant_qualification
WHERE deleted = 0
AND (document_url IS NULL
OR document_url NOT REGEXP '^/api/merchant/v1/files/qualifications/[0-9a-fA-F-]{36}\\.(jpg|png)$');
```
盘点结果中的每条记录都必须找到原始图片。找不到原始图片时,将记录标记为“待业务补传”,不得伪造文件,也不得直接改 URL。
## 可落地迁移步骤
1. 暂停对应资质的替换操作,记录资质 ID、租户 ID、旧 URL 和原文件校验和。
2. 从可信旧存储取得原始图片,校验文件签名、扩展名和不超过 5 MB 的大小限制。
3. 使用迁移工具按 File 服务同一规则生成 UUID 文件名,将真实文件写入共享存储的 `qualifications/{tenantId}/` 目录。
4. 写入完成后,从 File 服务平台预览接口读取新文件并核对 SHA-256;读取失败时不得修改数据库。
5. 在单条事务中按 `id + tenant_id + 旧 document_url` 条件更新 IAM 的 `document_url`。受影响行数不是 1 时立即回滚。
6. 再次通过平台预览接口验收;验收完成前保留旧文件和旧 URL 清单,以便回滚。
容器部署前必须确认 File 实例注册名为 `file-service`,Gateway 路由目标为 `lb://file-service`,并确认 `/data/files` 是持久卷且容器用户 UID 10001 可以实际创建和删除文件。镜像内的目录权限不会覆盖宿主机 bind mount 的属主;使用宿主机目录时,须先创建目录并把所有权授予 UID 10001。旧版本已创建的卷或目录可在维护窗口使用当前 File 镜像一次性修复后重启:
```sh
docker compose --env-file <环境文件> -f deploy/docker-compose.yml run --rm --user 0 --entrypoint sh file -c 'chown -R 10001:10001 /data/files'
```
`/actuator/health` 通过后,还应执行一次脱敏图片上传和平台预览,验证 Gateway、Nacos、挂载和 IAM 协作的完整链路。
当前 File 服务使用本地或共享文件目录时,可先运行仓库内脚本生成真实文件、前向 SQL 和回滚 SQL:
```powershell
.\scripts\migrate-local-qualification-file.ps1 `
-ImagePath D:\test-data\脱敏营业执照.png `
-StorageRoot D:\baiyue-firstleg-runtime\uploads `
-TenantId 10001 `
-QualificationId 资质ID `
-OldDocumentUrl /phase1-seed/demo-business-license.jpg
```
脚本会校验文件大小、JPG/PNG 文件签名和复制前后 SHA-256,并生成带 `id + tenant_id + 旧 URL` 乐观条件的前向 SQL及回滚 SQL。脚本不会连接数据库,也不会在生成的 SQL 中自动提交事务;执行人员确认文件已落到 File 服务实际挂载目录后,才可人工执行前向 SQL,并在 `affected_rows = 1` 且平台预览校验成功后显式 `COMMIT`。否则必须 `ROLLBACK` 并删除本次新增文件。对象存储环境不使用该脚本,应通过 File 上传接口迁移。
数据库更新模板如下,执行时必须替换为经过文件校验的真实值:
```sql
START TRANSACTION;
UPDATE baiyue_iam.iam_tenant_qualification
SET document_url = :verified_new_url
WHERE id = :qualification_id
AND tenant_id = :tenant_id
AND document_url = :expected_old_url
AND deleted = 0;
-- 仅当 ROW_COUNT() = 1 且新文件已通过 File 预览校验时提交,否则回滚。
-- 执行人员检查后显式 COMMIT 或 ROLLBACK,模板不自动提交。
```
## 新环境初始化
初始化脚本不再创建 `/phase1-seed/...` 虚假资质。测试环境需要可下单的商户时,应使用脱敏但真实存在的 JPG/PNG 文件走 File 上传、平台审核完整流程,使租户达到 `ACTIVE` 且资质达到 `APPROVED`。初始化账号、文件和审核结果应作为一套环境数据验收,不得仅靠 SQL 绕过文件保存。
用于联调的样本必须在名称或图片水印中明确标注“仅供测试”,并登记租户 ID、资质 ID、文件 SHA-256 和创建时间。验收结束后按生成的回滚 SQL恢复原元数据并删除本次文件;若样本通过正常上传审核流程产生,应由测试数据清理流程按同一组标识回收,禁止直接删除仍被资质元数据引用的文件。