This commit is contained in:
2026-08-14 14:50:44 +08:00
parent a81af4a664
commit 1c1c48f8d3
11 changed files with 116 additions and 23 deletions
@@ -91,7 +91,7 @@ describe('platform container loading API', () => {
it('normalizes aggregate ids and uses the frozen overview and exception contracts', async () => {
vi.mocked(http.get).mockResolvedValueOnce({ code: '200', data: {
container: { id: 9007199254740993, warehouseId: 9007199254740994, version: '4' }, loadingPlanId: 9007199254740995,
pda: { taskId: 9007199254740996, loadingPlanId: 9007199254740995, containerBookingId: 9007199254740993, taskVersion: '2', itemCount: '4', completedItemCount: '3', unresolvedItemCount: '1', photoCounts: [{ evidenceType: 'EMPTY_CONTAINER', count: '2' }], photos: [{ evidenceId: 20, tenantId: 21, inboundId: 22, fileId: 23, downloadPath: '/api/platform/v1/files/loading-evidence/21/22/23' }], exceptionReasons: [] },
pda: { taskId: 9007199254740996, loadingPlanId: 9007199254740995, containerBookingId: 9007199254740993, taskVersion: '2', itemCount: '4', completedItemCount: '3', unresolvedItemCount: '1', photoCounts: [{ evidenceType: 'EMPTY_CONTAINER', count: '2' }], photos: [{ evidenceId: 20, tenantId: 21, inboundId: 22, fileId: 23, downloadPath: '/api/platform/v1/containers/9007199254740993/pda/photos/23/download' }], exceptionReasons: [] },
documents: [{ id: 9007199254740997, documentType: 'DELIVERY_ORDER', fileId: 9007199254740998, uploadedBy: 9, version: '2' }],
exception: { active: false, markedBy: null }, exceptionHistory: [{ id: 10, operatorId: 11 }], timeline: [{ operatorId: 12 }],
} })
@@ -117,10 +117,11 @@ describe('platform container loading API', () => {
expect(http.get).toHaveBeenCalledWith('/platform/v1/containers/7/documents/DELIVERY_ORDER/2/download', { responseType: 'blob' })
})
it('downloads PDA photos only from the backend-provided protected evidence path', async () => {
it('downloads PDA photos only from the backend-provided protected container path', async () => {
vi.mocked(http.get).mockResolvedValueOnce(new Blob(['photo']))
await downloadContainerPdaPhoto('/api/platform/v1/files/loading-evidence/21/22/23')
expect(http.get).toHaveBeenCalledWith('/api/platform/v1/files/loading-evidence/21/22/23', { responseType: 'blob' })
await downloadContainerPdaPhoto('/api/platform/v1/containers/7/pda/photos/23/download')
expect(http.get).toHaveBeenCalledWith('/api/platform/v1/containers/7/pda/photos/23/download', { responseType: 'blob' })
expect(() => downloadContainerPdaPhoto('/api/platform/v1/files/loading-evidence/21/22/23')).toThrow('invalid container photo path')
expect(() => downloadContainerPdaPhoto('https://example.com/photo.jpg')).toThrow('invalid container photo path')
})
})
@@ -145,7 +145,7 @@ export function downloadContainerDocument(containerId: string, documentType: Ext
}
export function downloadContainerPdaPhoto(downloadPath: string) {
if (!downloadPath.startsWith('/api/platform/v1/files/loading-evidence/')) throw new Error('invalid container photo path')
if (!/^\/api\/platform\/v1\/containers\/[1-9][0-9]*\/pda\/photos\/[1-9][0-9]*\/download$/.test(downloadPath)) throw new Error('invalid container photo path')
return http.get<Blob, Blob>(downloadPath, { responseType: 'blob' })
}