优化
This commit is contained in:
@@ -161,6 +161,16 @@ describe('InboundFeePanel', () => {
|
||||
expect(document.body.textContent).toContain('没有查看入库费用的权限')
|
||||
})
|
||||
|
||||
it.each(['', ' ', 'null', 'undefined'])('does not request a fee for invalid inboundId %j', async (inboundId) => {
|
||||
const pinia = setupPermissions(['firstleg:fba-pricing:view'])
|
||||
mount(InboundFeePanel, {
|
||||
props: { customerId: '10001', inboundId },
|
||||
global: { plugins: [pinia, ElementPlus] },
|
||||
})
|
||||
await flushPromises()
|
||||
expect(getLatestInboundFee).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('treats A0404 as a neutral not-yet-generated state', async () => {
|
||||
vi.mocked(getLatestInboundFee).mockRejectedValue(new ApiResponseError('费用快照不存在', 'A0404'))
|
||||
mountPanel(['firstleg:fba-pricing:view'])
|
||||
|
||||
@@ -66,6 +66,10 @@ const adjustmentRules: FormRules = {
|
||||
const canView = computed(() => access.can('firstleg:fba-pricing:view'))
|
||||
const canAdjust = computed(() => access.can('firstleg:fba-pricing:adjust'))
|
||||
const customerContextId = computed(() => props.customerId || props.tenantId || '')
|
||||
const normalizedInboundId = computed(() => {
|
||||
const identifier = String(props.inboundId ?? '').trim()
|
||||
return identifier && identifier !== 'null' && identifier !== 'undefined' ? identifier : ''
|
||||
})
|
||||
const adjustmentEligible = computed(() => (
|
||||
snapshot.value?.feeStatus === 'CALCULATED'
|
||||
&& snapshot.value?.nextProcessStatus === 'WAIT_SPLIT'
|
||||
@@ -126,14 +130,14 @@ async function loadFee(options: { preserveAdjustment?: boolean } = {}) {
|
||||
const sequence = ++loadSequence
|
||||
loadError.value = null
|
||||
notFound.value = false
|
||||
if (!customerContextId.value || !props.inboundId || !canView.value) {
|
||||
if (!customerContextId.value || !normalizedInboundId.value || !canView.value) {
|
||||
snapshot.value = null
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
const result = await getLatestInboundFee(customerContextId.value, props.inboundId)
|
||||
const result = await getLatestInboundFee(customerContextId.value, normalizedInboundId.value)
|
||||
if (sequence !== loadSequence) return
|
||||
snapshot.value = result
|
||||
emit('loaded', result)
|
||||
@@ -197,7 +201,7 @@ async function submitAdjustment() {
|
||||
try {
|
||||
const result = await adjustPublishedInboundFee(
|
||||
customerContextId.value,
|
||||
props.inboundId,
|
||||
normalizedInboundId.value,
|
||||
payload,
|
||||
getAdjustmentKey(payload),
|
||||
)
|
||||
@@ -219,7 +223,7 @@ async function submitAdjustment() {
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [customerContextId.value, props.inboundId, access.permissionSignature],
|
||||
() => [customerContextId.value, normalizedInboundId.value, access.permissionSignature],
|
||||
() => {
|
||||
adjustOpen.value = false
|
||||
snapshot.value = null
|
||||
@@ -247,7 +251,7 @@ defineExpose({ reload: loadFee })
|
||||
circle
|
||||
aria-label="刷新费用快照"
|
||||
:loading="loading"
|
||||
:disabled="!customerContextId || !inboundId || !canView"
|
||||
:disabled="!customerContextId || !normalizedInboundId || !canView"
|
||||
@click="loadFee()"
|
||||
><RefreshCw :size="16" /></el-button>
|
||||
</el-tooltip>
|
||||
|
||||
@@ -23,6 +23,11 @@ const snapshot = {
|
||||
describe('inbound fee API', () => {
|
||||
beforeEach(() => vi.clearAllMocks())
|
||||
|
||||
it.each(['', ' ', 'null', 'undefined'])('rejects invalid inboundId %j without issuing HTTP', async (inboundId) => {
|
||||
await expect(getLatestInboundFee('10001', inboundId)).rejects.toThrow('inboundId is required')
|
||||
expect(http.get).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('loads the latest immutable fee snapshot with string IDs', async () => {
|
||||
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'success', data: snapshot })
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
||||
import type { AdjustPublishedInboundFeeRequest, InboundFeeSnapshot } from './types'
|
||||
|
||||
function feeBasePath(inboundId: string) {
|
||||
return `/platform/v1/inbounds/${encodeURIComponent(inboundId)}/fees`
|
||||
const identifier = String(inboundId ?? '').trim()
|
||||
if (!identifier || identifier === 'null' || identifier === 'undefined') throw new TypeError('inboundId is required')
|
||||
return `/platform/v1/inbounds/${encodeURIComponent(identifier)}/fees`
|
||||
}
|
||||
|
||||
export async function getLatestInboundFee(tenantId: string, inboundId: string) {
|
||||
|
||||
Reference in New Issue
Block a user