param( [string]$BaseUrl = $env:GOAUTO_ADMIN_BASE_URL, [int]$BatchSize = 100, [int]$PageSize = 500, [int]$SleepSeconds = 1, [switch]$Force, [switch]$DryRun ) $ErrorActionPreference = 'Stop' if ([string]::IsNullOrWhiteSpace($BaseUrl) -or [string]::IsNullOrWhiteSpace($env:GOAUTO_ADMIN_TOKEN)) { throw '请设置 GOAUTO_ADMIN_BASE_URL 与 GOAUTO_ADMIN_TOKEN 环境变量' } if ($BatchSize -lt 1 -or $BatchSize -gt 500) { throw 'BatchSize 必须在 1 到 500 之间' } $headers = @{ Authorization = "Bearer $($env:GOAUTO_ADMIN_TOKEN)" } $ids = [System.Collections.Generic.List[UInt64]]::new() for ($page = 1; ; $page++) { $uri = "$($BaseUrl.TrimEnd('/'))/api/admin/v1/syb-products?parseStatus=failed&page=$page&pageSize=$PageSize" $response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get $items = if ($response.data.items) { $response.data.items } elseif ($response.data.list) { $response.data.list } else { @() } foreach ($item in $items) { if ($item.id) { [void]$ids.Add([UInt64]$item.id) } } if ($items.Count -lt $PageSize) { break } } Write-Host "发现失败记录 $($ids.Count) 条" if ($DryRun -or $ids.Count -eq 0) { exit 0 } $ok = 0; $failed = 0 for ($i = 0; $i -lt $ids.Count; $i += $BatchSize) { $end = [Math]::Min($i + $BatchSize, $ids.Count) $body = @{ ids = @($ids[$i..($end - 1)]); force = [bool]$Force } | ConvertTo-Json -Compress try { $result = Invoke-RestMethod -Uri "$($BaseUrl.TrimEnd('/'))/api/admin/v1/syb-products/reparse-batch" -Headers ($headers + @{ 'Content-Type' = 'application/json' }) -Method Post -Body $body $rows = @($result.data.results) $ok += @($rows | Where-Object { $_.newStatus -eq 'success' }).Count $failed += @($rows | Where-Object { $_.newStatus -ne 'success' }).Count Write-Host "已处理 $end/$($ids.Count),成功 $ok,仍失败 $failed" } catch { Write-Warning "批次 $($i + 1)-$end 请求失败:$($_.Exception.Message)" } if ($SleepSeconds -gt 0 -and $end -lt $ids.Count) { Start-Sleep -Seconds $SleepSeconds } }