This commit is contained in:
2026-08-07 20:07:37 +08:00
parent 28d0b81c5a
commit 99413ee155
27 changed files with 1065 additions and 595 deletions
+28 -41
View File
@@ -1,54 +1,41 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
const http = vi.hoisted(() => ({
get: vi.fn(),
put: vi.fn(),
}))
const http = vi.hoisted(() => ({ get: vi.fn(), put: vi.fn() }))
vi.mock('@/shared/api/http', () => ({ http, unwrapApiResponse: <T>(response: { data: T }) => response.data }))
vi.mock('@/shared/api/http', () => ({
http,
unwrapApiResponse: <T>(response: { data: T }) => response.data,
}))
import { getCustomerDimensionConfig, updateCustomerDimensionConfig } from './api'
import type { CustomerDimensionRule, UpdateCustomerDimensionRule } from './types'
import {
getCustomerDimensionConfig,
updateCustomerDimensionConfig,
} from './api'
const rawConfig = {
tenantId: 9007199254740993n.toString(),
edgeAdditionCm: 2,
version: 3,
updatedAt: '2026-08-07T10:20:00',
}
const rawRule = {
id: '9007199254740995',
boxType: 'SMALL', boxTypeName: '小箱', innerLengthCm: 30, innerWidthCm: 20, innerHeightCm: 20,
edgeAdditionCm: 2, outerLengthCm: 34, outerWidthCm: 24, outerHeightCm: 24, volumeCbm: 0.02,
remark: '标准小箱', version: 3, createdAt: '2026-08-07T10:00:00', updatedAt: '2026-08-07T10:20:00',
} satisfies CustomerDimensionRule
describe('customer dimension config api', () => {
beforeEach(() => vi.clearAllMocks())
it('loads the current customer config and keeps long ids as strings', async () => {
http.get.mockResolvedValue({ data: rawConfig })
it('normalizes the wrapped config and keeps the customer id as a string', async () => {
http.get.mockResolvedValue({ data: { tenantId: 9007199254740993n.toString(), rules: [rawRule] } })
const result = await getCustomerDimensionConfig('9007199254740993')
expect(http.get).toHaveBeenCalledWith('/platform/v1/first-leg/customer-dimension-config', {
params: { tenantId: '9007199254740993' },
})
expect(result).toEqual(rawConfig)
expect(http.get).toHaveBeenCalledWith('/platform/v1/first-leg/customer-dimension-config', { params: { tenantId: '9007199254740993' } })
expect(result).toEqual({ tenantId: '9007199254740993', rules: [rawRule] })
expect(result.rules[0].id).toBe('9007199254740995')
})
it('sends the current version when updating the edge addition', async () => {
http.put.mockResolvedValue({ data: { ...rawConfig, edgeAdditionCm: 3, version: 4 } })
const result = await updateCustomerDimensionConfig('9007199254740993', {
edgeAdditionCm: 3,
version: 3,
})
expect(http.put).toHaveBeenCalledWith(
'/platform/v1/first-leg/customer-dimension-config',
{ edgeAdditionCm: 3, version: 3 },
{ params: { tenantId: '9007199254740993' } },
)
expect(result).toMatchObject({ tenantId: '9007199254740993', edgeAdditionCm: 3, version: 4 })
it('submits the complete rule set in one update request', async () => {
const updateRule = {
boxType: rawRule.boxType,
innerLengthCm: rawRule.innerLengthCm,
innerWidthCm: rawRule.innerWidthCm,
innerHeightCm: rawRule.innerHeightCm,
edgeAdditionCm: rawRule.edgeAdditionCm,
remark: rawRule.remark,
version: rawRule.version,
} satisfies UpdateCustomerDimensionRule
http.put.mockResolvedValue({ data: { tenantId: '8', rules: [rawRule] } })
await updateCustomerDimensionConfig('8', { rules: [updateRule] })
expect(http.put).toHaveBeenCalledWith('/platform/v1/first-leg/customer-dimension-config', { rules: [updateRule] }, { params: { tenantId: '8' } })
})
})
+15 -5
View File
@@ -1,24 +1,34 @@
import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
import type {
CustomerDimensionConfig,
CustomerDimensionRule,
UpdateCustomerDimensionConfigRequest,
} from './types'
const dimensionConfigPath = '/platform/v1/first-leg/customer-dimension-config'
type RawDimensionConfig = Omit<CustomerDimensionConfig, 'tenantId'> & {
type RawRule = Omit<CustomerDimensionRule, 'id' | 'version'> & {
id: string | number
version: string | number
}
type RawConfig = Omit<CustomerDimensionConfig, 'tenantId' | 'rules'> & {
tenantId: string | number
rules: RawRule[]
}
function normalizeConfig(config: RawDimensionConfig): CustomerDimensionConfig {
function normalizeRule(rule: RawRule): CustomerDimensionRule {
return { ...rule, id: String(rule.id), version: Number(rule.version) }
}
function normalizeConfig(config: RawConfig): CustomerDimensionConfig {
return {
...config,
tenantId: String(config.tenantId),
rules: config.rules.map(normalizeRule),
}
}
export async function getCustomerDimensionConfig(tenantId: string): Promise<CustomerDimensionConfig> {
const response = await http.get<never, ApiEnvelope<RawDimensionConfig>>(dimensionConfigPath, {
const response = await http.get<never, ApiEnvelope<RawConfig>>(dimensionConfigPath, {
params: { tenantId },
})
return normalizeConfig(unwrapApiResponse(response))
@@ -28,7 +38,7 @@ export async function updateCustomerDimensionConfig(
tenantId: string,
request: UpdateCustomerDimensionConfigRequest,
): Promise<CustomerDimensionConfig> {
const response = await http.put<never, ApiEnvelope<RawDimensionConfig>>(dimensionConfigPath, request, {
const response = await http.put<never, ApiEnvelope<RawConfig>>(dimensionConfigPath, request, {
params: { tenantId },
})
return normalizeConfig(unwrapApiResponse(response))
+3
View File
@@ -4,7 +4,10 @@ export {
} from './api'
export type {
CustomerDimensionBoxType,
CustomerDimensionConfig,
CustomerDimensionConfigFormModel,
CustomerDimensionRule,
UpdateCustomerDimensionConfigRequest,
UpdateCustomerDimensionRule,
} from './types'
+32 -5
View File
@@ -1,15 +1,42 @@
export interface CustomerDimensionConfig {
tenantId: string
export type CustomerDimensionBoxType = 'SMALL' | 'MEDIUM' | 'LARGE' | 'EXTRA_LARGE'
export interface CustomerDimensionRule {
id: string
boxType: CustomerDimensionBoxType
boxTypeName: string
innerLengthCm: number
innerWidthCm: number
innerHeightCm: number
edgeAdditionCm: number
outerLengthCm: number
outerWidthCm: number
outerHeightCm: number
volumeCbm: number
remark: string | null
version: number
createdAt: string | null
updatedAt: string | null
}
export interface CustomerDimensionConfig {
tenantId: string
rules: CustomerDimensionRule[]
}
export type UpdateCustomerDimensionRule = Pick<CustomerDimensionRule,
| 'boxType'
| 'innerLengthCm'
| 'innerWidthCm'
| 'innerHeightCm'
| 'edgeAdditionCm'
| 'remark'
| 'version'
>
export interface UpdateCustomerDimensionConfigRequest {
edgeAdditionCm: number
version: number
rules: UpdateCustomerDimensionRule[]
}
export interface CustomerDimensionConfigFormModel {
edgeAdditionCm: number
rules: CustomerDimensionRule[]
}