修复财务页面竞态并整理采购与运输展示
This commit is contained in:
@@ -5,7 +5,7 @@ import '../financeDensity.css'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { CircleCheck, Clock3, Download, Printer, RotateCcw, Search, Wallet } from '@lucide/vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { createPlatformExportTask } from '@/modules/downloads'
|
||||
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
|
||||
@@ -21,6 +21,7 @@ import type { ReceivableStatisticsResult, ReceivableStatisticsRow } from '../typ
|
||||
const now = new Date()
|
||||
const defaultMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`
|
||||
const access = useAccessPreviewStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const month = ref(defaultMonth)
|
||||
const customerId = ref('')
|
||||
@@ -33,6 +34,7 @@ const error = ref<ApiErrorDetails | null>(null)
|
||||
const result = ref<ReceivableStatisticsResult | null>(null)
|
||||
|
||||
const canView = computed(() => access.can('platform:finance:receivable-statistics:list'))
|
||||
const canPrint = computed(() => route.name === 'finance-receivable-statistics' && canView.value && !loading.value && !error.value && Boolean(result.value))
|
||||
const canExport = computed(() => access.can('platform:finance:receivable-statistics:export') && access.can('platform:download:list'))
|
||||
const rows = computed<ReceivableStatisticsRow[]>(() => result.value?.records ?? [])
|
||||
const customerNameById = computed(() => new Map(customers.value.map((item) => [String(item.id), item.tenantName])))
|
||||
@@ -65,7 +67,7 @@ async function loadCustomers() {
|
||||
|
||||
function search() { page.value = 1; void load() }
|
||||
function reset() { month.value = defaultMonth; customerId.value = ''; page.value = 1; void load() }
|
||||
function printCurrent() { window.print() }
|
||||
function printCurrent() { if (canPrint.value) window.print() }
|
||||
function statisticsRowKey(row: ReceivableStatisticsRow) { return `${row.customerId}:${row.customerName}` }
|
||||
function displayCustomerName(value: unknown) {
|
||||
const row = value as ReceivableStatisticsRow
|
||||
@@ -116,12 +118,30 @@ onMounted(() => { void loadCustomers(); void load() })
|
||||
</section></template>
|
||||
<template #notices><LoadErrorState v-if="error" title="应收款统计加载失败" :message="error.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="error" /></template></LoadErrorState></template>
|
||||
|
||||
<template #toolbar-actions><div class="report-actions"><el-button :disabled="loading || !result" @click="printCurrent"><Printer :size="16" />打印</el-button><el-button v-if="canExport" type="primary" :loading="exporting" :disabled="loading || exporting" @click="exportCurrent"><Download :size="16" />导出Excel</el-button></div></template>
|
||||
<template #toolbar-actions><div class="report-actions"><el-button :disabled="!canPrint" @click="printCurrent"><Printer :size="16" />打印</el-button><el-button v-if="canExport" type="primary" :loading="exporting" :disabled="loading || exporting" @click="exportCurrent"><Download :size="16" />导出Excel</el-button></div></template>
|
||||
<template #customerName="{ row }">{{ displayCustomerName(row) }}</template><template #totalReceivable="{ row }">{{ money(row.totalReceivable) }}</template><template #totalReceived="{ row }">{{ money(row.totalReceived) }}</template><template #totalOutstanding="{ row }"><span class="outstanding-cell">{{ money(row.totalOutstanding) }}</span></template>
|
||||
<template #pagination-left>统计月份:{{ result?.statisticsMonth }} · 币种:CNY</template>
|
||||
</DataTable></div>
|
||||
</template>
|
||||
</AdminPage>
|
||||
<Teleport to="body">
|
||||
<section v-if="canPrint && result" class="receivable-statistics-print" aria-label="应收款统计打印报表">
|
||||
<header>
|
||||
<h1>应收款统计表</h1>
|
||||
<p>统计月份:{{ result.statisticsMonth }} · 币种:CNY</p>
|
||||
</header>
|
||||
<table>
|
||||
<colgroup><col class="print-customer-column" /><col class="print-currency-column" /><col /><col /><col /></colgroup>
|
||||
<thead><tr><th scope="col">应收单位</th><th scope="col">币种</th><th scope="col">应收总额(CNY)</th><th scope="col">已收合计(CNY)</th><th scope="col">余额未收(CNY)</th></tr></thead>
|
||||
<tbody>
|
||||
<tr v-for="row in rows" :key="statisticsRowKey(row)"><td>{{ displayCustomerName(row) }}</td><td>{{ row.currency }}</td><td>{{ money(row.totalReceivable) }}</td><td>{{ money(row.totalReceived) }}</td><td>{{ money(row.totalOutstanding) }}</td></tr>
|
||||
<tr v-if="!rows.length"><td colspan="5">当前月份暂无应收数据</td></tr>
|
||||
</tbody>
|
||||
<tfoot><tr><th scope="row" colspan="2">统计汇总</th><td>{{ money(result.totalReceivable) }}</td><td>{{ money(result.totalReceived) }}</td><td>{{ money(result.totalOutstanding) }}</td></tr></tfoot>
|
||||
</table>
|
||||
<p>数据第 {{ result.page }} 页 · 共 {{ result.totalCustomers }} 家应收单位</p>
|
||||
</section>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@@ -133,10 +153,21 @@ onMounted(() => { void loadCustomers(); void load() })
|
||||
.query-actions :deep(.el-button), .report-actions :deep(.el-button) { margin-left: 0; }
|
||||
.outstanding-cell { color: var(--el-color-danger); font-variant-numeric: tabular-nums; }
|
||||
.statistics-table { overflow: hidden; }
|
||||
.receivable-statistics-print { display: none; }
|
||||
@media print {
|
||||
.statistics-query, :deep(.data-table__toolbar), :deep(.data-table__pagination) { display: none !important; }
|
||||
.receivable-statistics-page { gap: 10px; padding: 0; color: #000; }
|
||||
.workbench-table > :deep(.data-table) { border-radius: var(--admin-radius); box-shadow: none; }
|
||||
.finance-metric-grid > article, .statistics-table { border-color: #999; box-shadow: none; break-inside: avoid; }
|
||||
:global(body:has(> .receivable-statistics-print) > :not(.receivable-statistics-print)) { display: none !important; }
|
||||
:global(body:has(> .receivable-statistics-print)) { min-width: 0; height: auto; margin: 0; overflow: visible; background: #fff; }
|
||||
.receivable-statistics-print { display: block; width: 100%; color: #000; font: 10pt/1.5 Arial, 'Microsoft YaHei', sans-serif; }
|
||||
.receivable-statistics-print h1 { margin: 0 0 8pt; text-align: center; font-size: 18pt; }
|
||||
.receivable-statistics-print p { margin: 8pt 0; }
|
||||
.receivable-statistics-print table { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
||||
.receivable-statistics-print col { width: 18%; }
|
||||
.receivable-statistics-print .print-customer-column { width: 38%; }
|
||||
.receivable-statistics-print .print-currency-column { width: 8%; }
|
||||
.receivable-statistics-print th, .receivable-statistics-print td { padding: 5pt; border: 1px solid #999; text-align: left; overflow-wrap: anywhere; }
|
||||
.receivable-statistics-print tbody td:nth-child(n+3), .receivable-statistics-print thead th:nth-child(n+3), .receivable-statistics-print tfoot td { text-align: right; font-variant-numeric: tabular-nums; }
|
||||
.receivable-statistics-print thead { display: table-header-group; }
|
||||
.receivable-statistics-print tfoot { display: table-row-group; font-weight: 700; }
|
||||
.receivable-statistics-print tr { break-inside: avoid; }
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user