From f849e5d12420cd491ac79cb20d05ed998cf8b132 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Thu, 24 Sep 2026 15:00:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=BD=E6=94=B6=E5=8D=95=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=89=8B=E5=8A=A8=E5=88=9B=E5=BB=BA=E5=A4=A7=E5=8C=85?= =?UTF-8?q?=E8=BD=A8=E8=BF=B9=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 工具栏增加创建轨迹订单按钮,调用 track-upsert-big-bag 并展示三步结果。 Co-authored-by: Cursor --- src/api/order/pickupOrder.ts | 50 ++++++++++++++ src/constants/pageButtonCatalog.ts | 1 + src/locale/en-US.ts | 2 + src/locale/zh-CN.ts | 2 + src/views/order/pickupOrder/index.vue | 93 +++++++++++++++++++++++++++ 5 files changed, 148 insertions(+) diff --git a/src/api/order/pickupOrder.ts b/src/api/order/pickupOrder.ts index f06a871..b948fe8 100644 --- a/src/api/order/pickupOrder.ts +++ b/src/api/order/pickupOrder.ts @@ -94,3 +94,53 @@ export async function postPickupOrderDownstreamForward(id: number | string) { trackNo: d.trackNo ?? d.TrackNo, } } + +export type PickupBigBagTrackStepResult = { + skipped?: boolean + skipReason?: string + success?: boolean + url?: string + requestJson?: string + statusCode?: number + responseBody?: string +} + +export type PickupBigBagTrackSyncResult = { + pickupNo?: string + success?: boolean + failStep?: string + message?: string + upsertBigBag?: PickupBigBagTrackStepResult + link?: PickupBigBagTrackStepResult + trackUpsert?: PickupBigBagTrackStepResult +} + +function mapTrackStep(raw: any | undefined): PickupBigBagTrackStepResult | undefined { + if (!raw) return undefined + return { + skipped: raw.skipped ?? raw.Skipped, + skipReason: raw.skipReason ?? raw.SkipReason, + success: raw.success ?? raw.Success, + url: raw.url ?? raw.Url, + requestJson: raw.requestJson ?? raw.RequestJson, + statusCode: raw.statusCode ?? raw.StatusCode, + responseBody: raw.responseBody ?? raw.ResponseBody, + } +} + +/** POST /order/pickup-order/track-upsert-big-bag → UpsertBigBag + Link + Track A0201 */ +export async function postPickupOrderTrackUpsertBigBag( + id: number | string, +): Promise { + const data = await postOk('/order/pickup-order/track-upsert-big-bag', { id }) + const d = (data ?? {}) as Record + return { + pickupNo: d.pickupNo ?? d.PickupNo, + success: d.success ?? d.Success, + failStep: d.failStep ?? d.FailStep, + message: d.message ?? d.Message, + upsertBigBag: mapTrackStep(d.upsertBigBag ?? d.UpsertBigBag), + link: mapTrackStep(d.link ?? d.Link), + trackUpsert: mapTrackStep(d.trackUpsert ?? d.TrackUpsert), + } +} diff --git a/src/constants/pageButtonCatalog.ts b/src/constants/pageButtonCatalog.ts index fecfddb..52f1f12 100644 --- a/src/constants/pageButtonCatalog.ts +++ b/src/constants/pageButtonCatalog.ts @@ -597,6 +597,7 @@ const CORE_GROUPS: PageButtonGroup[] = [ { code: 'Query', name: '查询' }, { code: 'Search', name: '搜索' }, { code: 'Create', name: '创建揽收订单' }, + { code: 'CreateTrack', name: '创建轨迹订单' }, { code: 'ForwardDownstream', name: '预报下游订单' }, { code: 'DownstreamForecastResult', name: '下游预报结果' }, ]), diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index cd25894..87b2707 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -891,6 +891,8 @@ export default { 'order.pickupOrder.message.downstreamNeedSelect': 'Select pickup sheets to forward downstream', 'order.pickupOrder.message.downstreamNoBoundOrders': 'Selected pickup sheets cannot be forwarded', 'order.pickupOrder.message.downstreamPartialEmpty': 'Skipped pickup sheets: {pickups}', + 'order.pickupOrder.message.trackNeedSelect': 'Select pickup sheets to create track orders', + 'order.pickupOrder.modal.trackUpsertTitle': 'Create track order result', 'order.platformStoreOrder.status.all': 'All', 'order.platformStoreOrder.status.pending': 'Pending', 'order.platformStoreOrder.status.toShip': 'To Ship', diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index c2d0670..88a1c7a 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -882,6 +882,8 @@ export default { 'order.pickupOrder.message.downstreamNeedSelect': '请先选中要预报下游的揽收单', 'order.pickupOrder.message.downstreamNoBoundOrders': '所选揽收单无法预报下游', 'order.pickupOrder.message.downstreamPartialEmpty': '以下揽收单预报已跳过:{pickups}', + 'order.pickupOrder.message.trackNeedSelect': '请先选中要创建轨迹订单的揽收单', + 'order.pickupOrder.modal.trackUpsertTitle': '创建轨迹订单结果', 'order.platformStoreOrder.status.all': '全部', 'order.platformStoreOrder.status.pending': '待处理', 'order.platformStoreOrder.status.toShip': '待发货', diff --git a/src/views/order/pickupOrder/index.vue b/src/views/order/pickupOrder/index.vue index b486912..8d4d7ff 100644 --- a/src/views/order/pickupOrder/index.vue +++ b/src/views/order/pickupOrder/index.vue @@ -24,9 +24,12 @@ import { payPickupOrder, payPickupOrderBatch, postPickupOrderDownstreamForward, + postPickupOrderTrackUpsertBigBag, removePickupOrderOrders, reschedulePickupOrder, schedulePickupOrder, + type PickupBigBagTrackSyncResult, + type PickupBigBagTrackStepResult, } from '@/api/order/pickupOrder' import { type OrderDownstreamForwardResult } from '@/api/order' import { CustomerService } from '@/api/customer' @@ -123,6 +126,9 @@ const batchScheduling = ref(false) const batchDownstreamForwarding = ref(false) const downstreamForwardModalVisible = ref(false) const downstreamForwardResultText = ref('') +const batchTrackUpserting = ref(false) +const trackUpsertModalVisible = ref(false) +const trackUpsertResultText = ref('') /** batch schedule uses same schedule modal with multiple ids */ const batchScheduleIds = ref([]) @@ -130,6 +136,10 @@ const canForwardDownstream = computed( () => hasPermission('Order.Pickup.ForwardDownstream') || hasPermission('Order.Pickup.Create'), ) +const canCreateTrack = computed( + () => + hasPermission('Order.Pickup.CreateTrack') || hasPermission('Order.Pickup.Create'), +) const selectedRowCount = computed(() => selectedRows.value.length) const hasSelectedRows = computed(() => selectedRowCount.value > 0) @@ -646,6 +656,71 @@ async function handleForwardDownstreamCreate() { } } +function formatTrackStep(stepName: string, step?: PickupBigBagTrackStepResult): string[] { + if (!step) return [`【${stepName}】未执行`] + const lines = [`【${stepName}】`] + if (step.skipped) { + lines.push(`跳过:${step.skipReason || '未知原因'}`) + return lines + } + lines.push(`成功:${step.success ? '是' : '否'}`) + lines.push(`请求:${step.url || '-'}`) + if (step.requestJson) lines.push(`请求体:\n${step.requestJson}`) + lines.push(`HTTP:${step.statusCode ?? '-'}`) + if (step.responseBody) lines.push(`响应:\n${step.responseBody}`) + return lines +} + +function formatTrackUpsertResult(pickupNo: string, result: PickupBigBagTrackSyncResult): string { + const lines = [ + `【${pickupNo || result.pickupNo || '-'}】`, + `整体:${result.success ? '成功' : '失败'}`, + ] + if (result.failStep) lines.push(`失败步骤:${result.failStep}`) + if (result.message) lines.push(`说明:${result.message}`) + lines.push('') + lines.push(...formatTrackStep('1. UpsertBigBag', result.upsertBigBag)) + lines.push('') + lines.push(...formatTrackStep('2. Link', result.link)) + lines.push('') + lines.push(...formatTrackStep('3. Track A0201', result.trackUpsert)) + return lines.join('\n') +} + +async function handleCreateTrackOrder() { + if (!canCreateTrack.value) { + $baseMessage(t('order.pickupOrder.message.noPermission'), 'warning') + return + } + if (batchTrackUpserting.value) return + + const pickupRows = selectedRows.value.filter((row) => row?.id != null) + if (!pickupRows.length) { + $baseMessage(t('order.pickupOrder.message.trackNeedSelect'), 'warning') + return + } + + batchTrackUpserting.value = true + try { + const resultBlocks: string[] = [] + for (const pickup of pickupRows) { + const pickupNo = String(pickup.pickupNo || pickup.id) + try { + const result = await postPickupOrderTrackUpsertBigBag(pickup.id) + resultBlocks.push(formatTrackUpsertResult(pickupNo, result)) + } catch (err: any) { + resultBlocks.push(`【${pickupNo}】失败:${err?.message || '请求异常'}`) + } + } + trackUpsertResultText.value = resultBlocks.join('\n\n') + trackUpsertModalVisible.value = true + } catch (e: any) { + $baseMessage(e?.message || t('order.pickupOrder.message.actionFailed'), 'error') + } finally { + batchTrackUpserting.value = false + } +} + async function doBatchPay() { const ids = batchPayCandidates.value.map((row) => row.id).filter((id) => id != null) if (!ids.length) return @@ -1401,6 +1476,15 @@ onMounted(async () => { > {{ t('order.pickupOrder.actions.batchSchedule') }} + + {{ t('order.myOrders.actions.createTrackOrder') }} + { >
{{ downstreamForwardResultText }}
+ + +
{{ trackUpsertResultText }}
+