fix: align audit and dispatch workflows and release failed requests

This commit is contained in:
2026-10-22 23:10:09 +08:00
parent 9cdcb9c077
commit 4a3456756f
124 changed files with 1296 additions and 2120 deletions
@@ -54,28 +54,28 @@ it('has no requests without Finance list permission and does not give readers wr
access.permissions.add(api.companyCostPermissions.list); const w = mount(); await flushPromises()
expect(button(w, '登记付款')).toBeUndefined(); expect(button(w, '作废费用')).toBeUndefined(); expect(button(w, '确认入账')).toBeUndefined()
})
it('keeps one immutable payment request and key after an unknown response', async () => {
it('releases failed payment and submits the current amount with a new key', async () => {
vi.mocked(api.payCompanyCost).mockRejectedValueOnce(new Error('unknown outcome')).mockResolvedValueOnce({ ...detail, status: 'PARTIALLY_PAID', paidAmount: 20, outstandingAmount: 50, recordVersion: '3' })
const w = mount(); await flushPromises(); await button(w, '登记付款').trigger('click'); await flushPromises()
w.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 20); await files(w)
await button(w, '确认操作').trigger('click'); await flushPromises()
const first = vi.mocked(api.payCompanyCost).mock.calls[0]!
expect(first).toEqual(['VC-ONE', expect.any(String), expect.objectContaining({ expectedVersion: '2', amount: 20, voucherFileIds: ['11'] })])
expect(w.text()).toContain('上次操作结果尚未确认')
expect(w.text()).not.toContain('上次操作结果尚未确认')
w.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 60)
await button(w, '重试原操作').trigger('click'); await flushPromises()
expect(vi.mocked(api.payCompanyCost).mock.calls[1]).toEqual(first)
await button(w, '确认操作').trigger('click'); await flushPromises()
expect(vi.mocked(api.payCompanyCost).mock.calls[1]).toEqual([first[0], expect.any(String), { ...first[2], amount: 60 }]); expect(vi.mocked(api.payCompanyCost).mock.calls[1]![1]).not.toBe(first[1])
expect(w.text()).toContain('部分付款'); expect(w.text()).toContain('未付 CNY 50.00')
expect(api.uploadCompanyCostVoucher).toHaveBeenCalledTimes(1); expect(w.emitted('changed')).toHaveLength(1)
})
it('preserves successfully uploaded vouchers and resumes remaining uploads without paying', async () => {
it('preserves successful vouchers and lets the user reselect failed uploads without paying', async () => {
vi.mocked(api.uploadCompanyCostVoucher).mockResolvedValueOnce(voucher).mockRejectedValueOnce(new Error('upload failed'))
.mockResolvedValueOnce({ ...voucher, fileId: '12', fileName: 'second.png' })
const w = mount(); await flushPromises(); await button(w, '登记付款').trigger('click'); await flushPromises()
await files(w, ['payment.png', 'second.png'])
expect(w.text()).toContain('已上传:payment.png'); expect(w.text()).toContain('1 张凭证待完成上传')
expect(w.text()).toContain('已上传:payment.png'); expect(w.text()).toContain('凭证上传未完成')
expect(api.payCompanyCost).not.toHaveBeenCalled()
await button(w, '重试剩余凭证').trigger('click'); await flushPromises()
await files(w, ['second.png'])
expect(api.uploadCompanyCostVoucher).toHaveBeenCalledTimes(3)
expect((vi.mocked(api.uploadCompanyCostVoucher).mock.calls[2]![1]).name).toBe('second.png')
expect(w.text()).toContain('已上传:second.png'); expect(api.payCompanyCost).not.toHaveBeenCalled()