Files
admin-web/src/modules/overseas-master-data/routeLocations.ts
T
2026-10-09 17:36:32 +08:00

46 lines
2.9 KiB
TypeScript

import { getPlatformWarehouse, listAllPlatformWarehouses, type PlatformWarehouseAddressResource } from '@/modules/warehouses'
export type RouteLocation =
| { kind: 'address'; label: string; address: string }
| { kind: 'warehouse'; label: string; warehouseId?: string; warehouseCode?: string }
export class RouteAddressError extends Error {}
export function routeLocation(place: string, address?: string | null): RouteLocation {
const label = place.trim()
// FBA codes in free-text order fields also require authoritative address resolution.
if (/^[A-Z]{3}\d{1,2}$/i.test(label)) return { kind: 'warehouse', label, warehouseCode: label.toUpperCase() }
return { kind: 'address', label, address: [label, address?.trim()].filter(Boolean).join(' ') }
}
function formatAddress(address: PlatformWarehouseAddressResource | undefined, label: string) {
if (!address?.addressLine1?.trim() || !address.city?.trim() || !address.countryCode?.trim()) {
throw new RouteAddressError(`${label}缺少完整仓库地址,请在仓库资料中补充街道、城市和国家`)
}
return [address.addressLine1, address.addressLine2, address.district, address.city, address.stateProvince, address.postalCode, address.countryCode]
.map(value => value?.trim()).filter(Boolean).join(', ')
}
export async function resolveRouteLocation(location: RouteLocation): Promise<string> {
if (location.kind === 'address') return location.address.trim()
let warehouseId = location.warehouseId
if (!warehouseId) {
const keyword = location.warehouseCode?.trim() || location.label.trim()
if (!keyword || ['—', '-', '仓库名称待补充'].includes(keyword)) throw new RouteAddressError('缺少仓库标识,请核对仓库资料')
const warehouses = await listAllPlatformWarehouses({ keyword, ...(location.warehouseCode ? { warehouseType: 'FBA' as const } : {}) })
const matches = warehouses.filter(warehouse => location.warehouseCode
? warehouse.warehouseCode.toUpperCase() === keyword.toUpperCase()
: warehouse.warehouseName === keyword)
if (matches.length !== 1) throw new RouteAddressError(matches.length ? `${location.label}匹配到多个仓库,请核对仓库资料` : `未找到${location.label}的仓库资料`)
warehouseId = String(matches[0]!.id)
}
const detail = await getPlatformWarehouse(warehouseId)
if (location.warehouseCode && (detail.warehouse.warehouseType !== 'FBA' || detail.warehouse.warehouseCode.toUpperCase() !== location.warehouseCode.toUpperCase())) {
throw new RouteAddressError(`${location.label}与查询到的仓库资料不一致,请重新查询`)
}
const operating = detail.addresses.filter(address => address.addressType === 'OPERATING')
const addresses = operating.length ? operating : detail.addresses
if (addresses.length !== 1) throw new RouteAddressError(`${location.label}的运营地址不唯一或尚未维护,请核对仓库资料`)
return formatAddress(addresses[0], location.label)
}