import 'package:EasyDartModule/EasyDartModule.dart' as edm; import 'package:easydevice/easydevice.dart'; import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/util/DailyLogUtils.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; import 'package:vbvs_app/controller/device/body_device_controller.dart'; import 'package:vbvs_app/controller/home/home_controller.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/model/BleDeviceData.dart'; import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/pages/device_bind/blueteeth_device_page.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; class SingleBlueteethDeviceCompoentWidget extends StatefulWidget { final bleDevice; const SingleBlueteethDeviceCompoentWidget({ super.key, required this.bleDevice, }); @override State createState() => _SingleBlueteethDeviceCompoentWidgetState(); } class _SingleBlueteethDeviceCompoentWidgetState extends State { ThemeController themeController = Get.find(); BlueteethBindController blueteethBindController = Get.find(); var lisObj; @override Widget build(BuildContext context) { List rawData = widget.bleDevice.advertisementData.manufacturerData[0xFFED]!; BleDeviceData deviceData = parseBleData(rawData); deviceData.name = widget.bleDevice.advertisementData.advName; deviceData.rssi = widget.bleDevice.rssi; deviceData.mac = deviceData.deviceId.replaceAll(':', ''); BleDeviceData device = deviceData; // blueteethBindController.currentDeviceMac = device.mac; final match = blueteethBindController.model.betDevicelist! .firstWhereOrNull((d) => d.mac == device.mac); if (match == null) { return Container(); } device = match; if (device.slave == null) { return ClickableContainer( backgroundColor: themeController.currentColor.sc5, highlightColor: themeController.currentColor.sc21, borderRadius: 20.rpx, padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 36.rpx, 0, 52.rpx), onTap: () async { try { //1.先判斷当前是否有别的设备处于连接中,没有处于连接,判断是否绑定; //2.如果没有绑定,直接连接;如果绑定,弹出提示框,提示是否解绑; if (blueteethBindController.currentDeviceMac?.value != null && blueteethBindController.currentDeviceMac!.value.isNotEmpty) { if (blueteethBindController.currentDeviceMac?.value != device.mac) { showConfirmDialog( context, Container(), "其他设备正在绑定中,是否终止其他设备绑定?".tr, onConfirm: () { blueteethBindController.currentDeviceMac.value = ""; blueteethBindController.updateAll(); }, onCancel: () {}); } } else { blueteethBindController.currentDeviceMac?.value = device.mac!; blueteethBindController.updateAll(); } if (device.bind == true) { await showHaveBindDialog(context); blueteethBindController.currentDeviceMac.value = ""; blueteethBindController.updateAll(); } else { showConfirmDialog( context, Container(), '蓝牙绑定.确定绑定提示'.tr, onConfirm: () async { ApiResponse response = await blueteethBindController.bindDeviceAndMAC(device); TopSlideNotification.show(context, text: response.msg!); if (response.code == HttpStatusCodes.ok) { //更新设备绑定流程 updateDeviceBindStatus(device); if (AppConstants.is_test_account) { BlueteethBindController blueteethBindController = Get.find(); if (blueteethBindController.returnPage == 0) { HomeController homeController = Get.find(); BodyDeviceController deviceController = Get.find(); if (true) { homeController.getSleepReport(); deviceController .getDeviceNum() .then((apiResponse) { if (apiResponse.code != HttpStatusCodes.ok) {} }); deviceController .getDeviceList() .then((apiResponse) { if (apiResponse.code != HttpStatusCodes.ok) { } else { //请求睡眠报告 deviceController.getSleepReport(); } }); } Get.until((route) => Get.currentRoute == "/mianPageBottomChange"); } else { // Get.offNamed("/bodyDevice"); // Get.offNamedUntil(page, predicate); Get.until( (route) => Get.currentRoute == "/bodyDevice"); } } else { Get.toNamed("/wifiPage"); THapp bledevice = THapp(device: widget.bleDevice.device); blueteethBindController.currentDevice = bledevice; } // blueteethBindController.currentDeviceMac.value = ""; } else { blueteethBindController.currentDeviceMac.value = ""; blueteethBindController.updateAll(); TopSlideNotification.show( context, text: response.msg ?? "蓝牙绑定.连接异常".tr, textColor: themeController.currentColor.sc9, ); } }, onCancel: () { print('用户点击了取消'); blueteethBindController.currentDeviceMac.value = ""; blueteethBindController.updateAll(); }, ); } } catch (e) { Navigator.pop(context); TopSlideNotification.show( context, text: "蓝牙绑定.连接异常".tr, textColor: themeController.currentColor.sc9, ); edm.EasyDartModule.logger.info("蓝牙绑定.连接异常: $e"); DailyLogUtils.writeLog("蓝牙绑定.连接异常: $e"); } }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Padding( padding: EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( device.name ?? '蓝牙绑定.默认设备名称'.tr, style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 30.rpx, letterSpacing: 0.0, ), ), Obx(() { if (blueteethBindController.currentDeviceMac.value == device.mac) { return SizedBox( width: 24.rpx, height: 24.rpx, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( themeController.currentColor.sc1, ), ), ); } return Container(); }), ], ), ), Row( children: [ Text( "蓝牙绑定.信号强度".tr + ':${device.rssi ?? '-'}dBm', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFEBF2F8), fontSize: 26.rpx, letterSpacing: 0.0, ), ), SizedBox(width: 40.rpx), Text( "蓝牙绑定.SN".tr + ':${device.sn ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF5F9FD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), ], ), Text( "蓝牙绑定.蓝牙地址".tr + ':${device.deviceId ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), Text( "蓝牙绑定.mac".tr + ':${device.mac ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), Row( children: [ Text( "蓝牙绑定.网络".tr + ':${device.isOnline == true ? '蓝牙绑定.在线'.tr : '蓝牙绑定.离线'.tr}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFEBF2F8), fontSize: 26.rpx, letterSpacing: 0.0, ), ), SizedBox(width: 145.rpx), Row( children: [ Text( "蓝牙绑定.传感器".tr + ":", style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFEBF2F8), fontSize: 26.rpx, letterSpacing: 0.0, ), ), Text( device.bind == false ? '蓝牙绑定.可绑定'.tr : '蓝牙绑定.已被绑定'.tr, style: TextStyle( fontFamily: 'Inter', color: device.bind == false ? const Color(0xFF1AD2B5) : themeController.currentColor.sc9, fontSize: 26.rpx, letterSpacing: 0.0, ), ), ], ), ], ), Text( "版本".tr + '${device.version ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), ].divide(SizedBox(height: 37.rpx)), ), ); } else { List devices = []; devices.add(device); devices.add(device.slave!); return ClickableContainer( backgroundColor: themeController.currentColor.sc5, highlightColor: themeController.currentColor.sc21, borderRadius: 20.rpx, padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 36.rpx, 30.rpx, 52.rpx), onTap: () async { showBindDoubleDialog( context, devices, onConfirm: (int selectedIndex) { // selectedIndex 是 0(全选)或 1(主)或 2(从) bool flag1 = devices[0].bind!; bool flag2 = devices[1].bind!; if (selectedIndex == 0) { // 全选 if (flag1 == true || flag2 == true) { showHaveBindDialog(context); return; } else {} } else if (selectedIndex == 1) { // 主 if (flag1 == true) { showHaveBindDialog(context); return; } else {} } else if (selectedIndex == 2) { if (flag2 == true) { showHaveBindDialog(context); return; } else {} } TopSlideNotification.show(context, text: "双人版绑定修复中"); print('选中了设备索引:$selectedIndex'); //配置wifi }, onCancel: () { print("用户取消绑定"); }, ); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ _buildDeviceInfoSection(device, context), Divider( thickness: 1.rpx, color: themeController.currentColor.sc3, ), _buildDeviceInfoSection(device.slave!, context), ].divide(SizedBox(height: 37.rpx)), ), ); } } //更新设备绑定状态 void updateDeviceBindStatus(BleDeviceData device) { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.user_setting; String mac = device.mac!; String type = "device_bind_status_${mac}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; Map data = { "type": type, "mac": mac, "wifi": false, "celibration": false, "person_info": false, "time": DateTime.now().millisecondsSinceEpoch, }; requestWithLog( logTitle: "更新用户绑定流程", method: MyHttpMethod.put, queryUrl: queryUrl, data: data, onSuccess: (res) {}, onFailure: (res) {}, ); } Widget _buildDeviceInfoSection(device, BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( device.name ?? '蓝牙绑定.默认设备名称'.tr, style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 30.rpx, letterSpacing: 0.0, ), ), Obx(() { if (blueteethBindController.currentDeviceMac.value == device.mac) { return SizedBox( width: 24.rpx, height: 24.rpx, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( themeController.currentColor.sc1, ), ), ); } return Container(); }), ], ), ), Row( children: [ Text( "蓝牙绑定.信号强度".tr + ':${device.rssi ?? '-'}dBm', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFEBF2F8), fontSize: 26.rpx, letterSpacing: 0.0, ), ), SizedBox(width: 40.rpx), Text( "蓝牙绑定.SN".tr + ':${device.sn ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF5F9FD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), ], ), Text( "蓝牙绑定.蓝牙地址".tr + ':${device.deviceId ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), Text( "蓝牙绑定.mac".tr + ':${device.mac ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), Row( children: [ Text( "蓝牙绑定.网络".tr + ':${device.isOnline == true ? '蓝牙绑定.在线'.tr : '蓝牙绑定.离线'.tr}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFEBF2F8), fontSize: 26.rpx, letterSpacing: 0.0, ), ), SizedBox(width: 145.rpx), Row( children: [ Text( "蓝牙绑定.传感器".tr + ":", style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFEBF2F8), fontSize: 26.rpx, letterSpacing: 0.0, ), ), Text( device.bind == false ? '蓝牙绑定.可绑定'.tr : '蓝牙绑定.已被绑定'.tr, style: TextStyle( fontFamily: 'Inter', color: device.bind == false ? const Color(0xFF1AD2B5) : themeController.currentColor.sc9, fontSize: 26.rpx, letterSpacing: 0.0, ), ), ], ), ], ), Text( "版本".tr + '${device.version ?? '-'}', style: TextStyle( fontFamily: 'Inter', color: const Color(0xFFF6FAFD), fontSize: 26.rpx, letterSpacing: 0.0, ), ), ].divide(SizedBox( height: 37.rpx, )), ); } }