fix(workbench): show single expense distribution chart

This commit is contained in:
caoxiaozhu
2026-06-03 15:46:51 +08:00
parent 18d716bc6b
commit e12b140508
6 changed files with 139 additions and 15 deletions

View File

@@ -51,12 +51,29 @@
</div>
<div v-if="distributionChartItems.length" class="expense-distribution-chart">
<DonutChart
class="expense-distribution-donut"
:items="distributionChartItems"
:center-value="distributionCenterValue"
center-label="费用总额"
/>
<div class="expense-distribution-chart-layout">
<DonutChart
class="expense-distribution-donut"
:items="distributionChartItems"
:center-value="distributionCenterValue"
center-label="费用总额"
:show-legend="false"
/>
<div class="expense-distribution-summary-list" aria-label="费用分布明细">
<article
v-for="(row, index) in distributionRows"
:key="`${row.label}-${index}`"
class="expense-distribution-summary-row"
>
<i :style="{ background: resolveDistributionColor(index) }"></i>
<div>
<strong>{{ row.label }}</strong>
<span>{{ row.count || 0 }} · {{ row.amountLabel || '¥0' }}</span>
</div>
<em>{{ row.percentLabel || '0%' }}</em>
</article>
</div>
</div>
</div>
<p v-else class="expense-stats-empty">暂无历史报销费用分布</p>
</section>
@@ -188,6 +205,10 @@ const distributionChartItems = computed(() => distributionRows.value.map((row, i
color: distributionChartColors[index % distributionChartColors.length]
})))
function resolveDistributionColor(index) {
return distributionChartColors[index % distributionChartColors.length]
}
function emitClose() {
emit('close')
}
@@ -454,26 +475,84 @@ function resolveTagType(tone) {
align-items: stretch;
}
.expense-distribution-donut {
.expense-distribution-chart-layout {
display: grid;
grid-template-columns: minmax(170px, 0.86fr) minmax(0, 1.14fr);
align-items: center;
gap: 12px;
min-height: 286px;
}
.expense-distribution-donut {
min-height: 0;
}
.expense-distribution-donut :deep(.donut-body) {
height: 194px;
height: 220px;
margin-top: 0;
}
.expense-distribution-donut :deep(.donut-legend) {
gap: 7px 14px;
.expense-distribution-summary-list {
min-width: 0;
display: grid;
align-content: center;
gap: 8px;
}
.expense-distribution-donut :deep(.legend-name) {
.expense-distribution-summary-row {
min-width: 0;
display: grid;
grid-template-columns: 10px minmax(0, 1fr) auto;
align-items: center;
gap: 8px;
padding: 8px 0;
border-top: 1px solid #e8eef5;
}
.expense-distribution-summary-row:first-child {
border-top: 0;
}
.expense-distribution-summary-row i {
width: 10px;
height: 10px;
border-radius: 2px;
}
.expense-distribution-summary-row div {
min-width: 0;
display: grid;
gap: 2px;
}
.expense-distribution-summary-row strong,
.expense-distribution-summary-row span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.expense-distribution-summary-row strong {
color: #334155;
font-size: 12.5px;
font-weight: 850;
}
.expense-distribution-summary-row span {
color: #94a3b8;
font-size: 11px;
font-weight: 650;
}
.expense-distribution-summary-row em {
color: #0f172a;
font-size: 12px;
font-style: normal;
font-weight: 850;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.expense-processing-row {
display: grid;
grid-template-columns: minmax(124px, 0.8fr) minmax(164px, 1fr) auto 58px;
@@ -580,6 +659,14 @@ function resolveTagType(tone) {
}
@media (max-width: 620px) {
.expense-distribution-chart-layout {
grid-template-columns: 1fr;
}
.expense-distribution-donut :deep(.donut-body) {
height: 190px;
}
.expense-processing-row,
.expense-operation-row {
grid-template-columns: 1fr;