Merge origin/release/test and combine transport photo workflows
This commit is contained in:
@@ -3,15 +3,16 @@ import type { DispatchStage } from '../dispatchContracts'
|
||||
|
||||
export const loadingPhotoSlots = ['LOADING_SCENE', 'LOADING_LIST', 'PRE_DEPARTURE_CHECK', 'DRIVER_LICENSE', 'RECEIPT'] as const
|
||||
export type LoadingPhotoSlot = typeof loadingPhotoSlots[number]
|
||||
export const loadingPhotoLabels: Record<LoadingPhotoSlot, string> = { LOADING_SCENE: '司机驾驶证', LOADING_LIST: '车牌照片', PRE_DEPARTURE_CHECK: '装车完成', DRIVER_LICENSE: '封车照片', RECEIPT: 'BOL司机签字' }
|
||||
export interface LoadingPhoto { slot: LoadingPhotoSlot; fileId: string; fileName: string; contentType: string; savedAt: string | null }
|
||||
export interface LoadingDocuments { dispatchNo: string; recordVersion: string; dispatchRecordVersion: string; stage: DispatchStage; editable: boolean; complete: boolean; photos: LoadingPhoto[] }
|
||||
export interface BindLoadingPhoto { recordVersion: string; idempotencyKey: string; fileId: string }
|
||||
export interface LoadingDocuments { dispatchNo: string; recordVersion: string; dispatchRecordVersion: string; reviewRound: string; stage: DispatchStage; editable: boolean; complete: boolean; photos: LoadingPhoto[] }
|
||||
export interface BindLoadingPhoto { recordVersion: string; idempotencyKey: string; fileId: string; uploadKey: string; replaceFileId?: string }
|
||||
const path = (no: string) => `/platform/v1/last-leg/dispatches/${encodeURIComponent(no)}/loading-documents`
|
||||
export async function getLoadingDocuments(no: string) {
|
||||
return unwrapApiResponse(await http.get<ApiEnvelope<LoadingDocuments>, ApiEnvelope<LoadingDocuments>>(path(no)))
|
||||
}
|
||||
export async function uploadLoadingPhoto(no: string, slot: LoadingPhotoSlot, file: File, key: string) {
|
||||
const form = new FormData(); form.append('file', file); form.append('idempotencyKey', key)
|
||||
export async function uploadLoadingPhoto(no: string, slot: LoadingPhotoSlot, file: File, key: string, reviewRound: string) {
|
||||
const form = new FormData(); form.append('file', file); form.append('idempotencyKey', key); form.append('reviewRound', reviewRound)
|
||||
return unwrapApiResponse(await http.post<ApiEnvelope<LoadingPhoto>, ApiEnvelope<LoadingPhoto>>(`${path(no)}/${slot}/uploads`, form))
|
||||
}
|
||||
export async function recoverLoadingPhoto(no: string, key: string) {
|
||||
@@ -22,6 +23,6 @@ export async function bindLoadingPhoto(no: string, slot: LoadingPhotoSlot, body:
|
||||
}
|
||||
export async function readLoadingPhoto(no: string, photo: LoadingPhoto) {
|
||||
const blob = await http.get<Blob, Blob>(`${path(no)}/${photo.slot}/files/${encodeURIComponent(photo.fileId)}/content`, { responseType: 'blob' })
|
||||
if (!(blob instanceof Blob) || !['image/jpeg', 'image/png'].includes(blob.type) || !blob.size) throw new Error('图片读取失败,请重新核对')
|
||||
if (!(blob instanceof Blob) || !(['image/jpeg', 'image/png'].includes(blob.type) || photo.slot === 'LOADING_SCENE' && blob.type === 'application/pdf') || blob.type !== photo.contentType || !blob.size) throw new Error('资料读取失败,请重新核对')
|
||||
return blob
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { http } from '@/shared/api/http'
|
||||
import { getInboundPlan, listInboundPlans } from './inboundPlans'
|
||||
import { confirmInboundShortage, getInboundPlan, listInboundPlans } from './inboundPlans'
|
||||
|
||||
vi.mock('@/shared/api/http', async (importOriginal) => ({ ...(await importOriginal<typeof import('@/shared/api/http')>()), http: { get: vi.fn() } }))
|
||||
vi.mock('@/shared/api/http', async (importOriginal) => ({ ...(await importOriginal<typeof import('@/shared/api/http')>()), http: { get: vi.fn(), post: vi.fn() } }))
|
||||
describe('inbound plan overseas API', () => {
|
||||
beforeEach(() => vi.mocked(http.get).mockReset())
|
||||
it('confirms the current shortage with customer, version and idempotency key', async () => {
|
||||
vi.mocked(http.post).mockResolvedValue({ code: '200', data: { status: 'PARTIAL_INBOUND' } })
|
||||
const payload = { customerId: '190000000000000001', version: 4, expectedPackageCount: 21, receivedPackageCount: 20, reason: '短少1箱' }
|
||||
await confirmInboundShortage('IP/1', payload, 'request-key')
|
||||
expect(http.post).toHaveBeenCalledWith('/platform/v1/last-leg/inbound-plans/IP%2F1/confirm-shortage', payload, { headers: { 'Idempotency-Key': 'request-key' } })
|
||||
})
|
||||
it('pages plans with explicit customer scope', async () => {
|
||||
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'ok', data: { records: [], page: 1, size: 20, total: 0, pages: 0 } })
|
||||
await listInboundPlans({ customerId: '190000000000000001', page: 1, size: 20, inboundCode: 'IN-1' })
|
||||
|
||||
@@ -45,6 +45,7 @@ export interface InboundPlanSummaryDto {
|
||||
}
|
||||
|
||||
export interface InboundPlanDetailDto {
|
||||
version?: number
|
||||
id: string
|
||||
planNo: string
|
||||
customerId: string
|
||||
@@ -81,6 +82,21 @@ export async function getInboundPlan(planNo: string, customerId: string) {
|
||||
return unwrapApiResponse(await http.get<ApiEnvelope<InboundPlanDetailDto>, ApiEnvelope<InboundPlanDetailDto>>(`/platform/v1/last-leg/inbound-plans/${encodeURIComponent(planNo)}`, { params: { customerId } }))
|
||||
}
|
||||
|
||||
export interface ConfirmInboundShortagePayload {
|
||||
customerId: string
|
||||
version: number
|
||||
expectedPackageCount: number
|
||||
receivedPackageCount: number
|
||||
reason: string
|
||||
}
|
||||
|
||||
export async function confirmInboundShortage(planNo: string, payload: ConfirmInboundShortagePayload, idempotencyKey: string) {
|
||||
return unwrapApiResponse(await http.post<ApiEnvelope<{ status: string }>, ApiEnvelope<{ status: string }>>(
|
||||
`/platform/v1/last-leg/inbound-plans/${encodeURIComponent(planNo)}/confirm-shortage`, payload,
|
||||
{ headers: { 'Idempotency-Key': idempotencyKey } },
|
||||
))
|
||||
}
|
||||
|
||||
export interface PlatformInventoryMoveRequest {
|
||||
overseasWarehouseId: string
|
||||
sourcePalletCode: string
|
||||
|
||||
Reference in New Issue
Block a user