Dart Duration不符合预期:FlutterFlow支付判断自定义函数问题
FlutterFlow自定义函数支付判断逻辑修复
问题描述
我在FlutterFlow中实现了一个自定义函数,用于判断用户是否需要支付:根据用户选择的时间间隔(如Every 2 Weeks),若datePicked在当前日期的对应间隔范围内则返回false(无需支付),超出范围则返回true(需要支付)。但当前代码始终返回true,完全不符合预期。
原代码
import 'dart:convert'; import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:timeago/timeago.dart' as timeago; import '/flutter_flow/lat_lng.dart'; import '/flutter_flow/place.dart'; import '/flutter_flow/uploaded_file.dart'; import '/flutter_flow/custom_functions.dart'; import '/backend/backend.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import '/backend/supabase/supabase.dart'; import '/auth/supabase_auth/auth_util.dart'; bool? newCustomFunction( DateTime? datePicked, String? everySoOften, ) { /// MODIFY CODE ONLY BELOW THIS LINE String frequency = everySoOften?.toLowerCase() ?? ''; int interval = int.parse(RegExp(r'\d+').firstMatch(frequency)?.group(0) ?? '0'); String timeUnit = frequency.replaceAll(RegExp(r'\d+'), '').trim(); Duration duration = Duration(); switch (timeUnit) { case 'week': case 'weeks': duration = Duration(days: interval * 7); // 1 week = 7 days break; case 'month': case 'months': duration = Duration(days: interval * 30); break; case '3 months': duration = Duration(days: interval * 30 * 3); break; case '6 months': duration = Duration(days: interval * 30 * 6); break; case 'year': case 'years': duration = Duration(days: interval * 365); break; } bool isBeyondAllowance = DateTime.now().isAfter(datePicked?.add(duration) ?? DateTime.now()); return isBeyondAllowance; /// MODIFY CODE ONLY ABOVE THIS LINE }
问题根源
- 时间单位提取错误:仅移除字符串中的数字,未处理前缀
every,导致提取的timeUnit包含无效内容(如every weeks),无法匹配switch中的任何case,最终duration始终为默认的空时长(0天)。 - 特殊间隔匹配失效:
3 months、6 months这类特殊间隔的case设计不合理,实际处理时无法匹配到正确的时间单位。 - 空值处理不严谨:当
datePicked为null时,返回DateTime.now().isAfter(DateTime.now()),结果恒为false,未明确业务逻辑中的空值处理规则。
修复后的代码
import 'dart:convert'; import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:timeago/timeago.dart' as timeago; import '/flutter_flow/lat_lng.dart'; import '/flutter_flow/place.dart'; import '/flutter_flow/uploaded_file.dart'; import '/flutter_flow/custom_functions.dart'; import '/backend/backend.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import '/backend/supabase/supabase.dart'; import '/auth/supabase_auth/auth_util.dart'; bool? newCustomFunction( DateTime? datePicked, String? everySoOften, ) { /// MODIFY CODE ONLY BELOW THIS LINE // 空值处理:若datePicked或间隔参数为空,直接返回true(可根据业务需求调整) if (datePicked == null || everySoOften == null) { return true; } String frequency = everySoOften.toLowerCase().trim(); // 先移除前缀"every ",确保后续提取的数字和单位准确 frequency = frequency.replaceFirst('every ', ''); // 提取间隔数字,默认值设为1避免0值导致时长计算错误 RegExp numRegex = RegExp(r'\d+'); Match? numMatch = numRegex.firstMatch(frequency); int interval = numMatch != null ? int.parse(numMatch.group(0)!) : 1; // 提取时间单位(移除数字后清理空格) String timeUnit = frequency.replaceAll(numRegex, '').trim(); Duration duration = Duration(); switch (timeUnit) { case 'week': case 'weeks': duration = Duration(days: interval * 7); break; case 'month': case 'months': duration = Duration(days: interval * 30); break; case '3 months': // 直接计算3个月对应的时长,避免依赖可能错误的interval值 duration = Duration(days: 3 * 30); break; case '6 months': duration = Duration(days: 6 * 30); break; case 'year': case 'years': duration = Duration(days: interval * 365); break; } // 核心逻辑:当前时间超过datePicked加间隔的时间 → 返回true(需要支付) bool isBeyondAllowance = DateTime.now().isAfter(datePicked.add(duration)); return isBeyondAllowance; /// MODIFY CODE ONLY ABOVE THIS LINE }
修复说明
- 清理时间字符串:先移除前缀
every,确保后续提取的数字和时间单位准确。 - 优化数字提取:增加空值判断,默认间隔设为1,避免因提取失败导致间隔为0。
- 修正特殊间隔处理:针对
3 months、6 months的case,直接计算对应时长,避免依赖可能错误的interval值。 - 明确空值处理:当
datePicked或everySoOften为空时,直接返回true(可根据实际业务需求调整)。
内容的提问来源于stack exchange,提问作者Python12492
相关产品推荐
相关产品推荐

