diff --git a/.vscode/settings.json b/.vscode/settings.json index 8482c2c..f612255 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,9 @@ { - "cSpell.words": ["fenix", "Getx", "tdesign"] + "cSpell.words": [ + "fenix", + "Getx", + "tdesign", + "usecase", + "usecases" + ] } diff --git a/lib/app/core/extensions/datetime_extension.dart b/lib/app/core/extensions/datetime_extension.dart new file mode 100644 index 0000000..e6b2493 --- /dev/null +++ b/lib/app/core/extensions/datetime_extension.dart @@ -0,0 +1,21 @@ +// lib/app/core/extensions/datetime_extension.dart +import 'package:intl/intl.dart'; + +extension DateTimeFormatting on DateTime { + /// 格式化为 'yyyy-MM-dd HH:mm:ss' + String toDateTimeString() { + return DateFormat('yyyy-MM-dd HH:mm:ss').format(this); + } + + /// 格式化为 'yyyy-MM-dd' + String toDateString() { + return DateFormat('yyyy-MM-dd').format(this); + } + + /// 格式化为 'HH:mm:ss' + String toTimeString() { + return DateFormat('HH:mm:ss').format(this); + } + + // 你可以根据需要添加任意多的格式 +} diff --git a/lib/app/core/services/database_service.dart b/lib/app/core/services/database_service.dart index e97dd24..fe388aa 100644 --- a/lib/app/core/services/database_service.dart +++ b/lib/app/core/services/database_service.dart @@ -6,6 +6,7 @@ import 'package:path/path.dart'; const String _createProblemsTable = ''' CREATE TABLE problems( id TEXT PRIMARY KEY, + enterpriseId TEXT NOT NULL, description TEXT NOT NULL, location TEXT NOT NULL, imageUrls TEXT NOT NULL, @@ -39,7 +40,7 @@ const String _createEnterprisesTable = ''' /// 数据库服务,负责管理数据库的生命周期。 /// 这是一个核心服务,只处理连接、创建和升级,不关心具体的数据操作。 class DatabaseService extends GetxService { - static const String _dbName = 'problems.db'; + static const String _dbName = 'database.db'; static const int _dbVersion = 1; Database? _database; @@ -88,6 +89,14 @@ class DatabaseService extends GetxService { Future _onUpgrade(Database db, int oldVersion, int newVersion) async { Get.log('正在将数据库从版本 $oldVersion 升级到 $newVersion...'); // 实际项目中,这里应包含每个版本的迁移逻辑 + if (oldVersion < 2) { + // 从版本 1 升级到版本 2 的逻辑 + // 为 problems 表添加 enterpriseId 字段 + await db.execute(''' + ALTER TABLE problems ADD COLUMN enterpriseId TEXT + '''); + Get.log('`problems` 表已成功添加 `enterpriseId` 字段'); + } } @override diff --git a/lib/app/features/enterprise/data/datasources/enterprise_local_data_source.dart b/lib/app/features/enterprise/data/datasources/enterprise_local_data_source.dart index 9fa6773..4beaa21 100644 --- a/lib/app/features/enterprise/data/datasources/enterprise_local_data_source.dart +++ b/lib/app/features/enterprise/data/datasources/enterprise_local_data_source.dart @@ -1,20 +1,136 @@ +import 'package:problem_check_system/app/core/models/sync_status.dart'; +import 'package:problem_check_system/app/core/services/database_service.dart'; +import 'package:problem_check_system/app/features/enterprise/data/model/enterprise_list_item_model.dart'; import 'package:problem_check_system/app/features/enterprise/data/model/enterprise_model.dart'; import 'package:sqflite/sqflite.dart'; abstract class EnterpriseLocalDataSource { + /// 新增企业 Future addEnterprise(EnterpriseModel enterprise); + Future updateEnterprise(EnterpriseModel enterprise); + Future> getEnterpriseListItems({ + String? name, + String? type, + DateTime? startDate, + DateTime? endDate, + }); + + /// 查询企业列表 } class EnterpriseLocalDataSourceImpl implements EnterpriseLocalDataSource { + final DatabaseService _databaseService; + + const EnterpriseLocalDataSourceImpl({ + required DatabaseService databaseService, + }) : _databaseService = databaseService; + @override Future addEnterprise(EnterpriseModel enterprise) async { - // // 在这里实现将 Enterprise 保存到本地存储的逻辑 - // // 例如,使用 SQLite、SharedPreferences 或其他本地数据库 - // final db = await databaseService.database; - // await db.insert( - // 'enterprises', // 表名 - // enterprise.toMap(), - // conflictAlgorithm: ConflictAlgorithm.replace, - // ); + final db = await _databaseService.database; + await db.insert( + "enterprises", + enterprise.toMap(), + // conflictAlgorithm 用于定义当主键 (id) 冲突时的处理策略。 + // ConflictAlgorithm.replace 表示如果 ID 已存在,则用新数据替换旧数据。 + // 这在同步场景下通常比较有用。 + conflictAlgorithm: ConflictAlgorithm.replace, + ); + } + + @override + Future updateEnterprise(EnterpriseModel enterprise) async { + final db = await _databaseService.database; + await db.update( + 'enterprises', + enterprise.toMap(), + where: 'id = ?', // 关键:通过 ID 找到要更新的行 + whereArgs: [enterprise.id], + ); + } + + @override + Future> getEnterpriseListItems({ + String? name, + String? type, + DateTime? startDate, + DateTime? endDate, + }) async { + final db = await _databaseService.database; + + // pendingCreate 状态的索引值,通常是 0 + final int pendingCreateIndex = SyncStatus.pendingCreate.index; + + // 动态构建 WHERE 子句和参数 + final List whereClauses = []; + final List whereArgs = []; + + // 1. 添加名称查询条件 (模糊查询) + if (name != null && name.isNotEmpty) { + whereClauses.add('e.name LIKE ?'); + whereArgs.add('%$name%'); + } + + // 2. 添加类型查询条件 (精确匹配) + if (type != null && type.isNotEmpty) { + whereClauses.add('e.type = ?'); + whereArgs.add(type); + } + + // 3. 添加创建时间的起始日期条件 + if (startDate != null) { + whereClauses.add('e.creationTime >= ?'); + whereArgs.add(startDate.millisecondsSinceEpoch); + } + + // 4. [新增] 添加创建时间的结束日期条件 + if (endDate != null) { + // 为了包含 endDate 当天的所有数据,我们需要将时间设为当天的最后一刻 + final endOfDay = DateTime( + endDate.year, + endDate.month, + endDate.day, + 23, + 59, + 59, + ); + whereClauses.add('e.creationTime <= ?'); + whereArgs.add(endOfDay.millisecondsSinceEpoch); + } + // --- 修正部分结束 --- + + // 组合 WHERE 子句 + final String whereString = whereClauses.isNotEmpty + ? 'WHERE ${whereClauses.join(' AND ')}' + : ''; + + // 这是最核心的 SQL 查询语句 + final String sql = + ''' + SELECT + e.*, + COUNT(p.id) AS totalProblems, + COUNT(CASE WHEN p.syncStatus != $pendingCreateIndex THEN 1 ELSE NULL END) AS uploadedProblems, + COUNT(CASE WHEN p.syncStatus == $pendingCreateIndex THEN 1 ELSE NULL END) AS pendingProblems + FROM + enterprises e + LEFT JOIN + problems p ON e.id = p.enterpriseId + $whereString + GROUP BY + e.id + ORDER BY + e.creationTime DESC + '''; + + // 调试 + // Get.log('查询 SQL: $sql'); + // Get.log('参数: $whereArgs'); + + final List> maps = await db.rawQuery(sql, whereArgs); + + return List.generate(maps.length, (i) { + return EnterpriseListItemModel.fromMap(maps[i]); + }); } } diff --git a/lib/app/features/enterprise/data/model/enterprise_list_item_model.dart b/lib/app/features/enterprise/data/model/enterprise_list_item_model.dart new file mode 100644 index 0000000..5ab29f3 --- /dev/null +++ b/lib/app/features/enterprise/data/model/enterprise_list_item_model.dart @@ -0,0 +1,24 @@ +import 'package:problem_check_system/app/features/enterprise/data/model/enterprise_model.dart'; +import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise_list_item.dart'; + +class EnterpriseListItemModel extends EnterpriseListItem { + const EnterpriseListItemModel({ + required super.enterprise, + required super.totalProblems, + required super.uploadedProblems, + required super.pendingProblems, + }); + + /// 从数据库查询返回的 Map 创建模型 + /// 这个 map 将包含 JOIN 和 COUNT 后的结果 + factory EnterpriseListItemModel.fromMap(Map map) { + return EnterpriseListItemModel( + // 核心:复用 EnterpriseModel 的 fromMap 方法来解析企业自身的数据 + enterprise: EnterpriseModel.fromMap(map), + // 直接从 map 中获取聚合计算出的计数值 + totalProblems: map['totalProblems'] ?? 0, + uploadedProblems: map['uploadedProblems'] ?? 0, + pendingProblems: map['pendingProblems'] ?? 0, + ); + } +} 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 a3cd228..f83d0bf 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 @@ -1,10 +1,8 @@ -// ... - -import 'package:problem_check_system/app/core/models/sync_status.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_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_list_item.dart'; import 'package:problem_check_system/app/features/enterprise/domain/repositories/enterprise_repository.dart'; import 'package:uuid/uuid.dart'; @@ -20,23 +18,8 @@ class EnterpriseRepositoryImpl implements EnterpriseRepository { @override Future addEnterprise(Enterprise enterprise) async { - final now = DateTime.now(); - - // 1. 丰富实体:补充所有系统生成的字段 - final fullEnterprise = Enterprise( - id: uuid.v4(), // 生成一个新的唯一ID - name: enterprise.name, - type: enterprise.type, - // ... 复制用户输入的其他字段 ... - syncStatus: SyncStatus.pendingCreate, // 关键:设置为待创建状态 - lastModifiedTime: now, - creationTime: now, - ); + final enterpriseModel = EnterpriseModel.fromEntity(enterprise); - // 2. 将丰富的、完整的实体转换为数据模型 - final enterpriseModel = EnterpriseModel.fromEntity(fullEnterprise); - - // 3. 调用数据源进行持久化 await localDataSource.addEnterprise(enterpriseModel); } @@ -63,4 +46,30 @@ class EnterpriseRepositoryImpl implements EnterpriseRepository { // TODO: implement syncUpdate throw UnimplementedError(); } + + @override + Future> getEnterpriseListItems({ + String? name, + String? type, + DateTime? startDate, + DateTime? endDate, + }) async { + // 调用 DataSource 获取包含了聚合数据的数据模型 + final models = await localDataSource.getEnterpriseListItems( + name: name, + type: type, + startDate: startDate, + endDate: endDate, + ); + // 因为 EnterpriseListItemModel 继承自 EnterpriseListItem,所以可以直接返回 + return models; + } + + @override + Future updateEnterprise(Enterprise enterprise) async { + // 将领域实体转换为数据模型 + final enterpriseModel = EnterpriseModel.fromEntity(enterprise); + // 调用数据源执行操作 + await localDataSource.updateEnterprise(enterpriseModel); + } } diff --git a/lib/app/features/enterprise/domain/entities/enterprise.dart b/lib/app/features/enterprise/domain/entities/enterprise.dart index 86d296c..3f374aa 100644 --- a/lib/app/features/enterprise/domain/entities/enterprise.dart +++ b/lib/app/features/enterprise/domain/entities/enterprise.dart @@ -33,6 +33,35 @@ class Enterprise extends Equatable implements SyncableEntity { required this.syncStatus, }); + Enterprise copyWith({ + String? id, + SyncStatus? syncStatus, + DateTime? lastModifiedTime, + String? name, + String? type, + String? address, + String? scale, + String? contactPerson, + String? contactPhone, + String? majorHazardsDescription, + DateTime? creationTime, + }) { + return Enterprise( + id: id ?? this.id, + syncStatus: syncStatus ?? this.syncStatus, + lastModifiedTime: lastModifiedTime ?? this.lastModifiedTime, + name: name ?? this.name, + type: type ?? this.type, + address: address ?? this.address, + scale: scale ?? this.scale, + contactPerson: contactPerson ?? this.contactPerson, + contactPhone: contactPhone ?? this.contactPhone, + majorHazardsDescription: + majorHazardsDescription ?? this.majorHazardsDescription, + creationTime: creationTime ?? this.creationTime, + ); + } + @override List get props => [id, syncStatus, name, type]; } diff --git a/lib/app/features/enterprise/domain/entities/enterprise_list_item.dart b/lib/app/features/enterprise/domain/entities/enterprise_list_item.dart new file mode 100644 index 0000000..568f7c5 --- /dev/null +++ b/lib/app/features/enterprise/domain/entities/enterprise_list_item.dart @@ -0,0 +1,24 @@ +import 'package:equatable/equatable.dart'; +import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise.dart'; + +class EnterpriseListItem extends Equatable { + final Enterprise enterprise; + final int totalProblems; + final int uploadedProblems; + final int pendingProblems; + + const EnterpriseListItem({ + required this.enterprise, + required this.totalProblems, + required this.uploadedProblems, + required this.pendingProblems, + }); + + @override + List get props => [ + enterprise, + totalProblems, + uploadedProblems, + pendingProblems, + ]; +} diff --git a/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart b/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart index 33eda77..c961883 100644 --- a/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart +++ b/lib/app/features/enterprise/domain/repositories/enterprise_repository.dart @@ -1,12 +1,20 @@ import 'package:problem_check_system/app/core/repositories/syncable_repository.dart'; +import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise_list_item.dart'; import '../entities/enterprise.dart'; abstract class EnterpriseRepository implements SyncableRepository { - /// 将一个新的企业实体保存到数据层。 - /// 实现者应负责处理ID生成、时间戳和初始同步状态。 + /// 新增 Future addEnterprise(Enterprise enterprise); - // --- 已有方法 --- - // Future> getEnterpriseListItems(); + /// 更新 + Future updateEnterprise(Enterprise enterprise); + + /// 获取企业信息列表 + Future> getEnterpriseListItems({ + String? name, + String? type, + DateTime? startDate, + DateTime? endDate, + }); } diff --git a/lib/app/features/enterprise/domain/usecases/add_enterprise.dart b/lib/app/features/enterprise/domain/usecases/add_enterprise.dart deleted file mode 100644 index 723d94f..0000000 --- a/lib/app/features/enterprise/domain/usecases/add_enterprise.dart +++ /dev/null @@ -1,12 +0,0 @@ -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 AddEnterprise { - final EnterpriseRepository repository; - - AddEnterprise({required this.repository}); - - Future call(Enterprise enterprise) async { - await repository.addEnterprise(enterprise); - } -} diff --git a/lib/app/features/enterprise/domain/usecases/add_enterprise_usecase.dart b/lib/app/features/enterprise/domain/usecases/add_enterprise_usecase.dart new file mode 100644 index 0000000..9befd31 --- /dev/null +++ b/lib/app/features/enterprise/domain/usecases/add_enterprise_usecase.dart @@ -0,0 +1,36 @@ +import 'package:problem_check_system/app/core/models/sync_status.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'; +import 'package:uuid/uuid.dart'; + +class AddEnterpriseUsecase { + final EnterpriseRepository repository; + final Uuid uuid; + + AddEnterpriseUsecase({required this.repository, required this.uuid}); + + Future call({ + required String name, + required String type, + String address = "", + String scale = "", + String contactPerson = "", + String contactPhone = "", + String majorHazardsDescription = "", + }) async { + final enterprise = Enterprise( + id: uuid.v4(), + name: name, + type: type, + address: address, + scale: scale, + contactPerson: contactPerson, + contactPhone: contactPhone, + majorHazardsDescription: majorHazardsDescription, + lastModifiedTime: DateTime.now(), + creationTime: DateTime.now(), + syncStatus: SyncStatus.pendingCreate, + ); + await repository.addEnterprise(enterprise); + } +} diff --git a/lib/app/features/enterprise/domain/usecases/editor_enterprise.dart b/lib/app/features/enterprise/domain/usecases/editor_enterprise.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/app/features/enterprise/domain/usecases/editor_enterprise_usecase.dart b/lib/app/features/enterprise/domain/usecases/editor_enterprise_usecase.dart new file mode 100644 index 0000000..0e49b49 --- /dev/null +++ b/lib/app/features/enterprise/domain/usecases/editor_enterprise_usecase.dart @@ -0,0 +1,26 @@ +import 'package:problem_check_system/app/core/models/sync_status.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 EditEnterpriseUsecase { + final EnterpriseRepository repository; + + EditEnterpriseUsecase({required this.repository}); + + /// [核心] 这个 Usecase 的业务逻辑 + /// 它接收一个已经修改过的 Enterprise 对象 + Future call(Enterprise updatedEnterprise) async { + // 1. 业务规则:更新“最后修改时间” + final enterpriseToSave = updatedEnterprise.copyWith( + lastModifiedTime: DateTime.now(), + // 2. 业务规则:将同步状态标记为“待更新” + // 我们需要先判断它原始的状态,避免覆盖“待创建” + syncStatus: updatedEnterprise.syncStatus == SyncStatus.pendingCreate + ? SyncStatus.pendingCreate + : SyncStatus.pendingUpdate, + ); + + // 3. 调用仓库进行持久化 + await repository.updateEnterprise(enterpriseToSave); + } +} diff --git a/lib/app/features/enterprise/domain/usecases/get_enterprise_list_usecase.dart b/lib/app/features/enterprise/domain/usecases/get_enterprise_list_usecase.dart new file mode 100644 index 0000000..b69e048 --- /dev/null +++ b/lib/app/features/enterprise/domain/usecases/get_enterprise_list_usecase.dart @@ -0,0 +1,22 @@ +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'; + +class GetEnterpriseListUsecase { + final EnterpriseRepository repository; + + const GetEnterpriseListUsecase({required this.repository}); + + Future> call({ + String? name, + String? type, + DateTime? startDate, + DateTime? endDate, + }) async { + return await repository.getEnterpriseListItems( + name: name, + type: type, + startDate: startDate, + endDate: endDate, + ); + } +} diff --git a/lib/app/features/enterprise/presentation/bindings/enterprise_form_binding.dart b/lib/app/features/enterprise/presentation/bindings/enterprise_form_binding.dart index 83ec994..9492ffb 100644 --- a/lib/app/features/enterprise/presentation/bindings/enterprise_form_binding.dart +++ b/lib/app/features/enterprise/presentation/bindings/enterprise_form_binding.dart @@ -1,13 +1,16 @@ // lib/app/features/enterprise/presentation/bindings/enterprise_form_binding.dart import 'package:get/get.dart'; +import 'package:problem_check_system/app/core/services/database_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/repositories_impl/enterprise_repository_impl.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'; -import 'package:problem_check_system/app/features/enterprise/domain/usecases/add_enterprise.dart'; -import 'package:problem_check_system/app/features/enterprise/presentation/controllers/enterprise_form_controller.dart'; // 确保导入您的模型 +import 'package:problem_check_system/app/features/enterprise/domain/usecases/add_enterprise_usecase.dart'; +import 'package:problem_check_system/app/features/enterprise/domain/usecases/editor_enterprise_usecase.dart'; +import 'package:problem_check_system/app/features/enterprise/presentation/controllers/enterprise_form_controller.dart'; +import 'package:uuid/uuid.dart'; // 确保导入您的模型 class EnterpriseFormBinding extends Bindings { @override @@ -19,7 +22,9 @@ class EnterpriseFormBinding extends Bindings { final Enterprise? enterpriseToEdit = Get.arguments as Enterprise?; Get.lazyPut( - () => EnterpriseLocalDataSourceImpl(), + () => EnterpriseLocalDataSourceImpl( + databaseService: Get.find(), + ), ); Get.lazyPut( () => EnterpriseRemoteDataSourceImpl(), @@ -30,15 +35,22 @@ class EnterpriseFormBinding extends Bindings { remoteDataSource: Get.find(), )), ); - Get.lazyPut( - () => AddEnterprise(repository: Get.find()), + Get.lazyPut( + () => AddEnterpriseUsecase( + repository: Get.find(), + uuid: Get.find(), + ), + ); + Get.lazyPut( + () => EditEnterpriseUsecase(repository: Get.find()), ); // 2. 将获取到的参数(可能为 null)传递给 Controller 的构造函数。 Get.lazyPut( () => EnterpriseFormController( initialData: enterpriseToEdit, - usecase: Get.find(), + addEnterpriseUsecase: Get.find(), + editEnterpriseUsecase: Get.find(), ), ); } diff --git a/lib/app/features/enterprise/presentation/controllers/enterprise_form_controller.dart b/lib/app/features/enterprise/presentation/controllers/enterprise_form_controller.dart index ed1d3e7..261dd4b 100644 --- a/lib/app/features/enterprise/presentation/controllers/enterprise_form_controller.dart +++ b/lib/app/features/enterprise/presentation/controllers/enterprise_form_controller.dart @@ -1,19 +1,25 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:problem_check_system/app/core/models/company_enum.dart'; -import 'package:problem_check_system/app/core/models/sync_status.dart'; import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise.dart'; -import 'package:problem_check_system/app/features/enterprise/domain/usecases/add_enterprise.dart'; -import 'package:uuid/uuid.dart'; +import 'package:problem_check_system/app/features/enterprise/domain/usecases/add_enterprise_usecase.dart'; +import 'package:problem_check_system/app/features/enterprise/domain/usecases/editor_enterprise_usecase.dart'; class EnterpriseFormController extends GetxController { // 通过构造函数接收可能存在的初始数据 final Enterprise? initialData; - final AddEnterprise usecase; + final AddEnterpriseUsecase addEnterpriseUsecase; + final EditEnterpriseUsecase editEnterpriseUsecase; + final formKey = GlobalKey(); - EnterpriseFormController({this.initialData, required this.usecase}); + EnterpriseFormController({ + this.initialData, + required this.addEnterpriseUsecase, + required this.editEnterpriseUsecase, + }); // --- 状态管理 --- + var isSubmitting = false.obs; var isEditMode = false.obs; var pageTitle = '新增企业'.obs; final Rx selectedType = Rx(null); @@ -39,7 +45,16 @@ class EnterpriseFormController extends GetxController { pageTitle.value = '修改信息'; // 用初始数据填充表单 enterpriseNameController.text = initialData!.name; - // ... 初始化其他控制器 + enterpriseAddressController.text = initialData!.address ?? ''; + contactPersonController.text = initialData!.contactPerson ?? ''; + contactPhoneController.text = initialData!.contactPhone ?? ''; + hazardSourceController.text = initialData!.majorHazardsDescription ?? ''; + selectedType.value = CompanyType.values.firstWhereOrNull( + (e) => e.displayText == initialData!.type, + ); + selectedScope.value = CompanyScope.values.firstWhereOrNull( + (e) => e.displayText == initialData!.scale, + ); } else { isEditMode.value = false; pageTitle.value = '新增企业'; @@ -49,36 +64,74 @@ class EnterpriseFormController extends GetxController { // 提交表单的逻辑 void submitForm() { - if (isEditMode.value) { - _updateEnterprise(); - } else { - _createEnterprise(); + if (formKey.currentState?.validate() ?? false) { + if (isEditMode.value) { + _updateEnterprise(); + } else { + _createEnterprise(); + } } } void _createEnterprise() async { - final enterprise = Enterprise( - id: Uuid().v4(), - name: enterpriseNameController.text, - type: selectedType.value!.displayText, - address: enterpriseAddressController.text, - scale: selectedScope.value!.displayText, - contactPerson: contactPersonController.text, - contactPhone: contactPhoneController.text, - majorHazardsDescription: hazardSourceController.text, - lastModifiedTime: DateTime.now(), - creationTime: DateTime.now(), - syncStatus: SyncStatus.pendingCreate, - ); - await usecase.call(enterprise); - Get.back(result: true); // 返回并通知列表刷新 + try { + isSubmitting.value = true; // 开始提交,显示加载 + await addEnterpriseUsecase( + name: enterpriseNameController.text, + type: selectedType.value!.displayText, + address: enterpriseAddressController.text, + scale: selectedScope.value == null + ? "" + : selectedScope.value!.displayText, + contactPerson: contactPersonController.text, + contactPhone: contactPhoneController.text, + majorHazardsDescription: hazardSourceController.text, + ); + Get.back(result: true); // 返回并通知列表刷新 + // [可选] 显示成功提示 + Get.snackbar('成功', '企业信息已保存'); + } catch (e) { + // [新增] 捕获异常并提示用户 + Get.snackbar('错误', '保存失败,请稍后重试'); + } finally { + isSubmitting.value = false; // 结束提交,隐藏加载 + } } - void _updateEnterprise() { - print('执行修改逻辑, ID: ${initialData!.id}'); - // 调用修改 API - // Get.find().updateEnterprise(initialData!.id, ...); - Get.back(result: true); // 返回并通知列表刷新 + void _updateEnterprise() async { + // 确保 initialData 不为 null,这是编辑模式的前提 + if (initialData == null) return; + + try { + // 1. 开始提交,更新 UI 状态 (例如显示加载动画) + isSubmitting.value = true; + + // 2. 从 UI 收集更新后的数据,并与原始数据合并 + // 使用我们在 Usecase 步骤中创建的 copyWith 方法,这非常方便! + // 它能保留 id, creationTime 等不变的字段。 + final updatedEnterprise = initialData!.copyWith( + name: enterpriseNameController.text, + type: selectedType.value!.displayText, + address: enterpriseAddressController.text, + scale: selectedScope.value?.displayText, + contactPerson: contactPersonController.text, + contactPhone: contactPhoneController.text, + majorHazardsDescription: hazardSourceController.text, + ); + + // 3. 调用 EditEnterpriseUsecase + await editEnterpriseUsecase(updatedEnterprise); + + // 4. 操作成功,返回上一页并通知列表刷新 + Get.back(result: true); + Get.snackbar('成功', '企业信息已更新'); + } catch (e) { + // 5. 捕获并处理异常 + Get.snackbar('错误', '更新失败,请稍后重试'); + } finally { + // 6. 结束提交,恢复 UI 状态 + isSubmitting.value = false; + } } @override 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 2c57c67..d6cccae 100644 --- a/lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart +++ b/lib/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart @@ -1,14 +1,27 @@ // lib/app/modules/enterprise_list/enterprise_list_controller.dart +import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:problem_check_system/app/core/models/sync_status.dart'; -import 'package:problem_check_system/app/features/enterprise/data/model/enterprise_model.dart'; +import 'package:problem_check_system/app/core/models/company_enum.dart'; 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/usecases/get_enterprise_list_usecase.dart'; class EnterpriseListController extends GetxController { - // 使用 .obs 使列表变为响应式,当数据变化时,UI会自动更新 - final enterpriseList = [].obs; + // --- 状态管理 --- + var isLoading = false.obs; + var enterpriseList = [].obs; + + // --- 筛选条件的状态 --- + final nameController = TextEditingController(); + final Rx selectedType = Rx(null); + final Rx startDate = Rx(null); + final Rx endDate = Rx(null); + + final GetEnterpriseListUsecase getEnterpriseListUsecase; + + EnterpriseListController({required this.getEnterpriseListUsecase}); @override void onInit() { @@ -16,35 +29,46 @@ class EnterpriseListController extends GetxController { fetchEnterprises(); // 页面初始化时加载数据 } + /// 核心方法:获取企业列表 + Future fetchEnterprises() async { + try { + isLoading.value = true; + final result = await getEnterpriseListUsecase.call( + name: nameController.text, + type: selectedType.value?.displayText, + startDate: startDate.value, + endDate: endDate.value, + ); + enterpriseList.assignAll(result); + } catch (e) { + Get.snackbar('错误', '加载企业列表失败: $e'); + } finally { + isLoading.value = false; + } + } + + /// 供 UI 调用的搜索方法 + void search() { + fetchEnterprises(); + } + void refreshList() { - fetchEnterprises(); // 重新获取数据 + fetchEnterprises(); } - // 模拟从API获取数据的过程 - void fetchEnterprises() { - // 模拟网络延迟 - Future.delayed(const Duration(milliseconds: 500), () { - // // 创建一些示例数据 - // var mockData = [ - // Enterprise( - // id: "1", - // name: '企业A', - // type: '类型1', - // address: '地址A', - // contactPerson: '联系人A', - // contactPhone: '123456', - // lastModifiedTime: DateTime.now(), - // creationTime: DateTime.now(), - // syncStatus: SyncStatus.synced, - // ), - // ]; - // enterpriseList.assignAll(mockData); // 更新列表 - }); + /// 清空筛选条件并重新加载 + void clearFilters() { + nameController.clear(); + selectedType.value = null; + startDate.value = null; + endDate.value = null; + fetchEnterprises(); } - // 可以在这里添加其他业务逻辑,例如: - void onSearch() { - // 处理搜索逻辑 + @override + void onClose() { + nameController.dispose(); + super.onClose(); } /// 导航到编辑表单页面 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 eb03503..935e091 100644 --- a/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart +++ b/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart @@ -15,62 +15,74 @@ class EnterpriseFormPage extends GetView { backgroundColor: const Color(0xFFF5F5F5), appBar: _buildAppBar(), body: SafeArea( - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h), - child: Column( - children: [ - buildTitleSection(title: '必填信息'), - SizedBox(height: 12.h), - _buildInfoSection( - children: [ - _buildTextField( - label: '企业名称', - hint: '达拉特旗', - textController: controller.enterpriseNameController, - isRequired: true, - ), - _buildCompanyTypeDropdown(), - ], - ), - SizedBox(height: 12.h), - buildTitleSection(title: '选填信息'), - SizedBox(height: 12.h), - _buildInfoSection( - children: [ - _buildTextField( - label: '企业地址', - hint: '请输入企业地址', - textController: - controller.enterpriseAddressController, - ), - _buildCompanyScopeDropdown(), - _buildTextField( - label: '联系人', - hint: '请输入联系人姓名', - textController: controller.contactPersonController, - ), - _buildTextField( - label: '联系电话', - hint: '请输入联系电话', - textController: controller.contactPhoneController, - ), - _buildTextField( - label: '有无重大危险源;重大危险源情况', - hint: '请输入有无重大危险源;重大危险源情况', - textController: controller.hazardSourceController, - hasDivider: false, - ), - ], - ), - ], + child: Form( + key: controller.formKey, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: EdgeInsets.symmetric( + horizontal: 16.w, + vertical: 12.h, + ), + child: Column( + children: [ + buildTitleSection(title: '必填信息'), + SizedBox(height: 12.h), + _buildInfoSection( + children: [ + _buildTextField( + label: '企业名称', + hint: '达拉特旗', + textController: controller.enterpriseNameController, + validator: (value) { + if (value == null || value.isEmpty) { + return '企业名称不能为空'; + } + return null; + }, + isRequired: true, + ), + _buildCompanyTypeDropdown(), + ], + ), + SizedBox(height: 12.h), + buildTitleSection(title: '选填信息'), + SizedBox(height: 12.h), + _buildInfoSection( + children: [ + _buildTextField( + label: '企业地址', + hint: '请输入企业地址', + textController: + controller.enterpriseAddressController, + ), + _buildCompanyScopeDropdown(), + _buildTextField( + label: '联系人', + hint: '请输入联系人姓名', + textController: controller.contactPersonController, + ), + _buildTextField( + label: '联系电话', + hint: '请输入联系电话', + textController: controller.contactPhoneController, + ), + _buildTextField( + label: '有无重大危险源;重大危险源情况', + hint: '请输入有无重大危险源;重大危险源情况', + textController: controller.hazardSourceController, + hasDivider: false, + ), + ], + ), + ], + ), ), ), - ), - _buildBottomButtons(), - ], + _buildBottomButtons(), + ], + ), ), ), ); @@ -149,6 +161,7 @@ class EnterpriseFormPage extends GetView { required TextEditingController textController, bool isRequired = false, bool hasDivider = true, + String? Function(String?)? validator, }) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -159,6 +172,7 @@ class EnterpriseFormPage extends GetView { ), TextFormField( controller: textController, + validator: validator, decoration: InputDecoration( hintText: hint, hintStyle: TextStyle(color: Colors.grey[400], fontSize: 14.sp), @@ -187,6 +201,12 @@ class EnterpriseFormPage extends GetView { Obx( () => DropdownButtonFormField( initialValue: controller.selectedType.value, + validator: (value) { + if (value == null) { + return '请选择企业类型'; + } + return null; + }, hint: Text( '请选择企业类型', style: TextStyle(color: Colors.grey[400], fontSize: 14.sp), @@ -302,21 +322,29 @@ class EnterpriseFormPage extends GetView { ), SizedBox(width: 16.w), Expanded( - child: ElevatedButton( - onPressed: controller.submitForm, - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF2B8CFF), - padding: EdgeInsets.symmetric(vertical: 12.h), - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.r), + child: Obx(() { + return ElevatedButton( + onPressed: controller.isSubmitting.value + ? null + : controller.submitForm, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF2B8CFF), + padding: EdgeInsets.symmetric(vertical: 12.h), + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.r), + ), ), - ), - child: Text( - '确定', - style: TextStyle(fontSize: 16.sp, color: Colors.white), - ), - ), + child: controller.isSubmitting.value + ? const SizedBox( + child: CircularProgressIndicator(color: Colors.white), + ) + : Text( + '确定', + style: TextStyle(fontSize: 16.sp, color: Colors.white), + ), + ); + }), ), ], ), diff --git a/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart b/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart index 7406bf8..cf948d8 100644 --- a/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart +++ b/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.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/features/enterprise/presentation/widgets/enterprise_card.dart'; import '../controllers/enterprise_list_controller.dart'; @@ -39,50 +41,21 @@ class EnterpriseListPage extends GetView { controller.navigateToAddForm(); }, ), - IconButton( - icon: Icon(Icons.upload, color: Colors.pink[300]), // 使用 .sp - onPressed: () { - controller.navigateToUploadPage(); - }, - ), + // IconButton( + // icon: Icon(Icons.upload, color: Colors.pink[300]), // 使用 .sp + // onPressed: () { + // controller.navigateToUploadPage(); + // }, + // ), ], ), body: Stack( children: [ Column( children: [ - _buildFilterBar(), - // 使用 Obx 包裹需要响应式更新的 Widget - Expanded( - child: Obx(() { - if (controller.enterpriseList.isEmpty) { - return const Center(child: CircularProgressIndicator()); - } - return ListView.builder( - padding: EdgeInsets.symmetric( - horizontal: 16.w, // 使用 .w - vertical: 8.h, // 使用 .h - ), - itemCount: controller.enterpriseList.length, - itemBuilder: (context, index) { - final enterprise = controller.enterpriseList[index]; - return Padding( - padding: EdgeInsets.only(bottom: 12.h), // 使用 .h - // child: _EnterpriseCard(enterprise: enterprise), - child: EnterpriseCard( - enterprise: enterprise, - onEdit: () { - controller.navigateToEditForm(enterprise); - }, - onViewProblems: () { - controller.navigateToEnterpriseInfoPage(); - }, - ), - ); - }, - ); - }), - ), + _buildFilterSection(), + const Divider(height: 1, thickness: .1), + Expanded(child: _buildEnterpriseList()), ], ), ], @@ -90,43 +63,167 @@ class EnterpriseListPage extends GetView { ); } - Widget _buildFilterBar() { - return Container( - padding: EdgeInsets.fromLTRB(16.w, 12.h, 16.w, 12.h), // 使用 .w 和 .h - color: Colors.white, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - children: [ - const Text('企业名称', style: TextStyle(color: Colors.black54)), - SizedBox(width: 4.w), // 使用 .w - Icon( - Icons.search, - size: 20.sp, - color: Colors.black54, - ), // 使用 .sp - ], - ), + /// [新增] 构建可展开的筛选查询区域 + Widget _buildFilterSection() { + return ExpansionTile( + title: const Text('筛选查询'), + leading: const Icon(Icons.filter_alt_outlined), + initiallyExpanded: false, // 默认收起 + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 1.h), + child: Column( + children: [ + // 1. 企业名称输入框 + TextFormField( + controller: controller.nameController, + decoration: InputDecoration( + labelText: '企业名称', + hintText: '请输入关键词', + prefixIcon: const Icon(Icons.business_center), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.r), + ), + isDense: true, + ), + ), + SizedBox(height: 12.h), + + // 2. 企业类型下拉框 + Obx( + () => DropdownButtonFormField( + initialValue: controller.selectedType.value, + decoration: InputDecoration( + labelText: '企业类型', + prefixIcon: const Icon(Icons.category), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.r), + ), + isDense: true, + ), + hint: const Text('请选择企业类型'), + isExpanded: true, + items: CompanyType.values.map((type) { + return DropdownMenuItem( + value: type, + child: Text(type.displayText), + ); + }).toList(), + onChanged: (value) { + controller.selectedType.value = value; + }, + ), + ), + SizedBox(height: 12.h), + + // 3. 日期范围选择器 + Row( + children: [ + Expanded( + child: _buildDatePickerField('开始日期', controller.startDate), + ), + SizedBox(width: 12.w), + Expanded( + child: _buildDatePickerField('结束日期', controller.endDate), + ), + ], + ), + SizedBox(height: 16.h), + + // 4. 操作按钮 + Row( + children: [ + Expanded( + child: OutlinedButton.icon( + onPressed: controller.clearFilters, + icon: const Icon(Icons.refresh), + label: const Text('重置'), + style: OutlinedButton.styleFrom( + padding: EdgeInsets.symmetric(vertical: 12.h), + ), + ), + ), + SizedBox(width: 16.w), + Expanded( + child: ElevatedButton.icon( + onPressed: controller.search, + icon: const Icon(Icons.search), + label: const Text('查询'), + style: ElevatedButton.styleFrom( + padding: EdgeInsets.symmetric(vertical: 12.h), + ), + ), + ), + ], + ), + ], ), - _buildDropdown('选择日期'), - _buildDropdown('近一周'), - _buildDropdown('类型'), - ], - ), + ), + ], ); } - Widget _buildDropdown(String text) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 8.w), // 使用 .w - child: Row( - children: [ - Text(text, style: const TextStyle(color: Colors.black54)), - const Icon(Icons.arrow_drop_down, color: Colors.black54), - ], + /// [新增] 构建日期选择器的辅助方法 + Widget _buildDatePickerField(String label, Rx date) { + return InkWell( + onTap: () async { + final pickedDate = await showDatePicker( + context: Get.context!, + initialDate: date.value ?? DateTime.now(), + firstDate: DateTime(2020), + lastDate: DateTime(2101), + ); + if (pickedDate != null) { + date.value = pickedDate; + } + }, + child: InputDecorator( + decoration: InputDecoration( + labelText: label, + prefixIcon: const Icon(Icons.calendar_today), + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8.r)), + isDense: true, + ), + child: Obx( + () => Text( + date.value == null ? '请选择日期' : date.value!.toDateTimeString(), + style: TextStyle( + color: date.value == null ? Colors.grey[600] : Colors.black87, + ), + ), + ), ), ); } + + Widget _buildEnterpriseList() { + return Obx(() { + if (controller.isLoading.value) { + return const Center(child: CircularProgressIndicator()); + } + return ListView.builder( + padding: EdgeInsets.symmetric( + horizontal: 16.w, // 使用 .w + vertical: 8.h, // 使用 .h + ), + itemCount: controller.enterpriseList.length, + itemBuilder: (context, index) { + final item = controller.enterpriseList[index]; + return Padding( + padding: EdgeInsets.only(bottom: 12.h), // 使用 .h + // child: _EnterpriseCard(enterprise: enterprise), + child: EnterpriseCard( + enterpriseListItem: item, + onEdit: () { + controller.navigateToEditForm(item.enterprise); + }, + onViewProblems: () { + controller.navigateToEnterpriseInfoPage(); + }, + ), + ); + }, + ); + }); + } } diff --git a/lib/app/features/enterprise/presentation/widgets/enterprise_card.dart b/lib/app/features/enterprise/presentation/widgets/enterprise_card.dart index 61cebda..f858f80 100644 --- a/lib/app/features/enterprise/presentation/widgets/enterprise_card.dart +++ b/lib/app/features/enterprise/presentation/widgets/enterprise_card.dart @@ -1,16 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise.dart'; +import 'package:intl/intl.dart'; +import 'package:problem_check_system/app/core/extensions/datetime_extension.dart'; +import 'package:problem_check_system/app/core/models/sync_status.dart'; +import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise_list_item.dart'; // 主卡片组件 class EnterpriseCard extends StatelessWidget { - final Enterprise enterprise; + final EnterpriseListItem enterpriseListItem; final VoidCallback onEdit; final VoidCallback onViewProblems; const EnterpriseCard({ super.key, - required this.enterprise, + required this.enterpriseListItem, required this.onEdit, required this.onViewProblems, }); @@ -133,7 +136,7 @@ class EnterpriseCard extends StatelessWidget { ), SizedBox(height: 4.h), // .h 适配垂直间距 Text( - enterprise.name, + enterpriseListItem.enterprise.name, style: TextStyle( fontSize: 12.5.sp, fontWeight: FontWeight.w500, @@ -153,7 +156,7 @@ class EnterpriseCard extends StatelessWidget { ), SizedBox(height: 4.h), Text( - enterprise.type, + enterpriseListItem.enterprise.type, style: TextStyle( fontSize: 12.5.sp, fontWeight: FontWeight.w500, @@ -171,7 +174,9 @@ class EnterpriseCard extends StatelessWidget { border: Border.all(color: Colors.red.shade400, width: 1.w), ), child: Text( - '信息未上传', + enterpriseListItem.enterprise.syncStatus == SyncStatus.synced + ? '信息已上传' + : '信息未上传', style: TextStyle(fontSize: 7.sp, color: Colors.red.shade400), ), ), @@ -194,7 +199,7 @@ class EnterpriseCard extends StatelessWidget { style: TextStyle(fontSize: 12.sp, color: Colors.grey), ), Text( - "111", // enterprise.totalIssues.toString(), + enterpriseListItem.totalProblems.toString(), style: TextStyle( fontSize: 12.5.sp, color: Colors.black87, @@ -208,7 +213,7 @@ class EnterpriseCard extends StatelessWidget { children: [ Icon(Icons.access_time, color: Colors.grey, size: 16.sp), Text( - '创建时间: ${enterprise.creationTime}', + '创建时间: ${enterpriseListItem.enterprise.creationTime.toDateTimeString()}', style: TextStyle(fontSize: 12.sp, color: Colors.grey), ), ], @@ -222,13 +227,13 @@ class EnterpriseCard extends StatelessWidget { return Row( children: [ _buildTag( - text: '已上传 ${enterprise.id}', + text: '已上传 ${enterpriseListItem.uploadedProblems}', textColor: Colors.blue.shade700, backgroundColor: Colors.blue.shade50, ), SizedBox(width: 8.w), _buildTag( - text: '未上传 ${enterprise.id}', + text: '未上传 ${enterpriseListItem.pendingProblems}', textColor: Colors.red.shade600, backgroundColor: Colors.red.shade50, ), diff --git a/lib/app/features/home/bindings/home_binding.dart b/lib/app/features/home/bindings/home_binding.dart index 8283e50..e0c3937 100644 --- a/lib/app/features/home/bindings/home_binding.dart +++ b/lib/app/features/home/bindings/home_binding.dart @@ -2,7 +2,6 @@ import 'package:get/get.dart'; import 'package:problem_check_system/app/core/models/problem_sync_status.dart'; import 'package:problem_check_system/app/core/repositories/auth_repository.dart'; import 'package:problem_check_system/app/features/problem/data/repositories/problem_repository.dart'; -import 'package:problem_check_system/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart'; import 'package:problem_check_system/app/features/home/controllers/home_controller.dart'; import 'package:problem_check_system/app/features/my/controllers/my_controller.dart'; import 'package:problem_check_system/app/features/problem/presentation/controllers/problem_controller.dart'; @@ -13,7 +12,7 @@ class HomeBinding implements Bindings { /// 注册主页控制器 Get.lazyPut(() => HomeController()); Get.put(ProblemStateManager(uuid: Get.find(), authRepository: Get.find())); - Get.lazyPut(() => EnterpriseListController()); + // Get.lazyPut(() => EnterpriseListController()); /// 注册问题控制器 Get.lazyPut( diff --git a/lib/app/features/navigation/presentation/bindings/navigation_binding.dart b/lib/app/features/navigation/presentation/bindings/navigation_binding.dart index ae97bc4..ca73e5d 100644 --- a/lib/app/features/navigation/presentation/bindings/navigation_binding.dart +++ b/lib/app/features/navigation/presentation/bindings/navigation_binding.dart @@ -1,7 +1,13 @@ import 'package:get/get.dart'; import 'package:problem_check_system/app/core/models/problem_sync_status.dart'; import 'package:problem_check_system/app/core/repositories/auth_repository.dart'; +import 'package:problem_check_system/app/core/services/database_service.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/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/get_enterprise_list_usecase.dart'; import 'package:problem_check_system/app/features/problem/data/repositories/problem_repository.dart'; import 'package:problem_check_system/app/features/enterprise/presentation/controllers/enterprise_list_controller.dart'; import 'package:problem_check_system/app/features/navigation/presentation/controllers/navigation_controller.dart'; @@ -17,8 +23,28 @@ class NavigationBinding extends Bindings { networkStatusService: Get.find(), ), ); + Get.put( + EnterpriseLocalDataSourceImpl( + databaseService: Get.find(), + ), + ); + Get.put(EnterpriseRemoteDataSourceImpl()); + Get.put( + EnterpriseRepositoryImpl( + localDataSource: Get.find(), + remoteDataSource: Get.find(), + ), + ); + Get.put( + GetEnterpriseListUsecase(repository: Get.find()), + ); + Get.lazyPut( + () => EnterpriseListController( + getEnterpriseListUsecase: Get.find(), + ), + ); + Get.put(ProblemStateManager(uuid: Get.find(), authRepository: Get.find())); - Get.lazyPut(() => EnterpriseListController()); /// 注册问题控制器 Get.lazyPut( diff --git a/lib/app/features/navigation/presentation/pages/navigation_page.dart b/lib/app/features/navigation/presentation/pages/navigation_page.dart index 8491f82..3227b94 100644 --- a/lib/app/features/navigation/presentation/pages/navigation_page.dart +++ b/lib/app/features/navigation/presentation/pages/navigation_page.dart @@ -47,6 +47,7 @@ class NavigationPage extends GetView { }, child: FloatingActionButton( heroTag: "btn_upload", + shape: const CircleBorder(), onPressed: isOnline ? () => controller.handleFabUploadTap() : null,