feat(ecommerce): use FormData binary upload instead of base64 dataUrl

- Add uploadAssetBinary method to aiGenerationClient (FormData + busboy)
- Replace base64 dataUrl upload in uploadProductImages with direct blob upload
  via /oss/upload-binary multipart endpoint
- This eliminates the DATA_URL_PATTERN regex parsing bug that produced
  44-byte corrupt files on OSS, causing DashScope "image format illegal" errors

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 16:03:50 +08:00
parent 160552b45e
commit 44c748b0dc
2 changed files with 20 additions and 9 deletions
+16
View File
@@ -403,6 +403,22 @@ export const aiGenerationClient = {
return readJsonResponse<{ url: string; ossKey?: string }>(res, "Asset upload response failed");
},
async uploadAssetBinary(blob: Blob, options?: { name?: string; mimeType?: string; scope?: string }): Promise<{ url: string; signedUrl?: string; ossKey?: string }> {
const form = new FormData();
form.append("file", blob, options?.name || "upload.png");
if (options?.scope) form.append("scope", options.scope);
if (options?.mimeType) form.append("mimeType", options.mimeType);
const res = await fetch(buildApiUrl("oss/upload-binary"), {
method: "POST",
headers: { ...buildAuthHeaders() },
body: form,
});
if (!res.ok) {
await throwResponseError(res, "Binary asset upload failed");
}
return readJsonResponse<{ url: string; ossKey?: string }>(res, "Binary asset upload response failed");
},
async uploadAssetByUrl(input: UploadAssetByUrlInput): Promise<{ url: string; signedUrl?: string; ossKey?: string }> {
const res = await fetch(buildApiUrl("oss/upload-by-url"), {
method: "POST",