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

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
}

问题根源

  1. 时间单位提取错误:仅移除字符串中的数字,未处理前缀every,导致提取的timeUnit包含无效内容(如every weeks),无法匹配switch中的任何case,最终duration始终为默认的空时长(0天)。
  2. 特殊间隔匹配失效:3 months、6 months这类特殊间隔的case设计不合理,实际处理时无法匹配到正确的时间单位。
  3. 空值处理不严谨:当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
}

修复说明

  1. 清理时间字符串:先移除前缀every ,确保后续提取的数字和时间单位准确。
  2. 优化数字提取:增加空值判断,默认间隔设为1,避免因提取失败导致间隔为0。
  3. 修正特殊间隔处理:针对3 months、6 months的case,直接计算对应时长,避免依赖可能错误的interval值。
  4. 明确空值处理:当datePicked或everySoOften为空时,直接返回true(可根据实际业务需求调整)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:32:24