privacy_controller.dart 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import 'package:clean/base/base_controller.dart';
  2. import 'package:clean/model/asset_info.dart';
  3. import 'package:clean/utils/expand.dart';
  4. import 'package:clean/utils/file_utils.dart';
  5. import 'package:clean/utils/image_util.dart';
  6. import 'package:flutter/cupertino.dart';
  7. import 'package:flutter_screenutil/flutter_screenutil.dart';
  8. import 'package:get/get.dart';
  9. import 'package:permission_handler/permission_handler.dart';
  10. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  11. import 'package:wechat_camera_picker/wechat_camera_picker.dart';
  12. import '../../utils/toast_util.dart';
  13. import '../image_picker/image_picker_assets.dart';
  14. import 'package:intl/intl.dart';
  15. import 'dart:typed_data';
  16. import 'dart:io';
  17. class PrivacyController extends BaseController {
  18. late var passwordStr = "".obs;
  19. late var isUnlock = false.obs;
  20. late List<AssetEntity>? imageList;
  21. // 存储所有图片,按月份分组
  22. final assetsByMonth = <String, List<AssetInfo>>{}.obs;
  23. // 获取月份数量
  24. int get monthCount => assetsByMonth.length;
  25. // 获取总图片数量
  26. int get totalAssetCount =>
  27. assetsByMonth.values.fold(0, (sum, list) => sum + list.length);
  28. @override
  29. void onInit() {
  30. // TODO: implement onInit
  31. super.onInit();
  32. loadAssets();
  33. }
  34. // 加载并分组图片
  35. Future<void> loadAssets() async {
  36. final imageList = await FileUtils.getAllAssets();
  37. if (imageList.isEmpty) return;
  38. // 清空现有数据
  39. assetsByMonth.clear();
  40. // 按月份分组
  41. for (var asset in imageList) {
  42. final monthKey = ImageUtil.getMonthKey(asset.createDateTime);
  43. if (!assetsByMonth.containsKey(monthKey)) {
  44. assetsByMonth[monthKey] = [];
  45. }
  46. assetsByMonth[monthKey]!.add(asset);
  47. }
  48. // 对每个月份内的图片按时间排序(新的在前)
  49. assetsByMonth.forEach((key, list) {
  50. list.sort((a, b) => b.createDateTime.compareTo(a.createDateTime));
  51. });
  52. // 打印分组结果
  53. assetsByMonth.forEach((key, assets) {
  54. print('${ImageUtil.formatMonthKey(key)}: ${assets.length} photos');
  55. });
  56. }
  57. // // 生成月份 key (用于内部存储)
  58. // String _getMonthKey(DateTime date) {
  59. // return '${date.year}-${date.month.toString().padLeft(2, '0')}';
  60. // }
  61. //
  62. // // 格式化月份显示 (例如: Jan 2025)
  63. // String _formatMonthKey(String monthKey) {
  64. // final parts = monthKey.split('-');
  65. // if (parts.length == 2) {
  66. // final date = DateTime(int.parse(parts[0]), int.parse(parts[1]));
  67. // return DateFormat('MMM yyyy').format(date);
  68. // }
  69. // return monthKey;
  70. // }
  71. //
  72. // // 获取指定索引的月份显示文本
  73. // String getMonthText(int index) {
  74. // final monthKeys = assetsByMonth.keys.toList()
  75. // ..sort((a, b) => b.compareTo(a)); // 最新的月份在前
  76. //
  77. // if (index < monthKeys.length) {
  78. // return _formatMonthKey(monthKeys[index]);
  79. // }
  80. // return '';
  81. // }
  82. //
  83. // // 获取指定月份的图片
  84. // List<AssetEntity> getMonthAssets(int index) {
  85. // final monthKeys = assetsByMonth.keys.toList()
  86. // ..sort((a, b) => b.compareTo(a)); // 最新的月份在前
  87. //
  88. // if (index < monthKeys.length) {
  89. // return assetsByMonth[monthKeys[index]] ?? [];
  90. // }
  91. // return [];
  92. // }
  93. //
  94. // // 获取缩略图数据
  95. // Future<Uint8List?> getImageThumbnail(AssetEntity asset) async {
  96. // try {
  97. // return await asset.thumbnailDataWithSize(ThumbnailSize(200, 200));
  98. // } catch (e) {
  99. // print('获取缩略图失败: $e');
  100. // return null;
  101. // }
  102. // }
  103. //
  104. // // 获取原始图片文件
  105. // Future<File?> getImageFile(AssetEntity asset) async {
  106. // try {
  107. // return await asset.file;
  108. // } catch (e) {
  109. // print('获取图片文件失败: $e');
  110. // return null;
  111. // }
  112. // }
  113. // 处理输入密码逻辑
  114. void inputPassword(String num) {
  115. passwordStr.value = passwordStr.value + num;
  116. if (passwordStr.value.length == 4) {
  117. if (passwordStr.value != "1234") {
  118. ToastUtil.show("Input Error");
  119. Future.delayed(const Duration(milliseconds: 100), () {
  120. passwordStr.value = "";
  121. });
  122. } else {
  123. isUnlock.value = true;
  124. }
  125. }
  126. }
  127. // 上传按钮点击
  128. void uploadBtnClick() {
  129. showCupertinoModalPopup(
  130. context: Get.context!,
  131. builder: (context) {
  132. return CupertinoActionSheet(
  133. actions: <Widget>[
  134. //操作按钮集合
  135. CupertinoActionSheetAction(
  136. onPressed: () {
  137. Navigator.pop(context);
  138. openGallery();
  139. },
  140. child: Text(
  141. 'Upload from Gallery',
  142. style: TextStyle(
  143. color: "#007AFF".color,
  144. fontWeight: FontWeight.w500,
  145. fontSize: 16.sp,
  146. ),
  147. ),
  148. ),
  149. CupertinoActionSheetAction(
  150. onPressed: () {
  151. Navigator.pop(context);
  152. openCamera();
  153. },
  154. child: Text(
  155. 'Take and Upload',
  156. style: TextStyle(
  157. color: "#007AFF".color,
  158. fontWeight: FontWeight.w500,
  159. fontSize: 16.sp,
  160. ),
  161. ),
  162. ),
  163. ],
  164. cancelButton: CupertinoActionSheetAction(
  165. //取消按钮
  166. onPressed: () {
  167. Navigator.pop(context);
  168. },
  169. child: Text(
  170. 'Cancel',
  171. style: TextStyle(
  172. color: "#007AFF".color,
  173. fontWeight: FontWeight.w500,
  174. fontSize: 16.sp,
  175. ),
  176. ),
  177. ),
  178. );
  179. },
  180. );
  181. }
  182. // 保存并刷新图片列表
  183. Future<void> saveAndRefreshAssets(List<AssetEntity> assets) async {
  184. for (var asset in assets) {
  185. await FileUtils.saveAsset(asset);
  186. }
  187. // 重新加载图片列表
  188. loadAssets();
  189. }
  190. // 开启图库
  191. Future<void> openGallery() async {
  192. var status = await Permission.photos.status;
  193. if (status == PermissionStatus.granted) {
  194. List<AssetEntity>? pickList = await ImagePickAssets.pick();
  195. if (pickList != null && pickList.isNotEmpty) {
  196. await saveAndRefreshAssets(pickList);
  197. }
  198. } else {
  199. ToastUtil.show("请先开启权限");
  200. }
  201. }
  202. // 开启相机
  203. Future<void> openCamera() async {
  204. final entity = await CameraPicker.pickFromCamera(
  205. Get.context!,
  206. pickerConfig: const CameraPickerConfig(),
  207. );
  208. if (entity != null) {
  209. await saveAndRefreshAssets([entity]);
  210. }
  211. }
  212. }