import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http' export type LooseboardPhotoPhase = 'PICKUP' | 'ARRIVAL' export interface LooseboardPhoto { fileId: string; fileName: string; contentType: string; sizeBytes: string | number } export interface LooseboardExecutionItem { itemId: string; customerId: string; orderNo: string; destination: string | null; packages: number; pickupPhotos: LooseboardPhoto[]; arrivalPhotos: LooseboardPhoto[]; canPickup: boolean; canArrive: boolean; warehouseNotice?: string | null; pickupRequired?: boolean } export interface LooseboardExecution { dispatchNo: string; recordVersion: string | number; stage: string; direct: boolean; items: LooseboardExecutionItem[]; canCompletePickup?: boolean; pickupCompleted?: boolean } const path = (number: string) => `/platform/v1/last-leg/dispatches/${encodeURIComponent(number)}/looseboard-execution` const itemPath = (number: string, item: string, phase: LooseboardPhotoPhase) => `${path(number)}/${encodeURIComponent(item)}/${phase}` export async function getLooseboardExecution(number: string) { return unwrapApiResponse(await http.get, ApiEnvelope>(path(number))) } export async function completeLooseboardPickup(number: string, body: { recordVersion: string | number; idempotencyKey: string }) { return unwrapApiResponse(await http.post, ApiEnvelope>(`${path(number)}/pickup-complete`, body)) } export async function uploadLooseboardPhoto(number: string, item: string, phase: LooseboardPhotoPhase, file: File) { const body = new FormData(); body.append('file', file) return unwrapApiResponse(await http.post, ApiEnvelope>(`${itemPath(number, item, phase)}/uploads`, body)) } export async function saveLooseboardPhotos(number: string, item: string, phase: LooseboardPhotoPhase, body: { recordVersion: string | number; idempotencyKey: string; fileIds: string[] }) { return unwrapApiResponse(await http.put, ApiEnvelope>(itemPath(number, item, phase), body)) } export async function readLooseboardPhoto(number: string, item: string, phase: LooseboardPhotoPhase, photo: LooseboardPhoto) { const blob = await http.get(`${itemPath(number, item, phase)}/files/${encodeURIComponent(photo.fileId)}/content`, { responseType: 'blob' }) if (!(blob instanceof Blob) || !['image/jpeg', 'image/png'].includes(blob.type) || blob.type !== photo.contentType || !blob.size) throw new Error('散板照片读取失败') return blob }