/// 封装常用函数 library; import 'dart:math'; import 'package:photo_manager/photo_manager.dart'; import 'package:uuid/uuid.dart'; class Utils { /// 随机字符串 /// * [len] 字符串长度 static guid({int len = 32}) { String str = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; String chars = ''; for (var i = 0; i < len; i++) { chars += str[Random().nextInt(str.length)]; } return chars; } /// 获取全局唯一标识符uuid /// * [type] uuid类型 /// * [namespace] 生成指定内容uuid /// https://pub.dev/packages/uuid static uuid({String type = 'v1', String? namespace}) { var uuid = const Uuid(); switch (type) { // Generate a v1 (time-based) id case 'v1': return uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' // Generate a v4 (random) id case 'v4': return uuid.v4(); // Generate a v5 (namespace-name-sha1-based) id case 'v5': return uuid.v5(Namespace.url.value, namespace); // Generate a v6 (time-based) id case 'v6': return uuid.v6(); // Generate a v7 (time-based) id case 'v7': return uuid.v7(); // Generate a v8 (time-random) id case 'v8': return uuid.v8(); } } /// 验证手机号是否正确 /// * [tel] 手机号码 static bool checkTel(tel) { if (tel == null || tel.trim().isEmpty) return false; final reg = RegExp(r'^1[3-9]\d{9}$'); return reg.hasMatch(tel.trim()); } /// 是否为空 static bool isEmpty(val) { if (val == null) return true; if (val is bool && val == false) return true; if (val is String) return val.isEmpty; if (val is Iterable) return val.isEmpty; if (val is Map) return val.isEmpty; if (val is Set) return val.isEmpty; return false; } /// 网址正则 static isUrl(path) { // 网址正则 String urlExpString = r"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?"; RegExp reg = RegExp(urlExpString); if (reg.hasMatch(path)) { return true; } return false; } /// 秒数转换为时分秒 static secondsToHms(double seconds) { // String h = ((seconds / 3600) % 24).floor().toString().padLeft(2, '0'); String m = (seconds % 3600 / 60).floor().toString().padLeft(2, '0'); String s = (seconds % 3600 % 60).floor().toString().padLeft(2, '0'); // return "$h:$m:$s"; return "$m:$s"; } //翻译媒体库title static String translateAlbumName(AssetPathEntity album) { // logger.i(album.name); final Map albumNameMap = { 'recents': '最近项目', 'favorites': '收藏', 'videos': '视频', 'selfies': '自拍', 'live photos': '实况照片', 'portrait': '人像', 'long exposure': '长曝光', 'spatial': '空间照片', 'panoramas': '全景', 'time-lapse': '延时摄影', 'slo-mo': '慢动作', 'cinematic': '电影效果', 'bursts': '连拍', 'screenshots': '屏幕截图', 'animated': '动图', 'raw': 'RAW格式', 'hidden': '已隐藏', 'recent': '最近项目', // 安卓 'camera': '相机', // 安卓 }; return albumNameMap[album.name.toLowerCase()] ?? album.name; } // 大数字转换 String graceNumber(int number) { if (number == 0) return "0"; if (number < 1000) { return "$number"; } else if (number < 10000) { double result = number / 1000; return "${_trimTrailingZero(result)}k"; } else if (number < 100000000) { double result = number / 10000; return "${_trimTrailingZero(result)}w"; } else { double result = number / 100000000; return "${_trimTrailingZero(result)}亿+"; } } String _trimTrailingZero(double number) { return number.toStringAsFixed(1).replaceAll(RegExp(r'\.0$'), ''); } // 处理聊天消息时间 String formatChatTime(int timestamp) { // timestamp 是秒级时间戳,转成 DateTime DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); final msgDay = DateTime(dateTime.year, dateTime.month, dateTime.day); final difference = now.difference(dateTime); if (msgDay == today) { return _formatHourMinute(dateTime); } else if (msgDay == today.subtract(Duration(days: 1))) { return "昨天 ${_formatHourMinute(dateTime)}"; } else if (difference.inDays < 7) { return "${_weekdayLabel(dateTime.weekday)} ${_formatHourMinute(dateTime)}"; } else if (dateTime.year == now.year) { return "${dateTime.month}月${dateTime.day}日 ${_formatHourMinute(dateTime)}"; } else { return "${dateTime.year}年${dateTime.month}月${dateTime.day}日 ${_formatHourMinute(dateTime)}"; } } // 处理IM消息时间显示 static String formatTime(int timestamp) { // 确保是毫秒级 int ms = timestamp.toString().length == 10 ? timestamp * 1000 : timestamp; final messageTime = DateTime.fromMillisecondsSinceEpoch(ms).toLocal(); final now = DateTime.now(); bool isSameDay = messageTime.year == now.year && messageTime.month == now.month && messageTime.day == now.day; if (isSameDay) { // 同一天:显示时:分 return '${messageTime.hour.toString().padLeft(2, '0')}:${messageTime.minute.toString().padLeft(2, '0')}'; } if (messageTime.year == now.year) { // 同一年:显示月-日 时:分 return '${messageTime.month.toString().padLeft(2, '0')}-' '${messageTime.day.toString().padLeft(2, '0')} ' '${messageTime.hour.toString().padLeft(2, '0')}:' '${messageTime.minute.toString().padLeft(2, '0')}'; } // 不同年:显示完整日期 return '${messageTime.year}-' '${messageTime.month.toString().padLeft(2, '0')}-' '${messageTime.day.toString().padLeft(2, '0')} ' '${messageTime.hour.toString().padLeft(2, '0')}:' '${messageTime.minute.toString().padLeft(2, '0')}'; } String _formatHourMinute(DateTime dt) { final hour = dt.hour.toString().padLeft(2, '0'); final minute = dt.minute.toString().padLeft(2, '0'); return "$hour:$minute"; } String _weekdayLabel(int weekday) { const weekdays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]; return weekdays[(weekday - 1) % 7]; } // 格式化点赞数量 String formatLikeCount(int count) { if (count >= 10000) { return '${(count / 10000).toStringAsFixed(1)}w'; } else if (count >= 1000) { return '${(count / 1000).toStringAsFixed(1)}k'; } return count.toString(); } }