fix(receivables): unwrap response envelope once + align card/column field names

- Receivables.vue: const d = r (was r.data || r) -> cards/table no longer blank

- cards: pending_balance(待收余额) / overdue / completed_amount / completed_count

- columns: counterparty(+description fallback) / owner(未分配) / settled_amount / plan_date / aging_bucket

- cash.py: summary.completed_count + _plan_dict.settled_amount (existing keys untouched)

- api/index.ts untouched (global interceptor)

(cherry picked from commit d60557622441b971970fb9dc86ef7491c3a9d72b)
This commit is contained in:
Hermes CI Fix
2026-10-02 21:12:20 +08:00
parent ac4bbc6891
commit 29dc5c0bdc
2 changed files with 18 additions and 10 deletions
+4
View File
@@ -68,6 +68,7 @@ def _plan_dict(p: CashPlan) -> dict:
"plan_type_label": "收款" if p.plan_type == "receive" else "付款",
"amount": round(p.amount or 0, 2),
"paid_amount": paid,
"settled_amount": round(p.amount or 0, 2) if p.status == "completed" else paid,
"receivable_balance": max(balance, 0),
"plan_date": p.plan_date.strftime("%Y-%m-%d") if p.plan_date else "",
"counterparty": p.counterparty or "",
@@ -583,6 +584,7 @@ def api_receivables(
overdue_amount = 0.0
aging_amount = {}
completed_amount = 0.0
completed_count = 0
for p in plans:
d = _plan_dict(p)
if status:
@@ -605,6 +607,7 @@ def api_receivables(
aging_amount[d["aging_bucket"]] = aging_amount.get(d["aging_bucket"], 0) + d["receivable_balance"]
elif d["status"] == "completed":
completed_amount += d["amount"]
completed_count += 1
owners = [r[0] for r in db.query(CashPlan.owner).filter(
CashPlan.entity_id == entity_id,
@@ -625,6 +628,7 @@ def api_receivables(
"overdue_count": overdue_count,
"overdue_amount": round(overdue_amount, 2),
"completed_amount": round(completed_amount, 2),
"completed_count": completed_count,
"aging": {k: round(v, 2) for k, v in sorted(aging_amount.items(), key=lambda x: x[0])},
},
"data": items,
+14 -10
View File
@@ -17,9 +17,9 @@
<!-- 汇总卡片 -->
<el-row :gutter="16">
<el-col :span="6"><el-card shadow="never" class="stat-card red"><div class="stat-val">¥{{ (summary.total_balance || 0).toFixed(2) }}万</div><div class="stat-label">应收总额</div></el-card></el-col>
<el-col :span="6"><el-card shadow="never" class="stat-card red"><div class="stat-val">¥{{ (summary.pending_balance || 0).toFixed(2) }}万</div><div class="stat-label">待收余额</div></el-card></el-col>
<el-col :span="6"><el-card shadow="never" class="stat-card orange"><div class="stat-val">¥{{ (summary.overdue_amount || 0).toFixed(2) }}万</div><div class="stat-label">逾期金额 ({{ summary.overdue_count || 0 }}笔)</div></el-card></el-col>
<el-col :span="6"><el-card shadow="never" class="stat-card green"><div class="stat-val">¥{{ (summary.total_paid || 0).toFixed(2) }}万</div><div class="stat-label">已回款</div></el-card></el-col>
<el-col :span="6"><el-card shadow="never" class="stat-card green"><div class="stat-val">¥{{ (summary.completed_amount || 0).toFixed(2) }}万</div><div class="stat-label">已回款</div></el-card></el-col>
<el-col :span="6"><el-card shadow="never" class="stat-card blue"><div class="stat-val">{{ summary.completed_count || 0 }}</div><div class="stat-label">已完成笔数</div></el-card></el-col>
</el-row>
@@ -39,17 +39,21 @@
<el-card shadow="never">
<template #header>应收明细</template>
<el-table :data="items" size="small" v-loading="loading">
<el-table-column prop="name" label="客户/单位" min-width="140" />
<el-table-column prop="owner" label="负责人" width="90" />
<el-table-column label="客户/单位" min-width="140">
<template #default="{ row }">{{ row.counterparty || (row.description || '').slice(0, 20) || '—' }}</template>
</el-table-column>
<el-table-column label="负责人" width="90">
<template #default="{ row }">{{ row.owner || '未分配' }}</template>
</el-table-column>
<el-table-column prop="amount" label="金额(万)" width="90">
<template #default="{ row }"><span style="font-weight:600">¥{{ row.amount }}</span></template>
</el-table-column>
<el-table-column prop="paid_amount" label="已回款(万)" width="100" />
<el-table-column prop="due_date" label="到期日" width="100" />
<el-table-column prop="aging_label" label="账龄" width="100">
<el-table-column prop="settled_amount" label="已回款(万)" width="100" />
<el-table-column prop="plan_date" label="到期日" width="100" />
<el-table-column prop="aging_bucket" label="账龄" width="100">
<template #default="{ row }">
<el-tag :type="row.overdue ? 'danger' : (row.aging_label === '未到期' ? 'success' : 'warning')" size="small">
{{ row.aging_label }}
<el-tag :type="row.overdue ? 'danger' : (row.aging_bucket === '未到期' ? 'success' : 'warning')" size="small">
{{ row.aging_bucket }}
</el-tag>
</template>
</el-table-column>
@@ -119,7 +123,7 @@ async function loadData() {
if (owner.value) params.owner = owner.value
if (status.value) params.status = status.value
const r: any = await api.get('/cash/receivables', { params })
const d = r.data || r || {}
const d = r || {}
summary.value = d.summary || {}
owners.value = d.owners || []
const rawItems = d.data || d.items || d.receivables || []