1
This commit is contained in:
@@ -18,7 +18,7 @@ import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
|
||||
import { showExportTaskCreatedDialog } from '@/shared/components/exportTaskCreatedDialog'
|
||||
import { actionReconciliationStatement, createReconciliationStatement, getReconciliationStatement, listFinanceFeeSources, listFinanceStatements } from '../api/finance'
|
||||
import { financeSourceTypeLabel, financeStatusLabel, financeStatusTone } from '../status'
|
||||
import { financeBillStatusOptions, financeSourceTypeLabel, financeStatusLabel, financeStatusTone } from '../status'
|
||||
import type { FinanceFeeSourceSummary, FinanceReconciliationDetail, FinanceStatementReadModel, ReconciliationActionPayload } from '../types'
|
||||
|
||||
interface AdjustmentRow {
|
||||
@@ -47,6 +47,7 @@ const filters = ref<QueryModel>({
|
||||
status: '', billNo: '', customerId: '', containerNo: '', periodStartRange: [], periodEndRange: [],
|
||||
settled: '', lastPaymentRange: [], createdRange: [],
|
||||
})
|
||||
const appliedFilters = ref<QueryModel>({ ...filters.value })
|
||||
const rows = ref<StatementRow[]>([])
|
||||
const page = ref(1)
|
||||
const pageSize = ref(20)
|
||||
@@ -99,10 +100,7 @@ const selectedCreateAmount = computed(() => selectedCreateSources.value.reduce((
|
||||
const detailRouteId = computed(() => route.name === 'finance-customer-statement-detail' ? String(route.params.statementId || '') : '')
|
||||
const isDetailRoute = computed(() => Boolean(detailRouteId.value))
|
||||
const fields = computed<QueryField[]>(() => [
|
||||
{ key: 'status', type: 'select', label: '审核状态', width: 180, placeholder: '请选择审核状态', options: [
|
||||
{ label: '草稿', value: 'DRAFT' }, { label: '待审核', value: 'PENDING_REVIEW' }, { label: '审核通过', value: 'APPROVED' },
|
||||
{ label: '审核拒绝', value: 'REJECTED' }, { label: '已出账', value: 'ISSUED' }, { label: '已作废', value: 'VOIDED' },
|
||||
] },
|
||||
{ key: 'status', type: 'select', label: '对账单状态', width: 180, placeholder: '请选择对账单状态', options: financeBillStatusOptions },
|
||||
{ key: 'billNo', type: 'input', label: '对账单号', width: 210, placeholder: '请输入对账单号' },
|
||||
{ key: 'customerId', type: 'select', label: '客户名称', width: 260, placeholder: '请选择客户', props: { filterable: true, clearable: true }, options: customers.value.filter((item) => item.status === 'ACTIVE').map((item) => ({ label: item.tenantName, value: String(item.id) })) },
|
||||
{ key: 'containerNo', type: 'input', label: '柜次号', width: 190, placeholder: canViewFeeSource.value ? '请输入柜次号' : '缺少费用来源查看权限', props: { disabled: !canViewFeeSource.value } },
|
||||
@@ -114,7 +112,7 @@ const fields = computed<QueryField[]>(() => [
|
||||
])
|
||||
const columns: DataTableColumn[] = [
|
||||
{ key: 'actions', label: '操作', width: 280, fixed: 'left', slotName: 'actions' },
|
||||
{ key: 'status', label: '审核状态', width: 120, slotName: 'status' },
|
||||
{ key: 'status', label: '对账单状态', width: 120, slotName: 'status' },
|
||||
{ key: 'customerConfirmationStatus', label: '客户确认', width: 130, slotName: 'customerConfirmationStatus' },
|
||||
{ key: 'billNo', label: '对账单号', minWidth: 180 },
|
||||
{ key: 'customerName', label: '客户', minWidth: 180, slotName: 'customerName' },
|
||||
@@ -208,9 +206,9 @@ function detailToRow(row: FinanceStatementReadModel, current?: FinanceReconcilia
|
||||
}
|
||||
}
|
||||
|
||||
function stringFilter(key: string) { return String(filters.value[key] || '').trim().toLowerCase() }
|
||||
function stringFilter(key: string) { return String(appliedFilters.value[key] || '').trim().toLowerCase() }
|
||||
function inDateRange(value: string, key: string) {
|
||||
const range = filters.value[key]
|
||||
const range = appliedFilters.value[key]
|
||||
if (!Array.isArray(range) || range.length < 2 || !value) return !Array.isArray(range) || range.length < 2
|
||||
const date = value.slice(0, 10)
|
||||
return date >= String(range[0]) && date <= String(range[1])
|
||||
@@ -251,6 +249,7 @@ async function load(model?: QueryModel) {
|
||||
const hydrateDetails = model !== undefined
|
||||
if (model) {
|
||||
filters.value = { ...model }
|
||||
appliedFilters.value = { ...model }
|
||||
page.value = 1
|
||||
}
|
||||
rows.value = []
|
||||
@@ -260,7 +259,7 @@ async function load(model?: QueryModel) {
|
||||
error.value = null
|
||||
loading.value = true
|
||||
try {
|
||||
const statements = await listFinanceStatements(String(filters.value.customerId || '').trim() || undefined)
|
||||
const statements = await listFinanceStatements(String(appliedFilters.value.customerId || '').trim() || undefined)
|
||||
const detailErrors: ApiErrorDetails[] = []
|
||||
const hydrated = await Promise.all(statements.map(async (row) => {
|
||||
if (!hydrateDetails) return detailToRow(row)
|
||||
@@ -510,7 +509,7 @@ async function performAction(row: FinanceStatementReadModel, actionName: Reconci
|
||||
try {
|
||||
await actionReconciliationStatement(row.id, { action: actionName, expectedVersion: row.version, ...(reason ? { reason } : {}) })
|
||||
ElMessage.success('对账单状态已更新')
|
||||
await load(filters.value)
|
||||
await load(appliedFilters.value)
|
||||
} catch (cause) { error.value = getApiErrorDetails(cause, '对账单操作失败') }
|
||||
finally { actionBusy.value = false }
|
||||
}
|
||||
@@ -540,7 +539,7 @@ async function submitAdjustment() {
|
||||
})
|
||||
adjustOpen.value = false
|
||||
ElMessage.success('对账单调整已保存')
|
||||
await load(filters.value)
|
||||
await load(appliedFilters.value)
|
||||
await openDetail(statement)
|
||||
} catch (cause) { error.value = getApiErrorDetails(cause, '对账单调整失败') }
|
||||
finally { adjustBusy.value = false }
|
||||
@@ -648,7 +647,7 @@ watch(detailRouteId, (statementId) => {
|
||||
</el-tabs>
|
||||
</DetailPageLayout>
|
||||
<ListPageLayout v-else aria-label="客户对账单">
|
||||
<template #toolbar><QueryToolbar v-model="filters" class="surface-panel" ariaLabel="客户对账单筛选" :fields="fields" preference-key="finance-statements-query" @search="load" /></template>
|
||||
<template #toolbar><QueryToolbar v-model="filters" class="surface-panel" ariaLabel="客户对账单筛选" :fields="fields" preference-key="finance-statements-query" :search-on-clear="false" @search="load" /></template>
|
||||
<template v-if="customerError || error" #state><LoadErrorState title="客户对账单加载失败" :message="(customerError || error)?.message || ''" :loading="loading" @retry="customerError ? loadCustomers() : load()"><template #details><ApiErrorMeta :details="(customerError || error)!" /></template></LoadErrorState></template>
|
||||
<template v-if="!customerError && !error">
|
||||
<section class="surface-panel table-panel">
|
||||
|
||||
Reference in New Issue
Block a user