style(admin): unify dialog layouts and dense readonly presentation
This commit is contained in:
@@ -8,10 +8,12 @@ import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { useAuthStore } from '@/core/auth/auth'
|
||||
import { adjustContainerFee, createContainerFee, getContainerSettlementDetails, listApplicableFeeItems, listContainerFeeSupplierOptions, listContainerFees, uploadContainerFeePaymentVoucher } from '../api/containerFees'
|
||||
import ContainerFeesPanel from './ContainerFeesPanel.vue'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import { createContainerFeeAllocationGroup } from '../api/containerFees'
|
||||
|
||||
vi.mock('../api/containerFees', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('../api/containerFees')>()
|
||||
return { ...actual, listContainerFees: vi.fn(), listApplicableFeeItems: vi.fn(), listContainerFeeSupplierOptions: vi.fn(), getContainerSettlementDetails: vi.fn(), createContainerFee: vi.fn(), adjustContainerFee: vi.fn(), uploadContainerFeePaymentVoucher: vi.fn(), approveContainerFee: vi.fn(), rejectContainerFee: vi.fn(), voidContainerFee: vi.fn() }
|
||||
return { ...actual, listContainerFees: vi.fn(), listApplicableFeeItems: vi.fn(), listContainerFeeSupplierOptions: vi.fn(), getContainerSettlementDetails: vi.fn(), createContainerFee: vi.fn(), createContainerFeeAllocationGroup: vi.fn(), adjustContainerFee: vi.fn(), uploadContainerFeePaymentVoucher: vi.fn(), approveContainerFee: vi.fn(), rejectContainerFee: vi.fn(), voidContainerFee: vi.fn() }
|
||||
})
|
||||
|
||||
const panel = readFileSync(resolve(process.cwd(), 'src/modules/loading-lists/components/ContainerFeesPanel.vue'), 'utf8')
|
||||
@@ -24,7 +26,7 @@ async function mountPanel(permissions: string[], customers = [{ accountId: '11',
|
||||
const pinia = createPinia(); setActivePinia(pinia)
|
||||
const auth = useAuthStore(); auth.token = 'token'; auth.permissions = permissions
|
||||
useAccessPreviewStore().initializeAfterLogin()
|
||||
const wrapper = mount(ContainerFeesPanel, { attachTo: document.body, props: { planId: '9', containerBookingId, customers, businessReferences: [{ accountId: '11', customerName: '客户A', orderId: '501', orderNo: 'FL-501', inboundId: '601', inboundCode: 'NYEXX2608300001' }] }, global: { plugins: [pinia, ElementPlus] } })
|
||||
const wrapper = mount(ContainerFeesPanel, { attachTo: document.body, props: { planId: '9', cabinetNo: 'CAB-9', containerNo: 'CONT-9', containerBookingId, customers, businessReferences: [{ accountId: '11', customerName: '客户A', orderId: '501', orderNo: 'FL-501', inboundId: '601', inboundCode: 'NYEXX2608300001' }] }, global: { plugins: [pinia, ElementPlus] } })
|
||||
await flushPromises(); return wrapper
|
||||
}
|
||||
|
||||
@@ -35,10 +37,50 @@ beforeEach(() => {
|
||||
vi.mocked(getContainerSettlementDetails).mockReset().mockResolvedValue({ customerId: '11', containerBookingId: '99', settledSourceFeeIds: [], costs: [] }); vi.mocked(createContainerFee).mockReset()
|
||||
vi.mocked(adjustContainerFee).mockReset().mockResolvedValue({} as never)
|
||||
vi.mocked(uploadContainerFeePaymentVoucher).mockReset().mockResolvedValue({ fileId: '9001', fileName: '付款凭证.pdf' })
|
||||
vi.mocked(createContainerFeeAllocationGroup).mockReset().mockResolvedValue({} as never)
|
||||
document.body.innerHTML = ''
|
||||
})
|
||||
|
||||
describe('ContainerFeesPanel contract', () => {
|
||||
it('连续分摊表保留两个客户归属,合计不符时阻止保存,全屏后按原归属提交', async () => {
|
||||
vi.mocked(listApplicableFeeItems).mockResolvedValue([{ id: '7', name: '操作费', feeCode: 'OPERATION', defaultPrice: null, supplierCategory: null, warehouseReceivable: true, warehousePayable: false, pickupReceivable: false, pickupPayable: false }])
|
||||
const wrapper = await mountPanel(['firstleg:inbound:fee-detail:view', 'firstleg:inbound:fee-detail:edit', 'firstleg:fee-item:view'], [{ accountId: '11', customerName: '客户A' }, { accountId: '22', customerName: '客户B' }])
|
||||
await wrapper.setProps({ businessReferences: [
|
||||
{ accountId: '11', customerName: '客户A', orderId: '501', orderNo: 'FL-501', inboundId: '601', inboundCode: 'NYEXX2608300001' },
|
||||
{ accountId: '22', customerName: '客户B', orderId: '502', orderNo: 'FL-502', inboundId: null, inboundCode: null },
|
||||
] })
|
||||
const state = (wrapper.vm.$ as unknown as { setupState: {
|
||||
accountId: string; openCreate(): void; save(): Promise<void>; form: { feeItemId: string; amount: number; remark: string }
|
||||
} }).setupState
|
||||
state.accountId = '11'
|
||||
await flushPromises()
|
||||
state.openCreate()
|
||||
await flushPromises()
|
||||
state.form.feeItemId = '7'; state.form.amount = 100; state.form.remark = '分摊测试备注'
|
||||
const dialog = wrapper.findAllComponents(AppDialog).find(item => item.props('title').startsWith('新增柜次费用'))!
|
||||
const rows = dialog.findAll('table[aria-label="业务归属分摊"] tbody tr')
|
||||
expect(rows).toHaveLength(2)
|
||||
expect(rows[0]!.text()).toContain('客户A')
|
||||
expect(rows[1]!.text()).toContain('客户B')
|
||||
expect(rows[1]!.text()).toContain('无入仓码')
|
||||
rows[0]!.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 40)
|
||||
rows[1]!.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 50)
|
||||
await state.save()
|
||||
expect(createContainerFeeAllocationGroup).not.toHaveBeenCalled()
|
||||
rows[1]!.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 60)
|
||||
await dialog.get('[aria-label="展开全屏"]').trigger('click')
|
||||
expect(dialog.find('textarea').element.value).toBe('分摊测试备注')
|
||||
await state.save()
|
||||
expect(createContainerFeeAllocationGroup).toHaveBeenCalledWith('9', {
|
||||
fee: expect.objectContaining({ amount: 100, feeItemId: '7', remark: '分摊测试备注', direction: 'RECEIVABLE' }),
|
||||
allocations: [
|
||||
{ customerId: '11', orderId: '501', orderNo: 'FL-501', inboundId: '601', inboundCode: 'NYEXX2608300001', amount: 40 },
|
||||
{ customerId: '22', orderId: '502', orderNo: 'FL-502', inboundId: null, inboundCode: null, amount: 60 },
|
||||
],
|
||||
})
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it.each(['success', 'failure'])('ignores a closed editor request that finishes late: %s', async (outcome) => {
|
||||
const item = { id: '7', name: '操作费', feeCode: 'OPERATION', defaultPrice: 60, supplierCategory: null, warehouseReceivable: true, warehousePayable: false, pickupReceivable: false, pickupPayable: false }
|
||||
let resolveOld!: (items: typeof item[]) => void
|
||||
@@ -158,7 +200,15 @@ describe('ContainerFeesPanel contract', () => {
|
||||
const item = { id: '2', loadingPlanId: '9', containerBookingId: '99', containerNo: null, feeItemId: '7', feeItemName: '拖车费', direction: 'PAYABLE' as const, supplierId: '41', supplierName: '承运商A', supplierCategory: 'TRUCKING' as const, businessDate: '2026-08-12', amount: 100, currency: 'CNY' as const, reviewStatus: 'APPROVED' as const, sourceStatus: 'ACTIVE' as const, sourceVersion: 3, remark: '原备注', reviewerName: null, reviewedAt: null, reviewReason: null }
|
||||
const state = (wrapper.vm.$ as unknown as { setupState: { openAdjust(value: typeof item): void; save(): Promise<void>; form: { businessDate: string; amount: number } } }).setupState
|
||||
state.openAdjust(item); await flushPromises()
|
||||
const dialog = wrapper.findAllComponents(AppDialog).find(item => item.props('title').startsWith('调整已审核费用'))!
|
||||
expect(dialog.props('title')).toBe('调整已审核费用 · CAB-9')
|
||||
const fields = dialog.findAllComponents({ name: 'ElFormItem' })
|
||||
expect(fields.find(field => field.props('label') === '费用项目')!.findComponent({ name: 'ElSelect' }).exists()).toBe(false)
|
||||
expect(fields.find(field => field.props('label') === '供应商')!.text()).toContain('承运商A')
|
||||
state.form.businessDate = '2026-08-13'; state.form.amount = 120
|
||||
await dialog.get('[aria-label="展开全屏"]').trigger('click')
|
||||
expect(dialog.find('.el-dialog.is-fullscreen').exists()).toBe(true)
|
||||
expect(state.form.amount).toBe(120)
|
||||
await state.save()
|
||||
expect(adjustContainerFee).toHaveBeenCalledWith('9', '11', '2', { expectedSourceVersion: 3, businessDate: '2026-08-13', amount: 120 })
|
||||
expect(wrapper.text()).toContain('已审核费用仍可调整日期与金额')
|
||||
|
||||
Reference in New Issue
Block a user