Files
DMZJ_F/lib/app/utils.dart
2026-03-07 17:24:59 +08:00

277 lines
8.2 KiB
Dart

import 'dart:io';
import 'package:extended_image/extended_image.dart';
import 'package:file_selector/file_selector.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dmzj/app/app_style.dart';
import 'package:flutter_dmzj/app/log.dart';
import 'package:flutter_dmzj/requests/common_request.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart';
import 'package:intl/intl.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
// ignore: depend_on_referenced_packages
import 'package:path/path.dart' as p;
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher_string.dart';
class Utils {
static late PackageInfo packageInfo;
static DateFormat dateFormat = DateFormat("yyyy-MM-dd");
static DateFormat dateTimeFormat = DateFormat("MM-dd HH:mm");
static DateFormat dateTimeFormatWithYear = DateFormat("yyyy-MM-dd HH:mm");
/// 版本号解析
static int parseVersion(String version) {
var sp = version.split('.');
var num = "";
for (var item in sp) {
num = num + item.padLeft(2, '0');
}
return int.parse(num);
}
/// 时间戳格式化-秒
static String formatTimestamp(int ts) {
if (ts == 0) {
return "----";
}
return formatTimestampMS(ts * 1000);
}
static String formatTimestampToDate(int ts) {
if (ts == 0) {
return "----";
}
var dt = DateTime.fromMillisecondsSinceEpoch(ts * 1000);
return dateFormat.format(dt);
}
/// 时间戳格式化-毫秒
static String formatTimestampMS(int ts) {
var dt = DateTime.fromMillisecondsSinceEpoch(ts);
var dtNow = DateTime.now();
if (dt.year == dtNow.year &&
dt.month == dtNow.month &&
dt.day == dtNow.day) {
return "今天${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}";
}
if (dt.year == dtNow.year &&
dt.month == dtNow.month &&
dt.day == dtNow.day - 1) {
return "昨天${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}";
}
if (dt.year == dtNow.year) {
return dateTimeFormat.format(dt);
}
return dateTimeFormatWithYear.format(dt);
}
/// 检查相册权限
static Future<bool> checkPhotoPermission() async {
try {
var status = await Permission.photos.status;
if (status == PermissionStatus.granted) {
return true;
}
status = await Permission.photos.request();
if (status.isGranted) {
return true;
} else {
SmartDialog.showToast("请授予相册权限");
return false;
}
} catch (e) {
return false;
}
}
/// 保存图片
static void saveImage(String url) async {
if (Platform.isIOS && !await Utils.checkPhotoPermission()) {
return;
}
try {
Uint8List? data;
if (url.startsWith("http")) {
var provider = ExtendedNetworkImageProvider(url, cache: true);
data = await provider.getNetworkImageData();
} else {
data = await File(url).readAsBytes();
}
if (data == null) {
SmartDialog.showToast("图片保存失败");
return;
}
if (!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux)) {
saveImageDetktop(p.basename(url), data);
} else {
var cacheDir = await getTemporaryDirectory();
var file = File(p.join(cacheDir.path, p.basename(url)));
await file.writeAsBytes(data);
final result = await ImageGallerySaverPlus.saveFile(
file.path,
name: p.basename(url),
isReturnPathOfIOS: true,
);
Log.d(result.toString());
SmartDialog.showToast("保存成功");
}
} catch (e) {
SmartDialog.showToast("保存失败");
}
}
/// 保存图片-桌面平台
static void saveImageDetktop(String fileName, Uint8List list) async {
final FileSaveLocation? location =
await getSaveLocation(suggestedName: fileName);
if (location == null) {
return;
}
final XFile file = XFile.fromData(list, name: fileName);
await file.saveTo(location.path);
}
/// 分享
static void share(String url, {String content = ""}) {
showModalBottomSheet(
context: Get.context!,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
),
constraints: const BoxConstraints(
maxWidth: 500,
),
useSafeArea: true,
backgroundColor: Get.theme.cardColor,
builder: (context) => Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
leading: const Icon(Icons.copy),
title: const Text("复制链接"),
onTap: () {
Get.back();
Utils.copyText(url);
},
),
Visibility(
visible: content.isNotEmpty,
child: ListTile(
leading: const Icon(Icons.copy),
title: const Text("复制标题与链接"),
onTap: () {
Get.back();
Utils.copyText("$content\n$url");
},
),
),
ListTile(
leading: const Icon(Icons.public),
title: const Text("浏览器打开"),
onTap: () {
Get.back();
launchUrlString(url, mode: LaunchMode.externalApplication);
},
),
ListTile(
leading: const Icon(Icons.share),
title: const Text("系统分享"),
onTap: () {
Get.back();
Share.share(content.isEmpty ? url : "$content\n$url");
},
),
],
),
);
}
/// 检查更新
static void checkUpdate({bool showMsg = false}) async {
try {
int currentVer = Utils.parseVersion(packageInfo.version);
CommonRequest request = CommonRequest();
var versionInfo = await request.checkUpdate();
if (versionInfo.versionNum > currentVer) {
Get.dialog(
AlertDialog(
title: Text(
"发现新版本 ${versionInfo.version}",
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 18),
),
content: Text(
versionInfo.versionDesc,
style: const TextStyle(fontSize: 14, height: 1.4),
),
actionsPadding: AppStyle.edgeInsetsH12,
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextButton(
onPressed: () {
Get.back();
},
child: const Text("取消"),
),
),
AppStyle.hGap12,
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
),
onPressed: () {
launchUrlString(
versionInfo.downloadUrl,
mode: LaunchMode.externalApplication,
);
},
child: const Text("更新"),
),
),
],
),
],
),
);
} else {
if (showMsg) {
SmartDialog.showToast("当前已经是最新版本了");
}
}
} catch (e) {
Log.logPrint(e);
if (showMsg) {
SmartDialog.showToast("检查更新失败");
}
}
}
/// 复制文本
static void copyText(String text) async {
try {
await Clipboard.setData(ClipboardData(text: text));
SmartDialog.showToast("已复制到剪切板");
} catch (e) {
SmartDialog.showToast(e.toString());
}
}
}