feat: add inbound hold evidence controls
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { http } from '@/shared/api/http'
|
||||
import { downloadInboundCartonLabels, getPlatformInbound, getPlatformInboundHold, holdPlatformInbound, listPlatformInbounds, releasePlatformInbound } from './api'
|
||||
import { downloadInboundCartonLabels, downloadPlatformInboundHoldEvidence, getPlatformInbound, getPlatformInboundHold, holdPlatformInbound, listPlatformInbounds, releasePlatformInbound, uploadPlatformInboundHoldEvidence } from './api'
|
||||
|
||||
vi.mock('@/shared/api/http', () => ({
|
||||
ApiResponseError: class ApiResponseError extends Error {
|
||||
@@ -146,4 +146,27 @@ describe('platform inbound query API', () => {
|
||||
params: { tenantId: '10002' }, headers: { 'Idempotency-Key': 'release-key' },
|
||||
})
|
||||
})
|
||||
|
||||
it('uploads and downloads tenant-scoped hold evidence without narrowing long IDs', async () => {
|
||||
const file = new File(['evidence'], '扣货说明.pdf', { type: 'application/pdf' })
|
||||
vi.mocked(http.post).mockResolvedValueOnce({ data: {
|
||||
fileId: '9007199254740999', fileName: '扣货说明.pdf', contentType: 'application/pdf', sizeBytes: '8',
|
||||
} })
|
||||
await expect(uploadPlatformInboundHoldEvidence('10002', '19001', file)).resolves.toEqual({
|
||||
fileId: '9007199254740999', fileName: '扣货说明.pdf', contentType: 'application/pdf', sizeBytes: 8,
|
||||
})
|
||||
const [path, body, options] = vi.mocked(http.post).mock.calls[0]!
|
||||
expect(path).toBe('/platform/inbounds/19001/hold/evidence')
|
||||
expect(body).toBeInstanceOf(FormData)
|
||||
expect((body as FormData).get('file')).toBe(file)
|
||||
expect(options).toEqual({ params: { tenantId: '10002' }, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
|
||||
const blob = new Blob(['evidence'], { type: 'application/pdf' })
|
||||
vi.mocked(http.get).mockResolvedValueOnce(blob)
|
||||
await expect(downloadPlatformInboundHoldEvidence('10002', '19001', '9007199254740999')).resolves.toBe(blob)
|
||||
expect(http.get).toHaveBeenLastCalledWith(
|
||||
'/platform/inbounds/19001/hold/evidence/9007199254740999/download',
|
||||
{ params: { tenantId: '10002' }, responseType: 'blob' },
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
InboundInternalNote,
|
||||
InboundHoldCommand,
|
||||
InboundHoldDetail,
|
||||
InboundHoldEvidenceUpload,
|
||||
InboundListQuery,
|
||||
InboundOrderDetail,
|
||||
InboundOrderSummary,
|
||||
@@ -192,6 +193,30 @@ export function releasePlatformInbound(tenantId: string, inboundId: string, payl
|
||||
return postPlatformInboundHold(tenantId, inboundId, 'release', payload, idempotencyKey)
|
||||
}
|
||||
|
||||
export async function uploadPlatformInboundHoldEvidence(tenantId: string, inboundId: string, file: File) {
|
||||
const body = new FormData()
|
||||
body.append('file', file)
|
||||
const response = await http.post<ApiEnvelope<InboundHoldEvidenceUpload>, ApiEnvelope<InboundHoldEvidenceUpload>>(
|
||||
`${basePath}/${encodeURIComponent(inboundId)}/hold/evidence`,
|
||||
body,
|
||||
{ params: { tenantId }, headers: { 'Content-Type': 'multipart/form-data' } },
|
||||
)
|
||||
const raw = unwrapApiResponse(response)
|
||||
return {
|
||||
fileId: String(raw.fileId),
|
||||
fileName: String(raw.fileName || file.name),
|
||||
contentType: String(raw.contentType || file.type || 'application/octet-stream'),
|
||||
sizeBytes: numberValue(raw.sizeBytes) || 0,
|
||||
} satisfies InboundHoldEvidenceUpload
|
||||
}
|
||||
|
||||
export function downloadPlatformInboundHoldEvidence(tenantId: string, inboundId: string, fileId: string) {
|
||||
return http.get<Blob, Blob>(
|
||||
`${basePath}/${encodeURIComponent(inboundId)}/hold/evidence/${encodeURIComponent(fileId)}/download`,
|
||||
{ params: { tenantId }, responseType: 'blob' },
|
||||
)
|
||||
}
|
||||
|
||||
export async function downloadInboundCartonLabels(tenantId: string, inboundId: string, cartonIndexes?: number[]) {
|
||||
const response = await http.post<Blob, Blob>(
|
||||
`${basePath}/${encodeURIComponent(inboundId)}/carton-label-pdf`,
|
||||
|
||||
@@ -151,6 +151,13 @@ export interface InboundHoldCommand {
|
||||
evidenceFileId?: string
|
||||
}
|
||||
|
||||
export interface InboundHoldEvidenceUpload {
|
||||
fileId: string
|
||||
fileName: string
|
||||
contentType: string
|
||||
sizeBytes: number
|
||||
}
|
||||
|
||||
export interface InboundDropshipPallet {
|
||||
palletId: string
|
||||
palletNo: string | null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export { getInboundMeasurement, saveInboundMeasurementDraft } from './measurement/api'
|
||||
export { createInboundHoldIdempotencyKey, getPlatformInboundHold, holdPlatformInbound, releasePlatformInbound } from './core/api'
|
||||
export { createInboundHoldIdempotencyKey, downloadPlatformInboundHoldEvidence, getPlatformInboundHold, holdPlatformInbound, releasePlatformInbound, uploadPlatformInboundHoldEvidence } from './core/api'
|
||||
export { default as InboundMeasurementPanel } from './measurement/InboundMeasurementPanel.vue'
|
||||
export { default as InboundMeasurementDialog } from './measurement/InboundMeasurementDialog.vue'
|
||||
export { default as MeasurementEvidenceThumbnail } from './measurement/components/MeasurementEvidenceThumbnail.vue'
|
||||
@@ -14,4 +14,4 @@ export {
|
||||
export type { InboundFeeSnapshot } from './fee/types'
|
||||
export { downloadWeightImage } from './weight/api/weightOcr'
|
||||
export type { InboundMeasurementDetail } from './measurement/types'
|
||||
export type { InboundHoldCommand, InboundHoldDetail, InboundHoldHistoryEntry } from './core/types'
|
||||
export type { InboundHoldCommand, InboundHoldDetail, InboundHoldEvidenceUpload, InboundHoldHistoryEntry } from './core/types'
|
||||
|
||||
Reference in New Issue
Block a user