| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- import 'dart:convert';
- import 'dart:io';
- import 'package:clean/base/base_controller.dart';
- import 'package:clean/dialog/loading_dialog.dart';
- import 'package:clean/handler/event_handler.dart';
- import 'package:clean/utils/expand.dart';
- import 'package:clean/utils/toast_util.dart';
- import 'package:flutter/cupertino.dart';
- import 'package:flutter_contacts/flutter_contacts.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'package:get/get.dart';
- import 'package:get/get_core/src/get_main.dart';
- import 'package:get/get_rx/src/rx_types/rx_types.dart';
- import 'package:path_provider/path_provider.dart';
- import 'package:wechat_camera_picker/wechat_camera_picker.dart';
- import '../../../data/consts/event_report_id.dart';
- class ContactBackUpController extends BaseController {
- // 是否为编辑状态
- RxBool isEdit = false.obs;
- // 是否全选
- RxBool isAllSelected = false.obs;
- RxList<FileSystemEntity> backupFiles = <FileSystemEntity>[].obs;
- // 存储选中的
- final RxSet<String> selectedFiles = <String>{}.obs;
- RxMap<String, List<File>> backupFilesMap = <String, List<File>>{}.obs;
- @override
- void onInit() {
- // TODO: implement onInit
- super.onInit();
- loadBackupFiles();
- }
- void init() {
- }
- // 获取备份文件列表
- Future<void> loadBackupFiles() async {
- final directory = await getApplicationDocumentsDirectory();
- final files = Directory('${directory.path}/contacts').listSync();
- final List<FileSystemEntity> entities = await Directory(
- '${directory.path}/contacts').list().toList();
- // 使用sort方法对文件列表进行排序
- entities.sort((a, b) {
- FileStat fileStatA = a.statSync();
- FileStat fileStatB = b.statSync();
- return fileStatB.changed.compareTo(fileStatA.changed);
- });
- backupFiles.clear();
- Map<String, List<File>> filesMap = {};
- for (var entity in entities) {
- if (entity is File && entity.path.endsWith('.json')) {
- backupFiles.add(entity);
- final fileName = entity.path
- .split('/')
- .last;
- final timestamp = fileName
- .split('_')
- .last
- .split('.')
- .first;
- final dateTime = DateTime.fromMillisecondsSinceEpoch(
- int.parse(timestamp));
- final formattedDate = _formatDate(dateTime);
- if (!filesMap.containsKey(formattedDate)) {
- filesMap[formattedDate] = [];
- }
- filesMap[formattedDate]!.add(entity);
- }
- }
- backupFilesMap.value = filesMap;
- }
- // 格式化日期为 "MMM dd, yyyy"
- String _formatDate(DateTime dateTime) {
- return '${_getMonthAbbreviation(dateTime.month)} ${dateTime.day}, ${dateTime
- .year}';
- }
- // 获取月份的缩写(如 Jan, Feb)
- String _getMonthAbbreviation(int month) {
- switch (month) {
- case 1:
- return 'Jan';
- case 2:
- return 'Feb';
- case 3:
- return 'Mar';
- case 4:
- return 'Apr';
- case 5:
- return 'May';
- case 6:
- return 'Jun';
- case 7:
- return 'Jul';
- case 8:
- return 'Aug';
- case 9:
- return 'Sep';
- case 10:
- return 'Oct';
- case 11:
- return 'Nov';
- case 12:
- return 'Dec';
- default:
- return 'Unknown';
- }
- }
- // 备份通讯录
- Future<void> backupContacts() async {
- EventHandler.report(EventId.event_08012);
- LoadingDialog.show(displayTime: 100);
- try {
- if (!await FlutterContacts.requestPermission()) {
- throw Exception('通讯录权限被拒绝');
- }
- List<Contact> contacts = await FlutterContacts.getContacts(
- withProperties: true,
- withThumbnail: false,
- );
- // 生成文件名
- final timestamp = DateTime
- .now()
- .millisecondsSinceEpoch;
- final fileName = '${contacts.length} contacts_$timestamp.json';
- // 保存到文件
- final directory = await getApplicationDocumentsDirectory();
- final dir = Directory('${directory.path}/contacts');
- if (!dir.existsSync()) {
- dir.createSync(recursive: true);
- }
- final file = File('${directory.path}/contacts/$fileName');
- await file.writeAsString(jsonEncode(contacts));
- // 刷新备份文件列表
- loadBackupFiles();
- // LoadingDialog.hide();
- ToastUtil.show("Successful");
- print('备份成功: ${file.path}');
- } catch (e) {
- LoadingDialog.hide();
- ToastUtil.show("Failed");
- print('备份失败: $e');
- }
- }
- // 恢复通讯录
- Future<void> restoreContacts(File file) async {
- if (!isEdit.value) {
- showCupertinoModalPopup(
- context: Get.context!,
- builder: (context) {
- return CupertinoActionSheet(
- title: Text(
- "Replace the current contacts in the phonebook with the selected backup file.",
- style: TextStyle(color: "#6E6E6E".color, fontSize: 12.sp,),),
- actions: <Widget>[
- //操作按钮集合
- CupertinoActionSheetAction(
- onPressed: () async {
- Navigator.pop(context);
- try {
- // 获取所有联系人
- List<Contact> contacts = await FlutterContacts.getContacts(
- withProperties: true,
- withPhoto: true,
- );
- for (var contact in contacts) {
- await contact.delete();
- }
- // 读取文件内容
- String contactsJsonString = await file.readAsString();
- List<dynamic> contactsJson = jsonDecode(contactsJsonString);
- // 恢复联系人
- for (var contactJson in contactsJson) {
- Contact contact = Contact.fromJson(contactJson);
- contact.id = "";
- await FlutterContacts.insertContact(contact);
- }
- ToastUtil.show("Successful");
- print('恢复成功');
- } catch (e) {
- print('恢复失败: $e');
- ToastUtil.show("Failed");
- }
- },
- child: Text(
- 'Restore now',
- style: TextStyle(
- color: "#007AFF".color,
- fontWeight: FontWeight.w500,
- fontSize: 16.sp,
- ),
- ),
- ),
- ],
- cancelButton: CupertinoActionSheetAction(
- //取消按钮
- onPressed: () {
- Navigator.pop(context);
- },
- child: Text(
- 'Cancel',
- style: TextStyle(
- color: "#007AFF".color,
- fontWeight: FontWeight.w500,
- fontSize: 16.sp,
- ),
- ),
- ),
- );
- },
- );
- }
- }
- // 选择/取消选择联系人
- void toggleSelectFile(File selectFile) {
- final file = backupFiles.firstWhere((file) => file.path == selectFile.path);
- if (selectedFiles.contains(selectFile.path)) {
- selectedFiles.remove(selectFile.path);
- } else {
- selectedFiles.add(selectFile.path);
- }
- // 更新全选状态
- isAllSelected.value = selectedFiles.length == backupFiles.length;
- }
- // 全选/取消全选
- void toggleSelectAll() {
- if (isAllSelected.value) {
- selectedFiles.clear();
- } else {
- selectedFiles.addAll(backupFiles.map((file) => file.path));
- }
- isAllSelected.value = !isAllSelected.value;
- }
- // 退出编辑模式时清空选择
- void exitEditMode() {
- isEdit.value = false;
- selectedFiles.clear();
- isAllSelected.value = false;
- }
- Future<void> deleteBtnClick() async {
- showCupertinoModalPopup(
- context: Get.context!,
- builder: (context) {
- return CupertinoActionSheet(
- actions: <Widget>[
- //操作按钮集合
- CupertinoActionSheetAction(
- onPressed: () async {
- Navigator.pop(context);
- // 获取要删除的资产
- final fileToDelete = backupFiles.where((file) => selectedFiles.contains(file.path)).toList();
- //
- for (var file in fileToDelete) {
- await file.delete();
- }
- ToastUtil.show("Successful");
- exitEditMode();
- loadBackupFiles();
- },
- child: Text(
- 'Delete',
- style: TextStyle(
- color: "#FC4C4F".color,
- fontWeight: FontWeight.w500,
- fontSize: 16.sp,
- ),
- ),
- ),
- ],
- cancelButton: CupertinoActionSheetAction(
- //取消按钮
- onPressed: () {
- Navigator.pop(context);
- },
- child: Text(
- 'Cancel',
- style: TextStyle(
- color: "#007AFF".color,
- fontWeight: FontWeight.w500,
- fontSize: 16.sp,
- ),
- ),
- ),
- );
- },
- );
- }
- }
|