You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter记账应用中如何优化分类汇总模型以支持多维度筛选

改造CategorySummaryModel实现多维度收支汇总与实时更新

核心设计思路

  • 用时间维度枚举统一管理日/月/年三种汇总维度
  • 内部维护多维度汇总缓存,按「维度+时间键+分类ID+收支类型」分层存储数据
  • 绑定TransactionModel的新增事件,触发汇总数据的实时同步

具体实现方案

1. 定义时间维度枚举

# 以Python为例,可根据技术栈调整
from enum import Enum

class TimeDimension(Enum):
    DAY = "day"
    MONTH = "month"
    YEAR = "year"

2. 修改CategorySummaryModel结构

新增私有缓存属性,初始化时预加载全量交易的多维度汇总:

from collections import defaultdict

class CategorySummaryModel:
    _summary_cache = {
        TimeDimension.DAY: defaultdict(lambda: {"income": 0.0, "expense": 0.0}),
        TimeDimension.MONTH: defaultdict(lambda: {"income": 0.0, "expense": 0.0}),
        TimeDimension.YEAR: defaultdict(lambda: {"income": 0.0, "expense": 0.0})
    }

    def __init__(self, all_transactions):
        # 初始化时预计算各维度汇总
        for dimension in TimeDimension:
            self._summary_cache[dimension] = self._calculate_summary(all_transactions, dimension)
    
    @staticmethod
    def _get_time_key(timestamp, dimension):
        # 生成标准时间键:日→YYYY-MM-DD,月→YYYY-MM,年→YYYY
        dt = timestamp.date()
        if dimension == TimeDimension.DAY:
            return dt.strftime("%Y-%m-%d")
        elif dimension == TimeDimension.MONTH:
            return dt.strftime("%Y-%m")
        elif dimension == TimeDimension.YEAR:
            return dt.strftime("%Y")

3. 实现多维度汇总计算逻辑

def _calculate_summary(self, transactions, dimension):
        summary = defaultdict(lambda: {"income": 0.0, "expense": 0.0})
        for tx in transactions:
            time_key = self._get_time_key(tx.timestamp, dimension)
            # 用(时间键, 分类ID)作为缓存主键
            cache_key = (time_key, tx.category_id)
            if tx.type == "income":
                summary[cache_key]["income"] += tx.amount
            else:
                summary[cache_key]["expense"] += tx.amount
        return summary

4. 对外暴露汇总查询接口

支持按维度、时间范围获取分类收支数据:

def get_category_summary(self, dimension, time_key=None):
        """
        :param dimension: 时间维度(DAY/MONTH/YEAR)
        :param time_key: 可选,指定时间范围(如"2024-05"),不传则返回全量数据
        """
        if dimension not in self._summary_cache:
            return {}
        
        result = defaultdict(lambda: {"income": 0.0, "expense": 0.0})
        for (tk, cat_id), data in self._summary_cache[dimension].items():
            if not time_key or tk == time_key:
                result[cat_id]["income"] += data["income"]
                result[cat_id]["expense"] += data["expense"]
        
        # 关联分类名称(可选,需结合CategoryModel实现)
        for cat_id in result:
            result[cat_id]["category_name"] = CategoryModel.get_name_by_id(cat_id)
        
        return dict(result)

5. 实现新增交易的实时更新

在TransactionModel的新增方法中触发汇总更新:

# TransactionModel侧逻辑
class TransactionModel:
    @classmethod
    def add_transaction(cls, transaction):
        # 保存交易到持久化层
        cls._save_transaction(transaction)
        # 触发汇总缓存更新
        CategorySummaryModel.update_summary(transaction)

# CategorySummaryModel侧更新逻辑
class CategorySummaryModel:
    @classmethod
    def update_summary(cls, transaction):
        for dimension in TimeDimension:
            time_key = cls._get_time_key(transaction.timestamp, dimension)
            cache_key = (time_key, transaction.category_id)
            if transaction.type == "income":
                cls._summary_cache[dimension][cache_key]["income"] += transaction.amount
            else:
                cls._summary_cache[dimension][cache_key]["expense"] += transaction.amount

额外优化点

  • 若支持交易编辑/删除,复用上述update_summary逻辑(先扣减旧数据,再加新数据)
  • 初始化时可异步加载全量汇总,避免阻塞应用启动
  • 可定期与数据库全量数据校验缓存一致性,防止异常场景下的数据偏差

内容的提问来源于stack exchange,提问作者user22362195

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:22:36