This commit is contained in:
2026-08-17 17:49:10 +08:00
parent 911a3620e1
commit c7334b2cf8
30 changed files with 1043 additions and 249 deletions
@@ -5,12 +5,16 @@ import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { useAuthStore } from '@/core/auth/auth'
import { createPlatformExportTask } from '@/modules/downloads'
import { listPlatformTenants } from '@/modules/iam'
import { showExportTaskCreatedDialog } from '@/shared/components/exportTaskCreatedDialog'
import { getFinanceFeeSource, getReconciliationStatement, listFinanceStatements } from '../api/finance'
import type { FinanceReconciliationDetail, FinanceStatementReadModel } from '../types'
import FinanceCustomerStatementsView from './FinanceCustomerStatementsView.vue'
vi.mock('@/modules/iam', () => ({ listPlatformTenants: vi.fn() }))
vi.mock('@/modules/downloads', () => ({ createPlatformExportTask: vi.fn() }))
vi.mock('@/shared/components/exportTaskCreatedDialog', () => ({ showExportTaskCreatedDialog: vi.fn() }))
vi.mock('../api/finance', () => ({
actionReconciliationStatement: vi.fn(), createReconciliationStatement: vi.fn(),
getFinanceFeeSource: vi.fn(), getReconciliationStatement: vi.fn(), listFinanceStatements: vi.fn(),
@@ -42,6 +46,7 @@ async function mountPage(permissions = ['platform:finance:customer-statement:lis
const router = createRouter({ history: createMemoryHistory(), routes: [
{ path: '/finance/customer-statements', name: 'finance-customer-statements', component: FinanceCustomerStatementsView },
{ path: '/finance/customer-statements/:statementId', name: 'finance-customer-statement-detail', component: FinanceCustomerStatementsView },
{ path: '/downloads', name: 'download-center', component: { template: '<div>下载中心</div>' } },
] })
await router.push(initialPath); await router.isReady()
const wrapper = mount(FinanceCustomerStatementsView, { attachTo: document.body, global: { plugins: [pinia, ElementPlus, router] } })
@@ -62,6 +67,8 @@ describe('FinanceCustomerStatementsView', () => {
vi.mocked(listPlatformTenants).mockResolvedValue({ records: [{ id: '10001', tenantName: '客户A', status: 'ACTIVE' } as never], page: 1, size: 200, total: 1, pages: 1 })
vi.mocked(listFinanceStatements).mockResolvedValue([statement])
vi.mocked(getReconciliationStatement).mockResolvedValue(detail)
vi.mocked(createPlatformExportTask).mockReset().mockResolvedValue({ taskName: '客户对账单', taskNo: 'EXP-STMT-1' } as never)
vi.mocked(showExportTaskCreatedDialog).mockReset().mockResolvedValue(false)
vi.mocked(getFinanceFeeSource).mockResolvedValue({
poolItemId: '81', feeSourceId: '81', customerId: '10001', customerName: '客户A', supplierId: null, supplierName: '',
direction: 'RECEIVABLE', sourceType: 'CONTAINER_FEE', sourceId: 'FEE-81', sourceFeeId: 'FEE-81', sourceVersion: 2,
@@ -159,13 +166,35 @@ describe('FinanceCustomerStatementsView', () => {
expect(vm.filteredRows).toHaveLength(0)
})
it('hydrates and exports the currently filtered real statement rows as CSV', async () => {
const clicked = vi.spyOn(HTMLAnchorElement.prototype, 'click').mockImplementation(() => {})
it('creates a formal statement export task with only non-empty filters', async () => {
const { wrapper } = await mountPage()
const vm = wrapper.vm as unknown as { filters: Record<string, unknown>; exportStatements(): Promise<void> }
vm.filters = {
status: 'ISSUED', billNo: ' REC-501 ', customerId: '10001', containerNo: ' CONT-31 ',
periodStartRange: ['2026-08-01', '2026-08-05'], periodEndRange: [], settled: 'false',
lastPaymentRange: ['2026-08-20', '2026-08-21'], createdRange: [],
}
await (wrapper.vm as unknown as { exportStatements(): Promise<void> }).exportStatements()
expect(getReconciliationStatement).toHaveBeenCalledWith('501')
expect(URL.createObjectURL).toHaveBeenCalledWith(expect.any(Blob))
expect(clicked).toHaveBeenCalledOnce()
expect(createPlatformExportTask).toHaveBeenCalledWith({
exportType: 'FINANCE_RECONCILIATION_STATEMENT_LIST', format: 'XLSX', taskName: '客户对账单',
parameters: {
customerId: '10001', status: 'ISSUED', billNo: 'REC-501', containerNo: 'CONT-31',
periodStartFrom: '2026-08-01', periodStartTo: '2026-08-05', settled: false,
lastPaymentFrom: '2026-08-20', lastPaymentTo: '2026-08-21',
},
})
expect(showExportTaskCreatedDialog).toHaveBeenCalledWith({ taskName: '客户对账单', taskNo: 'EXP-STMT-1' })
expect(getReconciliationStatement).not.toHaveBeenCalledWith('501')
expect(URL.createObjectURL).not.toHaveBeenCalled()
})
it('requires both statement export and download-center list permissions for the export action', async () => {
await mountPage(['platform:finance:customer-statement:list', 'platform:finance:customer-statement:export'])
expect([...document.querySelectorAll('button')].some((item) => item.textContent?.includes('导出'))).toBe(false)
document.body.innerHTML = ''
await mountPage(['platform:finance:customer-statement:list', 'platform:finance:customer-statement:export', 'platform:download:list'])
expect([...document.querySelectorAll('button')].some((item) => item.textContent?.includes('导出'))).toBe(true)
})
it('disables statement generation when customer selection permission is missing', async () => {