4.9 KiB
企业资质文件迁移说明
统一接口边界
企业资质的唯一真实上传入口是:
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。
可落地迁移步骤
- 暂停对应资质的替换操作,记录资质 ID、租户 ID、旧 URL 和原文件校验和。
- 从可信旧存储取得原始图片,校验文件签名、扩展名和不超过 5 MB 的大小限制。
- 使用迁移工具按 File 服务同一规则生成 UUID 文件名,将真实文件写入共享存储的
qualifications/{tenantId}/目录。 - 写入完成后,从 File 服务平台预览接口读取新文件并核对 SHA-256;读取失败时不得修改数据库。
- 在单条事务中按
id + tenant_id + 旧 document_url条件更新 IAM 的document_url。受影响行数不是 1 时立即回滚。 - 再次通过平台预览接口验收;验收完成前保留旧文件和旧 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恢复原元数据并删除本次文件;若样本通过正常上传审核流程产生,应由测试数据清理流程按同一组标识回收,禁止直接删除仍被资质元数据引用的文件。