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

Flutter中到期后如何按规则追加税费?避免重复累加问题

解决税费重复累加问题

核心原因

StreamBuilder会实时监听Firestore快照变化,每次修改数据库后都会触发快照更新,导致builder重新执行;而你的代码没有判断是否已经完成过税费追加,所以每次都会重复执行累加操作。同时原代码的for循环在处理第一个文档后就直接return,导致只能显示第一个条目,这也是需要修复的问题。

解决方案

1. 添加标记字段避免重复执行

在Firestore的fine文档中新增一个布尔字段(比如hasAddedTax),用来标记是否已经完成税费追加。每次执行更新前先检查这个字段,只有当未标记时才执行累加和数据库更新。

2. 修正循环逻辑,展示所有条目

原代码在for循环中处理第一个文档后就return,导致只能显示第一个条目。需要将所有符合条件的Card收集到列表中,返回ListView展示所有结果。

修改后的完整代码

StreamBuilder(
  stream: FirebaseFirestore.instance
      .collection('Data')
      .doc(uid)
      .collection('fine')
      .where('mode', isEqualTo: 'notpaid')
      .snapshots(),
  builder: ((context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const CircularProgressIndicator();
    }

    final now = DateTime.now();
    final ds = snapshot.data!.docs;
    List<Widget> cards = [];

    for (var doc in ds) {
      final expirationDate = doc['expired'].toDate();
      final bool isExpired = expirationDate.isBefore(now);

      if (!isExpired) {
        // 未过期的条目,添加绿色卡片
        cards.add(Card(
          color: Colors.green,
          child: Text(doc['description']),
        ));
      } else {
        final dateTime1 = doc['expired'].toDate();
        final nextExpireDate = dateTime1.add(const Duration(days: 7));
        final expiredDays = nextExpireDate.difference(now).inDays;

        // 检查是否已经追加过税费:通过新增的标记字段或现有status判断
        final bool hasAddedTax = doc['hasAddedTax'] ?? false;
        final int currentStatus = doc['status'] ?? 0;

        if (expiredDays == -1 && !hasAddedTax && currentStatus != 1) {
          // 仅当未追加过税费时,执行累加和更新
          final amount = int.parse(doc['amount']);
          final withTax = amount + 1000;
          final fineWithTax = withTax.toString();

          FirebaseFirestore.instance
              .collection('Data')
              .doc(uid)
              .collection('fine')
              .doc(doc.id)
              .update({
            'status': 1,
            'paybefore': nextExpireDate,
            'amount': fineWithTax,
            'hasAddedTax': true, // 添加标记,避免重复执行
          });
        }

        // 添加当前金额的卡片
        cards.add(Card(
          child: Text(doc['amount']),
        ));
      }
    }

    return ListView(children: cards);
  }),
)

额外优化建议

  • 尽量避免在StreamBuilder的builder回调中直接执行数据库更新操作,建议将更新逻辑封装到单独的函数中,通过状态管理(如Provider、Riverpod)或定时任务触发,减少不必要的重复执行。
  • 如果需要定期检查到期状态,可以使用Timer定时触发检查逻辑,替代依赖StreamBuilder的实时快照触发,降低数据库操作频率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:20:18