This commit is contained in:
2026-08-04 21:01:39 +08:00
parent 88bd939170
commit 5cb1ca307d
77 changed files with 9914 additions and 131 deletions
@@ -0,0 +1,116 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
const mocks = vi.hoisted(() => ({
get: vi.fn(),
post: vi.fn(),
delete: vi.fn(),
}))
vi.mock('@/shared/api/http', () => ({
http: mocks,
unwrapApiResponse: <T>(response: { data: T }) => response.data,
}))
import {
createPlatformCarrierRateVersion,
getPlatformCarrierRate,
listPlatformCarrierRates,
retirePlatformCarrierRate,
} from './platformCarrierRates'
const payload = {
id: '9007199254740995',
tenantId: '10001',
rateCode: 'RATE-US-WEST',
rateVersion: 2,
originWarehouseId: '20001',
originWarehouseName: '义乌收货仓',
businessType: 'FBA_SEA',
channelCode: 'US-WEST-SEA',
carrierId: '30001',
carrierName: '示例船司',
destinationCode: 'ONT8',
chargeUnit: 'KG' as const,
unitPrice: 12.5,
currency: 'CNY',
additionalFee: 80,
effectiveFrom: '2026-08-01T00:00:00',
effectiveTo: null,
status: 'ACTIVE' as const,
remark: null,
createdBy: '10',
createdAt: '2026-08-01T10:00:00',
updatedBy: null,
updatedAt: null,
version: 1,
}
describe('platformCarrierRates api', () => {
beforeEach(() => vi.clearAllMocks())
it('queries the real carrier-rate path and keeps every long id as a string', async () => {
mocks.get.mockResolvedValue({ data: [payload] })
const result = await listPlatformCarrierRates({ customerId: ' 10001 ', rateCode: ' RATE-US ' })
expect(mocks.get).toHaveBeenCalledWith('/platform/v1/fba-pricing/carrier-rates', {
params: { tenantId: '10001', rateCode: 'RATE-US' },
})
expect(result[0]).toMatchObject({
id: '9007199254740995',
tenantId: '10001',
originWarehouseId: '20001',
carrierId: '30001',
})
})
it('omits the compatibility tenant parameter for an all-customer list query', async () => {
mocks.get.mockResolvedValue({ data: [payload] })
await listPlatformCarrierRates()
await listPlatformCarrierRates({ customerId: '', rateCode: ' ' })
expect(mocks.get).toHaveBeenNthCalledWith(1, '/platform/v1/fba-pricing/carrier-rates', { params: {} })
expect(mocks.get).toHaveBeenNthCalledWith(2, '/platform/v1/fba-pricing/carrier-rates', { params: {} })
})
it('loads a version detail with tenant scope', async () => {
mocks.get.mockResolvedValue({ data: payload })
await getPlatformCarrierRate('10001', '9001')
expect(mocks.get).toHaveBeenCalledWith('/platform/v1/fba-pricing/carrier-rates/9001', {
params: { tenantId: '10001' },
})
})
it('creates immutable versions and retires an active version', async () => {
mocks.post.mockResolvedValue({ data: payload })
mocks.delete.mockResolvedValue({ data: null })
const request = {
rateCode: 'RATE-US-WEST',
originWarehouseId: '20001',
originWarehouseName: '义乌收货仓',
businessType: 'FBA_SEA',
channelCode: 'US-WEST-SEA',
carrierId: '30001',
carrierName: '示例船司',
destinationCode: 'ONT8',
chargeUnit: 'KG' as const,
unitPrice: 12.5,
currency: 'CNY',
additionalFee: 80,
effectiveFrom: '2026-08-01T00:00:00',
effectiveTo: null,
remark: null,
}
await createPlatformCarrierRateVersion('10001', request)
await retirePlatformCarrierRate('10001', '9001')
expect(mocks.post).toHaveBeenCalledWith('/platform/v1/fba-pricing/carrier-rates/versions', request, {
params: { tenantId: '10001' },
})
expect(mocks.delete).toHaveBeenCalledWith('/platform/v1/fba-pricing/carrier-rates/9001', {
params: { tenantId: '10001' },
})
})
})
@@ -0,0 +1,124 @@
import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
export type CarrierRateChargeUnit = 'KG' | 'CBM'
export type CarrierRateStatus = 'ACTIVE' | 'INACTIVE'
export interface PlatformCarrierRateResource {
id: string
tenantId: string
rateCode: string
rateVersion: number
originWarehouseId: string
originWarehouseName: string
businessType: string
channelCode: string
carrierId: string
carrierName: string
destinationCode: string
chargeUnit: CarrierRateChargeUnit
unitPrice: number
currency: string
additionalFee: number
effectiveFrom: string
effectiveTo: string | null
status: CarrierRateStatus
remark: string | null
createdBy: string | null
createdAt: string | null
updatedBy: string | null
updatedAt: string | null
version: number | null
}
interface PlatformCarrierRatePayload extends Omit<PlatformCarrierRateResource,
'id' | 'tenantId' | 'originWarehouseId' | 'carrierId' | 'createdBy' | 'updatedBy'> {
id: string | number
tenantId: string | number
originWarehouseId: string | number
carrierId: string | number
createdBy?: string | number | null
updatedBy?: string | number | null
}
export interface CreatePlatformCarrierRateVersionRequest {
rateCode: string
originWarehouseId: string
originWarehouseName: string
businessType: string
channelCode: string
carrierId: string
carrierName: string
destinationCode: string
chargeUnit: CarrierRateChargeUnit
unitPrice: number
currency: string
additionalFee: number
effectiveFrom: string
effectiveTo: string | null
remark: string | null
}
export interface PlatformCarrierRateQuery {
customerId?: string
rateCode?: string
}
const basePath = '/platform/v1/fba-pricing/carrier-rates'
function nullableId(value: string | number | null | undefined) {
return value == null ? null : String(value)
}
function normalizeCarrierRate(value: PlatformCarrierRatePayload): PlatformCarrierRateResource {
return {
...value,
id: String(value.id),
tenantId: String(value.tenantId),
originWarehouseId: String(value.originWarehouseId),
carrierId: String(value.carrierId),
createdBy: nullableId(value.createdBy),
updatedBy: nullableId(value.updatedBy),
effectiveTo: value.effectiveTo ?? null,
remark: value.remark ?? null,
createdAt: value.createdAt ?? null,
updatedAt: value.updatedAt ?? null,
version: value.version ?? null,
}
}
export async function listPlatformCarrierRates(query: PlatformCarrierRateQuery = {}) {
const customerId = query.customerId?.trim()
const rateCode = query.rateCode?.trim()
const response = await http.get<ApiEnvelope<PlatformCarrierRatePayload[]>, ApiEnvelope<PlatformCarrierRatePayload[]>>(
basePath,
{ params: { ...(customerId ? { tenantId: customerId } : {}), ...(rateCode ? { rateCode } : {}) } },
)
return unwrapApiResponse(response).map(normalizeCarrierRate)
}
export async function getPlatformCarrierRate(tenantId: string, id: string) {
const response = await http.get<ApiEnvelope<PlatformCarrierRatePayload>, ApiEnvelope<PlatformCarrierRatePayload>>(
`${basePath}/${id}`,
{ params: { tenantId } },
)
return normalizeCarrierRate(unwrapApiResponse(response))
}
export async function createPlatformCarrierRateVersion(
tenantId: string,
payload: CreatePlatformCarrierRateVersionRequest,
) {
const response = await http.post<ApiEnvelope<PlatformCarrierRatePayload>, ApiEnvelope<PlatformCarrierRatePayload>>(
`${basePath}/versions`,
payload,
{ params: { tenantId } },
)
return normalizeCarrierRate(unwrapApiResponse(response))
}
export async function retirePlatformCarrierRate(tenantId: string, id: string) {
const response = await http.delete<ApiEnvelope<null>, ApiEnvelope<null>>(`${basePath}/${id}`, {
params: { tenantId },
})
return unwrapApiResponse(response)
}