diff --git a/src/modules/overseas-warehouse/api/lastMileOrders.ts b/src/modules/overseas-warehouse/api/lastMileOrders.ts index 76c1161e..d5136bee 100644 --- a/src/modules/overseas-warehouse/api/lastMileOrders.ts +++ b/src/modules/overseas-warehouse/api/lastMileOrders.ts @@ -374,6 +374,15 @@ export async function reviewReturnOrder(returnNo: string, customerId: string, de return unwrapApiResponse(response) } +export async function reviewDirectRelabelOrder(orderId: string, customerId: string, decision: 'APPROVE' | 'REJECT', remark?: string) { + const response = await overseasHttp.put, ApiEnvelope>( + `/platform/v1/last-leg/orders/${encodeURIComponent(orderId)}/relabel-review`, + { status: decision === 'APPROVE' ? 'PENDING_PROCESSING' : 'REJECTED', remark: remark?.trim() || undefined }, + { params: { customerId } }, + ) + return unwrapApiResponse(response) +} + export async function downloadLastMileOrders(query: Partial) { const { page: _page, size: _size, ...filters } = query const params = Object.fromEntries( diff --git a/src/modules/overseas-warehouse/api/relabelOrders.ts b/src/modules/overseas-warehouse/api/relabelOrders.ts index 1a5b747b..a79aa178 100644 --- a/src/modules/overseas-warehouse/api/relabelOrders.ts +++ b/src/modules/overseas-warehouse/api/relabelOrders.ts @@ -30,7 +30,9 @@ export interface CreateRelabelItemPayload { export interface CreateRelabelPayload { customerOrderNo: string - overseasWarehouseId: string + operationWarehouseId?: string + /** @deprecated compatibility alias for older platform fixtures */ + overseasWarehouseId?: string labelDeadline: string contactName: string contactPhone: string @@ -78,6 +80,8 @@ export interface RelabelSummaryDto { fulfillmentStatus?: string | null outboundOrderNo?: string | null customerConfirmedAt?: string | null + reviewChannel?: 'TAIL_ORDER' | 'RELABEL_ORDER' | null + reviewRemark?: string | null createdAt?: string | null } diff --git a/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue b/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue index d231dcea..71c1b291 100644 --- a/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue +++ b/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue @@ -15,7 +15,7 @@ import LoadErrorState from '@/shared/components/LoadErrorState.vue' import OperationErrorToast from '@/shared/components/OperationErrorToast.vue' import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue' import RowActions, { type RowActionItem } from '@/shared/components/RowActions.vue' -import { changeContainerReceivingWarehouse, convertLastMileContainerToInboundPlans, createManualInboundPlan, downloadLastMileOrders, getContainerInboundPlanPreview, getContainerPlanProgress, getLastMileOrderManualNodes, listContainerPlanProgress, listLastMileOrders, reviewReturnOrder, transferLastMileOrders, updateLastMileOrderHold, updateLastMileOrderManualNodes, type ContainerInboundPlanPreviewDto, type ContainerInboundPlanPreviewGroupDto, type ContainerInboundPlanPreviewOrderDto, type ContainerPlanProgressDetailDto, type ContainerPlanProgressSummaryDto, type ManualNodeCode } from '../api/lastMileOrders' +import { changeContainerReceivingWarehouse, convertLastMileContainerToInboundPlans, createManualInboundPlan, downloadLastMileOrders, getContainerInboundPlanPreview, getContainerPlanProgress, getLastMileOrderManualNodes, listContainerPlanProgress, listLastMileOrders, reviewDirectRelabelOrder, reviewReturnOrder, transferLastMileOrders, updateLastMileOrderHold, updateLastMileOrderManualNodes, type ContainerInboundPlanPreviewDto, type ContainerInboundPlanPreviewGroupDto, type ContainerInboundPlanPreviewOrderDto, type ContainerPlanProgressDetailDto, type ContainerPlanProgressSummaryDto, type ManualNodeCode } from '../api/lastMileOrders' import OrderReferenceText from '../components/OrderReferenceText.vue' import WarehouseTransferReviewDialog from '../components/WarehouseTransferReviewDialog.vue' import { confirmRelabelCompletion, getRelabelReviewTask, returnRelabelForRework } from '../api/relabelOrders' @@ -806,6 +806,25 @@ async function reviewReturn(source: object) { } else if (error !== 'close') ElMessage.error(getApiErrorDetails(error, '退货预报审核失败').message) } } +async function reviewDirectRelabel(source: object) { + const row = source as LastMileOrderListItem + if (!row.id || !row.customerId) return + try { + await ElMessageBox.confirm('审核通过后,贴标单将进入海外仓换标作业。', '贴标单审核', { confirmButtonText: '审核通过', cancelButtonText: '驳回', distinguishCancelAndClose: true }) + await reviewDirectRelabelOrder(row.id, row.customerId, 'APPROVE') + ElMessage.success('贴标单已审核通过') + await load() + } catch (error) { + if (error === 'cancel') { + try { + const { value } = await ElMessageBox.prompt('请填写驳回原因,客户可在贴标单详情查看并修改后重新提交。', '驳回贴标单', { inputType: 'textarea', inputValidator: (input) => Boolean(input?.trim()) || '请填写驳回原因', confirmButtonText: '确认驳回', cancelButtonText: '取消' }) + await reviewDirectRelabelOrder(row.id, row.customerId, 'REJECT', value) + ElMessage.success('贴标单已驳回') + await load() + } catch (rejectError) { if (rejectError !== 'cancel' && rejectError !== 'close') ElMessage.error(getApiErrorDetails(rejectError, '贴标单审核失败').message) } + } else if (error !== 'close') ElMessage.error(getApiErrorDetails(error, '贴标单审核失败').message) + } +} function canConfirmRelabel(row: { relabelStatusCode?: string }) { return row.relabelStatusCode === 'CUSTOMER_CONFIRM_PENDING' } function canReworkRelabel(row: { relabelStatusCode?: string }) { return ['CUSTOMER_CONFIRM_PENDING', 'PROCESSING'].includes(row.relabelStatusCode ?? '') } function hasRelabelActions(row: LastMileOrderListItem) { @@ -830,6 +849,7 @@ function lastMileRowActions(row: LastMileOrderListItem): RowActionItem[] { const inboundPlanCreated = hasInboundPlan(row) return [ { key: 'detail', label: '查看', priority: 500 }, + { key: 'review-direct-relabel', label: '审核', priority: 470, tone: 'warning', visible: access.can(permission.lastMileOrderTransfer) && row.orderTypeCode === 'RELABEL_APPLICATION' && row.currentStatusCode === 'PENDING_REVIEW' }, { key: 'review-return', label: '审核', priority: 460, tone: 'warning', visible: access.can(permission.returnOrderReview) && row.orderTypeCode === 'RETURN_RELABEL' && row.currentStatusCode === 'PENDING_REVIEW' }, { key: 'review', label: '审核', priority: 450, tone: 'warning', visible: access.can(permission.warehouseTransferApprove) && row.orderTypeCode === 'WAREHOUSE_TRANSFER' && row.currentStatusCode === 'PENDING_REVIEW' }, { key: 'inbound-plan', label: '生成入库计划', priority: 400, visible: access.can(permission.inboundOrderCreate) && !inboundPlanCreated }, @@ -841,6 +861,7 @@ function lastMileRowActions(row: LastMileOrderListItem): RowActionItem[] { } function handleLastMileRowAction(command: string, row: LastMileOrderListItem) { if (command === 'detail') openDetail(row) + else if (command === 'review-direct-relabel') void reviewDirectRelabel(row) else if (command === 'review-return') void reviewReturn(row) else if (command === 'review') openTransferReview(row) else if (command === 'inbound-plan') openInboundPlan(row) diff --git a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts index 595a3caa..b4d8dd92 100644 --- a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts +++ b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts @@ -19,4 +19,13 @@ describe('RelabelOrderDetailView', () => { expect(source).toContain('value?.application.customerOrderNo || value?.application.lastlegOrderNo') expect(source).toContain('item.destinationFbaWarehouseCode || item.destinationWarehouseId') }) + + it('lets platform operators confirm completion or return PDA work for rework', () => { + expect(source).toContain('@click="confirmCompletion"') + expect(source).toContain('确认换标完成') + expect(source).toContain('@click="returnForRework"') + expect(source).toContain('退回重新贴标') + expect(source).toContain('await confirmRelabelCompletion(orderId.value)') + expect(source).toContain('await returnRelabelForRework(orderId.value') + }) }) diff --git a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue index 7ff83847..1cbd6500 100644 --- a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue +++ b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue @@ -1,11 +1,11 @@