Files
flutter-template/lib/core/extensions/string_x.dart
T
SkyJourney 61017f1c39 chore: 初始化脚手架 — sunny_mochi 企业级 Flutter 模板
Core 基础设施:Flavor 三包体系、Drift+SQLCipher 加密数据库
7 拦截器 Dio 网络栈、CrashReporter 崩溃日志、Sealed Failure 错误体系
5 色板主题系统、Auth 认证骨架(Clean Architecture)、Dev Panel、Mock Adapter

通过验证:flutter analyze(0 errors)、flutter test(全绿)、staging APK 74.8MB
2026-05-14 12:51:05 +08:00

60 lines
2.0 KiB
Dart

/// 对应 iOS BasicModule/Extension/Extension+Optional.swift。
extension NullableStringX on String? {
/// null 或空字符串时返回 "-"(对应 iOS orPlaceholder)。
/// UI 层硬约束:所有 Optional 字符串展示前必须 .orPlaceholder。
String get orPlaceholder {
if (this == null || this!.isEmpty) return '-';
return this!;
}
/// 简洁的非空判断(替代散落的 `s != null && s!.isNotEmpty` 三段式)。
bool get isNotNullOrEmpty => this != null && this!.isNotEmpty;
/// 反向:null 或空。
bool get isNullOrEmpty => this == null || this!.isEmpty;
}
extension NullableIntX on int? {
String get orPlaceholder => this?.toString() ?? '-';
}
extension NullableDoubleX on double? {
String get orPlaceholder => this?.toString() ?? '-';
}
extension StringX on String {
/// 首字母大写。
String get capitalize =>
isEmpty ? this : '${this[0].toUpperCase()}${substring(1)}';
/// 中国大陆手机号校验(对应 iOS Validator.isValidPhone)。
bool get isMobile => RegExp(r'^1[3-9]\d{9}$').hasMatch(this);
/// 身份证号校验(对应 iOS Validator.isValidIDCard)。
bool get isIdCard => RegExp(r'^\d{17}[\dXx]$').hasMatch(this);
/// Email 简易校验。
bool get isEmail => RegExp(r'^[\w.+-]+@([\w-]+\.)+[\w-]{2,}$').hasMatch(this);
/// 脱敏手机号(保留首 3 + 末 4,中间 4 个 *):13800138000 → 138****8000
String get masked {
if (length < 7) return this;
return '${substring(0, 3)}****${substring(length - 4)}';
}
/// 密码强度(0=无 / 1=弱 / 2=中 / 3=强)。
/// 规则:长度 ≥6 +1;含大小写字母 +1;含数字 +1;含特殊符号 +1(最高 3)。
int get passwordStrength {
if (length < 6) return 0;
var score = 1;
if (RegExp('[A-Z]').hasMatch(this) && RegExp('[a-z]').hasMatch(this)) {
score++;
}
if (RegExp(r'\d').hasMatch(this)) score++;
if (RegExp(r'[!@#$%^&*(),.?":{}|<>_+\-=\[\]/\\;~`]').hasMatch(this)) {
score++;
}
return score.clamp(0, 3);
}
}