如何在Laravel的付款发票页面计算降序排序记录的每行余额?
问题根源
你当前在Student模型的billings关联中默认按created_at降序排序,前端遍历计算余额时是从最新的记录开始累加,不符合从最早交易开始计算余额的规则,同时原有计算逻辑没有区分交易类型的加减规则,导致结果不符合预期。
修复方案
我们可以先把账单转为升序计算好每条对应的余额,再转回降序用于前端展示,同时修正余额计算规则,代码修改如下:
Blade 完整修改代码
<table class="table table-bordered table-striped table-hover datatable datatable-Room"> <thead> <tr> <th>日期</th> <th>类型</th> <th>金额</th> <th>余额</th> <th> </th> </tr> </thead> <tbody> @php // 先将账单按创建时间升序,计算每条记录的余额 $ascBillings = $student->billings->sortBy('created_at'); $balance = 0; $processedBillings = $ascBillings->map(function($billing) use (&$balance) { // 直接用集合sum方法计算当前账单总金额,避免循环累加 $total = $billing->billingRecords->sum('amount'); // 按类型计算余额:Payment扣减,Invoice累加 if ($billing->type === 'Payment') { $balance -= $total; } elseif ($billing->type === 'Invoice') { $balance += $total; } // 给账单对象追加计算好的总金额和余额属性 $billing->total = $total; $billing->calculated_balance = $balance; return $billing; })->sortByDesc('created_at'); // 重新按降序排列,用于前端展示 @endphp @foreach($processedBillings as $key => $billing) <tr data-entry-id="{{ $billing->id }}"> <td> <p class="m-0">{{ $billing->created_at->format('M d, Y') ?? '' }}</p> <p class="small m-0">{{ $billing->created_at->format('h:i A') ?? '' }}</p> </td> <td>{{ $billing->type ?? '' }}</td> <td> @if($billing->type == "Payment") $-{{ $billing->total }} @elseif($billing->type == "Invoice") ${{ $billing->total }} @endif </td> <td> ${{ $billing->calculated_balance }} </td> </tr> @endforeach </tbody> </table>
优化建议
视图层尽量不要包含业务计算逻辑,你可以把上述余额计算逻辑迁移到控制器或者模型的访问器中,后续维护会更方便。
内容的提问来源于stack exchange,提问作者Ihtisham Khan
相关产品推荐
相关产品推荐

