Browse Source

feat : 删除企业

dev
徐振升 2 months ago
parent
commit
3879d0f9f6
  1. 6
      lib/app/features/enterprise/data/repositories_impl/enterprise_repository_impl.dart
  2. 2
      lib/app/features/enterprise/domain/repositories/enterprise_repository.dart
  3. 31
      lib/app/features/enterprise/domain/usecases/delete_enterprise_usecase.dart
  4. 8
      lib/app/features/enterprise/presentation/bindings/enterprise_list_binding.dart
  5. 50
      lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart
  6. 167
      lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart
  7. 44
      lib/app/features/enterprise/presentation/pages/widgets/unified_enterprise_card.dart

6
lib/app/features/enterprise/data/repositories_impl/enterprise_repository_impl.dart

@ -213,4 +213,10 @@ class EnterpriseRepositoryImpl implements EnterpriseRepository {
// 3. DTO
return EnterpriseModel.fromMap(problemMap).toEntity();
}
@override
Future<void> deleteEnterprise(String id) async {
// ID
await localDataSource.deleteEnterprise(id);
}
}

2
lib/app/features/enterprise/domain/repositories/enterprise_repository.dart

@ -36,4 +36,6 @@ abstract class EnterpriseRepository implements SyncableRepository<Enterprise> {
Future<List<Enterprise>> getAllEnterprises();
// ID获取企业信息
Future<Enterprise?> getEnterpriseById(String enterpriseId);
//
Future<void> deleteEnterprise(String id);
}

31
lib/app/features/enterprise/domain/usecases/delete_enterprise_usecase.dart

@ -0,0 +1,31 @@
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/enterprise/domain/entities/enterprise.dart';
import 'package:problem_check_system/app/features/enterprise/domain/repositories/enterprise_repository.dart';
class DeleteEnterpriseUsecase {
final EnterpriseRepository repository;
final AuthRepository authRepository;
DeleteEnterpriseUsecase({
required this.repository,
required this.authRepository,
});
Future<void> call(Enterprise enterprise) async {
final nowUtc = DateTime.now().toUtc();
final userId = authRepository.getUserId();
//
if (enterprise.syncStatus == SyncStatus.pendingCreate) {
await repository.deleteEnterprise(enterprise.id);
} else {
//
final enterpriseToDelete = enterprise.copyWith(
lastModifiedTime: nowUtc,
lastModifierId: userId,
syncStatus: SyncStatus.pendingDelete,
);
await repository.updateEnterprise(enterpriseToDelete);
}
}
}

8
lib/app/features/enterprise/presentation/bindings/enterprise_list_binding.dart

@ -5,6 +5,7 @@ import 'package:problem_check_system/app/features/enterprise/data/datasources/en
import 'package:problem_check_system/app/features/enterprise/data/datasources/enterprise_remote_data_source.dart';
import 'package:problem_check_system/app/features/enterprise/data/repositories_impl/enterprise_repository_impl.dart';
import 'package:problem_check_system/app/features/enterprise/domain/repositories/enterprise_repository.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/delete_enterprise_usecase.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/get_enterprise_list_usecase.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/resolve_conflict_usecase.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/sync_enterprises_usecase.dart';
@ -38,12 +39,19 @@ class EnterpriseListBinding extends Bindings {
Get.put<GetEnterpriseListUsecase>(
GetEnterpriseListUsecase(repository: Get.find<EnterpriseRepository>()),
);
Get.put<DeleteEnterpriseUsecase>(
DeleteEnterpriseUsecase(
repository: Get.find<EnterpriseRepository>(),
authRepository: Get.find(),
),
);
Get.lazyPut<EnterpriseListController>(
() => EnterpriseListController(
getEnterpriseListUsecase: Get.find<GetEnterpriseListUsecase>(),
syncEnterprisesUsecase: Get.find<SyncEnterprisesUsecase>(),
resolveConflictUsecase: Get.find<ResolveConflictUsecase>(),
deleteEnterpriseUsecase: Get.find<DeleteEnterpriseUsecase>(),
),
);
}

50
lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart

@ -9,6 +9,7 @@ import 'package:problem_check_system/app/core/routes/app_routes.dart';
import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise.dart';
import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise_list_item.dart';
import 'package:problem_check_system/app/features/enterprise/domain/repositories/enterprise_repository.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/delete_enterprise_usecase.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/get_enterprise_list_usecase.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/resolve_conflict_usecase.dart';
import 'package:problem_check_system/app/features/enterprise/domain/usecases/sync_enterprises_usecase.dart';
@ -29,11 +30,14 @@ class EnterpriseListController extends GetxController {
final GetEnterpriseListUsecase getEnterpriseListUsecase;
final SyncEnterprisesUsecase syncEnterprisesUsecase; //
final ResolveConflictUsecase resolveConflictUsecase; //
final DeleteEnterpriseUsecase
deleteEnterpriseUsecase; // 1. UseCase
EnterpriseListController({
required this.getEnterpriseListUsecase,
required this.syncEnterprisesUsecase,
required this.resolveConflictUsecase,
required this.deleteEnterpriseUsecase, // 2. UseCase
});
// --- ---
@ -215,6 +219,52 @@ class EnterpriseListController extends GetxController {
loadEnterprises();
}
// 3.
Future<bool?> confirmDeleteEnterprise(Enterprise enterprise) async {
return await Get.dialog<bool>(
AlertDialog(
title: const Text('确认删除'),
content: Text('您确定要删除企业 "${enterprise.name}" 吗?该企业下的所有问题也将无法查看。'),
actions: <Widget>[
TextButton(
child: const Text('取消'),
onPressed: () => Get.back(result: false),
),
TextButton(
style: TextButton.styleFrom(foregroundColor: Colors.red),
child: const Text('删除'),
onPressed: () => Get.back(result: true),
),
],
),
);
}
// 4.
void deleteEnterprise(Enterprise enterprise) async {
try {
// UseCase
await deleteEnterpriseUsecase(enterprise);
// UI列表中移除该项
enterpriseList.removeWhere((item) => item.enterprise.id == enterprise.id);
Get.snackbar(
'删除成功',
'"${enterprise.name}" 已被标记为删除。',
snackPosition: SnackPosition.BOTTOM,
);
} catch (e) {
Get.snackbar(
'删除失败',
'无法删除该企业: $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white,
);
}
}
Future<void> loadEnterprises() async {
expansibleController.collapse();
isLoading.value = true;

167
lib/app/features/enterprise/presentation/pages/enterprise_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/models/company_enum.dart';
import 'package:problem_check_system/app/core/pages/widgets/custom_app_bar.dart';
@ -251,77 +252,121 @@ class EnterpriseListPage extends GetView<EnterpriseListController> {
enterprise,
);
return Padding(
padding: EdgeInsets.only(bottom: 12.h),
child: UnifiedEnterpriseCard(
enterpriseListItem: item,
isSelected: isSelected,
// itemMode mode
// --- [] controller ---
onTap: () =>
controller.navigateToEnterpriseInfoPage(item.enterprise),
// [] actions
actions: Row(
// 1.
final bool isPendingDelete =
enterprise.syncStatus == SyncStatus.pendingDelete;
// 2. 使 Dismissible
return Dismissible(
key: Key(enterprise.id), // 使ID作为唯一Key
// 3.
direction: isPendingDelete
? DismissDirection.none
: DismissDirection.endToStart,
// 4.
background: Container(
color: Colors.red,
padding: EdgeInsets.symmetric(horizontal: 20.w),
alignment: Alignment.centerRight,
child: Row(
mainAxisSize: MainAxisSize.min,
//
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//
TextButton.icon(
onPressed: () =>
controller.navigateToEditForm(item.enterprise),
icon: Icon(
Icons.edit_outlined,
size: 16.sp,
color: Colors.grey.shade700,
),
label: Text(
'修改信息',
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey.shade700,
),
),
style: TextButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 12.w,
vertical: 12.h,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
Text(
'删除',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.sp,
),
),
SizedBox(width: 8.w),
const Icon(Icons.delete, color: Colors.white),
],
),
),
// ()
ElevatedButton(
onPressed: () => controller.navigateToEnterpriseInfoPage(
item.enterprise,
),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF42A5F5),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 20.w,
vertical: 12.h,
// 5.
confirmDismiss: (direction) async {
return await controller.confirmDeleteEnterprise(enterprise);
},
// 6.
onDismissed: (direction) {
controller.deleteEnterprise(enterprise);
},
child: Padding(
padding: EdgeInsets.only(bottom: 12.h),
child: UnifiedEnterpriseCard(
enterpriseListItem: item,
isSelected: isSelected,
// itemMode mode
// --- [] controller ---
onTap: () =>
controller.navigateToEnterpriseInfoPage(item.enterprise),
// [] actions
actions: Row(
mainAxisSize: MainAxisSize.min,
//
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//
if (!isPendingDelete)
TextButton.icon(
onPressed: () =>
controller.navigateToEditForm(item.enterprise),
icon: Icon(
Icons.edit_outlined,
size: 16.sp,
color: Colors.grey.shade700,
),
label: Text(
'修改信息',
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey.shade700,
),
),
style: TextButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 12.w,
vertical: 12.h,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// [!!!]
elevation: 0,
// [!!!]
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
// ()
ElevatedButton(
onPressed: () => controller
.navigateToEnterpriseInfoPage(item.enterprise),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF42A5F5),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 20.w,
vertical: 12.h,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// [!!!]
elevation: 0,
// [!!!]
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
),
),
),
),
child: Text(
"查看问题",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.bold,
child: Text(
"查看问题",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.bold,
),
),
),
),
],
],
),
),
),
);

44
lib/app/features/enterprise/presentation/pages/widgets/unified_enterprise_card.dart

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.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/features/enterprise/domain/entities/enterprise_list_item.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
@ -22,6 +23,8 @@ class UnifiedEnterpriseCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final bool isDeleted =
enterpriseListItem.enterprise.syncStatus == SyncStatus.pendingDelete;
return Card(
elevation: isSelected ? 4.0 : .2,
shape: RoundedRectangleBorder(
@ -33,6 +36,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
// [ 1]
clipBehavior: Clip.antiAlias,
margin: EdgeInsets.zero,
color: isDeleted ? Colors.grey[200] : Theme.of(context).cardColor,
child: InkWell(
onTap: onTap,
// [ 2] 使 Column
@ -48,9 +52,9 @@ class UnifiedEnterpriseCard extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildTopSection(),
_buildTopSection(isDeleted),
SizedBox(height: 12.h),
_buildMiddleSection(),
_buildMiddleSection(isDeleted),
],
),
),
@ -60,7 +64,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
// --- 2: ---
// [ 3]
if (actions != null) _buildBottomActionRow(),
if (actions != null) _buildBottomActionRow(isDeleted),
],
),
),
@ -68,7 +72,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
}
///
Widget _buildTopSection() {
Widget _buildTopSection(bool isDeleted) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -90,7 +94,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
style: TextStyle(
fontSize: 12.5.sp,
fontWeight: FontWeight.w500,
color: Colors.black87,
color: isDeleted ? Colors.grey : Colors.black87,
),
overflow: TextOverflow.ellipsis,
),
@ -113,7 +117,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
style: TextStyle(
fontSize: 12.5.sp,
fontWeight: FontWeight.w500,
color: Colors.black87,
color: isDeleted ? Colors.grey : Colors.black87,
),
overflow: TextOverflow.ellipsis,
),
@ -145,7 +149,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
}
///
Widget _buildMiddleSection() {
Widget _buildMiddleSection(bool isDeleted) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -162,8 +166,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
enterpriseListItem.totalProblems.toString(),
style: TextStyle(
fontSize: 12.5.sp,
color: Colors.black87,
fontWeight: FontWeight.w500,
color: isDeleted ? Colors.grey : Colors.black87,
),
),
],
@ -173,9 +176,16 @@ class UnifiedEnterpriseCard extends StatelessWidget {
children: [
Icon(Icons.access_time, color: Colors.grey, size: 16.sp),
Text(
'创建时间: ${enterpriseListItem.enterprise.creationTime.toDateTimeString()}',
'创建时间:',
style: TextStyle(fontSize: 12.sp, color: Colors.grey),
),
Text(
enterpriseListItem.enterprise.creationTime.toDateTimeString(),
style: TextStyle(
fontSize: 12.sp,
color: isDeleted ? Colors.grey : Colors.black87,
),
),
],
),
],
@ -183,7 +193,7 @@ class UnifiedEnterpriseCard extends StatelessWidget {
}
/// +
Widget _buildBottomActionRow() {
Widget _buildBottomActionRow(bool isDeleted) {
return Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
@ -194,14 +204,18 @@ class UnifiedEnterpriseCard extends StatelessWidget {
children: [
TDTag(
'已上传 ${enterpriseListItem.uploadedProblems}',
textColor: Colors.blue,
backgroundColor: Colors.blue.withAlpha(20),
textColor: isDeleted ? Colors.grey : Colors.blue,
backgroundColor: isDeleted
? Colors.grey.withAlpha(20)
: Colors.blue.withAlpha(20),
),
SizedBox(width: 8.w),
TDTag(
'未上传 ${enterpriseListItem.pendingProblems}',
textColor: Colors.red,
backgroundColor: Colors.red.withAlpha(20),
textColor: isDeleted ? Colors.grey : Colors.red,
backgroundColor: isDeleted
? Colors.grey.withAlpha(20)
: Colors.red.withAlpha(20),
),
],
),

Loading…
Cancel
Save