|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:dio/dio.dart';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart';
|
|
|
|
import 'package:flutter_baidu_mapapi_utils/flutter_baidu_mapapi_utils.dart';
|
|
|
|
import 'package:intl/intl.dart';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
|
|
|
|
class AppUtils {
|
|
|
|
|
|
|
|
///计算距离(当前位置到店位置直线距离)
|
|
|
|
static Future<String> calculateDistance(BMFCoordinate bmfCoordinate, BMFCoordinate myLatLng) async {
|
|
|
|
double mi = await BMFCalculateUtils.getLocationDistance(bmfCoordinate, myLatLng);
|
|
|
|
NumberFormat numberFormat = NumberFormat("#.#");
|
|
|
|
return "${numberFormat.format(mi / 1000)}";
|
|
|
|
}
|
|
|
|
|
|
|
|
///版本号
|
|
|
|
static bool versionCompare(String localVersion,String serverVersion){
|
|
|
|
try{
|
|
|
|
var localVersionArr = localVersion.split(".");
|
|
|
|
var serverVersionArr = serverVersion.split(".");
|
|
|
|
if((int.tryParse(localVersionArr[0]) < int.tryParse(serverVersionArr[0]))
|
|
|
|
|| (int.tryParse(localVersionArr[1]) < int.tryParse(serverVersionArr[1]))
|
|
|
|
|| (int.tryParse(localVersionArr[2]) < int.tryParse(serverVersionArr[2])))
|
|
|
|
return true;
|
|
|
|
}catch(ex){ }
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static String trimEnd(String resString,String char){
|
|
|
|
while(resString.endsWith(char)){
|
|
|
|
resString = resString.substring(0,resString.length - 1);
|
|
|
|
}
|
|
|
|
return resString;
|
|
|
|
}
|
|
|
|
|
|
|
|
///金额保留整数/后两位
|
|
|
|
static String calculateDouble(double res){
|
|
|
|
String resString = res.toStringAsFixed(2);
|
|
|
|
resString = trimEnd(resString, "0");
|
|
|
|
resString = trimEnd(resString, ".");
|
|
|
|
return resString;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Future<BMFCoordinate> coordConvert(BMFCoordinate latLng) async {
|
|
|
|
return BMFCalculateUtils.coordConvert(
|
|
|
|
coordinate: latLng,
|
|
|
|
fromType: BMF_COORD_TYPE.BD09LL,
|
|
|
|
toType: BMF_COORD_TYPE.COMMON);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isPhone(mobile) {
|
|
|
|
RegExp exp = RegExp(
|
|
|
|
r'^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\d{8}$');
|
|
|
|
return exp.hasMatch(mobile);
|
|
|
|
}
|
|
|
|
|
|
|
|
static String phoneEncode(String phone){
|
|
|
|
if(phone == null || phone.length != 11)
|
|
|
|
return phone;
|
|
|
|
return phone.substring(0,3) + "****" + phone.substring(phone.length-4);
|
|
|
|
}
|
|
|
|
|
|
|
|
static double textScale(context) {
|
|
|
|
double textScaleFactor = MediaQuery.of(context).textScaleFactor;
|
|
|
|
// print("textScaleFactor: $textScaleFactor");
|
|
|
|
return textScaleFactor > 1.15 ? 1.15 : textScaleFactor;
|
|
|
|
}
|
|
|
|
|
|
|
|
static String getAge(DateTime brt) {
|
|
|
|
int age = 0;
|
|
|
|
DateTime dateTime = DateTime.now();
|
|
|
|
if (dateTime.isBefore(brt)) {
|
|
|
|
//出生日期晚于当前时间,无法计算
|
|
|
|
return '出生日期不正確';
|
|
|
|
}
|
|
|
|
int yearNow = dateTime.year; //当前年份
|
|
|
|
int monthNow = dateTime.month; //当前月份
|
|
|
|
int dayOfMonthNow = dateTime.day; //当前日期
|
|
|
|
|
|
|
|
int yearBirth = brt.year;
|
|
|
|
int monthBirth = brt.month;
|
|
|
|
int dayOfMonthBirth = brt.day;
|
|
|
|
age = yearNow - yearBirth; //计算整岁数
|
|
|
|
if (monthNow <= monthBirth) {
|
|
|
|
if (monthNow == monthBirth) {
|
|
|
|
if (dayOfMonthNow < dayOfMonthBirth) age--; //当前日期在生日之前,年龄减一
|
|
|
|
} else {
|
|
|
|
age--; //当前月份在生日之前,年龄减一
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return age.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
static String getAgeByString(String birth) {
|
|
|
|
if (birth == null || birth == "") return "";
|
|
|
|
int age = 0;
|
|
|
|
DateTime brt = DateFormat("yyyy-MM-dd").parse(birth);
|
|
|
|
|
|
|
|
DateTime dateTime = DateTime.now();
|
|
|
|
if (dateTime.isBefore(brt)) {
|
|
|
|
//出生日期晚于当前时间,无法计算
|
|
|
|
return '出生日期不正確';
|
|
|
|
}
|
|
|
|
int yearNow = dateTime.year; //当前年份
|
|
|
|
int monthNow = dateTime.month; //当前月份
|
|
|
|
int dayOfMonthNow = dateTime.day; //当前日期
|
|
|
|
|
|
|
|
int yearBirth = brt.year;
|
|
|
|
int monthBirth = brt.month;
|
|
|
|
int dayOfMonthBirth = brt.day;
|
|
|
|
age = yearNow - yearBirth; //计算整岁数
|
|
|
|
if (monthNow <= monthBirth) {
|
|
|
|
if (monthNow == monthBirth) {
|
|
|
|
if (dayOfMonthNow < dayOfMonthBirth) age--; //当前日期在生日之前,年龄减一
|
|
|
|
} else {
|
|
|
|
age--; //当前月份在生日之前,年龄减一
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return age.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
static String getHourMinuteByString(String birth) {
|
|
|
|
if (birth == null || birth == "") return "";
|
|
|
|
DateTime brt = DateFormat("yyyy-MM-dd HH:mm:ss").parse(birth);
|
|
|
|
return DateFormat("HH:mm").format(brt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static String getHourMinuteAfter30mByString(String birth) {
|
|
|
|
if (birth == null || birth == "") return "";
|
|
|
|
DateTime brt = DateFormat("yyyy-MM-dd HH:mm:ss").parse(birth);
|
|
|
|
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
|
|
|
brt.millisecondsSinceEpoch + 30 * 60 * 1000);
|
|
|
|
return DateFormat("HH:mm").format(dateTime); //分钟
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 获取缓存大小
|
|
|
|
static Future<int> total() async {
|
|
|
|
Directory tempDir = await getTemporaryDirectory();
|
|
|
|
if (tempDir == null) return 0;
|
|
|
|
int total = await _reduce(tempDir);
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 清除缓存
|
|
|
|
static Future<void> clear() async {
|
|
|
|
Directory tempDir = await getTemporaryDirectory();
|
|
|
|
if (tempDir == null) return 0;
|
|
|
|
await _delete(tempDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 递归缓存目录,计算缓存大小
|
|
|
|
static Future<int> _reduce(FileSystemEntity file) async {
|
|
|
|
/// 如果是一个文件,则直接返回文件大小
|
|
|
|
if (file is File) {
|
|
|
|
int length = await file.length();
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 如果是目录,则遍历目录并累计大小
|
|
|
|
if (file is Directory) {
|
|
|
|
final List<FileSystemEntity> children = file.listSync();
|
|
|
|
int total = 0;
|
|
|
|
if (children != null && children.isNotEmpty)
|
|
|
|
for (final FileSystemEntity child in children)
|
|
|
|
total += await _reduce(child);
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 递归删除缓存目录和文件
|
|
|
|
static Future<void> _delete(FileSystemEntity file) async {
|
|
|
|
if (file is Directory) {
|
|
|
|
final List<FileSystemEntity> children = file.listSync();
|
|
|
|
for (final FileSystemEntity child in children) {
|
|
|
|
await child.delete(recursive: true);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
await file.delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 递归删除缓存目录和文件
|
|
|
|
static Future<void> deleteDirectory(FileSystemEntity file) async {
|
|
|
|
if (file is Directory) {
|
|
|
|
final List<FileSystemEntity> children = file.listSync();
|
|
|
|
for (final FileSystemEntity child in children) {
|
|
|
|
child.deleteSync(recursive: true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static String dioErrorTypeToString(DioErrorType type){
|
|
|
|
String errorStr = "";
|
|
|
|
switch(type){
|
|
|
|
case DioErrorType.CANCEL:{
|
|
|
|
errorStr = "取消请求";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DioErrorType.CONNECT_TIMEOUT:{
|
|
|
|
errorStr = "链接超时";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DioErrorType.RECEIVE_TIMEOUT:{
|
|
|
|
errorStr = "响应超时";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DioErrorType.SEND_TIMEOUT:{
|
|
|
|
errorStr = "请求超时";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DioErrorType.RESPONSE:{
|
|
|
|
errorStr = "服务器异常";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DioErrorType.DEFAULT:
|
|
|
|
default:{
|
|
|
|
errorStr = "请求异常";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
errorStr += ",请检查手机网络是否正常";
|
|
|
|
return errorStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static String textSubStr(String input, int length) {
|
|
|
|
length -= 1;
|
|
|
|
if(length < 0 || input.length < length)
|
|
|
|
return input;
|
|
|
|
return "${input.substring(0,length)}...";
|
|
|
|
}
|
|
|
|
}
|