Flutter实现每日数据按月分组并汇总人员收入明细
Flutter 月度收入分组汇总解决方案
明确实体类结构
假设你的实体类定义如下(若和实际结构有出入,调整字段名即可):
class StaffIncome { final String staffName; final double amount; StaffIncome({required this.staffName, required this.amount}); } class DailySummary { final DateTime date; final double totalDaily; final List<StaffIncome> staffIncomes; DailySummary({ required this.date, required this.totalDaily, required this.staffIncomes, }); }
核心实现逻辑
借助collection包的groupBy先按月份分组每日数据,再对每个月的分组完成两层汇总:
- 月度总金额:累加当月所有每日总金额
- 人员月度收入:将当月所有
StaffIncome按人员名称分组,再求和每个人员的收入总额
import 'package:collection/collection.dart'; // 定义月度汇总实体类(按需调整字段) class MonthlySummary { final String monthKey; // 格式示例:"2024-05" final double totalMonthly; final Map<String, double> staffMonthlyIncomes; MonthlySummary({ required this.monthKey, required this.totalMonthly, required this.staffMonthlyIncomes, }); } List<MonthlySummary> generateMonthlySummaries(List<DailySummary> dailySummaries) { // 第一步:按"yyyy-MM"格式的月份字符串分组每日数据 final groupedByMonth = groupBy(dailySummaries, (DailySummary ds) { return "${ds.date.year}-${ds.date.month.toString().padLeft(2, '0')}"; }); // 第二步:遍历每个月的分组,生成月度汇总数据 return groupedByMonth.entries.map((entry) { final monthKey = entry.key; final dailyList = entry.value; // 计算当月总金额 final totalMonthly = dailyList.fold(0.0, (sum, ds) => sum + ds.totalDaily); // 扁平化当月所有人员收入记录,再按人员分组求和 final allStaffIncomes = dailyList.expand((ds) => ds.staffIncomes).toList(); final staffGrouped = groupBy(allStaffIncomes, (StaffIncome si) => si.staffName); final staffMonthlyIncomes = staffGrouped.map((staffName, incomes) { final staffTotal = incomes.fold(0.0, (sum, si) => sum + si.amount); return MapEntry(staffName, staffTotal); }); return MonthlySummary( monthKey: monthKey, totalMonthly: totalMonthly, staffMonthlyIncomes: staffMonthlyIncomes, ); }).toList(); }
输入输出示例验证
输入示例
final dailyData = [ DailySummary( date: DateTime(2024, 5, 1), totalDaily: 500.0, staffIncomes: [ StaffIncome(staffName: "张三", amount: 200.0), StaffIncome(staffName: "李四", amount: 300.0), ], ), DailySummary( date: DateTime(2024, 5, 15), totalDaily: 600.0, staffIncomes: [ StaffIncome(staffName: "张三", amount: 250.0), StaffIncome(staffName: "王五", amount: 350.0), ], ), DailySummary( date: DateTime(2024, 6, 2), totalDaily: 400.0, staffIncomes: [ StaffIncome(staffName: "李四", amount: 180.0), StaffIncome(staffName: "王五", amount: 220.0), ], ), ];
输出结果
调用generateMonthlySummaries(dailyData)后,会得到:
[ MonthlySummary( monthKey: "2024-05", totalMonthly: 1100.0, staffMonthlyIncomes: { "张三": 450.0, "李四": 300.0, "王五": 350.0, }, ), MonthlySummary( monthKey: "2024-06", totalMonthly: 400.0, staffMonthlyIncomes: { "李四": 180.0, "王五": 220.0, }, ), ]
关键说明
- 月份分组使用
yyyy-MM格式的字符串作为key,确保同一月份的不同日期数据会被分到同一组 - 通过
expand方法将每日的人员收入列表扁平化为一个大列表,再按人员分组求和,自动适配新增的人员 - 所有求和操作使用
fold实现,逻辑清晰且性能高效
内容的提问来源于stack exchange,提问作者Jacob Handaya
相关产品推荐
相关产品推荐

