import 'package:clean/base/base_controller.dart'; import 'package:clean/data/repositories/user_repository.dart'; import 'package:clean/dialog/photo_delete_finish_dialog.dart'; import 'package:clean/dialog/photo_deleting_dialog.dart'; import 'package:clean/module/store/store_view.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import 'package:clean/module/image_picker/image_picker_util.dart'; import 'package:clean/module/people_photo/photo_group.dart'; import 'package:clean/utils/toast_util.dart'; import 'package:clean/data/bean/photos_type.dart'; import 'package:clean/module/photo_preview/photo_preview_view.dart'; import '../data/consts/event_report_id.dart'; import '../handler/event_handler.dart'; import '../utils/file_size_calculator_util.dart'; abstract class BasePhotoController extends BaseController { final RxList photoGroups = [].obs; final RxDouble selectedFilesSize = 0.0.obs; RxInt selectedFileCount = 0.obs; final RxSet selectedPhotosIds = {}.obs; // 将selectedFilesSize转成String类型,然后单位转换,如果超过1MB,则转成MB,超过1GB,则转成GB,否则KB String get selectedFilesSizeString { debugPrint( "BasePhotoController selectedFilesSize.value ${selectedFilesSize.value}"); final double sizeInKB = selectedFilesSize.value; if (sizeInKB >= 1024 * 1024) { // 先检查最大单位(GB) return "${(sizeInKB / (1024 * 1024)).toStringAsFixed(2)}GB"; } else if (sizeInKB >= 1024) { // 然后检查MB return "${(sizeInKB / 1024).toStringAsFixed(2)}MB"; } else { // 最后是KB return "${sizeInKB.toStringAsFixed(2)}KB"; } } Future updateSelectedFilesSize() async { if (selectedPhotosIds.isEmpty) { selectedFilesSize.value = 0; return; } FileSizeCalculatorUtil.calculateTotalSize( assetIds: selectedPhotosIds, updateValue: (double totalSize) { selectedFilesSize.value = totalSize; // 监听并更新 UI }); } // 切换图片选中状态 Future toggleImageSelection( List groupTitle, int imageIndex) async { debugPrint("BasePhotoController toggleImageSelection"); final group = getGroupByImages(groupTitle); final image = group.images[imageIndex]; final selected = !group.selectedImages[imageIndex]; group.selectedImages[imageIndex] = selected; updateSelectedPhotosIds(image.id, selected); group.isSelected.value = group.selectedImages.every((selected) => selected); selectedFileCount.value = selectedPhotosIds.length; // 更新文件大小 // if (selected) { // // 如果选中,增加文件大小 // if (FileSizeCalculatorUtil.fileSizeCache.containsKey(image.id)) { // selectedFilesSize.value += // FileSizeCalculatorUtil.fileSizeCache[image.id]!; // } else { // final file = await image.file; // if (file != null) { // selectedFilesSize.value += (await file.length()) / 1024; // 转换为KB // } // } // } else { // // 如果取消选中,减少文件大小 // if (FileSizeCalculatorUtil.fileSizeCache.containsKey(image.id)) { // selectedFilesSize.value -= // FileSizeCalculatorUtil.fileSizeCache[image.id]!; // } else { // final file = await image.file; // if (file != null) { // selectedFilesSize.value -= (await file.length()) / 1024; // 转换为KB // } // } // } updateSelectedFilesSize(); PhotoManager.clearFileCache(); } void clickImage(List images, int imageIndex, PhotosType type) { debugPrint("BasePhotoController clickImage"); final group = getGroupByImages(images); final image = group.images[imageIndex]; PhotoPreviewPage.start(type, image.id); } // 切换图片组选中状态 void toggleGroupSelection(List imagesList) { final group = getGroupByImages(imagesList); final newValue = !group.isSelected.value; group.toggleSelectAll(newValue); for (var image in group.images) { updateSelectedPhotosIds(image.id, newValue); } selectedFileCount.value = selectedPhotosIds.length; updateSelectedFilesSize(); } PhotoGroup getGroupByImages(List images) { final imageIds = images.map((img) => img.id).toSet(); return photoGroups.firstWhere( (group) => group.images.every((image) => imageIds.contains(image.id))); } void updateSelectedPhotosIds(String photoId, bool isSelected) { if (isSelected) { selectedPhotosIds.add(photoId); } else { selectedPhotosIds.remove(photoId); } } // 恢复选中状态 void restoreSelections() async { final selectedIds = selectedPhotosIds.toSet(); for (var group in photoGroups) { for (int i = 0; i < group.images.length; i++) { group.selectedImages[i] = selectedIds.contains(group.images[i].id); } group.isSelected.value = group.selectedImages.every((selected) => selected); } selectedFileCount.value = selectedIds.length; if (selectedIds.isEmpty) { selectedFilesSize.value = 0; return; } updateSelectedFilesSize(); } @override void onInit() { debugPrint("BasePhotoController onInit"); super.onInit(); loadPhotos(); restoreSelections(); } void loadPhotos(); // 点击删除 void clickDelete() async { if (selectedPhotosIds.isEmpty) { ToastUtil.show('Please select the picture'); return; } EventHandler.report(EventId.event_03008, params: {EventId.type: getPhotosType().name}); print('BasePhotoController getPhotosType().toString() ${getPhotosType().toString()}'); if (userRepository.isVip()) { if (selectedPhotosIds.isNotEmpty) { photoDeletingDialog(); final assetsToDelete = photoGroups .expand((group) => group.images .where((asset) => selectedPhotosIds.contains(asset.id))) .toList(); final List result = await PhotoManager.editor.deleteWithIds( assetsToDelete.map((e) => e.id).toList(), ); if (result.length == selectedPhotosIds.length) { for (var group in photoGroups) { group.images.removeWhere( (element) => selectedPhotosIds.contains(element.id)); } ImagePickerUtil.updatePhotoGroupDate( getPhotosType(), selectedPhotosIds); selectedPhotosIds.clear(); selectedFileCount.value = selectedPhotosIds.length; debugPrint( "BasePhotoController clickDelete selectedPhotosIds $selectedPhotosIds"); updateSelectedFilesSize(); ToastUtil.show("Delete success"); Future.delayed(Duration(seconds: 2), () { SmartDialog.dismiss(tag: 'photoDeletingDialog'); photoDeleteFinishDialog(); }); } else { SmartDialog.dismiss(tag: 'photoDeletingDialog'); ToastUtil.show("Delete failed"); } } } else { StorePage.start(); } } void updateSelections(Set selectedIds) { debugPrint( "BasePhotoController updateSelections selectedIds $selectedIds, selectedPhotosIds $selectedPhotosIds getPhotosType() ${getPhotosType()}"); // selectedId如果是selectedPhotosIds对象,那么selectedPhotosIds.assignAll(selectedIds)会清空 // selectedPhotosIds.assignAll(selectedIds); selectedPhotosIds.assignAll(Set.from(selectedIds)); debugPrint( "BasePhotoController updateSelections selectedIds $selectedIds, selectedPhotosIds $selectedPhotosIds getPhotosType() ${getPhotosType()}"); switch (getPhotosType()) { case PhotosType.peoplePhotos: ImagePickerUtil.selectedPeoplePhotosIds.assignAll(selectedPhotosIds); break; case PhotosType.screenshots: ImagePickerUtil.selectedScreenshotPhotosIds .assignAll(selectedPhotosIds); break; case PhotosType.similarPhotos: ImagePickerUtil.selectedSimilarPhotosIds.assignAll(selectedPhotosIds); break; case PhotosType.locationPhotos: ImagePickerUtil.selectedLocationPhotosIds.assignAll(selectedPhotosIds); break; case PhotosType.blurryPhotos: ImagePickerUtil.selectedBlurryPhotosIds.assignAll(selectedPhotosIds); break; } } PhotosType getPhotosType(); // 将photoGroups中所有的图片返回 List getAllPhotos() { return photoGroups.expand((group) => group.images).toList(); } @override void onClose() { super.onClose(); PhotoManager.clearFileCache(); } }