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

4.9 KiB
Raw Blame History

企业资质文件迁移说明

统一接口边界

企业资质的唯一真实上传入口是:

POST /api/merchant/v1/files/qualifications
Content-Type: multipart/form-data

表单字段为 file,可选字段为 certificateNo。File 服务先校验并保存真实图片,再通过内部接口通知 IAM 创建资质和审核记录。IAM 的商户资质接口只负责查询,不再提供 JSON 上传入口。

有效的商户预览地址格式为:

/api/merchant/v1/files/qualifications/{uuid}.jpg
/api/merchant/v1/files/qualifications/{uuid}.png

数据库中的 URL 不是文件本身。禁止只生成 UUID 并修改 document_url,也禁止用空文件或任意图片冒充营业执照。

历史数据盘点

发布前先以只读方式盘点历史路径:

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 镜像一次性修复后重启:

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:

.\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 上传接口迁移。

数据库更新模板如下,执行时必须替换为经过文件校验的真实值:

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恢复原元数据并删除本次文件;若样本通过正常上传审核流程产生,应由测试数据清理流程按同一组标识回收,禁止直接删除仍被资质元数据引用的文件。