import { apiBase } from './api'; import { getStoreProfile } from './api'; const UPLOAD_TIMEOUT_MS = 120_000; export type UploadFileResult = { url: string; ossKey: string; bucket: string; mock: boolean; }; export type RegisteredResource = { id: string; url: string; }; export async function uploadFileToOss(file: File, bizType: string): Promise { const formData = new FormData(); formData.append('file', file); formData.append('bizType', bizType); formData.append('mediaType', 'IMAGE'); const token = localStorage.getItem('accessToken'); const headers: Record = { 'X-Client-App': 'SHOP_H5' }; if (token) headers.Authorization = `Bearer ${token}`; const controller = new AbortController(); const timeoutId = window.setTimeout(() => controller.abort(), UPLOAD_TIMEOUT_MS); try { const res = await fetch(`${apiBase}/common/resources/upload`, { method: 'POST', headers, body: formData, signal: controller.signal, }); const json = await res.json(); if (json.code === 401) { localStorage.removeItem('accessToken'); throw new Error('未登录'); } if (json.code !== 0) { throw new Error(json.message || '上传失败'); } return json.data as UploadFileResult; } catch (e) { if (e instanceof DOMException && e.name === 'AbortError') { throw new Error('上传超时,请检查网络后重试'); } throw e; } finally { window.clearTimeout(timeoutId); } } async function registerResource(upload: UploadFileResult, fileName: string): Promise { const profile = getStoreProfile(); if (!profile?.storeId) throw new Error('门店信息缺失,请重新登录'); const token = localStorage.getItem('accessToken'); const headers: Record = { 'Content-Type': 'application/json', 'X-Client-App': 'SHOP_H5', }; if (token) headers.Authorization = `Bearer ${token}`; const res = await fetch(`${apiBase}/common/resources`, { method: 'POST', headers, body: JSON.stringify({ ownerType: 'STORE', ownerId: profile.storeId, bizType: 'REDEEM_PENDING_PHOTO', mediaType: 'IMAGE', ossKey: upload.ossKey, url: upload.url, ossBucket: upload.bucket, fileName, }), }); const json = await res.json(); if (json.code !== 0) throw new Error(json.message || '登记资源失败'); return { id: String(json.data.id), url: String(json.data.url) }; } /** 上传核销码照片并登记为 CommonResource,返回 resourceId */ export async function uploadRedeemPendingPhoto(file: File): Promise { const uploaded = await uploadFileToOss(file, 'REDEEM_PENDING_PHOTO'); return registerResource(uploaded, file.name || 'redeem-pending.jpg'); }