| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- import 'dart:io';
- import 'dart:math';
- import 'package:classify_photo/classify_photo.dart';
- import 'package:clean/base/base_controller.dart';
- import 'package:clean/data/repositories/user_repository.dart';
- import 'package:clean/dialog/photo_uploading_dialog.dart';
- import 'package:clean/handler/event_handler.dart';
- import 'package:clean/module/analysis/analysis_state.dart';
- import 'package:clean/module/store/store_view.dart';
- import 'package:clean/router/app_pages.dart';
- import 'package:clean/utils/expand.dart';
- import 'package:flutter/Material.dart';
- import 'package:flutter/cupertino.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:permission_handler/permission_handler.dart';
- import 'package:wechat_camera_picker/wechat_camera_picker.dart';
- import '../../data/consts/event_report_id.dart';
- import '../../model/asset_info.dart';
- import '../../utils/file_utils.dart';
- import '../../utils/image_util.dart';
- import '../../utils/toast_util.dart';
- import '../image_picker/image_picker_assets.dart';
- class AnalysisController extends BaseController {
- // 是否为编辑状态
- RxBool isEdit = false.obs;
- // 使用共享状态
- RxList<AssetInfo> imageList = AnalysisState.imageList;
- RxMap<String, List<AssetInfo>> assetsByMonth = AnalysisState.assetsByMonth;
- // 获取月份数量
- int get monthCount => assetsByMonth.length;
- // 获取总图片数量
- int get totalAssetCount =>
- assetsByMonth.values.fold(0, (sum, list) => sum + list.length);
- // 存储选中的图片ID
- final RxSet<String> selectedAssets = <String>{}.obs;
- // 是否全选
- RxBool isAllSelected = false.obs;
- // 选中图片的总容量(字节)
- final RxInt selectedTotalSize = 0.obs;
- @override
- void onInit() {
- // TODO: implement onInit
- super.onInit();
- loadAssets();
- }
- // 加载并分组图片
- Future<void> loadAssets() async {
- var newImageList = <AssetInfo>[];
- newImageList = await FileUtils.getAllAssets(FileType.analysis);
- AnalysisState.imageList.value = newImageList;
- AnalysisState.updateMonthlyAssets();
- if (newImageList.isEmpty) {
- isEdit.value = false;
- return;
- }
- // 清空现有数据
- assetsByMonth.clear();
- // 按月份分组
- for (var asset in newImageList) {
- final monthKey = ImageUtil.getMonthKey(asset.createDateTime);
- if (!assetsByMonth.containsKey(monthKey)) {
- assetsByMonth[monthKey] = [];
- }
- assetsByMonth[monthKey]!.add(asset);
- asset.dateTitle = ImageUtil.formatMonthKey(monthKey);
- }
- newImageList.sort((a, b) => b.createDateTime.compareTo(a.createDateTime));
- AnalysisState.imageList.value = newImageList;
- AnalysisState.updateMonthlyAssets();
- // 对每个月份内的图片按时间排序(新的在前)
- assetsByMonth.forEach((key, list) {
- list.sort((a, b) => b.createDateTime.compareTo(a.createDateTime));
- });
- // 打印分组结果
- assetsByMonth.forEach((key, assets) {
- print('${ImageUtil.formatMonthKey(key)}: ${assets.length} photos');
- });
- }
- // 上传按钮点击
- void uploadBtnClick() {
- EventHandler.report(EventId.event_09001);
- if (userRepository.isVip()) {
- openGallery();
- } else {
- StorePage.start();
- }
- // showCupertinoModalPopup(
- // context: Get.context!,
- // builder: (context) {
- // return CupertinoActionSheet(
- // actions: <Widget>[
- // //操作按钮集合
- // CupertinoActionSheetAction(
- // onPressed: () {
- // Navigator.pop(context);
- // openGallery();
- // },
- // child: Text(
- // 'Upload from Gallery',
- // style: TextStyle(
- // color: "#007AFF".color,
- // fontWeight: FontWeight.w500,
- // fontSize: 16.sp,
- // ),
- // ),
- // ),
- // CupertinoActionSheetAction(
- // onPressed: () {
- // Navigator.pop(context);
- // openCamera();
- // },
- // child: Text(
- // 'Take and Upload',
- // 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,
- // ),
- // ),
- // ),
- // );
- // },
- // );
- }
- // 保存并刷新图片列表
- Future<void> saveAndRefreshAssets(List<AssetEntity> assets) async {
- for (var asset in assets) {
- await FileUtils.saveAsset(FileType.analysis, asset);
- }
- showDialog(
- context: Get.context!,
- barrierDismissible: false, // 防止点击外部关闭
- builder: (context) => UploadingDialog(
- duration: const Duration(seconds: 3),
- onComplete: () {
- loadAssets();
- ToastUtil.show("Successful");
- // 这里可以添加完成后的操作
- },
- ),
- );
- // 重新加载图片列表
- }
- // 选择/取消选择图片
- void toggleSelectAsset(String assetId) {
- final asset = imageList.firstWhere((asset) => asset.id == assetId);
- if (selectedAssets.contains(assetId)) {
- selectedAssets.remove(assetId);
- if (asset.size != null) {
- selectedTotalSize.value -= asset.size!;
- }
- } else {
- selectedAssets.add(assetId);
- if (asset.size != null) {
- selectedTotalSize.value += asset.size!;
- }
- }
- // 更新全选状态
- isAllSelected.value = selectedAssets.length == imageList.length;
- }
- // 全选/取消全选
- void toggleSelectAll() {
- if (isAllSelected.value) {
- selectedAssets.clear();
- selectedTotalSize.value = 0;
- } else {
- selectedAssets.addAll(imageList.map((asset) => asset.id));
- selectedTotalSize.value = imageList.fold(
- 0, (sum, asset) => sum + (asset.size != null ? asset.size! : 0));
- }
- isAllSelected.value = !isAllSelected.value;
- }
- // 退出编辑模式时清空选择
- void exitEditMode() {
- isEdit.value = false;
- selectedAssets.clear();
- isAllSelected.value = false;
- selectedTotalSize.value = 0;
- }
- // 删除文件
- void deleteBtnClick() {
- // 获取要删除的资产
- final assetsToDelete =
- imageList.where((asset) => selectedAssets.contains(asset.id)).toList();
- for (var asset in assetsToDelete) {
- FileUtils.deleteAsset(FileType.analysis, Platform.isIOS ? asset.id.substring(0, 36) : asset.id);
- }
- selectedTotalSize.value = 0;
- loadAssets();
- }
- // 格式化文件大小显示
- String formatFileSize(int bytes) {
- if (bytes <= 0) return "Delete";
- final units = ['B', 'KB', 'MB', 'GB'];
- int digitGroups = (log(bytes) / log(1024)).floor();
- if (bytes == 0) {
- return "Delete";
- } else {
- return "Delete(${(bytes / pow(1024, digitGroups)).toStringAsFixed(1)} ${units[digitGroups]})";
- }
- }
- // 开启图库
- Future<void> openGallery() async {
- var status = await Permission.photos.status;
- if(Platform.isAndroid){
- status = await Permission.storage.request();
- }
- if (status == PermissionStatus.granted) {
- List<AssetEntity> assets = <AssetEntity>[];
- for (var asset in imageList) {
- var newAsset = await asset.toAssetEntity();
- if (newAsset != null) {
- assets.add(newAsset);
- }
- }
- List<AssetEntity>? pickList = await ImagePickAssets.pick();
- if (pickList != null && pickList.isNotEmpty) {
- await saveAndRefreshAssets(pickList);
- final asset = pickList.first;
- final file = await asset.originFile;
- // final exifInfo = await ClassifyPhoto().getPhotoExif(file!.path);
- // print(exifInfo);
- }
- } else if (status == PermissionStatus.denied) {
- var result = await Permission.photos.request();
- if (result.isGranted) {
- openGallery();
- } else if (result.isPermanentlyDenied) {
- ToastUtil.show("Please enable the photo permission first.");
- openAppSettings();
- } else {
- ToastUtil.show("Please enable the photo permission first.");
- }
- } else {
- openAppSettings();
- }
- }
- // 开启相机
- Future<void> openCamera() async {
- var status = await Permission.camera.status;
- if (status == PermissionStatus.granted) {
- final entity = await CameraPicker.pickFromCamera(
- Get.context!,
- pickerConfig: const CameraPickerConfig(),
- );
- if (entity != null) {
- await saveAndRefreshAssets([entity]);
- }
- } else {
- var result = await Permission.camera.request();
- if (result.isGranted) {
- openCamera();
- } else if (result.isPermanentlyDenied) {
- ToastUtil.show("Please enable the camera permission first.");
- openAppSettings();
- } else{
- ToastUtil.show("Please enable the camera permission first.");
- }
- }
- }
- }
|