Template
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
60 lines
2.0 KiB
Dart
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);
|
|
}
|
|
}
|