2025-09-11 14:13:25 +08:00
|
|
|
|
import 'dart:async';
|
2025-09-29 17:11:08 +08:00
|
|
|
|
import 'dart:convert';
|
2025-09-11 14:13:25 +08:00
|
|
|
|
|
2025-08-27 18:20:37 +08:00
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
import 'package:flutter/widgets.dart';
|
2025-09-03 14:09:32 +08:00
|
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
2025-08-27 18:20:37 +08:00
|
|
|
|
import 'package:get/get.dart';
|
2025-09-15 16:00:10 +08:00
|
|
|
|
import 'package:starcloud/entity/star_cloud_lock_list.dart';
|
2025-09-12 15:25:36 +08:00
|
|
|
|
import 'package:starcloud/sdk/entity/cloud_user_info.dart';
|
2025-09-15 16:00:10 +08:00
|
|
|
|
import 'package:starcloud/sdk/sdk_device_operate_extension.dart';
|
2025-09-12 15:25:36 +08:00
|
|
|
|
import 'package:starcloud/sdk/starcloud.dart';
|
2025-09-15 16:00:10 +08:00
|
|
|
|
import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart';
|
2025-09-12 10:35:07 +08:00
|
|
|
|
import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart';
|
2025-10-10 09:40:14 +08:00
|
|
|
|
import 'package:starwork_flutter/api/model/team/response/team_details_response.dart';
|
2025-09-11 14:13:25 +08:00
|
|
|
|
import 'package:starwork_flutter/api/model/team/response/team_info_response.dart';
|
2025-09-29 17:11:08 +08:00
|
|
|
|
import 'package:starwork_flutter/api/model/user/response/user_info_response.dart';
|
2025-09-11 14:13:25 +08:00
|
|
|
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
2025-09-29 17:11:08 +08:00
|
|
|
|
import 'package:starwork_flutter/api/service/user_api_service.dart';
|
2025-09-12 10:35:07 +08:00
|
|
|
|
import 'package:starwork_flutter/base/app_logger.dart';
|
2025-08-27 18:20:37 +08:00
|
|
|
|
import 'package:starwork_flutter/base/base_controller.dart';
|
2025-09-03 14:09:32 +08:00
|
|
|
|
import 'package:starwork_flutter/common/constant/app_images.dart';
|
2025-09-29 17:11:08 +08:00
|
|
|
|
import 'package:starwork_flutter/common/constant/cache_keys.dart';
|
2025-09-15 16:00:10 +08:00
|
|
|
|
import 'package:starwork_flutter/common/events/refresh_device_list_event.dart';
|
|
|
|
|
|
import 'package:starwork_flutter/common/utils/event_bus_util.dart';
|
2025-09-29 17:11:08 +08:00
|
|
|
|
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
|
2025-09-11 14:13:25 +08:00
|
|
|
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
|
|
|
|
|
import 'package:starwork_flutter/views/home/home_controller.dart';
|
2025-08-27 18:20:37 +08:00
|
|
|
|
import 'package:starwork_flutter/views/home/home_view.dart';
|
|
|
|
|
|
import 'package:starwork_flutter/views/messages/messages_view.dart';
|
|
|
|
|
|
import 'package:starwork_flutter/views/mine/mine_view.dart';
|
|
|
|
|
|
|
|
|
|
|
|
class MainController extends BaseController {
|
2025-09-11 14:13:25 +08:00
|
|
|
|
final teamApi = Get.find<TeamApiService>();
|
2025-09-29 17:11:08 +08:00
|
|
|
|
final userApi = Get.find<UserApiService>();
|
2025-09-11 14:13:25 +08:00
|
|
|
|
|
|
|
|
|
|
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
2025-08-27 18:20:37 +08:00
|
|
|
|
|
|
|
|
|
|
// 当前选中的索引
|
|
|
|
|
|
var currentIndex = 0.obs;
|
|
|
|
|
|
|
|
|
|
|
|
// 页面列表
|
|
|
|
|
|
final pages = [
|
|
|
|
|
|
HomeView(),
|
|
|
|
|
|
MessagesView(),
|
|
|
|
|
|
MineView(),
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2025-09-11 14:13:25 +08:00
|
|
|
|
// 我的团队列表
|
|
|
|
|
|
final myTeamList = <TeamInfoResponse>[].obs;
|
|
|
|
|
|
|
|
|
|
|
|
// 选中的团队
|
|
|
|
|
|
var selectedTeam = TeamInfoResponse().obs;
|
|
|
|
|
|
|
2025-10-10 09:40:14 +08:00
|
|
|
|
// 选中团队的详情
|
|
|
|
|
|
var selectedTeamDetails = TeamDetailsResponse().obs;
|
|
|
|
|
|
|
2025-09-15 16:00:10 +08:00
|
|
|
|
// 设备数量
|
|
|
|
|
|
final deviceCountSize = 0.obs;
|
|
|
|
|
|
|
|
|
|
|
|
// 团队数量
|
|
|
|
|
|
final teamCountSize = 0.obs;
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新设备列表事件留监听
|
|
|
|
|
|
late StreamSubscription _refreshDeviceListSubscription;
|
|
|
|
|
|
|
2025-09-11 14:13:25 +08:00
|
|
|
|
@override
|
2025-10-14 13:53:01 +08:00
|
|
|
|
void onInit() {
|
2025-09-15 16:00:10 +08:00
|
|
|
|
|
2025-09-11 14:13:25 +08:00
|
|
|
|
/// 请求团队信息
|
|
|
|
|
|
requestAllTeamInfoList();
|
2025-09-15 16:00:10 +08:00
|
|
|
|
|
2025-09-17 14:31:59 +08:00
|
|
|
|
/// 请求设备列表
|
|
|
|
|
|
_requestTeamDeviceList();
|
2025-09-29 17:11:08 +08:00
|
|
|
|
|
|
|
|
|
|
/// 请求账户信息
|
|
|
|
|
|
requestUserAccountInfo();
|
2025-10-14 13:53:01 +08:00
|
|
|
|
super.onInit();
|
|
|
|
|
|
|
2025-09-15 16:00:10 +08:00
|
|
|
|
// 监听刷新设备列表事件
|
|
|
|
|
|
_refreshDeviceListSubscription = EventBusUtil().instance.on<RefreshDeviceListEvent>().listen((event) {
|
|
|
|
|
|
_requestTeamDeviceList();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
void onClose() {
|
|
|
|
|
|
super.onClose();
|
|
|
|
|
|
_refreshDeviceListSubscription.cancel();
|
2025-09-11 14:13:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 18:20:37 +08:00
|
|
|
|
// 更新索引
|
|
|
|
|
|
void changeIndex(int index) {
|
|
|
|
|
|
currentIndex.value = index;
|
|
|
|
|
|
}
|
2025-09-03 14:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
// 定义底部导航的标题和图标
|
|
|
|
|
|
List<BottomNavigationBarItem> get bottomNavItems => [
|
|
|
|
|
|
BottomNavigationBarItem(
|
|
|
|
|
|
icon: _buildTabIcon(AppImages.iconHome, AppImages.iconHomeSelected, 0),
|
|
|
|
|
|
label: '首页',
|
|
|
|
|
|
),
|
|
|
|
|
|
BottomNavigationBarItem(
|
|
|
|
|
|
icon: _buildTabIcon(AppImages.iconNotification, AppImages.iconNotificationSelected, 1),
|
|
|
|
|
|
label: '消息',
|
|
|
|
|
|
),
|
|
|
|
|
|
BottomNavigationBarItem(
|
|
|
|
|
|
icon: _buildTabIcon(AppImages.iconMine, AppImages.iconMineSelected, 2),
|
|
|
|
|
|
label: '我的',
|
|
|
|
|
|
),
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 构建自定义图标组件
|
|
|
|
|
|
Widget _buildTabIcon(String unselectedIcon, String selectedIcon, int index) {
|
2025-10-10 09:40:14 +08:00
|
|
|
|
return Obx(
|
|
|
|
|
|
() => Image.asset(
|
|
|
|
|
|
currentIndex.value == index ? selectedIcon : unselectedIcon,
|
|
|
|
|
|
width: 24.w,
|
|
|
|
|
|
height: 24.w,
|
|
|
|
|
|
fit: BoxFit.contain,
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
2025-09-03 14:09:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打开抽屉的方法
|
|
|
|
|
|
void openDrawer() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
final scaffoldState = scaffoldKey.currentState;
|
|
|
|
|
|
if (scaffoldState != null && scaffoldState.hasDrawer) {
|
|
|
|
|
|
scaffoldState.openDrawer();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print('Cannot open drawer: Scaffold state is null or has no drawer');
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
print('Error opening drawer: $e');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭抽屉的方法
|
|
|
|
|
|
void closeDrawer() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
final scaffoldState = scaffoldKey.currentState;
|
|
|
|
|
|
if (scaffoldState != null && scaffoldState.isDrawerOpen) {
|
|
|
|
|
|
scaffoldState.closeDrawer();
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
print('Error closing drawer: $e');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-11 14:13:25 +08:00
|
|
|
|
|
|
|
|
|
|
/// 请求团队信息
|
|
|
|
|
|
void requestAllTeamInfoList() async {
|
|
|
|
|
|
var teamList = await teamApi.requestAllTeamInfoList();
|
|
|
|
|
|
if (teamList.isSuccess) {
|
|
|
|
|
|
// 我的团队信息
|
|
|
|
|
|
myTeamList.value = teamList.data?.myTeam ?? [];
|
|
|
|
|
|
myTeamList.refresh();
|
|
|
|
|
|
// 待加入团队信息
|
|
|
|
|
|
List<TeamInfoResponse> pendTeamList = teamList.data?.pendTeam ?? [];
|
|
|
|
|
|
if (myTeamList.isEmpty) {
|
|
|
|
|
|
// 如果是空的则自动创建并跳转到团队使用场景页面
|
|
|
|
|
|
Get.toNamed(AppRoutes.teamUseCaseSetting);
|
2025-09-15 16:00:10 +08:00
|
|
|
|
return;
|
2025-09-11 14:13:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
selectedTeam.value = myTeamList.first;
|
2025-10-10 09:40:14 +08:00
|
|
|
|
await requestTeamDetail();
|
2025-09-15 16:00:10 +08:00
|
|
|
|
|
|
|
|
|
|
// 设置星云账户
|
|
|
|
|
|
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();
|
|
|
|
|
|
}
|
2025-09-11 14:13:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-12 10:35:07 +08:00
|
|
|
|
|
|
|
|
|
|
/// 切换当前团队
|
|
|
|
|
|
void requestChangeCurrentTeam(TeamInfoResponse teamInfo) async {
|
2025-09-15 16:00:10 +08:00
|
|
|
|
if (teamInfo.teamNo == selectedTeam.value.teamNo) return;
|
2025-09-12 10:35:07 +08:00
|
|
|
|
var teamNo = teamInfo.teamNo;
|
|
|
|
|
|
if (teamNo == null) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
var changeCurrentTeamResponse = await teamApi.requestChangeCurrentTeam(
|
|
|
|
|
|
request: ChangeCurrentTeamRequest(
|
|
|
|
|
|
teamNo: teamNo,
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
if (changeCurrentTeamResponse.isSuccess) {
|
|
|
|
|
|
selectedTeam.value = teamInfo;
|
2025-09-12 15:25:36 +08:00
|
|
|
|
// 如果teamInfo中的cloudInfo不为空,则设置云账号
|
2025-09-15 16:00:10 +08:00
|
|
|
|
if (teamInfo.teamCloudInfo != null) {
|
2025-09-12 15:25:36 +08:00
|
|
|
|
StarCloudSDK.instance.setCloudAccounts([
|
|
|
|
|
|
CloudUserInfo(
|
2025-09-15 16:00:10 +08:00
|
|
|
|
username: teamInfo.teamCloudInfo!.username!,
|
|
|
|
|
|
password: teamInfo.teamCloudInfo!.password!,
|
|
|
|
|
|
uid: teamInfo.teamCloudInfo!.uid!,
|
2025-09-12 15:25:36 +08:00
|
|
|
|
)
|
|
|
|
|
|
]);
|
2025-09-15 16:00:10 +08:00
|
|
|
|
_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) {},
|
|
|
|
|
|
);
|
2025-09-12 15:25:36 +08:00
|
|
|
|
}
|
2025-10-10 09:40:14 +08:00
|
|
|
|
|
|
|
|
|
|
// 请求切换团队后的详情数据
|
|
|
|
|
|
await requestTeamDetail();
|
2025-09-12 10:35:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-15 16:00:10 +08:00
|
|
|
|
|
|
|
|
|
|
void _requestTeamDeviceList() async {
|
2025-09-19 15:05:08 +08:00
|
|
|
|
if (selectedTeam.value.teamCloudInfo == null) return;
|
2025-09-15 18:16:35 +08:00
|
|
|
|
showLoading();
|
2025-09-15 16:00:10 +08:00
|
|
|
|
await StarCloudSDK.instance.getDeviceList(
|
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
|
pageSize: 999,
|
|
|
|
|
|
cloudUid: selectedTeam.value.teamCloudInfo!.uid!,
|
|
|
|
|
|
onSuccess: (StarCloudLockList list) {
|
|
|
|
|
|
deviceCountSize.value = list.total;
|
2025-09-15 18:16:35 +08:00
|
|
|
|
hideLoading();
|
2025-09-15 16:00:10 +08:00
|
|
|
|
},
|
|
|
|
|
|
onError: (err) {
|
|
|
|
|
|
AppLogger.error('获取设备列表失败:${err}');
|
2025-09-15 18:16:35 +08:00
|
|
|
|
hideLoading();
|
2025-09-15 16:00:10 +08:00
|
|
|
|
},
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2025-09-29 17:11:08 +08:00
|
|
|
|
|
|
|
|
|
|
void requestUserAccountInfo() async {
|
|
|
|
|
|
var userInfo = await userApi.requestUserInfo();
|
|
|
|
|
|
if (userInfo.isSuccess) {
|
|
|
|
|
|
await SharedPreferencesUtils.setString(CacheKeys.userAccountInfo, jsonEncode(userInfo.data!.toJson()));
|
|
|
|
|
|
// 从缓存中读取
|
|
|
|
|
|
// String? cachedJson = await SharedPreferencesUtils.getString(CacheKeys.userAccountInfo);
|
|
|
|
|
|
// if (cachedJson != null) {
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// Map<String, dynamic> jsonMap = jsonDecode(cachedJson);
|
|
|
|
|
|
// UserInfoResponse userInfoResponse = UserInfoResponse.fromJson(jsonMap);
|
|
|
|
|
|
// } catch (e) {
|
|
|
|
|
|
// AppLogger.error('JSON 解析错误: $e');
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-10 09:40:14 +08:00
|
|
|
|
|
|
|
|
|
|
requestTeamDetail() async {
|
|
|
|
|
|
var response = await teamApi.requestTeamDetails();
|
|
|
|
|
|
if (response.isSuccess) {
|
|
|
|
|
|
selectedTeamDetails.value = response.data!;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-27 18:20:37 +08:00
|
|
|
|
}
|