Browse Source

feat : 删除问题

dev
徐振升 2 months ago
parent
commit
da29a0d2c0
  1. 10
      lib/app/features/problem/domain/usecases/delete_problem.dart
  2. 29
      lib/app/features/problem/domain/usecases/delete_problem_usecase.dart
  3. 8
      lib/app/features/problem/presentation/bindings/problem_list_binding.dart
  4. 66
      lib/app/features/problem/presentation/controllers/problem_list_controller.dart
  5. 191
      lib/app/features/problem/presentation/pages/problem_list_page.dart

10
lib/app/features/problem/domain/usecases/delete_problem.dart

@ -1,10 +0,0 @@
import 'package:problem_check_system/app/features/problem/domain/repositories/problem_repository.dart';
class DeleteProblem {
final ProblemRepository problemRepository;
DeleteProblem({required this.problemRepository});
Future<void> call(String id) async {
await problemRepository.deleteProblem(id);
}
}

29
lib/app/features/problem/domain/usecases/delete_problem_usecase.dart

@ -0,0 +1,29 @@
import 'package:problem_check_system/app/core/domain/entities/sync_status.dart';
import 'package:problem_check_system/app/core/repositories/auth_repository.dart';
import 'package:problem_check_system/app/features/problem/domain/entities/problem_entity.dart';
import 'package:problem_check_system/app/features/problem/domain/repositories/problem_repository.dart';
class DeleteProblemUsecase {
final ProblemRepository problemRepository;
final AuthRepository authRepository;
DeleteProblemUsecase({
required this.problemRepository,
required this.authRepository,
});
Future<void> call(ProblemEntity problemEntity) async {
final nowUtc = DateTime.now().toUtc();
final userId = authRepository.getUserId();
if (problemEntity.syncStatus == SyncStatus.pendingCreate) {
await problemRepository.deleteProblem(problemEntity.id);
} else {
final newProblem = problemEntity.copyWith(
lastModifiedTime: nowUtc,
lastModifierId: userId,
syncStatus: SyncStatus.pendingDelete,
);
await problemRepository.updateProblem(newProblem);
}
}
}

8
lib/app/features/problem/presentation/bindings/problem_list_binding.dart

@ -8,6 +8,7 @@ import 'package:problem_check_system/app/features/problem/data/datasources/probl
import 'package:problem_check_system/app/features/problem/data/datasources/problem_remote_data_source.dart';
import 'package:problem_check_system/app/features/problem/data/repositories/problem_repository_impl.dart';
import 'package:problem_check_system/app/features/problem/domain/repositories/problem_repository.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/delete_problem_usecase.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/get_all_problems_usecase.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/resolve_conflict_usecase.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/sync_problems_usecase.dart';
@ -58,6 +59,12 @@ class ProblemListBinding extends BaseBindings {
Get.lazyPut<ProblemResolveConflictUsecase>(
() => ProblemResolveConflictUsecase(repository: Get.find()),
);
Get.lazyPut<DeleteProblemUsecase>(
() => DeleteProblemUsecase(
problemRepository: Get.find(),
authRepository: Get.find(),
),
);
}
@override
@ -68,6 +75,7 @@ class ProblemListBinding extends BaseBindings {
syncProblemsUsecase: Get.find(),
problemResolveConflictUsecase: Get.find(),
getEnterprisesUsecase: Get.find(),
deleteProblemUsecase: Get.find(),
),
);
}

66
lib/app/features/problem/presentation/controllers/problem_list_controller.dart

@ -11,6 +11,7 @@ import 'package:problem_check_system/app/features/problem/domain/entities/proble
import 'package:problem_check_system/app/features/problem/domain/entities/problem_list_item_entity.dart';
import 'package:problem_check_system/app/features/problem/domain/entities/problem_upload_status.dart';
import 'package:problem_check_system/app/features/problem/domain/repositories/problem_repository.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/delete_problem_usecase.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/get_all_problems_usecase.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/resolve_conflict_usecase.dart';
import 'package:problem_check_system/app/features/problem/domain/usecases/sync_problems_usecase.dart';
@ -20,12 +21,14 @@ class ProblemListController extends GetxController {
final GetEnterprisesUsecase getEnterprisesUsecase;
final SyncProblemsUsecase syncProblemsUsecase;
final ProblemResolveConflictUsecase problemResolveConflictUsecase;
final DeleteProblemUsecase deleteProblemUsecase;
ProblemListController({
required this.getAllProblemsUsecase,
required this.syncProblemsUsecase,
required this.problemResolveConflictUsecase,
required this.getEnterprisesUsecase,
required this.deleteProblemUsecase,
});
final problemList = <ProblemListItemEntity>[].obs;
@ -218,6 +221,69 @@ class ProblemListController extends GetxController {
}
}
///
Future<bool?> confirmDeleteProblem(ProblemEntity problem) async {
// 使 Get.dialog
return await Get.dialog<bool>(
AlertDialog(
title: const Text('确认删除'),
content: Text('您确定要删除问题 "${problem.description}" 吗?此操作不可恢复。'),
actions: <Widget>[
TextButton(
child: const Text('取消'),
onPressed: () {
// false
Get.back(result: false);
},
),
TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.red, //
),
child: const Text('删除'),
onPressed: () {
// true
Get.back(result: true);
},
),
],
),
);
}
///
Future<void> deleteProblem(ProblemEntity problem) async {
// 使 try-catch
try {
// deleteProblemUsecase
await deleteProblemUsecase(problem);
// [!!!] UI列表中移除该项
// problemList .obsUI会自动更新
problemList.removeWhere((item) => item.problemEntity.id == problem.id);
//
Get.snackbar(
'删除成功',
'"${problem.description}" 已被删除。',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.green,
colorText: Colors.white,
);
} catch (e) {
//
Get.snackbar(
'删除失败',
'无法删除该问题: $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white,
);
// UI状态
// loadAndSyncProblems();
}
}
//
void setFilters(Enterprise enterprise) {
showAppBar.value = false;

191
lib/app/features/problem/presentation/pages/problem_list_page.dart

@ -2,6 +2,7 @@ import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:problem_check_system/app/core/domain/entities/sync_status.dart';
import 'package:problem_check_system/app/core/extensions/datetime_extension.dart';
import 'package:problem_check_system/app/core/pages/widgets/custom_app_bar.dart';
import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise.dart';
@ -339,82 +340,142 @@ class ProblemListPage extends GetView<ProblemListController> {
itemCount: controller.problemList.length,
itemBuilder: (context, index) {
final item = controller.problemList[index];
final enterprise = item.problemEntity;
final problemEntity = item.problemEntity;
// : base controller
final isSelected = controller.selectedProblems.contains(enterprise);
final isSelected = controller.selectedProblems.contains(
problemEntity,
);
//
final bool isPendingDelete =
problemEntity.syncStatus == SyncStatus.pendingDelete;
// 1.使 Dismissible
return Dismissible(
// 2. Dismissible Key
// Flutter
// 使ID
key: Key(problemEntity.id),
// 3.
// isPendingDelete true none
// endToStart
direction: isPendingDelete
? DismissDirection.none
: DismissDirection.endToStart,
return Padding(
padding: EdgeInsets.only(bottom: 12.h),
child: ProblemCard(
problemListItem: item,
isSelected: isSelected,
onTap: () =>
controller.navigateToDetailsView(item.problemEntity),
actions: Row(
crossAxisAlignment: CrossAxisAlignment.end,
// 4.
//
background: Container(
color: Colors.red, //
padding: EdgeInsets.symmetric(horizontal: 20.w),
alignment: Alignment.centerRight, //
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
//
ElevatedButton(
onPressed: () =>
controller.navigateToEditForm(item.problemEntity),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF42A5F5),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 20.w,
vertical: 8.h,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// [!!!]
elevation: 0,
// [!!!]
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
bottomRight: Radius.circular(12.r),
),
),
),
child: Text(
"修改",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.bold,
),
Text(
'删除',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.sp,
),
),
SizedBox(width: 8.w),
// ()
ElevatedButton(
onPressed: () =>
controller.navigateToDetailsView(item.problemEntity),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF42A5F5),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 20.w,
vertical: 8.h,
const Icon(Icons.delete, color: Colors.white),
],
),
),
// 5.
//
confirmDismiss: (direction) async {
//
return await controller.confirmDeleteProblem(problemEntity);
},
// 6. true
//
// confirmDismiss true onDismissed
onDismissed: (direction) {
//
controller.deleteProblem(problemEntity);
},
// 7. child Dismissible
child: Padding(
padding: EdgeInsets.only(bottom: 12.h),
child: ProblemCard(
problemListItem: item,
isSelected: isSelected,
onTap: () =>
controller.navigateToDetailsView(item.problemEntity),
actions: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
//
if (isPendingDelete == false)
ElevatedButton(
onPressed: () =>
controller.navigateToEditForm(item.problemEntity),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF42A5F5),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 20.w,
vertical: 8.h,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// [!!!]
elevation: 0,
// [!!!]
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
bottomRight: Radius.circular(12.r),
),
),
),
child: Text(
"修改",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.bold,
),
),
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// [!!!]
elevation: 0,
// [!!!]
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
bottomRight: Radius.circular(12.r),
SizedBox(width: 8.w),
// ()
ElevatedButton(
onPressed: () => controller.navigateToDetailsView(
item.problemEntity,
),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF42A5F5),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 20.w,
vertical: 8.h,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// [!!!]
elevation: 0,
// [!!!]
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
bottomRight: Radius.circular(12.r),
),
),
),
),
child: Text(
"查看",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.bold,
child: Text(
"查看",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.bold,
),
),
),
),
],
],
),
),
),
);

Loading…
Cancel
Save