From 80d8a7b104fc23b6f005e8e081107a63e6f4000e Mon Sep 17 00:00:00 2001 From: liyi Date: Mon, 15 Sep 2025 16:00:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E3=80=81=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E3=80=81=E5=88=A0=E9=99=A4=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bind_team_star_cloud_account_request.dart | 12 +- .../team/response/create_team_response.dart | 4 + .../team/response/team_info_response.dart | 10 +- lib/api/service/team_api_service.dart | 10 +- lib/app.dart | 34 ++-- lib/base/base_controller.dart | 11 +- .../constant/app_support_device_type.dart | 3 - .../constant/app_view_parameter_keys.dart | 4 + .../events/refresh_device_list_event.dart | 3 + lib/common/utils/event_bus_util.dart | 49 +++++ lib/routes/app_pages.dart | 7 + lib/routes/app_routes.dart | 1 + .../device_manage_controller.dart | 108 ++++++++++- .../deviceManage/device_manage_view.dart | 168 ++++++++++-------- .../removeDevice/remove_device_binding.dart | 10 ++ .../remove_device_controller.dart | 104 +++++++++++ .../removeDevice/remove_device_view.dart | 159 +++++++++++++++++ .../search_device_controller.dart | 34 +--- lib/views/home/home_controller.dart | 35 +--- lib/views/home/home_view.dart | 12 +- .../widget/home_statistics_row_widget.dart | 152 ++++++++-------- lib/views/main/main_controller.dart | 93 +++++++++- .../createTeam/create_team_controller.dart | 59 ++++-- .../use_case_setting_controller.dart | 79 ++++---- pubspec.lock | 8 + pubspec.yaml | 2 + 26 files changed, 865 insertions(+), 306 deletions(-) create mode 100644 lib/common/constant/app_view_parameter_keys.dart create mode 100644 lib/common/events/refresh_device_list_event.dart create mode 100644 lib/common/utils/event_bus_util.dart create mode 100644 lib/views/device/removeDevice/remove_device_binding.dart create mode 100644 lib/views/device/removeDevice/remove_device_controller.dart create mode 100644 lib/views/device/removeDevice/remove_device_view.dart diff --git a/lib/api/model/team/request/bind_team_star_cloud_account_request.dart b/lib/api/model/team/request/bind_team_star_cloud_account_request.dart index f80ca11..fd7ec41 100644 --- a/lib/api/model/team/request/bind_team_star_cloud_account_request.dart +++ b/lib/api/model/team/request/bind_team_star_cloud_account_request.dart @@ -1,13 +1,15 @@ class BindTeamStarCloudAccountRequest { - String teamId; + int teamId; String teamNo; String username; + int cloudUid; String password; BindTeamStarCloudAccountRequest({ required this.teamId, required this.teamNo, required this.username, + required this.cloudUid, required this.password, }); @@ -16,21 +18,25 @@ class BindTeamStarCloudAccountRequest { data['teamId'] = teamId; data['teamNo'] = teamNo; data['username'] = username; + data['cloudUid'] = cloudUid; data['password'] = password; return data; } factory BindTeamStarCloudAccountRequest.fromJson(Map json) { return BindTeamStarCloudAccountRequest( - teamId: json['teamId'] as String, + teamId: json['teamId'] as int, teamNo: json['teamNo'] as String, username: json['username'] as String, + cloudUid: json['cloudUid'] as int, password: json['password'] as String, ); } @override String toString() { - return 'BindTeamStarCloudAccountRequest{teamId: $teamId, teamNo: $teamNo, username: $username, password: $password}'; + return 'BindTeamStarCloudAccountRequest{teamId: $teamId,cloudUid:$cloudUid, teamNo: $teamNo, username: $username,' + ' password:' + ' $password}'; } } diff --git a/lib/api/model/team/response/create_team_response.dart b/lib/api/model/team/response/create_team_response.dart index c3989e3..25b971c 100644 --- a/lib/api/model/team/response/create_team_response.dart +++ b/lib/api/model/team/response/create_team_response.dart @@ -1,19 +1,23 @@ class CreateTeamResponse { final String? teamNo; + final int? teamId; CreateTeamResponse({ this.teamNo, + this.teamId, }); factory CreateTeamResponse.fromJson(Map json) { return CreateTeamResponse( teamNo: json['teamNo'] as String?, + teamId: json['teamId'] as int?, ); } Map toJson() { return { 'teamNo': teamNo, + 'teamId': teamId, }; } } diff --git a/lib/api/model/team/response/team_info_response.dart b/lib/api/model/team/response/team_info_response.dart index 40cb716..83c9c18 100644 --- a/lib/api/model/team/response/team_info_response.dart +++ b/lib/api/model/team/response/team_info_response.dart @@ -8,7 +8,7 @@ class TeamInfoResponse { String? sceneCustomName; // 其他场景名称 String? personNo; // 人员编号 bool? isOwner; // 是否我的团队 - TeamCloudInfo? cloudInfo; + TeamCloudInfo? teamCloudInfo; TeamInfoResponse({ this.id, @@ -20,7 +20,7 @@ class TeamInfoResponse { this.sceneCustomName, this.personNo, this.isOwner, - this.cloudInfo, + this.teamCloudInfo, }); // 从JSON构造函数 @@ -35,7 +35,7 @@ class TeamInfoResponse { sceneCustomName: json['sceneCustomName'] as String?, personNo: json['personNo'] as String?, isOwner: json['isOwner'] as bool?, - cloudInfo: json['cloudInfo'] != null ? TeamCloudInfo.fromJson(json['cloudInfo']) : null, + teamCloudInfo: json['teamCloudInfo'] != null ? TeamCloudInfo.fromJson(json['teamCloudInfo']) : null, ); } @@ -51,7 +51,7 @@ class TeamInfoResponse { 'sceneCustomName': sceneCustomName, 'personNo': personNo, 'isOwner': isOwner, - 'cloudInfo': cloudInfo?.toJson(), + 'teamCloudInfo': teamCloudInfo?.toJson(), }; } @@ -62,7 +62,7 @@ class TeamInfoResponse { 'scene: $scene, sceneCustomName: $sceneCustomName,' ' sceneName: $sceneName, ' ' personNo: $personNo, ' - ' cloudInfo: $cloudInfo,' + ' teamCloudInfo: $teamCloudInfo,' ' isOwner: $isOwner}'; } } diff --git a/lib/api/service/team_api_service.dart b/lib/api/service/team_api_service.dart index 53ab5f6..6ec3365 100644 --- a/lib/api/service/team_api_service.dart +++ b/lib/api/service/team_api_service.dart @@ -59,21 +59,21 @@ class TeamApiService { // 通过实例调用 path: ApiPath.changeTeam, method: HttpConstant.post, - data: request, + data: request.toJson(), fromJson: (data) {}, ); } // 团队绑定星云账号 - Future> requestBindTeamStarCloudAccount({ + Future> requestBindTeamStarCloudAccount({ required BindTeamStarCloudAccountRequest request, }) { return _api.makeRequest( // 通过实例调用 path: ApiPath.bindTeamStarCloudAccount, method: HttpConstant.post, - data: request, - fromJson: (data) => SceneInfoResponseList.fromJson(data), + data: request.toJson(), + fromJson: (data){}, ); } @@ -85,7 +85,7 @@ class TeamApiService { // 通过实例调用 path: ApiPath.updateTeamInfo, method: HttpConstant.post, - data: request, + data: request.toJson(), fromJson: (data) {}, ); } diff --git a/lib/app.dart b/lib/app.dart index 46632e0..f35edab 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -29,21 +29,27 @@ class _AppState extends State { builder: (_, child) { return GetMaterialApp( theme: ThemeData( - scaffoldBackgroundColor: Colors.white, - brightness: Brightness.light, - textSelectionTheme: TextSelectionThemeData( - cursorColor: Colors.blue.shade200, - selectionColor: Colors.blue.shade100, - selectionHandleColor: Colors.blue.shade300, + scaffoldBackgroundColor: Colors.white, + brightness: Brightness.light, + textSelectionTheme: TextSelectionThemeData( + cursorColor: Colors.blue.shade200, + selectionColor: Colors.blue.shade100, + selectionHandleColor: Colors.blue.shade300, + ), + dialogBackgroundColor: Colors.white, + appBarTheme: AppBarTheme( + backgroundColor: Colors.white, + elevation: 0, + surfaceTintColor: Colors.transparent, + shadowColor: Colors.transparent, + scrolledUnderElevation: 0, + titleTextStyle: TextStyle( + color: Colors.black87, + fontSize: 18.sp, + fontWeight: FontWeight.w500, ), - dialogBackgroundColor: Colors.white, - appBarTheme: AppBarTheme( - backgroundColor: Colors.white, - elevation: 0, - surfaceTintColor: Colors.transparent, - shadowColor: Colors.transparent, - scrolledUnderElevation: 0, - )), + ), + ), // 必须配置以下三个本地化代理 localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, // 提供Material组件本地化字符串 diff --git a/lib/base/base_controller.dart b/lib/base/base_controller.dart index 920760a..bed984f 100644 --- a/lib/base/base_controller.dart +++ b/lib/base/base_controller.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:starwork_flutter/common/constant/app_toast_messages.dart'; import 'package:starwork_flutter/common/widgets/custom_dialog_widget.dart'; class BaseController extends GetxController { @@ -14,7 +15,7 @@ class BaseController extends GetxController { } void showLoading() { - EasyLoading.show(status: 'loading...'); + EasyLoading.show(status: AppToastMessages.loading); } void hideLoading() { @@ -33,12 +34,8 @@ class BaseController extends GetxController { EasyLoading.showError(message.tr); } - void showCustomDialog({ - required String title, - required Widget content, - required VoidCallback onConfirm, - String? confirmText - }) { + void showCustomDialog( + {required String title, required Widget content, required VoidCallback onConfirm, String? confirmText}) { Get.dialog( CustomDialogWidget( title: title, diff --git a/lib/common/constant/app_support_device_type.dart b/lib/common/constant/app_support_device_type.dart index 7f127e1..2afdb23 100644 --- a/lib/common/constant/app_support_device_type.dart +++ b/lib/common/constant/app_support_device_type.dart @@ -8,10 +8,7 @@ class AppSupportDeviceType { // 获取所有类型 static List get allTypes => [ - all, lock, - gateway, - attendanceMachine, ]; final String value; diff --git a/lib/common/constant/app_view_parameter_keys.dart b/lib/common/constant/app_view_parameter_keys.dart new file mode 100644 index 0000000..f3b7ce2 --- /dev/null +++ b/lib/common/constant/app_view_parameter_keys.dart @@ -0,0 +1,4 @@ +class AppViewParameterKeys { + static const String deviceList = "deviceList"; + +} \ No newline at end of file diff --git a/lib/common/events/refresh_device_list_event.dart b/lib/common/events/refresh_device_list_event.dart new file mode 100644 index 0000000..c85a8ea --- /dev/null +++ b/lib/common/events/refresh_device_list_event.dart @@ -0,0 +1,3 @@ +class RefreshDeviceListEvent { + RefreshDeviceListEvent(); +} diff --git a/lib/common/utils/event_bus_util.dart b/lib/common/utils/event_bus_util.dart new file mode 100644 index 0000000..a6c9c0f --- /dev/null +++ b/lib/common/utils/event_bus_util.dart @@ -0,0 +1,49 @@ +import 'package:event_bus/event_bus.dart'; + +// 创建 EventBus 实例(私有) +EventBus _eventBus = EventBus(); + +/// 全局事件总线工具类(单例) +class EventBusUtil { + // 工厂构造函数,确保返回唯一实例 + factory EventBusUtil() => _instance; + + // 私有构造函数 + EventBusUtil._internal(); + + // 静态实例 + static final EventBusUtil _instance = EventBusUtil._internal(); + + /// 获取 EventBus 实例 + EventBus get instance => _eventBus; + + /// 监听指定类型的事件 + /// + /// 示例: + /// ```dart + /// EventBusUtil().on((event) { + /// print('用户登录:${event.userId}'); + /// }); + /// ``` + Stream on() { + return _eventBus.on(); + } + + /// 发送事件 + /// + /// 示例: + /// ```dart + /// EventBusUtil().fire(UserLoginEvent('123')); + /// ``` + void fire(T event) { + _eventBus.fire(event); + } + + /// 销毁 EventBus(一般不用调用,除非应用退出) + void destroy() { + _eventBus.destroy(); + } +} + +/// 快捷访问方式(可选) +EventBusUtil $eventBus = EventBusUtil(); diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 09af634..d1a3b16 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -4,6 +4,8 @@ import 'package:starwork_flutter/views/device/confirmPairDevice/confirm_pair_dev import 'package:starwork_flutter/views/device/confirmPairDevice/confirm_pair_device_view.dart'; import 'package:starwork_flutter/views/device/deviceManage/device_manage_binding.dart'; import 'package:starwork_flutter/views/device/deviceManage/device_manage_view.dart'; +import 'package:starwork_flutter/views/device/removeDevice/remove_device_binding.dart'; +import 'package:starwork_flutter/views/device/removeDevice/remove_device_view.dart'; import 'package:starwork_flutter/views/device/searchDevice/search_device_binding.dart'; import 'package:starwork_flutter/views/device/searchDevice/search_device_view.dart'; import 'package:starwork_flutter/views/home/home_binding.dart'; @@ -130,5 +132,10 @@ class AppPages { page: () => DeviceManageView(), binding: DeviceManageBinding(), ), + GetPage( + name: AppRoutes.deviceRemoveDevice, + page: () => RemoveDeviceView(), + binding: RemoveDeviceBinding(), + ), ]; } diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index eea4167..79aa67f 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -18,4 +18,5 @@ class AppRoutes{ static const String deviceManage = '/device/deviceManage'; static const String searchDevice = '/device/searchDevice'; static const String confirmPairDevice = '/device/confirmPairDevice'; + static const String deviceRemoveDevice = '/device/removeDevice'; } \ No newline at end of file diff --git a/lib/views/device/deviceManage/device_manage_controller.dart b/lib/views/device/deviceManage/device_manage_controller.dart index e1fe639..4a9bac8 100644 --- a/lib/views/device/deviceManage/device_manage_controller.dart +++ b/lib/views/device/deviceManage/device_manage_controller.dart @@ -1,12 +1,116 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:get/get_rx/get_rx.dart'; +import 'package:starcloud/entity/star_cloud_lock_list.dart'; +import 'package:starcloud/sdk/sdk_device_operate_extension.dart'; +import 'package:starcloud/sdk/starcloud.dart'; +import 'package:starwork_flutter/base/app_logger.dart'; +import 'package:starwork_flutter/base/base_controller.dart'; import 'package:starwork_flutter/common/constant/app_support_device_type.dart'; +import 'package:starwork_flutter/common/events/refresh_device_list_event.dart'; +import 'package:starwork_flutter/common/utils/event_bus_util.dart'; +import 'package:starwork_flutter/views/main/main_controller.dart'; + +class DeviceManageController extends BaseController with GetSingleTickerProviderStateMixin { + final mainController = Get.find(); -class DeviceManageController extends GetxController with GetSingleTickerProviderStateMixin { // 选中状态 0:全部状态 1:在线 2:离线 final RxInt selectedStatusIndex = 0.obs; // 选中设备类型 - final selectedDeviceType = AppSupportDeviceType.all.obs; + final selectedDeviceType = AppSupportDeviceType.lock.obs; + + // 设备列表管理 + final deviceList = [].obs; + + // 用于 UI 显示的过滤后列表 + final filteredDeviceList = [].obs; + + // 在线设备数量 + final onlineDeviceCount = 0.obs; + + // 离线设备数量 + final offlineDeviceCount = 0.obs; + + // 刷新设备列表事件留监听 + late StreamSubscription _refreshDeviceListSubscription; + + @override + void onInit() { + super.onInit(); + initData(); + + // 监听刷新设备列表事件 + _refreshDeviceListSubscription = EventBusUtil().instance.on().listen((event) async { + _requestTeamDeviceList(); + }); + } + + @override + void onClose() { + super.onClose(); + _refreshDeviceListSubscription.cancel(); + } + + void initData() async { + _requestTeamDeviceList(); + } + + /// 切换设备状态筛选 + void changeStatusFilter(int index) { + selectedStatusIndex.value = index; + _updateFilteredList(); + } + + /// 根据当前 selectedStatusIndex 过滤设备列表 + void _updateFilteredList() { + List filtered = []; + + switch (selectedStatusIndex.value) { + case 0: // 全部 + filtered = deviceList; + break; + case 1: // 在线 + filtered = deviceList.where((device) => device.isOnline == true).toList(); + break; + case 2: // 离线 + filtered = deviceList.where((device) => device.isOnline == false).toList(); + break; + default: + filtered = deviceList; + } + filteredDeviceList.assignAll(filtered); // 更新响应式列表 + } + + void _requestTeamDeviceList() async { + showLoading(); + await StarCloudSDK.instance.getDeviceList( + pageNo: 1, + pageSize: 999, + cloudUid: mainController.selectedTeam.value.teamCloudInfo!.uid!, + onSuccess: (StarCloudLockList list) { + filteredDeviceList.clear(); + deviceList.clear(); + for (var groupItem in list.groupList) { + for (var lock in groupItem.lockList) { + deviceList.add(lock); + if (lock.isOnline ?? false) { + onlineDeviceCount.value++; + } else { + offlineDeviceCount.value++; + } + } + } + // ✅ 加载完原始数据后,更新过滤列表 + _updateFilteredList(); + hideLoading(); + }, + onError: (err) { + AppLogger.error('获取设备列表失败:${err}'); + hideLoading(); + }, + ); + } } diff --git a/lib/views/device/deviceManage/device_manage_view.dart b/lib/views/device/deviceManage/device_manage_view.dart index ad14594..cea868c 100644 --- a/lib/views/device/deviceManage/device_manage_view.dart +++ b/lib/views/device/deviceManage/device_manage_view.dart @@ -5,8 +5,10 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:starwork_flutter/common/constant/app_colors.dart'; import 'package:starwork_flutter/common/constant/app_support_device_type.dart'; +import 'package:starwork_flutter/common/constant/app_view_parameter_keys.dart'; import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart'; import 'package:starwork_flutter/extension/function_extension.dart'; +import 'package:starwork_flutter/routes/app_routes.dart'; import 'package:starwork_flutter/views/device/deviceManage/device_manage_controller.dart'; class DeviceManageView extends GetView { @@ -35,7 +37,7 @@ class DeviceManageView extends GetView { horizontal: 10.w, vertical: 10.h, ), - decoration: BoxDecoration( + decoration: const BoxDecoration( color: Colors.white, ), child: Column( @@ -57,7 +59,9 @@ class DeviceManageView extends GetView { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextButton( - onPressed: () {}, + onPressed: () { + Get.toNamed(AppRoutes.searchDevice); + }, child: Text( '添加设备', style: TextStyle( @@ -68,7 +72,14 @@ class DeviceManageView extends GetView { ), ), TextButton( - onPressed: () {}, + onPressed: () { + Get.toNamed( + AppRoutes.deviceRemoveDevice, + arguments: { + AppViewParameterKeys.deviceList: controller.deviceList, + }, + ); + }, child: Text( '删除设备', style: TextStyle( @@ -79,7 +90,9 @@ class DeviceManageView extends GetView { ), ), TextButton( - onPressed: () {}, + onPressed: () { + controller.showFunctionNotOpen(); + }, child: Text( '更多管理', style: TextStyle( @@ -139,7 +152,7 @@ class DeviceManageView extends GetView { children: [ GestureDetector( onTap: () { - controller.selectedStatusIndex.value = 0; + controller.changeStatusFilter(0); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h), @@ -162,7 +175,7 @@ class DeviceManageView extends GetView { ), GestureDetector( onTap: () { - controller.selectedStatusIndex.value = 1; + controller.changeStatusFilter(1); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h), @@ -171,7 +184,7 @@ class DeviceManageView extends GetView { borderRadius: BorderRadius.circular(4.r), ), child: Text( - '在线(${1})'.tr, + '在线(${controller.onlineDeviceCount.value})'.tr, style: TextStyle( fontSize: 12.sp, color: controller.selectedStatusIndex == 1 ? Colors.white : Colors.grey[500], @@ -185,7 +198,7 @@ class DeviceManageView extends GetView { ), GestureDetector( onTap: () { - controller.selectedStatusIndex.value = 2; + controller.changeStatusFilter(2); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h), @@ -194,7 +207,7 @@ class DeviceManageView extends GetView { borderRadius: BorderRadius.circular(4.r), ), child: Text( - '离线(${1})'.tr, + '离线(${controller.offlineDeviceCount.value})'.tr, style: TextStyle( fontSize: 12.sp, color: controller.selectedStatusIndex == 2 ? Colors.white : Colors.grey[500], @@ -246,7 +259,7 @@ class DeviceManageView extends GetView { ), alignment: Alignment.center, child: Text( - '${deviceType.label}(${0})', + '${deviceType.label}(${controller.deviceList.length})', style: TextStyle( fontSize: 10.sp, color: Colors.black, @@ -262,78 +275,81 @@ class DeviceManageView extends GetView { } _buildRightDeviceList() { - return Container( - padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), - child: GridView.builder( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, // 每行两列 - crossAxisSpacing: 6.w, // 列间距 - mainAxisSpacing: 6.h, // 行间距 - childAspectRatio: 1.6, // 宽高比,可根据需要调整 - ), - itemCount: 100, - itemBuilder: (context, index) { - return Container( - width: double.infinity, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(8.r)), - ), - padding: EdgeInsets.symmetric( - horizontal: 10.w, - ), - alignment: Alignment.centerLeft, - child: Obx( - () => Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (controller.selectedDeviceType.value.iconImagePath != null) - Image( - image: AssetImage(controller.selectedDeviceType.value.iconImagePath!), - width: 26.w, - height: 26.w, - fit: BoxFit.contain, - gaplessPlayback: true, - // 防止闪烁 - filterQuality: FilterQuality.medium, - // 优化过滤质量 - errorBuilder: (context, error, stackTrace) { - return Icon( - Icons.image_not_supported, - size: 26.sp, - color: Colors.grey, - ); - }, - ), + return Obx( + () => Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, // 每行两列 + crossAxisSpacing: 6.w, // 列间距 + mainAxisSpacing: 6.h, // 行间距 + childAspectRatio: 1.6, // 宽高比,可根据需要调整 + ), + itemCount: controller.filteredDeviceList.length, + itemBuilder: (context, index) { + final lock = controller.filteredDeviceList[index]; + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(8.r)), + ), + padding: EdgeInsets.symmetric( + horizontal: 10.w, + ), + alignment: Alignment.centerLeft, + child: Obx( + () => Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (controller.selectedDeviceType.value.iconImagePath != null) + Image( + image: AssetImage(controller.selectedDeviceType.value.iconImagePath!), + width: 26.w, + height: 26.w, + fit: BoxFit.contain, + gaplessPlayback: true, + // 防止闪烁 + filterQuality: FilterQuality.medium, + // 优化过滤质量 + errorBuilder: (context, error, stackTrace) { + return Icon( + Icons.image_not_supported, + size: 26.sp, + color: Colors.grey, + ); + }, + ), SizedBox( height: 6.h, ), - Text( - 'TMH_5sdds5465a4sd5665$index', - style: TextStyle( - fontSize: 10.sp, - fontWeight: FontWeight.w400, + Text( + lock.lockName, + style: TextStyle( + fontSize: 10.sp, + fontWeight: FontWeight.w400, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - SizedBox( - height: 4.h, - ), - Text( - '在线', - style: TextStyle( - color: Colors.green, - fontSize: 10.sp, - fontWeight: FontWeight.w500, + SizedBox( + height: 4.h, ), - ) - ], + Text( + lock.isOnline ?? false ? '在线' : '离线', + style: TextStyle( + color: lock.isOnline ?? false ? Colors.green : Colors.grey, + fontSize: 10.sp, + fontWeight: FontWeight.w500, + ), + ) + ], + ), ), - ), - ); - }, + ); + }, + ), ), ); } diff --git a/lib/views/device/removeDevice/remove_device_binding.dart b/lib/views/device/removeDevice/remove_device_binding.dart new file mode 100644 index 0000000..d036eb8 --- /dev/null +++ b/lib/views/device/removeDevice/remove_device_binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; +import 'package:starwork_flutter/views/device/deviceManage/device_manage_controller.dart'; +import 'package:starwork_flutter/views/device/removeDevice/remove_device_controller.dart'; + +class RemoveDeviceBinding implements Bindings { + @override + void dependencies() { + Get.lazyPut(() => RemoveDeviceController()); + } +} diff --git a/lib/views/device/removeDevice/remove_device_controller.dart b/lib/views/device/removeDevice/remove_device_controller.dart new file mode 100644 index 0000000..670b30c --- /dev/null +++ b/lib/views/device/removeDevice/remove_device_controller.dart @@ -0,0 +1,104 @@ +import 'package:get/get.dart'; +import 'package:starcloud/entity/star_cloud_lock_list.dart'; +import 'package:starcloud/sdk/sdk_lock_operate_extension.dart'; +import 'package:starcloud/sdk/starcloud.dart'; +import 'package:starwork_flutter/base/app_logger.dart'; +import 'package:starwork_flutter/base/base_controller.dart'; +import 'package:starwork_flutter/common/constant/app_view_parameter_keys.dart'; +import 'package:starwork_flutter/common/events/refresh_device_list_event.dart'; +import 'package:starwork_flutter/common/utils/event_bus_util.dart'; +import 'package:starwork_flutter/views/main/main_controller.dart'; + +class RemoveDeviceController extends BaseController { + // 选中的设备 + RxList selectedDevices = [].obs; + RxList deviceList = [].obs; + final mainController = Get.find(); + final currentProgress = ''.obs; // 显示进度文本,如 "正在重置设备 1/3" + @override + void onInit() { + deviceList.value = (Get.arguments?[AppViewParameterKeys.deviceList] as List?) ?? []; + super.onInit(); + } + + // 判断某个设备是否被选中 + bool isSelected(StarCloudLock device) { + AppLogger.highlight('${selectedDevices.contains(device)}'); + return selectedDevices.contains(device); + } + + // 切换选中状态 + void toggleDevice(StarCloudLock device) { + if (isSelected(device)) { + selectedDevices.remove(device); + } else { + selectedDevices.add(device); + } + } + + // 全选 + void selectAll(List allDevices) { + selectedDevices.assignAll(allDevices); + } + + // 清空选择 + void clearSelection() { + selectedDevices.clear(); + } + + // 是否全选 + bool isAllSelected(List allDevices) { + return allDevices.isNotEmpty && selectedDevices.length == allDevices.length; + } + + // 删除设备 + void removeDevice(RxList selectedDevices) async { + showLoading(); + var teamInfo = mainController.selectedTeam.value; + var teamCloudInfo = teamInfo.teamCloudInfo; + + if (teamCloudInfo == null) { + showToast('没找到对应的星云账户信息'); + hideLoading(); + return; + } + + if (selectedDevices.isEmpty) { + showToast('没有选择要重置的设备'); + hideLoading(); + return; + } + + bool allSuccess = true; // 标记是否全部成功 + + for (int i = 0; i < selectedDevices.length; i++) { + final device = selectedDevices[i]; + + try { + await StarCloudSDK.instance.resetLock( + lockId: device.lockId, + cloudUid: teamCloudInfo.uid, + onSuccess: () { + // 可以在这里做点成功反馈(如打印日志) + }, + onError: (err) { + allSuccess = false; // 标记为非全成功 + }, + ); + } catch (e) { + allSuccess = false; + } + } + + // === 所有设备处理完成后判断 === + if (allSuccess) { + Future.delayed(1.seconds, () { + EventBusUtil().instance.fire(RefreshDeviceListEvent()); + Get.back(); + }); + } else { + Future.delayed(2.seconds, () {}); + } + hideLoading(); + } +} diff --git a/lib/views/device/removeDevice/remove_device_view.dart b/lib/views/device/removeDevice/remove_device_view.dart new file mode 100644 index 0000000..fa87a33 --- /dev/null +++ b/lib/views/device/removeDevice/remove_device_view.dart @@ -0,0 +1,159 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:starcloud/entity/star_cloud_lock_list.dart'; +import 'package:starwork_flutter/base/app_logger.dart'; +import 'package:starwork_flutter/common/constant/app_colors.dart'; +import 'package:starwork_flutter/common/constant/app_images.dart'; +import 'package:starwork_flutter/common/constant/app_view_parameter_keys.dart'; +import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart'; +import 'package:starwork_flutter/extension/function_extension.dart'; +import 'package:starwork_flutter/views/device/removeDevice/remove_device_controller.dart'; + +class RemoveDeviceView extends GetView { + const RemoveDeviceView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.scaffoldBackgroundColor, + appBar: CustomAppBarWidget( + title: '选择设备'.tr, + actions: [ + TextButton( + onPressed: () { + var allSelected = controller.isAllSelected(controller.deviceList); + if (allSelected) { + controller.clearSelection(); + } else { + controller.selectAll(controller.deviceList); + } + }, + child: Text( + '全选'.tr, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), + ), + ) + ], + ), + body: SafeArea( + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 10.h, + ), + child: Column( + children: [ + _buildDeviceList(), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () { + if (controller.selectedDevices.isEmpty) { + controller.showToast('请至少选中一个设备'); + } + controller.removeDevice(controller.selectedDevices); + }.debounce(), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue, + padding: EdgeInsets.symmetric(vertical: 12.h), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)), + ), + child: Text( + '删除'.tr, + style: TextStyle( + fontSize: 16.sp, + color: Colors.white, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ], + ), + ), + ), + ); + } + + _buildDeviceList() { + return Expanded( + child: ListView.builder( + itemCount: controller.deviceList.length, + itemBuilder: (context, index) { + final device = controller.deviceList[index]; + return GestureDetector( + onTap: () { + controller.toggleDevice(device); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10.h), + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 4.h, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.r), + ), + child: Row( + children: [ + Obx( + () => Checkbox( + value: controller.isSelected(device), // 动态判断是否选中 + shape: CircleBorder( + side: BorderSide(width: 0.4.w), + ), + activeColor: Colors.blue, + onChanged: (value) { + controller.toggleDevice(device); // 切换状态 + }, + ), + ), + Image( + image: const AssetImage(AppImages.iconLockTypeDoorLock), + width: 26.w, + height: 26.w, + fit: BoxFit.contain, + gaplessPlayback: true, + // 防止闪烁 + filterQuality: FilterQuality.medium, + // 优化过滤质量 + errorBuilder: (context, error, stackTrace) { + return Icon( + Icons.image_not_supported, + size: 26.sp, + color: Colors.grey, + ); + }, + ), + SizedBox( + width: 8.w, + ), + Expanded( + child: Text( + device.lockName, + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/views/device/searchDevice/search_device_controller.dart b/lib/views/device/searchDevice/search_device_controller.dart index a520aa7..15043c6 100644 --- a/lib/views/device/searchDevice/search_device_controller.dart +++ b/lib/views/device/searchDevice/search_device_controller.dart @@ -11,6 +11,8 @@ import 'package:starwork_flutter/base/app_permission.dart'; import 'package:starwork_flutter/base/base_controller.dart'; import 'package:starwork_flutter/common/constant/app_toast_messages.dart'; import 'package:starwork_flutter/common/constant/cache_keys.dart'; +import 'package:starwork_flutter/common/events/refresh_device_list_event.dart'; +import 'package:starwork_flutter/common/utils/event_bus_util.dart'; import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart'; class SearchDeviceController extends BaseController { @@ -35,6 +37,7 @@ class SearchDeviceController extends BaseController { void onClose() { StarCloudSDK.instance.stopScan(onError: (err) {}); isSearching.value = false; + deviceList.clear(); super.onClose(); } @@ -121,40 +124,17 @@ class SearchDeviceController extends BaseController { void connectingDevices(StarCloudScanResult device) async { showLoading(); try { - var cacheStarCloudUserName = await SharedPreferencesUtils.getString(CacheKeys.starCloudUserName); - var cacheStarCloudPassword = await SharedPreferencesUtils.getString(CacheKeys.starCloudPassword); - var cacheStarCloudUid = await SharedPreferencesUtils.getString(CacheKeys.starCloudUid); - if (cacheStarCloudUserName == null || cacheStarCloudPassword == null || cacheStarCloudUid == null) { - await StarCloudSDK.instance.createCloudUser( - onError: (err) { - AppLogger.error('err:${err}'); - hideLoading(); - }, - onSuccess: (userInfo) { - SharedPreferencesUtils.setString(CacheKeys.starCloudUserName, userInfo.username); - SharedPreferencesUtils.setString(CacheKeys.starCloudPassword, userInfo.password); - SharedPreferencesUtils.setString(CacheKeys.starCloudUid, userInfo.uid.toString()); - }, - ); - } - StarCloudSDK.instance.setCloudAccounts( - [ - CloudUserInfo( - username: cacheStarCloudUserName!, - password: cacheStarCloudPassword!, - uid: int.parse(cacheStarCloudUid!), - ) - ], - ); await StarCloudSDK.instance.pairDevice( onError: (err) { - AppLogger.error('err:${err}'); + AppLogger.error('连接设备时出现错误:${err}'); hideLoading(); }, onSuccess: (StarCloudLock lockInfo) { - AppLogger.highlight('lockInfo:${lockInfo.toString()}'); // 设备连接成功 showSuccess(message: '设备添加成功'.tr); + hideLoading(); + // 触发刷新设备列表 + EventBusUtil().instance.fire(RefreshDeviceListEvent()); Get.back(); }, scanResult: device, diff --git a/lib/views/home/home_controller.dart b/lib/views/home/home_controller.dart index 167bb40..40f25da 100644 --- a/lib/views/home/home_controller.dart +++ b/lib/views/home/home_controller.dart @@ -2,11 +2,16 @@ import 'package:carousel_slider/carousel_controller.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:starcloud/entity/star_cloud_lock_list.dart'; +import 'package:starcloud/sdk/sdk_device_operate_extension.dart'; +import 'package:starcloud/sdk/starcloud.dart'; import 'package:starwork_flutter/api/model/team/response/team_info_response.dart'; import 'package:starwork_flutter/api/service/team_api_service.dart'; import 'package:starwork_flutter/base/app_logger.dart'; import 'package:starwork_flutter/base/app_permission.dart'; import 'package:starwork_flutter/base/base_controller.dart'; +import 'package:starwork_flutter/common/events/refresh_device_list_event.dart'; +import 'package:starwork_flutter/common/utils/event_bus_util.dart'; import 'package:starwork_flutter/routes/app_routes.dart'; import 'package:starwork_flutter/views/main/main_controller.dart'; @@ -15,7 +20,6 @@ class HomeController extends BaseController { final isOpenNotificationPermission = false.obs; - var carouselCurrentIndex = 0.obs; // 渐变颜色列表 @@ -42,18 +46,14 @@ class HomeController extends BaseController { // 初始化数据 void _initializeData() async { - showLoading(); - - // 检查通知权限 isOpenNotificationPermission.value = await AppPermission.checkPermission( permission: Permission.notification, ); - hideLoading(); + // 触发刷新设备列表 + EventBusUtil().instance.fire(RefreshDeviceListEvent()); } - - // 根据轮播图索引更新渐变颜色 void updateGradientColor(int index) { if (index < gradientColors.length) { @@ -66,27 +66,8 @@ class HomeController extends BaseController { // 首页刷新方法 Future refreshHome() async { - // 显示加载状态(可选) - // isLoading.value = true; - // 模拟网络请求延迟 await Future.delayed(const Duration(seconds: 1)); - - // 这里可以添加实际的刷新逻辑,比如: - // 1. 重新获取轮播图数据 - // 2. 刷新统计数据 - // 3. 更新功能列表 - // 4. 刷新考勤图表数据 - // 5. 更新门禁列表 - - // 重新检查通知权限 - isOpenNotificationPermission.value = await AppPermission.checkPermission( - permission: Permission.notification, - ); - - // 隐藏加载状态 - // isLoading.value = false; - - print('首页数据刷新完成'); + _initializeData(); } } diff --git a/lib/views/home/home_view.dart b/lib/views/home/home_view.dart index 94d0f34..e1127df 100644 --- a/lib/views/home/home_view.dart +++ b/lib/views/home/home_view.dart @@ -232,12 +232,18 @@ class HomeView extends GetView { HomeCarouselAreaWidget( carouselCurrentIndex: controller.carouselCurrentIndex, ), - SizedBox(height: 10.h), - HomeNotDeviceArea(), + Visibility( + child: SizedBox(height: 10.h), + visible: controller.mainController.deviceCountSize.value == 0, + ), + Visibility( + visible: controller.mainController.deviceCountSize.value == 0, + child: HomeNotDeviceArea(), + ), HomeTeamNoticeRowWidget(), HomeStatisticsRowWidget( personCount: 0, - deviceCount: 0, + deviceCount: controller.mainController.deviceCountSize.value, ), SizedBox(height: 10.h), HomeFunctionListAreaWidget(), diff --git a/lib/views/home/widget/home_statistics_row_widget.dart b/lib/views/home/widget/home_statistics_row_widget.dart index 44b3b7e..3ec7628 100644 --- a/lib/views/home/widget/home_statistics_row_widget.dart +++ b/lib/views/home/widget/home_statistics_row_widget.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:starwork_flutter/routes/app_routes.dart'; class HomeStatisticsRowWidget extends StatelessWidget { final int personCount; @@ -47,80 +48,85 @@ class HomeStatisticsRowWidget extends StatelessWidget { }) { return Expanded( // 使用Expanded让卡片自适应宽度 - child: Container( - height: 62.h, - padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), - decoration: BoxDecoration( - color: backgroundColor, - borderRadius: BorderRadius.circular(8.r), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 1, - blurRadius: 4, - offset: const Offset(0, 2), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // 上半部分:数字 + 单位 + 管理按钮 - Row( - children: [ - // 数字和单位 - Row( - crossAxisAlignment: CrossAxisAlignment.baseline, - // 使用baseline对齐 - textBaseline: TextBaseline.alphabetic, - // 设置文本基线 - children: [ - Text( - count.toString(), - style: TextStyle( - fontSize: 20.sp, // text-5 - fontWeight: FontWeight.bold, - color: textColor, - ), - ), - Text( - unit, - style: TextStyle( - fontSize: 12.sp, // text-3 - color: textColor, - ), - ), - ], - ), - const Spacer(), - // 管理按钮 - Container( - padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 4.h), - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.5), - borderRadius: BorderRadius.circular(4.r), - ), - child: Text( - buttonText, - style: TextStyle( - fontSize: 10.sp, // text-2.5 - fontWeight: FontWeight.w600, - color: textColor, - ), - ), - ), - ], - ), - SizedBox(height: 4.h), // mt-1 - // 下半部分:标签 - Text( - label, - style: TextStyle( - fontSize: 10.sp, // text-2.5 - color: textColor, + child: GestureDetector( + onTap: (){ + Get.toNamed(AppRoutes.deviceManage); + }, + child: Container( + height: 62.h, + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(8.r), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 4, + offset: const Offset(0, 2), ), - ), - ], + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 上半部分:数字 + 单位 + 管理按钮 + Row( + children: [ + // 数字和单位 + Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + // 使用baseline对齐 + textBaseline: TextBaseline.alphabetic, + // 设置文本基线 + children: [ + Text( + count.toString(), + style: TextStyle( + fontSize: 20.sp, // text-5 + fontWeight: FontWeight.bold, + color: textColor, + ), + ), + Text( + unit, + style: TextStyle( + fontSize: 12.sp, // text-3 + color: textColor, + ), + ), + ], + ), + const Spacer(), + // 管理按钮 + Container( + padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 4.h), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.5), + borderRadius: BorderRadius.circular(4.r), + ), + child: Text( + buttonText, + style: TextStyle( + fontSize: 10.sp, // text-2.5 + fontWeight: FontWeight.w600, + color: textColor, + ), + ), + ), + ], + ), + SizedBox(height: 4.h), // mt-1 + // 下半部分:标签 + Text( + label, + style: TextStyle( + fontSize: 10.sp, // text-2.5 + color: textColor, + ), + ), + ], + ), ), ), ); diff --git a/lib/views/main/main_controller.dart b/lib/views/main/main_controller.dart index 45931b8..3fd0ced 100644 --- a/lib/views/main/main_controller.dart +++ b/lib/views/main/main_controller.dart @@ -4,14 +4,19 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:starcloud/entity/star_cloud_lock_list.dart'; import 'package:starcloud/sdk/entity/cloud_user_info.dart'; +import 'package:starcloud/sdk/sdk_device_operate_extension.dart'; import 'package:starcloud/sdk/starcloud.dart'; +import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart'; import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart'; import 'package:starwork_flutter/api/model/team/response/team_info_response.dart'; import 'package:starwork_flutter/api/service/team_api_service.dart'; import 'package:starwork_flutter/base/app_logger.dart'; import 'package:starwork_flutter/base/base_controller.dart'; import 'package:starwork_flutter/common/constant/app_images.dart'; +import 'package:starwork_flutter/common/events/refresh_device_list_event.dart'; +import 'package:starwork_flutter/common/utils/event_bus_util.dart'; import 'package:starwork_flutter/routes/app_routes.dart'; import 'package:starwork_flutter/views/home/home_controller.dart'; import 'package:starwork_flutter/views/home/home_view.dart'; @@ -39,11 +44,32 @@ class MainController extends BaseController { // 选中的团队 var selectedTeam = TeamInfoResponse().obs; + // 设备数量 + final deviceCountSize = 0.obs; + + // 团队数量 + final teamCountSize = 0.obs; + + // 刷新设备列表事件留监听 + late StreamSubscription _refreshDeviceListSubscription; + @override void onInit() { + super.onInit(); + /// 请求团队信息 requestAllTeamInfoList(); - super.onInit(); + + // 监听刷新设备列表事件 + _refreshDeviceListSubscription = EventBusUtil().instance.on().listen((event) { + _requestTeamDeviceList(); + }); + } + + @override + void onClose() { + super.onClose(); + _refreshDeviceListSubscription.cancel(); } // 更新索引 @@ -115,13 +141,27 @@ class MainController extends BaseController { if (myTeamList.isEmpty) { // 如果是空的则自动创建并跳转到团队使用场景页面 Get.toNamed(AppRoutes.teamUseCaseSetting); + return; } selectedTeam.value = myTeamList.first; + + // 设置星云账户 + if (selectedTeam.value.teamCloudInfo != null) { + StarCloudSDK.instance.setCloudAccounts([ + CloudUserInfo( + username: selectedTeam.value.teamCloudInfo!.username!, + password: selectedTeam.value.teamCloudInfo!.password!, + uid: selectedTeam.value.teamCloudInfo!.uid!, + ) + ]); + _requestTeamDeviceList(); + } } } /// 切换当前团队 void requestChangeCurrentTeam(TeamInfoResponse teamInfo) async { + if (teamInfo.teamNo == selectedTeam.value.teamNo) return; var teamNo = teamInfo.teamNo; if (teamNo == null) { return; @@ -132,19 +172,58 @@ class MainController extends BaseController { ), ); if (changeCurrentTeamResponse.isSuccess) { - AppLogger.highlight('切换当前团队成功'); selectedTeam.value = teamInfo; - // 如果teamInfo中的cloudInfo不为空,则设置云账号 - if (teamInfo.cloudInfo != null) { + if (teamInfo.teamCloudInfo != null) { StarCloudSDK.instance.setCloudAccounts([ CloudUserInfo( - username: teamInfo.cloudInfo!.username!, - password: teamInfo.cloudInfo!.password!, - uid: teamInfo.cloudInfo!.uid!, + username: teamInfo.teamCloudInfo!.username!, + password: teamInfo.teamCloudInfo!.password!, + uid: teamInfo.teamCloudInfo!.uid!, ) ]); + _requestTeamDeviceList(); + } else { + // 如果是空的就申请新的云账户进行绑定 + StarCloudSDK.instance.createCloudUser( + onSuccess: (CloudUserInfo userInfo) async { + var teamStarCloudAccountResponse = await teamApi.requestBindTeamStarCloudAccount( + request: BindTeamStarCloudAccountRequest( + teamNo: teamNo, + username: userInfo.username, + password: userInfo.password, + teamId: teamInfo.id!, + cloudUid: userInfo.uid, + ), + ); + if (teamStarCloudAccountResponse.isSuccess) { + StarCloudSDK.instance.setCloudAccounts([ + CloudUserInfo( + username: userInfo.username, + password: userInfo.password, + uid: userInfo.uid, + ) + ]); + _requestTeamDeviceList(); + } + }, + onError: (err) {}, + ); } } } + + void _requestTeamDeviceList() async { + await StarCloudSDK.instance.getDeviceList( + pageNo: 1, + pageSize: 999, + cloudUid: selectedTeam.value.teamCloudInfo!.uid!, + onSuccess: (StarCloudLockList list) { + deviceCountSize.value = list.total; + }, + onError: (err) { + AppLogger.error('获取设备列表失败:${err}'); + }, + ); + } } diff --git a/lib/views/team/createTeam/create_team_controller.dart b/lib/views/team/createTeam/create_team_controller.dart index 51241da..1715df8 100644 --- a/lib/views/team/createTeam/create_team_controller.dart +++ b/lib/views/team/createTeam/create_team_controller.dart @@ -1,8 +1,12 @@ import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; +import 'package:starcloud/sdk/entity/cloud_user_info.dart'; +import 'package:starcloud/sdk/starcloud.dart'; +import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart'; import 'package:starwork_flutter/api/model/team/request/create_team_request.dart'; import 'package:starwork_flutter/api/model/team/response/scene_info_response.dart'; import 'package:starwork_flutter/api/service/team_api_service.dart'; +import 'package:starwork_flutter/base/app_logger.dart'; import 'package:starwork_flutter/base/base_controller.dart'; class CreateTeamController extends BaseController { @@ -35,21 +39,46 @@ class CreateTeamController extends BaseController { } void requestCreateTeam() async { - showLoading(); - var createTeamResponse = await teamApi.requestCreateTeam( - request: CreateTeamRequest( - teamName: teamNameInputController.text, - scene: selectedUseCase.value?.id ?? 0, - ), + // 先注册星云用户 + await StarCloudSDK.instance.createCloudUser( + onSuccess: (CloudUserInfo userInfo) async { + // 创建团队 + var createTeamResponse = await teamApi.requestCreateTeam( + request: CreateTeamRequest( + teamName: teamNameInputController.text, + scene: selectedUseCase.value?.id ?? 0, + ), + ); + if (createTeamResponse.isSuccess) { + var teamNo = createTeamResponse.data?.teamNo; + var teamId = createTeamResponse.data?.teamId; + var username = userInfo.username; + var cloudUid = userInfo.uid; + var password = userInfo.password; + if (teamNo != null && teamId != null) { + var bindTeamStarCloudAccountResponse = await teamApi.requestBindTeamStarCloudAccount( + request: BindTeamStarCloudAccountRequest( + teamId: teamId, + teamNo: teamNo, + username: username, + cloudUid: cloudUid, + password: password, + ), + ); + AppLogger.highlight('bindTeamStarCloudAccountResponse:${bindTeamStarCloudAccountResponse.toString()}'); + if (bindTeamStarCloudAccountResponse.isSuccess) { + // 创建成功,使用 Get.back(result: true) 返回并传递结果 + showSuccess(); + // 返回添加成功结果 + Get.back(result: {'created': true}); + } + } + } else { + // 创建失败 + showError(message: createTeamResponse.errorMsg!); + } + }, + onError: (err) {}, ); - if (createTeamResponse.isSuccess) { - // 创建成功,使用 Get.back(result: true) 返回并传递结果 - showSuccess(); - // 返回添加成功结果 - Get.back(result: {'created': true}); - } else { - // 创建失败 - showError(message: createTeamResponse.errorMsg!); - } } } diff --git a/lib/views/team/useCaseSetting/use_case_setting_controller.dart b/lib/views/team/useCaseSetting/use_case_setting_controller.dart index 4908798..a06bef2 100644 --- a/lib/views/team/useCaseSetting/use_case_setting_controller.dart +++ b/lib/views/team/useCaseSetting/use_case_setting_controller.dart @@ -2,6 +2,7 @@ import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:starcloud/sdk/entity/cloud_user_info.dart'; import 'package:starcloud/sdk/starcloud.dart'; +import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart'; import 'package:starwork_flutter/api/model/team/request/create_team_request.dart'; import 'package:starwork_flutter/api/model/team/response/scene_info_response.dart'; import 'package:starwork_flutter/api/service/team_api_service.dart'; @@ -39,46 +40,46 @@ class UseCaseSettingController extends BaseController { } void requestCreateTeam() async { - var cacheStarCloudUserName = await SharedPreferencesUtils.getString(CacheKeys.starCloudUserName); - var cacheStarCloudPassword = await SharedPreferencesUtils.getString(CacheKeys.starCloudPassword); - var cacheStarCloudUid = await SharedPreferencesUtils.getString(CacheKeys.starCloudUid); - if (cacheStarCloudUserName == null || cacheStarCloudPassword == null || cacheStarCloudUid == null) { - await StarCloudSDK.instance.createCloudUser( - onError: (err) { - AppLogger.error('err:${err}'); - hideLoading(); - }, - onSuccess: (userInfo) { - SharedPreferencesUtils.setString(CacheKeys.starCloudUserName, userInfo.username); - SharedPreferencesUtils.setString(CacheKeys.starCloudPassword, userInfo.password); - SharedPreferencesUtils.setString(CacheKeys.starCloudUid, userInfo.uid.toString()); - }, - ); - } - StarCloudSDK.instance.setCloudAccounts( - [ - CloudUserInfo( - username: cacheStarCloudUserName!, - password: cacheStarCloudPassword!, - uid: int.parse(cacheStarCloudUid!), - ) - ], + // 先注册星云用户 + await StarCloudSDK.instance.createCloudUser( + onSuccess: (CloudUserInfo userInfo) async { + // 创建团队 + var createTeamResponse = await teamApi.requestCreateTeam( + request: CreateTeamRequest( + teamName: teamNameInputController.text, + scene: selectedUseCase.value?.id ?? 0, + ), + ); + if (createTeamResponse.isSuccess) { + var teamNo = createTeamResponse.data?.teamNo; + var teamId = createTeamResponse.data?.teamId; + var username = userInfo.username; + var cloudUid = userInfo.uid; + var password = userInfo.password; + if (teamNo != null && teamId != null) { + var bindTeamStarCloudAccountResponse = await teamApi.requestBindTeamStarCloudAccount( + request: BindTeamStarCloudAccountRequest( + teamId: teamId, + teamNo: teamNo, + username: username, + cloudUid: cloudUid, + password: password, + ), + ); + if (bindTeamStarCloudAccountResponse.isSuccess) { + // 创建成功,使用 Get.back(result: true) 返回并传递结果 + showSuccess(); + // 返回添加成功结果 + Get.back(result: {'created': true}); + } + } + } else { + // 创建失败 + showError(message: createTeamResponse.errorMsg!); + } + }, + onError: (err) {}, ); - - var createTeamResponse = await teamApi.requestCreateTeam( - request: CreateTeamRequest( - teamName: teamNameInputController.text, - scene: selectedUseCase.value?.id ?? 0, - ), - ); - if (createTeamResponse.isSuccess) { - // 创建成功 - showSuccess(); - Get.back(); - } else { - // 创建失败 - showError(message: createTeamResponse.errorMsg!); - } } /// 基于时间戳生成一个9位随机数 diff --git a/pubspec.lock b/pubspec.lock index 193b029..1e85ffa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -121,6 +121,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" + event_bus: + dependency: "direct main" + description: + name: event_bus + sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.1" fake_async: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1db2bc5..5d714b2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,8 @@ dependencies: carousel_slider: ^5.1.1 # 气泡提示框 super_tooltip: ^2.0.8 + # 事件总线 + event_bus: ^2.0.1 # 星云sdk starcloud: path: ../starcloud-sdk-flutter