diff --git a/src/components/InterfaceDetail/index.vue b/src/components/InterfaceDetail/index.vue index 4a13975..bfde355 100644 --- a/src/components/InterfaceDetail/index.vue +++ b/src/components/InterfaceDetail/index.vue @@ -3709,11 +3709,11 @@ /> - 复制 + @@ -4489,11 +4489,11 @@ /> - 复制 + @@ -5230,8 +5230,9 @@ .content-type-copy-btn { margin-left: auto; flex-shrink: 0; + width: 24px; height: 24px; - padding: 0 10px; + padding: 0; border-radius: 4px; } } diff --git a/src/constants/pageButtonCatalog.ts b/src/constants/pageButtonCatalog.ts index f54546d..9e4740d 100644 --- a/src/constants/pageButtonCatalog.ts +++ b/src/constants/pageButtonCatalog.ts @@ -596,6 +596,8 @@ const CORE_GROUPS: PageButtonGroup[] = [ { code: 'Query', name: '查询' }, { code: 'Search', name: '搜索' }, { code: 'Create', name: '创建揽收订单' }, + { code: 'ForwardDownstream', name: '预报下游订单' }, + { code: 'DownstreamForecastResult', name: '下游预报结果' }, ]), B('Order.Customs9610', [ { code: 'Query', name: '查询' }, diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index 9804187..ab6975e 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -829,6 +829,9 @@ export default { 'order.pickupOrder.message.batchScheduleNoCandidates': 'No draft/scheduled sheets selected for forecast', 'order.pickupOrder.message.batchScheduleHint': 'Draft-forecast {count} pickup sheet(s)', 'order.pickupOrder.message.batchScheduleResult': 'Batch schedule: {success} succeeded, {fail} failed', + 'order.pickupOrder.message.downstreamNeedSelect': 'Select pickup sheets to forward downstream', + 'order.pickupOrder.message.downstreamNoBoundOrders': 'Selected pickup sheets have no bound orders to forward', + 'order.pickupOrder.message.downstreamPartialEmpty': 'Skipped pickup sheets with no bound orders: {pickups}', 'order.platformStoreOrder.status.all': 'All', 'order.platformStoreOrder.status.pending': 'Pending', 'order.platformStoreOrder.status.toShip': 'To Ship', @@ -1878,6 +1881,8 @@ export default { 'order.myOrders.drawer.issueHandling.processFailed': 'Failed to mark as processed', 'order.myOrders.drawer.attachments.upload': 'Upload', 'order.myOrders.drawer.attachments.preview': 'Preview', + 'order.myOrders.drawer.attachments.previewFailed': 'Preview failed', + 'order.myOrders.drawer.attachments.previewBlocked': 'Please allow pop-ups to preview the attachment', 'order.myOrders.drawer.attachments.delete': 'Delete', 'order.myOrders.drawer.attachments.empty': 'No attachments', 'order.myOrders.drawer.attachments.loadFailed': 'Failed to load attachments', diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index 926905b..e674baf 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -825,6 +825,9 @@ export default { 'order.pickupOrder.message.batchScheduleNoCandidates': '所选揽收单无草稿/已预约可预报项', 'order.pickupOrder.message.batchScheduleHint': '将对已选 {count} 张揽收单统一草稿预报', 'order.pickupOrder.message.batchScheduleResult': '批量预报:成功 {success},失败 {fail}', + 'order.pickupOrder.message.downstreamNeedSelect': '请先选中要预报下游的揽收单', + 'order.pickupOrder.message.downstreamNoBoundOrders': '所选揽收单没有可预报的绑定运单', + 'order.pickupOrder.message.downstreamPartialEmpty': '以下揽收单无绑定运单或拉取失败,已跳过:{pickups}', 'order.platformStoreOrder.status.all': '全部', 'order.platformStoreOrder.status.pending': '待处理', 'order.platformStoreOrder.status.toShip': '待发货', @@ -1771,6 +1774,8 @@ export default { 'order.myOrders.drawer.issueHandling.processFailed': '标记已处理失败', 'order.myOrders.drawer.attachments.upload': '上传', 'order.myOrders.drawer.attachments.preview': '预览', + 'order.myOrders.drawer.attachments.previewFailed': '预览失败', + 'order.myOrders.drawer.attachments.previewBlocked': '请允许弹出窗口以预览附件', 'order.myOrders.drawer.attachments.delete': '删除', 'order.myOrders.drawer.attachments.empty': '暂无附件', 'order.myOrders.drawer.attachments.loadFailed': '加载附件失败', diff --git a/src/utils/orderCreateOneBody.ts b/src/utils/orderCreateOneBody.ts index 8519089..86a5002 100644 --- a/src/utils/orderCreateOneBody.ts +++ b/src/utils/orderCreateOneBody.ts @@ -1,4 +1,4 @@ -/** 从订单详情组装 createOrderOne 标准请求体(与 parcel/create 一致) */ +/** 从订单详情组装 createOrderOne 标准请求体(ForwardWithSubscribe) */ function pick(raw: Record | undefined, ...keys: string[]) { if (!raw) return undefined @@ -62,9 +62,20 @@ export function buildCountryIdToCodeMap(countries: any[]): Map { return map } +export type BuildCreateOrderOneBodyOptions = { + /** 服务渠道「预报渠道 code」,写入 productCode;不传则不带 productCode */ + forecastCode?: string | null +} + +/** + * 组装 createOrderOne 请求体。 + * - productCode:取渠道「预报渠道 code」(forecastCode),不是销售产品 code + * - 不传 channelCode / requestId / exportCustomsMode 等 OMS 扩展字段 + */ export function buildCreateOrderOneBody( order: Record, - countryIdToCode: Map + countryIdToCode: Map, + options?: BuildCreateOrderOneBodyOptions ): Record { const weightList = (order.weightList ?? order.WeightList ?? []) as any[] const forecast = @@ -88,21 +99,22 @@ export function buildCreateOrderOneBody( countryIdToCode ) - return { - requestId: pick(order, 'requestId', 'RequestId'), + const forecastCode = String(options?.forecastCode ?? '').trim() + + const body: Record = { clientNo: pick(order, 'clientNo', 'ClientNo'), trackNo: pick(order, 'trackNo', 'TrackNo'), serviceNo: pick(order, 'serviceNo', 'ServiceNo'), - productCode: pick(order, 'productCode', 'ProductCode'), - channelCode: pick(order, 'channelCode', 'ChannelCode'), cargoAttribute: pick(order, 'cargoAttribute', 'CargoAttribute'), - exportCustomsMode: pick(order, 'exportCustomsMode', 'ExportCustomsMode'), warehouseId: pick(order, 'warehouseId', 'WarehouseId'), customerId: pick(order, 'customerId', 'CustomerId'), length: pick(forecast, 'length', 'Length'), width: pick(forecast, 'width', 'Width'), height: pick(forecast, 'height', 'Height'), actualWeight: pick(forecast, 'actualWeight', 'ActualWeight'), + volumetricWeight: pick(forecast, 'volumetricWeight', 'VolumetricWeight'), + chargeableWeight: pick(forecast, 'chargeableWeight', 'ChargeableWeight'), + cubic: pick(forecast, 'cubic', 'Cubic'), isCod: order.isCod === true || order.IsCod === true || order.isCod === 1 || order.IsCod === 1, codSum: pick(order, 'codSum', 'CodSum') != null ? String(pick(order, 'codSum', 'CodSum')) : undefined, codCurrency: pick(order, 'codCurrency', 'CodCurrency'), @@ -153,4 +165,10 @@ export function buildCreateOrderOneBody( }, items: itemsRaw.map((row) => mapItem(row)), } + + if (forecastCode) { + body.productCode = forecastCode + } + + return body } diff --git a/src/utils/publishSnapshotDiff.ts b/src/utils/publishSnapshotDiff.ts index 2f77372..4219ff8 100644 --- a/src/utils/publishSnapshotDiff.ts +++ b/src/utils/publishSnapshotDiff.ts @@ -236,8 +236,11 @@ export function computeSnapshotDiff( modifiedRaw: unknown ): { length: number; rows: SnapshotDiffRow[]; equal: boolean } { try { - const original = normalizeSnapshotForDiff(parseSnapshotJson(originalRaw)) - const modified = normalizeSnapshotForDiff(parseSnapshotJson(modifiedRaw)) + const originalNorm = normalizeSnapshotForDiff(parseSnapshotJson(originalRaw)) + const modifiedNorm = normalizeSnapshotForDiff(parseSnapshotJson(modifiedRaw)) + // 空快照规范化后为 undefined;对比时按 {} 处理,避免 JSON.stringify(undefined) 异常及首次发布误判无差异 + const original = originalNorm === undefined ? {} : originalNorm + const modified = modifiedNorm === undefined ? {} : modifiedNorm const originalText = JSON.stringify(original) const modifiedText = JSON.stringify(modified) if (originalText === modifiedText) { diff --git a/src/views/api/downstreamInterface/comps/FixedParameterConfig.vue b/src/views/api/downstreamInterface/comps/FixedParameterConfig.vue index b8f45e5..5acb3a1 100644 --- a/src/views/api/downstreamInterface/comps/FixedParameterConfig.vue +++ b/src/views/api/downstreamInterface/comps/FixedParameterConfig.vue @@ -297,7 +297,9 @@ >
- 配置当前服务商的公共参数,供其下接口共用。路径:修改 → 保存 → 发布映射缓存后才对线上生效。 + 配置当前服务商的公共参数,供其下接口共用。路径:修改 → 保存 → 发布映射缓存后才对线上生效。若赋值到 + Body,需填写完整参数路径,例如 + [*].autoWaybillNo。
@@ -375,6 +377,16 @@ .fixed-parameter-body { .modal-form-tip { margin-bottom: 16px; + + code { + margin: 0 2px; + padding: 0 4px; + font-family: Consolas, Monaco, monospace; + font-size: 12px; + color: var(--color-text-1); + background: var(--color-fill-2); + border-radius: 2px; + } } .table-toolbar { diff --git a/src/views/api/downstreamInterface/comps/ProviderMapPublishModal.vue b/src/views/api/downstreamInterface/comps/ProviderMapPublishModal.vue index 9186352..582b64d 100644 --- a/src/views/api/downstreamInterface/comps/ProviderMapPublishModal.vue +++ b/src/views/api/downstreamInterface/comps/ProviderMapPublishModal.vue @@ -367,7 +367,7 @@ } function handlerSendMap() { - if (!diffLength.value) { + if (publishDiffStatus.value === 'synced') { $baseMessage( t('system.interface.mapping.message.noContentToPublish'), 'warning', @@ -514,11 +514,11 @@