优化
This commit is contained in:
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user