Files

87 lines
3.5 KiB
PowerShell
Raw Permalink Normal View History

2026-07-31 16:53:07 +08:00
param(
[Parameter(Mandatory = $true)][string]$ImagePath,
[Parameter(Mandatory = $true)][string]$StorageRoot,
[Parameter(Mandatory = $true)][UInt64]$TenantId,
[Parameter(Mandatory = $true)][UInt64]$QualificationId,
[Parameter(Mandatory = $true)][string]$OldDocumentUrl,
[string]$OutputDirectory = ".\reports\qualification-migration"
)
$ErrorActionPreference = "Stop"
$source = (Resolve-Path -LiteralPath $ImagePath).Path
$file = Get-Item -LiteralPath $source
if ($file.Length -le 0 -or $file.Length -gt 5MB) {
throw "资质图片必须大于 0 字节且不超过 5 MB。"
}
$bytes = [System.IO.File]::ReadAllBytes($source)
$isJpeg = $bytes.Length -ge 3 -and $bytes[0] -eq 0xFF -and $bytes[1] -eq 0xD8 -and $bytes[2] -eq 0xFF
$pngSignature = [byte[]](0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)
$isPng = $bytes.Length -ge 8
for ($index = 0; $isPng -and $index -lt $pngSignature.Length; $index++) {
$isPng = $bytes[$index] -eq $pngSignature[$index]
}
if (-not $isJpeg -and -not $isPng) {
throw "资质文件签名不是有效的 JPG 或 PNG。"
}
$extension = if ($isPng) { ".png" } else { ".jpg" }
$fileName = "{0}{1}" -f ([guid]::NewGuid().ToString()), $extension
$qualificationDirectory = Join-Path (Join-Path $StorageRoot "qualifications") $TenantId
$target = Join-Path $qualificationDirectory $fileName
New-Item -ItemType Directory -Force -Path $qualificationDirectory | Out-Null
Copy-Item -LiteralPath $source -Destination $target -ErrorAction Stop
$sourceHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $source).Hash
$targetHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $target).Hash
if ($sourceHash -ne $targetHash) {
Remove-Item -LiteralPath $target -Force
throw "复制后的文件校验和不一致,迁移已终止并清理目标文件。"
}
$newUrl = "/api/merchant/v1/files/qualifications/$fileName"
$escapedOldUrl = $OldDocumentUrl.Replace("'", "''")
$escapedNewUrl = $newUrl.Replace("'", "''")
$output = [System.IO.Path]::GetFullPath($OutputDirectory)
New-Item -ItemType Directory -Force -Path $output | Out-Null
$forwardSql = @"
START TRANSACTION;
UPDATE baiyue_iam.iam_tenant_qualification
SET document_url = '$escapedNewUrl'
WHERE id = $QualificationId
AND tenant_id = $TenantId
AND document_url = '$escapedOldUrl'
AND deleted = 0;
2026-07-31 18:10:32 +08:00
SELECT ROW_COUNT() AS affected_rows;
-- 仅当 affected_rows = 1 且平台预览校验成功时,由执行人员显式 COMMIT;否则 ROLLBACK 并删除:$target
2026-07-31 16:53:07 +08:00
"@
$rollbackSql = @"
START TRANSACTION;
UPDATE baiyue_iam.iam_tenant_qualification
SET document_url = '$escapedOldUrl'
WHERE id = $QualificationId
AND tenant_id = $TenantId
AND document_url = '$escapedNewUrl'
AND deleted = 0;
2026-07-31 18:10:32 +08:00
SELECT ROW_COUNT() AS affected_rows;
-- 仅当 affected_rows = 1 且旧文件可用时,由执行人员显式 COMMIT;否则 ROLLBACK。
2026-07-31 16:53:07 +08:00
"@
$forwardPath = Join-Path $output "qualification-$QualificationId-forward.sql"
$rollbackPath = Join-Path $output "qualification-$QualificationId-rollback.sql"
[System.IO.File]::WriteAllText($forwardPath, $forwardSql, [System.Text.UTF8Encoding]::new($false))
[System.IO.File]::WriteAllText($rollbackPath, $rollbackSql, [System.Text.UTF8Encoding]::new($false))
[pscustomobject]@{
TenantId = $TenantId
QualificationId = $QualificationId
DocumentUrl = $newUrl
PhysicalFile = $target
Sha256 = $targetHash
ForwardSql = $forwardPath
RollbackSql = $rollbackPath
MerchantPreview = $newUrl
PlatformPreview = "/api/platform/v1/files/qualifications/$TenantId/$fileName"
}