优化
This commit is contained in:
@@ -133,8 +133,8 @@ function formatDateTime(value: unknown) {
|
||||
}
|
||||
function displayOperator(value: unknown) {
|
||||
const operator = String(value || '').trim()
|
||||
if (!operator) return '系统'
|
||||
return /^(?:operator-)?\d+$/i.test(operator) ? '操作人信息缺失' : operator
|
||||
if (!operator) return '名称数据缺失'
|
||||
return /^(?:operator-)?\d+$/i.test(operator) ? '名称数据缺失' : operator
|
||||
}
|
||||
const filteredRows = computed(() => {
|
||||
const keyword = String(filters.value.keyword || '').trim().toLowerCase(); const direction = String(filters.value.direction || ''); const reviewStatus = String(filters.value.reviewStatus || '')
|
||||
@@ -210,10 +210,16 @@ function statusLabel(status: string) { return financeStatusLabel(status) }
|
||||
function money(value: unknown) { return Number(value || 0).toFixed(2) }
|
||||
function onSelectionChange(rows: ArapRow[]) { selectedRows.value = rows }
|
||||
function openGeneration(mode: 'BY_CUTOFF' | 'SELECTED') {
|
||||
generationForm.mode = mode; generationForm.customerId = String(filters.value.customerId || ''); generationForm.period = Array.isArray(filters.value.businessRange) ? filters.value.businessRange.map(String) : []; generationForm.cutoffDate = generationForm.period[1] || ''; generationForm.remark = ''; generationError.value = null; generationOpen.value = true
|
||||
generationForm.mode = mode
|
||||
generationForm.customerId = ''
|
||||
generationForm.period = Array.isArray(filters.value.businessRange) ? filters.value.businessRange.map(String) : []
|
||||
generationForm.cutoffDate = generationForm.period[1] || ''
|
||||
generationForm.remark = ''
|
||||
generationError.value = null
|
||||
generationOpen.value = true
|
||||
}
|
||||
async function submitGeneration() {
|
||||
const eligible = selectedRows.value.filter((row) => row.feeSourceId && row.direction === 'RECEIVABLE' && row.reviewStatus === 'APPROVED' && row.settlementIncluded === true && row.statementGenerated === false)
|
||||
const eligible = selectedRows.value.filter((row) => row.feeSourceId && row.direction === 'RECEIVABLE' && row.reviewStatus === 'APPROVED' && row.settlementIncluded === true && row.statementGenerated === false && row.customerId === generationForm.customerId)
|
||||
const period = generationForm.period
|
||||
if (!generationForm.customerId || !period[0] || !period[1]) { ElMessage.warning('请选择客户和业务期间'); return }
|
||||
if (generationForm.mode === 'SELECTED' && !eligible.length) { ElMessage.warning('请选择审核通过、参与结算且未出账的应收费用'); return }
|
||||
@@ -251,7 +257,7 @@ watch(() => [route.name, String(route.params.feeSourceId || '')], ([name, feeSou
|
||||
<template v-if="stateError" #state><LoadErrorState title="客户应收应付加载失败" :message="stateError.message" :loading="customersLoading || loading" @retry="customersError ? loadCustomers() : load()"><template #details><ApiErrorMeta :details="stateError" /></template></LoadErrorState></template>
|
||||
<section v-if="!customersError && !loadError" class="surface-panel table-panel">
|
||||
<DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :loading="loading" :total="filteredRows.length" preference-key="finance-customer-arap-table" aria-label="客户应收应付列表" row-key="id" empty-text="暂无客户应收应付数据" @selection-change="onSelectionChange">
|
||||
<template #toolbar-actions><div v-if="canCreateStatement" class="generation-actions"><el-button :disabled="!filters.customerId" @click="openGeneration('BY_CUTOFF')"><FilePlus2 :size="16" />按截止日期生成</el-button><el-button type="primary" :disabled="!selectedRows.length" @click="openGeneration('SELECTED')"><FilePlus2 :size="16" />按勾选生成</el-button></div></template>
|
||||
<template #toolbar-actions><div v-if="canCreateStatement" class="generation-actions"><el-button @click="openGeneration('BY_CUTOFF')"><FilePlus2 :size="16" />按截止日期生成</el-button><el-button type="primary" :disabled="!selectedRows.length" @click="openGeneration('SELECTED')"><FilePlus2 :size="16" />按勾选生成</el-button></div></template>
|
||||
<template #actions="{ row }"><div class="row-actions"><template v-if="row.feeSourceId"><el-button v-if="canViewSource" link type="primary" @click="openDetail(row)"><Eye :size="15" />详情</el-button><el-button v-if="canReviewSource" link type="primary" @click="openReview(row)"><FileCheck2 :size="15" />审核</el-button><el-button v-if="canSettleSource" link type="primary" @click="openInclusion(row)"><Link2 :size="15" />结算</el-button></template><span v-else class="muted-action">手工成本</span></div></template>
|
||||
<template #customerName="{ row }">{{ customerName(row.customerId, row.customerName) }}</template><template #direction="{ row }"><el-tag :type="row.direction === 'RECEIVABLE' ? 'success' : row.direction === 'PAYABLE' ? 'warning' : 'info'">{{ financeDirectionLabel(row.direction) }}</el-tag></template>
|
||||
<template #documentNo="{ row }">{{ feeDocumentLabel(row.direction, row.feeName) }}</template><template #sourceType="{ row }">{{ sourceTypeDisplay(row.sourceType) }}</template><template #sourceId="{ row }">{{ row.sourceId }}</template>
|
||||
@@ -287,41 +293,246 @@ watch(() => [route.name, String(route.params.feeSourceId || '')], ([name, feeSou
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.finance-arap-page { min-width: 0; }
|
||||
.finance-arap-detail { width: 100%; min-width: 0; }
|
||||
.finance-arap-detail__surface { width: min(100%, 1600px); margin: 0 auto; overflow: hidden; }
|
||||
.finance-arap-detail__layout { width: 100%; margin: 0 auto; }
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout) { gap: 0; }
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout__header) { min-height: 72px; align-items: center; padding: 16px 24px; border-bottom: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout__summary) { padding: 16px 24px 0; }
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout__content) { padding: 0 24px 20px; }
|
||||
.row-actions { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
|
||||
.row-actions .el-button { margin-left: 0; }
|
||||
.generation-actions,.detail-heading,.detail-actions { display: flex; align-items: center; gap: 8px; }
|
||||
.detail-heading { min-width: 0; align-items: flex-start; }
|
||||
.detail-title { min-width: 0; }
|
||||
.detail-heading h2 { margin: 0; font-size: 18px; }
|
||||
.detail-heading p { overflow: hidden; margin: 4px 0 0; color: var(--cc-muted); text-overflow: ellipsis; white-space: nowrap; }
|
||||
.detail-actions { margin-left: auto; }
|
||||
.muted-action { color: var(--cc-muted); }
|
||||
.arap-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; padding: 0 0 16px; border-bottom: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.arap-metric { min-width: 0; padding: 0 20px; }
|
||||
.arap-metric:first-child { padding-left: 0; }
|
||||
.arap-metric + .arap-metric { border-left: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.arap-metric span { display: block; color: var(--cc-muted); font-size: 12px; }
|
||||
.arap-metric strong { display: inline-block; margin-top: 7px; color: var(--cc-text); font-size: 20px; line-height: 1.1; font-variant-numeric: tabular-nums; }
|
||||
.arap-metric small { margin-left: 6px; color: var(--cc-muted); font-size: 11px; }
|
||||
.arap-metric.is-amount strong { color: #4f46e5; }
|
||||
.arap-detail-grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(360px, .65fr); gap: 24px; border-bottom: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.arap-information,.arap-settlement,.operation-log { padding: 16px 0; }
|
||||
.arap-settlement { padding-left: 24px; border-left: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.operation-log { min-height: 150px; }
|
||||
:deep(.arap-detail .el-descriptions__content) { min-width: 0; overflow-wrap: anywhere; }
|
||||
:deep(.arap-detail .el-descriptions__label) { width: 112px; color: var(--cc-muted); }
|
||||
.operation-log :deep(.el-empty) { padding: 12px 0 4px; }
|
||||
.operation-log :deep(.el-empty__image) { display: none; }
|
||||
.operation-log small { display: block; margin-top: 4px; color: var(--cc-muted); }
|
||||
@media (max-width: 1080px) { .finance-arap-detail__surface { width: 100%; } .arap-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } .arap-metric:nth-child(3) { padding-left: 0; border-left: 0; } .arap-detail-grid { grid-template-columns: 1fr; gap: 0; } .arap-settlement { padding-left: 0; border-left: 0; border-top: 1px solid var(--cc-border, #e3e8ef); } }
|
||||
@media (max-width: 720px) { .detail-heading { align-items: stretch; flex-direction: column; } .detail-actions { margin-left: 0; } .arap-metrics { grid-template-columns: 1fr; gap: 12px; } .arap-metric,.arap-metric:first-child,.arap-metric:nth-child(3) { padding-left: 0; } .arap-metric + .arap-metric { border-left: 0; } :deep(.arap-detail .el-descriptions__body .el-descriptions__table) { table-layout: fixed; } }
|
||||
@media (max-width: 480px) { :deep(.arap-detail .el-descriptions__cell) { display: block; width: 100%; } }
|
||||
.finance-arap-page {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.finance-arap-detail {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.finance-arap-detail__surface {
|
||||
width: min(100%, 1920px);
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.finance-arap-detail__layout {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout) {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout__header) {
|
||||
min-height: 64px;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--cc-border, #e3e8ef);
|
||||
}
|
||||
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout__summary) {
|
||||
padding: 10px 16px 0;
|
||||
}
|
||||
|
||||
.finance-arap-detail__layout :deep(.detail-page-layout__content) {
|
||||
padding: 0 16px 12px;
|
||||
}
|
||||
|
||||
.row-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.row-actions .el-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.generation-actions,
|
||||
.detail-heading,
|
||||
.detail-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.detail-heading {
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.detail-heading h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.detail-heading p {
|
||||
overflow: hidden;
|
||||
margin: 3px 0 0;
|
||||
color: var(--cc-muted);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.detail-actions {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.muted-action {
|
||||
color: var(--cc-muted);
|
||||
}
|
||||
|
||||
.arap-metrics {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
padding: 0 0 12px;
|
||||
border-bottom: 1px solid var(--cc-border, #e3e8ef);
|
||||
}
|
||||
|
||||
.arap-metric {
|
||||
min-width: 0;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.arap-metric:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.arap-metric + .arap-metric {
|
||||
border-left: 1px solid var(--cc-border, #e3e8ef);
|
||||
}
|
||||
|
||||
.arap-metric span {
|
||||
display: block;
|
||||
color: var(--cc-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.arap-metric strong {
|
||||
display: inline-block;
|
||||
margin-top: 6px;
|
||||
color: var(--cc-text);
|
||||
font-size: 20px;
|
||||
line-height: 1.1;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.arap-metric small {
|
||||
margin-left: 6px;
|
||||
color: var(--cc-muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.arap-metric.is-amount strong {
|
||||
color: #4f46e5;
|
||||
}
|
||||
|
||||
.arap-detail-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.35fr) minmax(320px, 0.65fr);
|
||||
gap: 16px;
|
||||
border-bottom: 1px solid var(--cc-border, #e3e8ef);
|
||||
}
|
||||
|
||||
.arap-information,
|
||||
.arap-settlement,
|
||||
.operation-log {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.arap-settlement {
|
||||
padding-left: 16px;
|
||||
border-left: 1px solid var(--cc-border, #e3e8ef);
|
||||
}
|
||||
|
||||
.operation-log {
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
:deep(.arap-detail .el-descriptions__content) {
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
:deep(.arap-detail .el-descriptions__label) {
|
||||
width: 112px;
|
||||
color: var(--cc-muted);
|
||||
}
|
||||
|
||||
.operation-log :deep(.el-empty) {
|
||||
padding: 10px 0 2px;
|
||||
}
|
||||
|
||||
.operation-log :deep(.el-empty__image) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.operation-log small {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: var(--cc-muted);
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.finance-arap-detail__surface {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.arap-metrics {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.arap-metric:nth-child(3) {
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.arap-detail-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.arap-settlement {
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
border-top: 1px solid var(--cc-border, #e3e8ef);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.detail-heading {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.detail-actions {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.arap-metrics {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.arap-metric,
|
||||
.arap-metric:first-child,
|
||||
.arap-metric:nth-child(3) {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.arap-metric + .arap-metric {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
:deep(.arap-detail .el-descriptions__body .el-descriptions__table) {
|
||||
table-layout: fixed;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
:deep(.arap-detail .el-descriptions__cell) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user