From d459d905fffda858fec6e572441882997bfe91f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=8C=AF=E5=8D=87?= <359059686@qq.com> Date: Wed, 29 Oct 2025 08:46:24 +0800 Subject: [PATCH] =?UTF-8?q?fix=20:=20=E5=90=8C=E6=AD=A5=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=BF=AE=E6=94=B9=E6=97=B6=E9=97=B4=E5=88=B0?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enterprise_remote_data_source.dart | 19 ++- .../enterprise_repository_impl.dart | 15 +- .../repositories/enterprise_repository.dart | 2 +- .../usecases/upload_enterprises_usecase.dart | 11 +- .../enterprise_list_controller.dart | 140 ++++++++++++++---- .../pages/enterprise_form_page.dart | 2 +- 6 files changed, 138 insertions(+), 51 deletions(-) diff --git a/lib/app/features/enterprise/data/datasources/enterprise_remote_data_source.dart b/lib/app/features/enterprise/data/datasources/enterprise_remote_data_source.dart index a6025ea..67a3396 100644 --- a/lib/app/features/enterprise/data/datasources/enterprise_remote_data_source.dart +++ b/lib/app/features/enterprise/data/datasources/enterprise_remote_data_source.dart @@ -7,10 +7,10 @@ import 'package:problem_check_system/app/features/enterprise/data/model/enterpri /// 定义了所有与企业相关的网络 API 调用 abstract class EnterpriseRemoteDataSource { /// 创建企业 - Future createEnterprise(EnterpriseModel enterprise); + Future createEnterprise(EnterpriseModel enterprise); /// 更新企业 - Future updateEnterprise(EnterpriseModel enterprise); + Future updateEnterprise(EnterpriseModel enterprise); /// 删除企业 Future deleteEnterprise(String enterpriseId); @@ -25,14 +25,15 @@ class EnterpriseRemoteDataSourceImpl implements EnterpriseRemoteDataSource { static const String enterprisesEndpoint = '/api/Companies'; @override - Future createEnterprise(EnterpriseModel enterprise) async { + Future createEnterprise(EnterpriseModel enterprise) async { try { final enterpriseDto = EnterpriseDto.fromModel(enterprise); final data = enterpriseDto.toJson(); - await http.post( + final response = await http.post( '$enterprisesEndpoint/CreateWithId?Id=${enterprise.id}', data: data, ); + return EnterpriseDto.fromJson(response.data); } catch (e) { rethrow; } @@ -48,12 +49,16 @@ class EnterpriseRemoteDataSourceImpl implements EnterpriseRemoteDataSource { } @override - Future updateEnterprise(EnterpriseModel enterprise) async { + Future updateEnterprise(EnterpriseModel enterprise) async { try { final enterpriseDto = EnterpriseDto.fromModel(enterprise); final data = enterpriseDto.toJson(); // 通常更新操作需要一个 ID - await http.patch('$enterprisesEndpoint/${enterprise.id}', data: data); + final response = await http.patch( + '$enterprisesEndpoint/${enterprise.id}', + data: data, + ); + return EnterpriseDto.fromJson(response.data); } catch (e) { rethrow; } @@ -62,7 +67,7 @@ class EnterpriseRemoteDataSourceImpl implements EnterpriseRemoteDataSource { @override Future> getEnterprises() async { try { - final response = await http.get(enterprisesEndpoint); + final response = await http.get("$enterprisesEndpoint?PageSize=999"); final Map data = response.data; final List enterprises = data['items']; return enterprises.map((json) => EnterpriseDto.fromJson(json)).toList(); diff --git a/lib/app/features/enterprise/data/repositories_impl/enterprise_repository_impl.dart b/lib/app/features/enterprise/data/repositories_impl/enterprise_repository_impl.dart index 54eb2a5..cd04aa9 100644 --- a/lib/app/features/enterprise/data/repositories_impl/enterprise_repository_impl.dart +++ b/lib/app/features/enterprise/data/repositories_impl/enterprise_repository_impl.dart @@ -2,6 +2,7 @@ import 'package:problem_check_system/app/core/models/sync_status.dart'; import 'package:problem_check_system/app/core/services/network_status_service.dart'; import 'package:problem_check_system/app/features/enterprise/data/datasources/enterprise_local_data_source.dart'; import 'package:problem_check_system/app/features/enterprise/data/datasources/enterprise_remote_data_source.dart'; +import 'package:problem_check_system/app/features/enterprise/data/model/enterprise_dto.dart'; import 'package:problem_check_system/app/features/enterprise/data/model/enterprise_model.dart'; import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise.dart'; import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise_conflict.dart'; @@ -83,29 +84,31 @@ class EnterpriseRepositoryImpl implements EnterpriseRepository { } @override - Future syncEnterpriseToServer(Enterprise enterprise) async { + Future syncEnterpriseToServer(Enterprise enterprise) async { // 将 Domain 层的纯净实体转换为 Data 层的 Model final enterpriseModel = EnterpriseModel.fromEntity(enterprise); - + EnterpriseDto syncedDto; // **核心调度逻辑** // Repository 像一个指挥官,根据情况向不同的士兵(DataSource)下达命令 switch (enterprise.syncStatus) { case SyncStatus.pendingCreate: - await remoteDataSource.createEnterprise(enterpriseModel); + syncedDto = await remoteDataSource.createEnterprise(enterpriseModel); break; case SyncStatus.pendingUpdate: - await remoteDataSource.updateEnterprise(enterpriseModel); + syncedDto = await remoteDataSource.updateEnterprise(enterpriseModel); break; case SyncStatus.pendingDelete: await remoteDataSource.deleteEnterprise(enterprise.id); - break; + return enterprise; // 对于其他状态,此方法不执行任何网络操作 case SyncStatus.synced: case SyncStatus.untracked: - break; + return enterprise; } + return syncedDto.toModel().toEntity(); } + // todo ********************************应该修改这个地方了****************************************** @override Future updateEnterpriseSyncStatus( String enterpriseId, diff --git a/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart b/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart index 8f07718..3305146 100644 --- a/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart +++ b/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart @@ -21,7 +21,7 @@ abstract class EnterpriseRepository implements SyncableRepository { bool? isUploaded, }); - Future syncEnterpriseToServer(Enterprise enterprise) async {} + Future syncEnterpriseToServer(Enterprise enterprise); Future updateEnterpriseSyncStatus(String id, SyncStatus synced) async {} diff --git a/lib/app/features/enterprise/domain/usecases/upload_enterprises_usecase.dart b/lib/app/features/enterprise/domain/usecases/upload_enterprises_usecase.dart index 46ed307..09bac23 100644 --- a/lib/app/features/enterprise/domain/usecases/upload_enterprises_usecase.dart +++ b/lib/app/features/enterprise/domain/usecases/upload_enterprises_usecase.dart @@ -58,15 +58,14 @@ class UploadEnterprisesUseCase { final enterprise = enterprisesToUpload[i].enterprise; try { // 1. 调用通用的同步方法 - await repository.syncEnterpriseToServer(enterprise); + final syncedEnterprise = await repository.syncEnterpriseToServer( + enterprise, + ); // 2. 同步成功后,更新本地状态 if (enterprise.syncStatus == SyncStatus.pendingDelete) { - // repository.deleteLocalEnterprise(enterprise.id); // 从本地删除 + // repository.deleteLocalEnterprise(enterprise.id); } else { - await repository.updateEnterpriseSyncStatus( - enterprise.id, - SyncStatus.synced, - ); + await repository.updateEnterprise(syncedEnterprise); } successCount++; } catch (e) { diff --git a/lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart b/lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart index edd5d18..124765a 100644 --- a/lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart +++ b/lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart @@ -51,7 +51,8 @@ class EnterpriseListController extends GetxController { @override void onInit() { // 页面初始化时,启动完整的“同步-再加载”流程 - loadAndSyncEnterprises(); + // loadAndSyncEnterprises(); + search(); super.onInit(); } @@ -96,51 +97,119 @@ class EnterpriseListController extends GetxController { } } - // 弹出冲突选择对话框的辅助方法 + // [修改后] 弹出冲突选择对话框的辅助方法 Future _showConflictDialog(EnterpriseConflict conflict) { return Get.dialog( AlertDialog( - title: Text('数据冲突: ${conflict.localVersion.name}'), - - // [修改 1] 将所有内容(包括按钮)都放在 content 中 + title: Text('数据冲突'), content: Column( - // mainAxisSize.min 让 Column 的高度自适应内容,防止它无限高 mainAxisSize: MainAxisSize.min, - // crossAxisAlignment.stretch 让所有子元素水平撑满 crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - const Text('服务器上的数据与本地数据不一致,请选择要保留的版本。'), - const SizedBox(height: 24), // 在文本和按钮之间添加一些间距 - // 第一个按钮 - ElevatedButton( - child: Text( - '使用客户端版本\n(修改于: ${conflict.localVersion.lastModifiedTime.toUtc().toDateTimeString2()})', - textAlign: TextAlign.center, - ), - onPressed: () => Get.back(result: conflict.localVersion), + Text('${conflict.localVersion.name} 服务器上的数据与本地数据不一致,请选择要保留的版本。'), + const SizedBox(height: 24), + + // --- 本地版本选择区 --- + Row( + children: [ + // 使用 Expanded 让主按钮填充可用空间 + Expanded( + child: ElevatedButton( + child: Text( + '使用客户端版本\n(修改于: ${conflict.localVersion.lastModifiedTime.toLocal().toDateTimeString2()})', + textAlign: TextAlign.center, + ), + onPressed: () => Get.back(result: conflict.localVersion), + ), + ), + const SizedBox(width: 8), // 按钮间的间距 + // 查看详情按钮 + IconButton( + icon: const Icon(Icons.info_outline), + tooltip: '查看客户端版本详情', + onPressed: () => navigateToDetailsView(conflict.localVersion), + ), + ], ), const SizedBox(height: 8), - // 第二个按钮 - ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: Get.theme.colorScheme.primary, - foregroundColor: Get.theme.colorScheme.onPrimary, - ), - child: Text( - '使用服务器版本\n(修改于: ${conflict.serverVersion.lastModifiedTime.toUtc().toDateTimeString2()})', - textAlign: TextAlign.center, - ), - onPressed: () => Get.back(result: conflict.serverVersion), + // --- 服务器版本选择区 --- + Row( + children: [ + Expanded( + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Get.theme.colorScheme.primary, + foregroundColor: Get.theme.colorScheme.onPrimary, + ), + child: Text( + '使用服务器版本\n(修改于: ${conflict.serverVersion.lastModifiedTime.toLocal().toDateTimeString2()})', + textAlign: TextAlign.center, + ), + onPressed: () => Get.back(result: conflict.serverVersion), + ), + ), + const SizedBox(width: 8), + IconButton( + icon: const Icon(Icons.info_outline), + tooltip: '查看服务器版本详情', + onPressed: () => + navigateToDetailsView(conflict.serverVersion), + ), + ], ), ], ), - - // [修改 2] 不再需要 actions 属性 - // actions: [ ... ], ), + // 设置为 false,防止用户点击对话框外部意外关闭它 + barrierDismissible: false, ); } + // // 弹出冲突选择对话框的辅助方法 + // Future _showConflictDialog(EnterpriseConflict conflict) { + // return Get.dialog( + // AlertDialog( + // title: Text('数据冲突: ${conflict.localVersion.name}'), + + // // [修改 1] 将所有内容(包括按钮)都放在 content 中 + // content: Column( + // // mainAxisSize.min 让 Column 的高度自适应内容,防止它无限高 + // mainAxisSize: MainAxisSize.min, + // // crossAxisAlignment.stretch 让所有子元素水平撑满 + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: [ + // const Text('服务器上的数据与本地数据不一致,请选择要保留的版本。'), + // const SizedBox(height: 24), // 在文本和按钮之间添加一些间距 + // // 第一个按钮 + // ElevatedButton( + // child: Text( + // '使用客户端版本\n(修改于: ${conflict.localVersion.lastModifiedTime.toUtc().toDateTimeString2()})', + // textAlign: TextAlign.center, + // ), + // onPressed: () => Get.back(result: conflict.localVersion), + // ), + // const SizedBox(height: 8), + + // // 第二个按钮 + // ElevatedButton( + // style: ElevatedButton.styleFrom( + // backgroundColor: Get.theme.colorScheme.primary, + // foregroundColor: Get.theme.colorScheme.onPrimary, + // ), + // child: Text( + // '使用服务器版本\n(修改于: ${conflict.serverVersion.lastModifiedTime.toUtc().toDateTimeString2()})', + // textAlign: TextAlign.center, + // ), + // onPressed: () => Get.back(result: conflict.serverVersion), + // ), + // ], + // ), + + // // [修改 2] 不再需要 actions 属性 + // // actions: [ ... ], + // ), + // ); + // } void search() { loadEnterprises(); @@ -191,6 +260,17 @@ class EnterpriseListController extends GetxController { } } + // [新] 封装一个导航到详情页的辅助方法,避免代码重复 + void navigateToDetailsView(Enterprise enterprise) { + Get.toNamed( + AppRoutes.enterpriseForm, + arguments: { + 'data': enterprise, + 'mode': FormMode.view, // 关键:以只读模式打开 + }, + ); + } + /// 导航到新增表单页面 Future navigateToAddForm() async { final result = await Get.toNamed( diff --git a/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart b/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart index 5501950..2c9c734 100644 --- a/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart +++ b/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart @@ -22,7 +22,7 @@ class EnterpriseFormPage extends GetView { child: Column( children: [ Expanded(child: EnterpriseFormView()), - _buildBottomButtons(), + if (!controller.isReadOnly) _buildBottomButtons(), ], ), ),