Laravel按日期分组统计现金与信用卡收款报表方案咨询
按日期分组统计Cash与Card收款总额的实现方案
针对你提供的店铺销售数组,这里给出基于PHP的最优实现方案,步骤清晰且效率较高:
实现思路
- 先提取所有涉及的日期,确保每个日期都包含
Cash和Card两种支付方式的统计(即使金额为0) - 遍历原始订单数据,拆分订单的
created_at字段获取日期部分 - 对每个订单下的支付记录,按日期和支付方式累加金额
- 最后整理成目标格式的数组
代码实现
<?php // 原始销售数据 $salesData = [ [ 'id' => 1, 'receipt_number' => '1-1000', 'total_payment' => 1000, 'created_at' => '19.10.2023 22:02', 'payments' => [ ['name' => 'Cash', 'money_amount' => 200], ['name' => 'Card', 'money_amount' => 500], ['name' => 'Card', 'money_amount' => 300] ] ], [ 'id' => 2, 'receipt_number' => '1-1001', 'total_payment' => 500, 'created_at' => '19.10.2023 22:25', 'payments' => [ ['name' => 'Cash', 'money_amount' => 500] ] ], [ 'id' => 3, 'receipt_number' => '1-1002', 'total_payment' => 200, 'created_at' => '20.10.2023 09:25', 'payments' => [ ['name' => 'Card', 'money_amount' => 200] ] ], [ 'id' => 4, 'receipt_number' => '1-1003', 'total_payment' => 1200, 'created_at' => '20.10.2023 11:42', 'payments' => [ ['name' => 'Card', 'money_amount' => 200], ['name' => 'Cash', 'money_amount' => 1000] ] ], [ 'id' => 5, 'receipt_number' => '1-1004', 'total_payment' => 2000, 'created_at' => '21.10.2023 19:25', 'payments' => [ ['name' => 'Card', 'money_amount' => 2000] ] ] ]; // 初始化分组统计数组 $dailyStats = []; $paymentMethods = ['Cash', 'Card']; // 第一步:遍历所有订单,按日期分组初始化统计项 foreach ($salesData as $order) { // 拆分日期和时间,仅保留日期部分 $date = explode(' ', $order['created_at'])[0]; // 如果该日期未初始化,创建Cash和Card的默认统计(金额0) if (!isset($dailyStats[$date])) { $dailyStats[$date] = []; foreach ($paymentMethods as $method) { $dailyStats[$date][$method] = [ 'date' => $date, 'total_amount' => 0 ]; } } // 第二步:累加当前订单的各支付方式金额 foreach ($order['payments'] as $payment) { $method = $payment['name']; $amount = $payment['money_amount']; $dailyStats[$date][$method]['total_amount'] += $amount; } } // 第三步:将关联数组转为索引数组(匹配目标格式) $result = array_values($dailyStats); // 输出结果 echo "<pre>"; print_r($result); echo "</pre>"; ?>
代码说明
- 日期提取:通过
explode(' ', $order['created_at'])[0]快速拆分出日期部分,避免复杂的日期处理函数 - 默认初始化:确保每个日期下的两种支付方式都存在,解决了某日期无Cash或Card记录时显示0的需求
- 高效遍历:仅需两次遍历(一次初始化日期分组,一次累加金额),时间复杂度为O(n),n为订单和支付记录的总数量
- 格式转换:最后用
array_values()将按日期为键的关联数组转为索引数组,完全匹配目标输出格式
输出结果
运行代码后将得到与你需求完全一致的数组:
Array ( [0] => Array ( [Cash] => Array ( [date] => 19.10.2023 [total_amount] => 700 ) [Card] => Array ( [date] => 19.10.2023 [total_amount] => 800 ) ) [1] => Array ( [Cash] => Array ( [date] => 20.10.2023 [total_amount] => 1000 ) [Card] => Array ( [date] => 20.10.2023 [total_amount] => 400 ) ) [2] => Array ( [Cash] => Array ( [date] => 21.10.2023 [total_amount] => 0 ) [Card] => Array ( [date] => 21.10.2023 [total_amount] => 2000 ) ) )
内容的提问来源于stack exchange,提问作者Cuddie
相关产品推荐
相关产品推荐

