Files
tuiche/lib/common/util/MyUtils.dart
2025-05-24 17:02:47 +08:00

412 lines
12 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/controller/setting/language/language_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/model/api_response.dart';
ThemeController themeController = Get.find();
LanguageController languageController = Get.find();
class MyUtils {
static ApiResponse formatResponse(
ApiResponse res,
String successMsg,
String errorMsg,
) {
if (res.code == HttpStatusCodes.ok) {
// 成功但 msg 为空时填默认成功提示
if (res.msg == null || res.msg!.isEmpty) {
res.msg = successMsg;
}
} else {
// 失败且 msg 为空时填默认失败提示
if (res.msg == null || res.msg!.isEmpty) {
res.msg = errorMsg;
}
}
return res;
}
static String timestampToDateString(int timestamp) {
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
String formattedDate =
'${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')} '
'${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}';
return formattedDate;
}
static String hidePhoneNumber(String phoneNumber) {
if (phoneNumber.length != 11) {
// 检查手机号是否为11位
throw Exception("手机号格式不正确");
}
// 将中间四位替换为星号
return phoneNumber.replaceRange(3, 7, '****');
}
static double initialScrollOffset = 0.0;
// 判断手机号格式是否正确的方法
static bool isValidPhoneNumber(String phoneNumber) {
final RegExp phoneRegExp = RegExp(r'^1[3-9]\d{9}$');
return phoneRegExp.hasMatch(phoneNumber);
}
static bool isValidEmail(String email) {
final RegExp emailRegExp = RegExp(
r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$',
);
return emailRegExp.hasMatch(email);
}
static Future<void> makePhoneCall(String phoneNumber) async {
final Uri launchUri = Uri(
scheme: 'tel',
path: phoneNumber,
);
if (await canLaunchUrl(launchUri)) {
await launchUrl(launchUri);
} else {
throw '无法拨打电话';
}
}
static String formatDateTime(DateTime dateTime) {
// 定义日期格式
// dateTime.toLocal();
final DateFormat formatter = DateFormat('yyyy-MM-dd HH:mm');
// 返回格式化后的字符串
return formatter.format(dateTime);
}
static void scrollToFocusedInput(FocusNode focusNode, _scrollController) {
// 获取输入框相对于整个页面的偏移量
RenderObject? object = focusNode.context?.findRenderObject();
if (object != null) {
final RenderBox box = object as RenderBox;
final Offset position = box.localToGlobal(Offset.zero);
// 将页面滚动到使输入框显示在屏幕上的位置
_scrollController.animateTo(
position.dy - MediaQuery.of(focusNode.context!).size.height / 4,
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
}
static void resetScrollPosition(_scrollController) {
_scrollController.animateTo(
initialScrollOffset,
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
static String formatBindTime(DateTime d) {
final DateFormat formatter = DateFormat('yyyy/MM/dd');
return formatter.format(d);
}
static DateTime? formatBirthdayTime(String? device) {
if (device == null || device.isEmpty) return null;
try {
return DateTime.parse(device.replaceAll('/', '-')); // 替换为标准格式
} catch (e) {
return null; // 解析失败时返回 null
}
}
static int getAgeByDate(DateTime? formatBirthdayTime) {
if (formatBirthdayTime == null) return 0;
final now = DateTime.now();
int age = now.year - formatBirthdayTime.year;
// 如果还没到今年生日,减一岁
if (now.month < formatBirthdayTime.month ||
(now.month == formatBirthdayTime.month &&
now.day < formatBirthdayTime.day)) {
age--;
}
return age;
}
static String formatDateTimeWeek(DateTime date) {
DateTime now = DateTime.now();
// 去除时间部分,仅比较年月日
DateTime today = DateTime(now.year, now.month, now.day);
DateTime target = DateTime(date.year, date.month, date.day);
if (target == today) {
return '今日';
}
const List<String> weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return weekdays[date.weekday % 7]; // Dart中星期日是7要映射到索引0
}
/// 返回 MM/dd 格式
static String formatDateTimeDay(DateTime date) {
String twoDigits(int n) => n.toString().padLeft(2, '0');
return '${twoDigits(date.month)}/${twoDigits(date.day)}';
}
static String getFormatChineseTime(int date, {bool showWeekday = true}) {
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(date);
// 格式化年月日
String dateStr = DateFormat('yyyy年MM月dd日').format(dateTime);
if (!showWeekday) return dateStr;
// 获取星期
const weekDays = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
String weekStr = weekDays[dateTime.weekday - 1];
return '$dateStr $weekStr';
}
}
Color stringToColor(String hexColor) {
String formattedColor = hexColor.replaceAll("#", "");
int colorValue = int.parse("0xFF$formattedColor");
return Color(colorValue);
}
//字节转16进制
String ab2str(List<int> buffer) {
return buffer.map((x) => x.toRadixString(16).padLeft(2, '0')).join('');
}
enum ToastColor { success, error, warn }
ToastColor color_success = ToastColor.success;
ToastColor color_warning = ToastColor.warn;
ToastColor color_error = ToastColor.error;
showToast(String msg,
{ToastColor color = ToastColor.error, int closeTime = 3}) {
// Fluttertoast.showToast(
// msg: msg,
// toastLength: Toast.LENGTH_LONG,
// gravity: ToastGravity.CENTER,
// timeInSecForIosWeb: 1,
// backgroundColor: color == null ? color_error : color,
// fontSize: 14.0,
// );
final context = Get.overlayContext; // 获取 Overlay 的上下文
Color background = Colors.red;
Color color_text = stringToColor("#FA5A4C");
String icon = "";
if (color == color_success) {
background = stringToColor("#DBF1E1");
icon = "success";
color_text = stringToColor("#31CA79");
} else if (color == color_warning) {
background = stringToColor("#FDF6EC");
icon = "warn";
color_text = stringToColor("#F8AE00");
} else if (color == color_error) {
background = stringToColor("#FEF0F0");
icon = "error";
color_text = stringToColor("#FA5A4C");
}
if (context == null) return;
OverlayEntry overlayEntry = OverlayEntry(
builder: (context) => Positioned(
top: MediaQuery.of(context).size.height * 0.10,
left: MediaQuery.of(context).size.width * 0.5 - 225.rpx,
child: Material(
color: Colors.transparent,
child: Container(
width: 450.rpx,
padding: EdgeInsets.only(top: 20.rpx, bottom: 20.rpx),
decoration: BoxDecoration(
color: background,
borderRadius: BorderRadius.circular(10.rpx),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/toast/${icon}_.png",
width: 30.rpx,
height: 30.rpx,
),
SizedBox(
width: 18.rpx,
),
Container(
constraints: BoxConstraints(maxWidth: 380.rpx),
child: Text(
msg,
maxLines: 9,
style: TextStyle(
color: color_text,
fontSize: 28.rpx,
fontWeight: FontWeight.w400),
),
)
],
),
),
),
),
);
Overlay.of(context)?.insert(overlayEntry);
Future.delayed(Duration(seconds: closeTime), () {
overlayEntry.remove();
});
}
var closeIcon = GestureDetector(
onTapDown: (f) {
Get.back();
},
child: Container(
padding: EdgeInsets.fromLTRB(10.rpx, 18.rpx, 10.rpx, 10.rpx),
child: Container(
height: 42.rpx,
width: 42.rpx,
alignment: Alignment.center,
child: Icon(
Icons.close,
),
),
),
);
var closeIconWhite = GestureDetector(
onTapDown: (f) {
Get.back();
},
child: Container(
padding: EdgeInsets.all(10.rpx),
child: Container(
height: 42.rpx,
width: 42.rpx,
alignment: Alignment.center,
child: Icon(
Icons.close,
color: themeController.currentColor.sc3,
),
),
),
);
var returnIconButtom = IconButton(
// padding: EdgeInsets.zero, // 去除默认 padding
// constraints: BoxConstraints(), // 去除最小尺寸限制
onPressed: () => Get.back(),
icon: Icon(Icons.navigate_before, size: 60.rpx),
);
var returnIconButtomAddCallback = (
VoidCallback? returnCallBack, {
bool enableBack = true,
}) {
return IconButton(
onPressed: () {
returnCallBack?.call();
if (enableBack) {
Get.back();
}
},
icon: Icon(Icons.navigate_before, size: 60.rpx),
);
};
String time_08_Formatter(String time) {
if (time == null || time == "") {
return "";
}
return DateFormat("yyyy-MM-dd HH:mm:ss")
.format(DateTime.parse(time).toLocal());
}
String time_08_Formatter_pattern(String time, String pattern) {
if (time == null || time == "") {
return "";
}
return DateFormat(pattern).format(DateTime.parse(time).toLocal());
}
enum LoadingDialogIcon { ble, wifi, none }
class LoadingDialog {
static show(String name, {LoadingDialogIcon icon = LoadingDialogIcon.none}) {
ThemeController themeController = Get.find();
String iconUrl = "";
if (icon == LoadingDialogIcon.wifi) {
iconUrl = "wifi";
} else if (icon == LoadingDialogIcon.ble) {
iconUrl = "ble";
}
Get.dialog(
PopScope(
canPop: false,
child: Container(
// color: Colors.transparent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
constraints:
BoxConstraints(minWidth: 300.rpx, maxWidth: 500.rpx),
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(8)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (iconUrl.isNotEmpty)
Container(
width: 120.rpx,
height: 120.rpx,
margin: EdgeInsets.only(bottom: 60.rpx),
child:
Image.asset("assets/images/toast/${iconUrl}.png"),
),
Text(
textAlign: TextAlign.center,
name,
style: TextStyle(
fontSize: 16,
color: themeController.currentColor.sc3,
decoration: TextDecoration.none),
),
SizedBox(
height: 30.rpx,
),
CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(
themeController.currentColor.sc3,
),
),
],
),
)
],
),
),
),
barrierDismissible: false,
barrierColor: Color.fromRGBO(0, 0, 0, 0.8));
}
static hide() {
Get.back();
}
}