1
This commit is contained in:
@@ -296,6 +296,8 @@ export interface MerchantFirstLegOrderRow {
|
||||
inboundedAt: string | null
|
||||
businessDate: string | null
|
||||
shipmentId: string | null
|
||||
fulfillmentType?: 'STANDARD' | 'ONE_CLICK_DROPSHIP' | null
|
||||
lxCode?: string | null
|
||||
createdAt: string
|
||||
cargoes?: Array<{ skuNo?: string | null }>
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ test('shows the published merchant inbound, measurement details and customer con
|
||||
assert.match(source, /latestFee\.rateCode/)
|
||||
assert.match(source, /latestFee\.chargeRuleVersion/)
|
||||
assert.match(source, /latestFee\.carrierRateVersion/)
|
||||
assert.doesNotMatch(source, /箱规规则|calculationRuleVersion/)
|
||||
assert.match(source, /箱规规则/)
|
||||
assert.match(source, /getCalculationRuleLabel\(row\.calculationRuleVersion\)/)
|
||||
})
|
||||
|
||||
test('stacks core information for 720 and 360 pixel layouts', () => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
formatInboundMeasure,
|
||||
formatInboundMoney,
|
||||
formatInboundNumber,
|
||||
getCalculationRuleLabel,
|
||||
getChargeModeLabel,
|
||||
getTaxModeLabel,
|
||||
} from '@/modules/first-leg/utils/inboundBilling'
|
||||
@@ -139,6 +140,7 @@ async function confirmFee() {
|
||||
<el-table-column label="每箱体积" min-width="105"><template #default="{ row }">{{ formatInboundMeasure(row.unitVolumeCbm, 'm³') }}</template></el-table-column>
|
||||
<el-table-column label="总体积" min-width="105"><template #default="{ row }">{{ formatInboundMeasure(row.totalVolumeCbm, 'm³') }}</template></el-table-column>
|
||||
<el-table-column label="总材积重" min-width="105"><template #default="{ row }">{{ formatInboundMeasure(row.volumeWeightKg, 'kg') }}</template></el-table-column>
|
||||
<el-table-column label="箱规规则" min-width="170"><template #default="{ row }">{{ getCalculationRuleLabel(row.calculationRuleVersion) }}</template></el-table-column>
|
||||
<el-table-column prop="boxSpecification" label="备注" min-width="130" />
|
||||
</el-table>
|
||||
</div>
|
||||
@@ -241,6 +243,7 @@ async function confirmFee() {
|
||||
<el-table-column label="每箱体积" min-width="105"><template #default="{ row }">{{ formatInboundMeasure(row.unitVolumeCbm, 'm³') }}</template></el-table-column>
|
||||
<el-table-column label="总体积" min-width="105"><template #default="{ row }">{{ formatInboundMeasure(row.totalVolumeCbm, 'm³') }}</template></el-table-column>
|
||||
<el-table-column label="总材积重" min-width="105"><template #default="{ row }">{{ formatInboundMeasure(row.volumeWeightKg, 'kg') }}</template></el-table-column>
|
||||
<el-table-column label="箱规规则" min-width="170"><template #default="{ row }">{{ getCalculationRuleLabel(row.calculationRuleVersion) }}</template></el-table-column>
|
||||
<el-table-column prop="boxSpecification" label="备注" min-width="130" />
|
||||
</el-table>
|
||||
<el-alert
|
||||
|
||||
@@ -12,7 +12,7 @@ test('maps the first-leg aggregate list fields without loading detail rows', ()
|
||||
assert.match(apiSource, /cargoes\?: Array<\{ skuNo\?: string \| null \}>/)
|
||||
assert.match(apiSource, /apiRequest<PageResult<MerchantFirstLegOrderRow>>/)
|
||||
assert.match(storeSource, /function mapFirstLegOrderRow/)
|
||||
for (const field of ['inboundId', 'inboundCode', 'channelName', 'destinationWarehouseName', 'pickupMethod', 'packageCount', 'expressCompany', 'trackingNo', 'totalGrossWeightKg', 'totalNetWeightKg', 'totalVolumeCbm', 'totalQuantity', 'remark', 'shipmentId', 'referenceId', 'createdAt']) {
|
||||
for (const field of ['inboundId', 'inboundCode', 'channelName', 'destinationWarehouseName', 'pickupMethod', 'packageCount', 'expressCompany', 'trackingNo', 'totalGrossWeightKg', 'totalNetWeightKg', 'totalVolumeCbm', 'totalQuantity', 'remark', 'shipmentId', 'fulfillmentType', 'lxCode', 'referenceId', 'createdAt']) {
|
||||
assert.match(storeSource, new RegExp(`row\\.${field}`))
|
||||
}
|
||||
assert.match(storeSource, /row\.skuNos/)
|
||||
@@ -102,7 +102,9 @@ test('keeps unified order pagination valid when the store omits page and size',
|
||||
|
||||
test('keeps drafts on the legacy read path without assigning a unified main status', () => {
|
||||
assert.match(storeSource, /getMerchantFirstLegOrders\(legacyQuery\(query, 'DRAFT'\)\)/)
|
||||
assert.match(storeSource, /getById\(id\)\?\.status === 'DRAFT' \? loadLegacyDetail\(id\) : loadUnifiedDetail\(id\)/)
|
||||
assert.match(storeSource, /const listOrder = getById\(id\)/)
|
||||
assert.match(storeSource, /listOrder\?\.status === 'DRAFT' \? loadLegacyDetail\(id, listOrder\) : loadUnifiedDetail\(id\)/)
|
||||
assert.match(storeSource, /detail\.order\.lxCode == null && listOrder\?\.lxCode/)
|
||||
assert.match(storeSource, /return loadLegacyDetail\(String\(createdId\)\)/)
|
||||
assert.match(storeSource, /draftLoadError/)
|
||||
})
|
||||
|
||||
@@ -359,7 +359,7 @@ function mapFirstLegOrderRow(row: MerchantFirstLegOrderRow): FirstLegOrder {
|
||||
const uniqueSkuNos = [...new Set(resolvedSkuNos)]
|
||||
return {
|
||||
id: String(row.orderId), orderNo: row.orderNo, referenceNo: row.referenceId ?? '', transportMode: null,
|
||||
businessType: 'EXPORT', origin: '', destination: row.destinationWarehouseName ?? '', receivingWarehouseId: '',
|
||||
businessType: 'EXPORT', fulfillmentType: row.fulfillmentType ?? 'STANDARD', lxCode: row.lxCode ?? '', origin: '', destination: row.destinationWarehouseName ?? '', receivingWarehouseId: '',
|
||||
receivingWarehouseName: '', receivingWarehouseSnapshot: null, expectedDepartureDate: '', etd: '', eta: '',
|
||||
shipperPartyId: '', shipperPartySnapshot: null, shipper: '', consigneePartyId: '', consigneePartySnapshot: null,
|
||||
consignee: row.receivingCompanyName ?? '', expressCompanyName: row.expressCompany ?? '', trackingNumber: row.trackingNo ?? '',
|
||||
@@ -542,9 +542,19 @@ export const useFirstLegOrdersStore = defineStore('client-first-leg-orders', ()
|
||||
return mapped
|
||||
}
|
||||
|
||||
async function loadLegacyDetail(id: string) {
|
||||
async function loadLegacyDetail(id: string, listOrder?: FirstLegOrder) {
|
||||
const detail = await getMerchantFirstLegOrder(id)
|
||||
return upsertOrder(mapOrder(detail.order, warehouses.value, detail))
|
||||
const mapped = mapOrder(detail.order, warehouses.value, detail)
|
||||
// Older detail responses may omit newly added dropship fields. Keep the
|
||||
// values already returned by the list row so editing a draft does not
|
||||
// clear the persisted LX code in the form.
|
||||
if (detail.order.fulfillmentType == null && listOrder?.fulfillmentType) {
|
||||
mapped.fulfillmentType = listOrder.fulfillmentType
|
||||
}
|
||||
if (detail.order.lxCode == null && listOrder?.lxCode) {
|
||||
mapped.lxCode = listOrder.lxCode
|
||||
}
|
||||
return upsertOrder(mapped)
|
||||
}
|
||||
|
||||
async function loadUnifiedDetail(id: string) {
|
||||
@@ -558,7 +568,8 @@ export const useFirstLegOrdersStore = defineStore('client-first-leg-orders', ()
|
||||
}
|
||||
|
||||
async function loadDetail(id: string) {
|
||||
return getById(id)?.status === 'DRAFT' ? loadLegacyDetail(id) : loadUnifiedDetail(id)
|
||||
const listOrder = getById(id)
|
||||
return listOrder?.status === 'DRAFT' ? loadLegacyDetail(id, listOrder) : loadUnifiedDetail(id)
|
||||
}
|
||||
|
||||
async function loadWarehouseDetail(id: string) {
|
||||
@@ -616,7 +627,7 @@ export const useFirstLegOrdersStore = defineStore('client-first-leg-orders', ()
|
||||
}
|
||||
|
||||
async function loadDraftDetail(id: string) {
|
||||
return loadLegacyDetail(id)
|
||||
return loadLegacyDetail(id, getById(id))
|
||||
}
|
||||
|
||||
return { orders, warehouses, loading, loadedFromApi, loadError, warehouseLoadError, draftLoadError, activeCount, pendingCount, getById, load, loadDetail, loadDraftDetail, loadWarehouseDetail, loadWarehouseType, saveDraft, saveDraftBatch, submitSaved, submit }
|
||||
|
||||
@@ -19,6 +19,13 @@ test('translates backend rounding modes into customer-facing calculation labels'
|
||||
assert.match(source, /return value \? labels\[value\] \|\| value : '-'/)
|
||||
})
|
||||
|
||||
test('translates carton calculation rules into customer-facing labels', () => {
|
||||
assert.match(source, /export function getCalculationRuleLabel/)
|
||||
assert.match(source, /ACTUAL_DIMENSION_V1/)
|
||||
assert.match(source, /按实际箱规计算/)
|
||||
assert.match(source, /CUSTOMER_DIMENSION_\(SMALL\|MEDIUM\|LARGE\|EXTRA_LARGE\)_V/)
|
||||
})
|
||||
|
||||
test('renders conversion metadata as one complete label or a single empty marker', () => {
|
||||
assert.match(source, /export function formatConversionPrecision/)
|
||||
assert.match(source, /roundingScale === null \|\| roundingScale === undefined/)
|
||||
|
||||
@@ -46,6 +46,20 @@ export function getTaxModeLabel(value: string) {
|
||||
return value || '-'
|
||||
}
|
||||
|
||||
export function getCalculationRuleLabel(value: string | null | undefined) {
|
||||
if (!value) return '-'
|
||||
if (value === 'ACTUAL_DIMENSION_V1' || value === 'DIMENSION_ACTUAL_V1') return '按实际箱规计算'
|
||||
const customerRule = /^CUSTOMER_DIMENSION_(SMALL|MEDIUM|LARGE|EXTRA_LARGE)_V(\d+)$/.exec(value)
|
||||
if (customerRule) {
|
||||
const sizeLabel: Record<string, string> = {
|
||||
SMALL: '小号', MEDIUM: '中号', LARGE: '大号', EXTRA_LARGE: '超大号',
|
||||
}
|
||||
return `客户箱规规则(${sizeLabel[customerRule[1]]},V${customerRule[2]})`
|
||||
}
|
||||
const warehouseRule = /^WAREHOUSE_OUTER_OVERRIDE_(.+)$/.exec(value)
|
||||
return warehouseRule ? `仓库外箱规覆盖(${warehouseRule[1]})` : value
|
||||
}
|
||||
|
||||
export function getRoundingModeLabel(value: string | null | undefined) {
|
||||
const labels: Record<string, string> = {
|
||||
UP: '向上舍入',
|
||||
|
||||
Reference in New Issue
Block a user