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:
@@ -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,
|
||||
|
||||
@@ -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 || []
|
||||
|
||||
Reference in New Issue
Block a user