Merge branch 'master' of http://10.20.2.7:8080/r/~enchantedwyf/vbvs_app
This commit is contained in:
@@ -394,7 +394,7 @@
|
|||||||
"全部消息": "全部消息",
|
"全部消息": "全部消息",
|
||||||
"请先在设置里的消息通知打开全部消息配置": "请先在设置里的消息通知打开全部消息配置",
|
"请先在设置里的消息通知打开全部消息配置": "请先在设置里的消息通知打开全部消息配置",
|
||||||
"请先打开全部消息配置": "请先打开全部消息配置",
|
"请先打开全部消息配置": "请先打开全部消息配置",
|
||||||
"正常值": "正常值:",
|
"正常值": "范围:",
|
||||||
"今日": "今日",
|
"今日": "今日",
|
||||||
"深色": "深色",
|
"深色": "深色",
|
||||||
"皮肤指数": "皮肤指数",
|
"皮肤指数": "皮肤指数",
|
||||||
|
|||||||
@@ -395,7 +395,7 @@
|
|||||||
"全部消息": "全部消息",
|
"全部消息": "全部消息",
|
||||||
"请先在设置里的消息通知打开全部消息配置": "請先在設置裡的消息通知打開全部消息配置",
|
"请先在设置里的消息通知打开全部消息配置": "請先在設置裡的消息通知打開全部消息配置",
|
||||||
"请先打开全部消息配置": "請先打開全部消息配置",
|
"请先打开全部消息配置": "請先打開全部消息配置",
|
||||||
"正常值": "正常值:",
|
"正常值": "范围:",
|
||||||
"今日": "今日",
|
"今日": "今日",
|
||||||
"深色": "深色",
|
"深色": "深色",
|
||||||
"皮肤指数": "皮膚指數",
|
"皮肤指数": "皮膚指數",
|
||||||
|
|||||||
@@ -593,7 +593,7 @@
|
|||||||
"该设备的历史数据将被清除": "该设备的历史数据将被清除",
|
"该设备的历史数据将被清除": "该设备的历史数据将被清除",
|
||||||
"有一条新的设备分享消息": "有一条新的设备分享消息",
|
"有一条新的设备分享消息": "有一条新的设备分享消息",
|
||||||
"去查看": "去查看",
|
"去查看": "去查看",
|
||||||
"正常值": "正常值:",
|
"正常值": "范围:",
|
||||||
"绑定设备": "绑定设备",
|
"绑定设备": "绑定设备",
|
||||||
"设备分享提醒": "设备分享提醒",
|
"设备分享提醒": "设备分享提醒",
|
||||||
"生命体征": "生命体征",
|
"生命体征": "生命体征",
|
||||||
|
|||||||
@@ -593,7 +593,7 @@
|
|||||||
"该设备的历史数据将被清除": "該設備的歷史數據將被清除",
|
"该设备的历史数据将被清除": "該設備的歷史數據將被清除",
|
||||||
"有一条新的设备分享消息": "有一條新的設備分享消息",
|
"有一条新的设备分享消息": "有一條新的設備分享消息",
|
||||||
"去查看": "去查看",
|
"去查看": "去查看",
|
||||||
"正常值": "正常值:",
|
"正常值": "范围:",
|
||||||
"绑定设备": "绑定设备",
|
"绑定设备": "绑定设备",
|
||||||
"设备分享提醒": "設備分享提醒",
|
"设备分享提醒": "設備分享提醒",
|
||||||
"生命体征": "生命體徵",
|
"生命体征": "生命體徵",
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ part 'blueteeth_bind_controller.g.dart';
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class BlueteethBindModel {
|
class BlueteethBindModel {
|
||||||
int? read = 1;
|
int? read = 1;
|
||||||
double? singal = -70;
|
double? singal = -90;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
List<BleDeviceData>? devicelist = []; //蓝牙扫描
|
List<BleDeviceData>? devicelist = []; //蓝牙扫描
|
||||||
|
|||||||
@@ -242,13 +242,7 @@ class LoginController extends GetControllerEx<LoginModel> {
|
|||||||
data: data);
|
data: data);
|
||||||
if (apiResponse.code == HttpStatusCodes.ok) {
|
if (apiResponse.code == HttpStatusCodes.ok) {
|
||||||
UserInfoController userInfoController = Get.find();
|
UserInfoController userInfoController = Get.find();
|
||||||
userInfoController.model.login = 1;
|
|
||||||
userInfoController.model.user = UserModel.fromJson(apiResponse.data);
|
userInfoController.model.user = UserModel.fromJson(apiResponse.data);
|
||||||
String token = apiResponse.rawResponse.headers['token']!.first;
|
|
||||||
EasyDartModule.dio.token = token;
|
|
||||||
final box = GetStorage();
|
|
||||||
box.write('token', token); // 存储 token
|
|
||||||
box.write('user', userInfoController.model.user!.toJson()); // 存储用户信息
|
|
||||||
if (userInfoController.model.user!.phone == null ||
|
if (userInfoController.model.user!.phone == null ||
|
||||||
userInfoController.model.user!.phone!.isEmpty) {
|
userInfoController.model.user!.phone!.isEmpty) {
|
||||||
Map data = {
|
Map data = {
|
||||||
@@ -260,6 +254,13 @@ class LoginController extends GetControllerEx<LoginModel> {
|
|||||||
userInfoController.model.user!.phone!.isEmpty) {
|
userInfoController.model.user!.phone!.isEmpty) {
|
||||||
userInfoController.model.login = 0;
|
userInfoController.model.login = 0;
|
||||||
}
|
}
|
||||||
|
userInfoController.model.login = 1;
|
||||||
|
|
||||||
|
String token = apiResponse.rawResponse.headers['token']!.first;
|
||||||
|
EasyDartModule.dio.token = token;
|
||||||
|
final box = GetStorage();
|
||||||
|
box.write('token', token); // 存储 token
|
||||||
|
box.write('user', userInfoController.model.user!.toJson()); // 存储用户信息
|
||||||
}
|
}
|
||||||
return apiResponse;
|
return apiResponse;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:ef/ef.dart';
|
import 'package:ef/ef.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -7,14 +8,17 @@ import 'package:flutter_svg/svg.dart';
|
|||||||
import 'package:flutterflow_ui/flutterflow_ui.dart';
|
import 'package:flutterflow_ui/flutterflow_ui.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart'; // 引入permission_handler
|
import 'package:permission_handler/permission_handler.dart'; // 引入permission_handler
|
||||||
import 'package:vbvs_app/common/color/appConstants.dart';
|
import 'package:vbvs_app/common/color/appConstants.dart';
|
||||||
|
import 'package:vbvs_app/common/util/CommonVariables.dart';
|
||||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||||
import 'package:vbvs_app/component/tool/ClickableContainer.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/blueteeth_bind_controller.dart';
|
||||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||||
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
||||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||||
import 'package:vbvs_app/model/BleDeviceData.dart';
|
import 'package:vbvs_app/model/BleDeviceData.dart';
|
||||||
|
import 'package:vbvs_app/pages/common/selectDialog.dart';
|
||||||
import 'package:vbvs_app/pages/device_bind/componnet/SingleBlueteethDeviceCompoentWidget.dart';
|
import 'package:vbvs_app/pages/device_bind/componnet/SingleBlueteethDeviceCompoentWidget.dart';
|
||||||
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
|
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
|
||||||
|
|
||||||
@@ -69,33 +73,109 @@ class _BlueteethDevicePageState extends State<BlueteethDevicePage> {
|
|||||||
_startPeriodicScan(); // 开始定时扫描
|
_startPeriodicScan(); // 开始定时扫描
|
||||||
} else {
|
} else {
|
||||||
// 权限未授予,请求权限
|
// 权限未授予,请求权限
|
||||||
_requestBluetoothPermission();
|
_requestBluetoothPermission(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _requestBluetoothPermission() async {
|
// Future<void> _requestBluetoothPermission() async {
|
||||||
Map<Permission, PermissionStatus> statuses = await [
|
// Map<Permission, PermissionStatus> statuses = await [
|
||||||
|
// Permission.bluetoothScan,
|
||||||
|
// Permission.bluetoothConnect,
|
||||||
|
// Permission.location, // Android 12 及以下仍需要位置权限来进行扫描
|
||||||
|
// ].request();
|
||||||
|
|
||||||
|
// bool allGranted = statuses[Permission.bluetoothScan]?.isGranted == true &&
|
||||||
|
// statuses[Permission.bluetoothConnect]?.isGranted == true &&
|
||||||
|
// statuses[Permission.location]?.isGranted == true;
|
||||||
|
|
||||||
|
// if (allGranted) {
|
||||||
|
// // 用户授予了权限,开始扫描
|
||||||
|
// _startScanning();
|
||||||
|
// _startPeriodicScan();
|
||||||
|
// } else {
|
||||||
|
// // 权限被拒绝,提示用户
|
||||||
|
// _showPermissionDeniedDialog();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<void> _requestBluetoothPermission(BuildContext context) async {
|
||||||
|
Map<Permission, PermissionStatus> statuses = {};
|
||||||
|
bool dialogShown = false; // 标记是否弹过权限提示弹窗
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
PermissionStatus isBleGranted = await Permission.bluetooth.request();
|
||||||
|
print('checkBlePermissions-ios, isBleGranted=$isBleGranted');
|
||||||
|
if (isBleGranted.isGranted) {
|
||||||
|
// startBluetoothScanning();
|
||||||
|
_startScanning();
|
||||||
|
_startPeriodicScan();
|
||||||
|
} else {
|
||||||
|
// showToast("蓝牙开关或蓝牙权限未开启,请开启蓝牙开关与蓝牙权限".tr, closeTime: 7);
|
||||||
|
try {
|
||||||
|
_startScanning();
|
||||||
|
_startPeriodicScan();
|
||||||
|
} catch (e) {
|
||||||
|
TopSlideNotification.show(context,
|
||||||
|
text: "蓝牙权限未开启,请在设置中开启蓝牙权限".tr,
|
||||||
|
textColor: themeController.currentColor.sc9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (Platform.isAndroid) {
|
||||||
|
try {
|
||||||
|
// 检查是否已授权
|
||||||
|
bool alreadyGranted = await Permission.bluetoothScan.isGranted &&
|
||||||
|
await Permission.bluetoothConnect.isGranted &&
|
||||||
|
await Permission.location.isGranted;
|
||||||
|
|
||||||
|
if (!alreadyGranted) {
|
||||||
|
// 弹出自定义提示
|
||||||
|
showPermissionInfoDialog(
|
||||||
|
Get.context!, CommonVariables().bluetoothpermissionInfo);
|
||||||
|
dialogShown = true;
|
||||||
|
|
||||||
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
|
|
||||||
|
// 请求权限
|
||||||
|
statuses = await [
|
||||||
Permission.bluetoothScan,
|
Permission.bluetoothScan,
|
||||||
Permission.bluetoothConnect,
|
Permission.bluetoothConnect,
|
||||||
Permission.location, // Android 12 及以下仍需要位置权限来进行扫描
|
Permission.location,
|
||||||
].request();
|
].request();
|
||||||
|
|
||||||
|
ef.log("权限状态: $statuses");
|
||||||
|
} else {
|
||||||
|
statuses = {
|
||||||
|
Permission.bluetoothScan: PermissionStatus.granted,
|
||||||
|
Permission.bluetoothConnect: PermissionStatus.granted,
|
||||||
|
Permission.location: PermissionStatus.granted,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ef.log("申请权限出错: $e");
|
||||||
|
} finally {
|
||||||
|
// 只有真的弹过提示才关闭
|
||||||
|
if (dialogShown && Get.context != null) {
|
||||||
|
Navigator.of(Get.context!, rootNavigator: true).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
bool allGranted = statuses[Permission.bluetoothScan]?.isGranted == true &&
|
bool allGranted = statuses[Permission.bluetoothScan]?.isGranted == true &&
|
||||||
statuses[Permission.bluetoothConnect]?.isGranted == true &&
|
statuses[Permission.bluetoothConnect]?.isGranted == true &&
|
||||||
statuses[Permission.location]?.isGranted == true;
|
statuses[Permission.location]?.isGranted == true;
|
||||||
|
|
||||||
if (allGranted) {
|
if (allGranted) {
|
||||||
// 用户授予了权限,开始扫描
|
|
||||||
_startScanning();
|
_startScanning();
|
||||||
_startPeriodicScan();
|
_startPeriodicScan();
|
||||||
} else {
|
} else {
|
||||||
// 权限被拒绝,提示用户
|
_showPermissionDeniedDialog(context);
|
||||||
_showPermissionDeniedDialog();
|
}
|
||||||
|
} else {
|
||||||
|
TopSlideNotification.show(context,
|
||||||
|
text: "当前系统不支持蓝牙,无法使用此功能".tr,
|
||||||
|
textColor: themeController.currentColor.sc9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示权限被拒绝的提示
|
// 显示权限被拒绝的提示
|
||||||
void _showPermissionDeniedDialog() {
|
void _showPermissionDeniedDialog(BuildContext context) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:ef/ef.dart';
|
import 'package:ef/ef.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -11,7 +12,6 @@ import 'package:vbvs_app/common/color/appConstants.dart';
|
|||||||
import 'package:vbvs_app/common/util/CommonVariables.dart';
|
import 'package:vbvs_app/common/util/CommonVariables.dart';
|
||||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||||
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
|
|
||||||
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
|
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
|
||||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||||
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
||||||
@@ -133,10 +133,15 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
|
|||||||
_startPeriodicScan();
|
_startPeriodicScan();
|
||||||
} else {
|
} else {
|
||||||
// showToast("蓝牙开关或蓝牙权限未开启,请开启蓝牙开关与蓝牙权限".tr, closeTime: 7);
|
// showToast("蓝牙开关或蓝牙权限未开启,请开启蓝牙开关与蓝牙权限".tr, closeTime: 7);
|
||||||
|
try {
|
||||||
|
_startScanning();
|
||||||
|
_startPeriodicScan();
|
||||||
|
} catch (e) {
|
||||||
TopSlideNotification.show(context,
|
TopSlideNotification.show(context,
|
||||||
text: "蓝牙开关或蓝牙权限未开启,请开启蓝牙开关与蓝牙权限".tr,
|
text: "蓝牙权限未开启,请在设置中开启蓝牙权限".tr,
|
||||||
textColor: themeController.currentColor.sc9);
|
textColor: themeController.currentColor.sc9);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (Platform.isAndroid) {
|
} else if (Platform.isAndroid) {
|
||||||
try {
|
try {
|
||||||
// 检查是否已授权
|
// 检查是否已授权
|
||||||
@@ -225,6 +230,66 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
|
|||||||
|
|
||||||
await FlutterBluePlus.startScan(timeout: Duration(seconds: 10));
|
await FlutterBluePlus.startScan(timeout: Duration(seconds: 10));
|
||||||
|
|
||||||
|
// _scanSubscription = FlutterBluePlus.scanResults.listen((results) {
|
||||||
|
// if (!mounted) return;
|
||||||
|
|
||||||
|
// final signalThreshold = mhtBlueToothController.model.singal!;
|
||||||
|
// final searchKey =
|
||||||
|
// mhtBlueToothController.search.value.trim().toLowerCase();
|
||||||
|
|
||||||
|
// final filteredResults = results.where((r) {
|
||||||
|
// final localName = r.advertisementData.localName;
|
||||||
|
// final isTarget = r.rssi > signalThreshold &&
|
||||||
|
// isTargetDevice(
|
||||||
|
// localName, widget.deviceType['reg'].cast<String>());
|
||||||
|
// if (!isTarget) return false;
|
||||||
|
// final name = r.advertisementData.advName.toLowerCase();
|
||||||
|
|
||||||
|
// // String macAddress = r.device.remoteId.str;
|
||||||
|
// String macAddress = getDeviceId(r);
|
||||||
|
// final mac = macAddress.replaceAll(':', '');
|
||||||
|
// final search = searchKey.trim().replaceAll(':', '').toLowerCase();
|
||||||
|
|
||||||
|
// if (search.isNotEmpty &&
|
||||||
|
// !name.contains(search) &&
|
||||||
|
// !mac.replaceAll(':', '').toLowerCase().contains(search)) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return true;
|
||||||
|
// }).map((r) {
|
||||||
|
// return BlueToothDataModel.fromScanResult(
|
||||||
|
// r, widget.deviceType['type']?.toInt(),
|
||||||
|
// bind: false,
|
||||||
|
// name: r.advertisementData.localName,
|
||||||
|
// mac:getDeviceId(r).replaceAll(':', ''));
|
||||||
|
// }).toList();
|
||||||
|
|
||||||
|
// final currentDevices = mhtBlueToothController.model.blueRawData ?? [];
|
||||||
|
// final newDevices = <BlueToothDataModel>[];
|
||||||
|
|
||||||
|
// for (var newDevice in filteredResults) {
|
||||||
|
// // 检查设备是否已存在
|
||||||
|
// final existingIndex =
|
||||||
|
// currentDevices.indexWhere((d) => d.mac == newDevice.mac);
|
||||||
|
|
||||||
|
// if (existingIndex >= 0) {
|
||||||
|
// // 更新已有设备信息(如信号强度)
|
||||||
|
// currentDevices[existingIndex] = newDevice;
|
||||||
|
// } else {
|
||||||
|
// // 添加新设备
|
||||||
|
// newDevices.add(newDevice);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// setState(() {
|
||||||
|
// mhtBlueToothController.model.blueRawData = [
|
||||||
|
// ...currentDevices,
|
||||||
|
// ...newDevices
|
||||||
|
// ];
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
_scanSubscription = FlutterBluePlus.scanResults.listen((results) {
|
_scanSubscription = FlutterBluePlus.scanResults.listen((results) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
@@ -232,45 +297,90 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
|
|||||||
final searchKey =
|
final searchKey =
|
||||||
mhtBlueToothController.search.value.trim().toLowerCase();
|
mhtBlueToothController.search.value.trim().toLowerCase();
|
||||||
|
|
||||||
final filteredResults = results.where((r) {
|
final filteredResults = results.map((r) {
|
||||||
final localName = r.advertisementData.localName;
|
Map<String, dynamic> d = {
|
||||||
final isTarget = r.rssi > signalThreshold &&
|
"updateTime": DateTime.now().millisecondsSinceEpoch,
|
||||||
isTargetDevice(
|
"name": r.advertisementData.localName?.trim() ??
|
||||||
localName, widget.deviceType['reg'].cast<String>());
|
r.advertisementData.advName?.trim() ??
|
||||||
if (!isTarget) return false;
|
r.device.name ??
|
||||||
final name = r.advertisementData.advName.toLowerCase();
|
"",
|
||||||
String macAddress = r.device.remoteId.str;
|
"rssi": r.rssi,
|
||||||
final mac = macAddress.replaceAll(':', '');
|
"device": r.device,
|
||||||
final search = searchKey.trim().replaceAll(':', '').toLowerCase();
|
"connectable": r.advertisementData.connectable
|
||||||
|
};
|
||||||
|
|
||||||
if (search.isNotEmpty &&
|
// 从 manufacturerData 解析设备唯一 ID
|
||||||
!name.contains(search) &&
|
Map<int, List<int>> m_d = r.advertisementData.manufacturerData;
|
||||||
!mac.replaceAll(':', '').toLowerCase().contains(search)) {
|
String? deviceId;
|
||||||
|
|
||||||
|
m_d.forEach((key, value) {
|
||||||
|
if (value == null || value.isEmpty) return;
|
||||||
|
|
||||||
|
if (key == 65517) {
|
||||||
|
List<int> a = [0, 0, ...value];
|
||||||
|
advertisDataFormatter(a, d); // 你原来的处理
|
||||||
|
if (d['adData']?['deviceId'] != null)
|
||||||
|
deviceId = d['adData']['deviceId'];
|
||||||
|
} else if (key == 11125 && value.length == 8) {
|
||||||
|
deviceId = ab2str(value.sublist(2, 8)).toUpperCase();
|
||||||
|
} else if (value.length == 8 && isQuanShiDevice(d["name"])) {
|
||||||
|
deviceId = ab2str(value.sublist(2, 8)).toUpperCase();
|
||||||
|
} else if ((value.length == 4 || value.length == 6) &&
|
||||||
|
isMHTSWES(d["name"])) {
|
||||||
|
List<int> a;
|
||||||
|
if (value.length == 4) {
|
||||||
|
ByteData bd = ByteData(2);
|
||||||
|
bd.setUint16(0, key, Endian.little);
|
||||||
|
a = [bd.getUint8(0), bd.getUint8(1), ...value];
|
||||||
|
} else {
|
||||||
|
a = [...value];
|
||||||
|
}
|
||||||
|
deviceId = ab2str(a).toUpperCase();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
d['id'] = deviceId ?? r.device.remoteId.str; // fallback UUID
|
||||||
|
return BlueToothDataModel.fromScanResult(
|
||||||
|
r,
|
||||||
|
widget.deviceType['type']?.toInt(),
|
||||||
|
bind: false,
|
||||||
|
name: d['name'],
|
||||||
|
mac: d['id'],
|
||||||
|
);
|
||||||
|
}).where((d) {
|
||||||
|
// 信号强度过滤
|
||||||
|
if (d.scanResult.rssi <= signalThreshold) return false;
|
||||||
|
|
||||||
|
// 搜索关键字过滤
|
||||||
|
if (searchKey.isNotEmpty) {
|
||||||
|
String name = d.name.toLowerCase();
|
||||||
|
String mac = d.mac.toLowerCase();
|
||||||
|
if (!name.contains(searchKey) && !mac.contains(searchKey))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 名称过滤规则,必须包含 deviceType['reg'] 列表中的某个字符串
|
||||||
|
List<String> regList =
|
||||||
|
widget.deviceType['reg']?.cast<String>() ?? [];
|
||||||
|
if (regList.isNotEmpty) {
|
||||||
|
String lowerName = d.name.toLowerCase();
|
||||||
|
bool match =
|
||||||
|
regList.any((reg) => lowerName.contains(reg.toLowerCase()));
|
||||||
|
if (!match) return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}).map((r) {
|
|
||||||
return BlueToothDataModel.fromScanResult(
|
|
||||||
r, widget.deviceType['type']?.toInt(),
|
|
||||||
bind: false,
|
|
||||||
name: r.advertisementData.localName,
|
|
||||||
mac: r.device.remoteId.str.replaceAll(':', ''));
|
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
final currentDevices = mhtBlueToothController.model.blueRawData ?? [];
|
final currentDevices = mhtBlueToothController.model.blueRawData ?? [];
|
||||||
final newDevices = <BlueToothDataModel>[];
|
final newDevices = <BlueToothDataModel>[];
|
||||||
|
|
||||||
for (var newDevice in filteredResults) {
|
for (var newDevice in filteredResults) {
|
||||||
// 检查设备是否已存在
|
|
||||||
final existingIndex =
|
final existingIndex =
|
||||||
currentDevices.indexWhere((d) => d.mac == newDevice.mac);
|
currentDevices.indexWhere((d) => d.mac == newDevice.mac);
|
||||||
|
|
||||||
if (existingIndex >= 0) {
|
if (existingIndex >= 0) {
|
||||||
// 更新已有设备信息(如信号强度)
|
|
||||||
currentDevices[existingIndex] = newDevice;
|
currentDevices[existingIndex] = newDevice;
|
||||||
} else {
|
} else {
|
||||||
// 添加新设备
|
|
||||||
newDevices.add(newDevice);
|
newDevices.add(newDevice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -858,4 +968,118 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getDeviceId(ScanResult result) {
|
||||||
|
// Android:remoteId 就是 MAC
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
return result.device.remoteId.str.replaceAll(':', '').toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// iOS:尝试从 manufacturerData 里解析
|
||||||
|
Map<int, List<int>> mData = result.advertisementData.manufacturerData;
|
||||||
|
for (var key in mData.keys) {
|
||||||
|
List<int>? bytes = mData[key];
|
||||||
|
if (bytes != null && bytes.length == 6) {
|
||||||
|
// 假设这 6 个字节就是 MAC
|
||||||
|
return bytes
|
||||||
|
.map((b) => b.toRadixString(16).padLeft(2, '0'))
|
||||||
|
.join('')
|
||||||
|
.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.device.remoteId.str.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void advertisDataFormatter(var a, item) {
|
||||||
|
Map<String, dynamic> obj = {};
|
||||||
|
try {
|
||||||
|
if (a[2] == 1) {
|
||||||
|
obj['sn'] = a[3];
|
||||||
|
obj['deviceId'] = ab2str(a.sublist(4, 10)).toUpperCase();
|
||||||
|
obj['b'] = a[10];
|
||||||
|
obj['h'] = a[11];
|
||||||
|
obj['t'] = a[12];
|
||||||
|
item['adData'] = obj;
|
||||||
|
} else if (a[2] == 2) {
|
||||||
|
obj['sn'] = a[3];
|
||||||
|
obj['deviceId'] = ab2str(a.sublist(4, 10)).toUpperCase();
|
||||||
|
obj['b'] = a[10];
|
||||||
|
obj['h'] = a[11];
|
||||||
|
obj['t'] = a[12];
|
||||||
|
obj['net'] = (a[13] & 1) == 1 ? '在线' : '离线';
|
||||||
|
obj['flag'] = (a[13] & 2) == 2 ? '异常' : '正常';
|
||||||
|
ByteData byteData = ByteData.sublistView(
|
||||||
|
Uint8List.fromList(a.sublist(14, 18).reversed.toList()));
|
||||||
|
obj['version'] = byteData.getUint32(0);
|
||||||
|
item['adData'] = obj;
|
||||||
|
} else if (a[2] == 3) {
|
||||||
|
List<String> otherstr = [];
|
||||||
|
obj['sn'] = a[3];
|
||||||
|
obj['deviceId'] = ab2str(a.sublist(4, 10)).toUpperCase();
|
||||||
|
obj['b'] = a[10];
|
||||||
|
obj['h'] = a[11];
|
||||||
|
obj['t'] = a[12];
|
||||||
|
obj['net'] = (a[13] & 1) == 1 ? '在线' : '离线';
|
||||||
|
obj['flag'] = (a[13] & 2) == 2 ? '异常' : '正常';
|
||||||
|
|
||||||
|
if ((a[13] & 4) == 4) {
|
||||||
|
otherstr.add('呼吸暂停');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((a[13] & 8) == 8 && (a[13] & 1) == 1) {
|
||||||
|
obj['isbed'] = '在床';
|
||||||
|
} else {
|
||||||
|
obj['isbed'] = '离床';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((a[13] & 16) == 16) {
|
||||||
|
otherstr.add('授权过期');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((a[13] & 64) == 64) {
|
||||||
|
otherstr.add('设备休眠');
|
||||||
|
}
|
||||||
|
|
||||||
|
obj['other'] = otherstr.join('、');
|
||||||
|
|
||||||
|
ByteData byteData = ByteData.sublistView(
|
||||||
|
Uint8List.fromList(a.sublist(14, 18).reversed.toList()));
|
||||||
|
obj['version'] = byteData.getUint32(0);
|
||||||
|
|
||||||
|
ByteData qsnData =
|
||||||
|
ByteData.sublistView(Uint8List.fromList(a.sublist(17, 19)));
|
||||||
|
obj['qsn'] = qsnData.getUint16(0) * 256 + obj['sn'];
|
||||||
|
|
||||||
|
item['adData'] = obj;
|
||||||
|
} else if (a.length > 17) {
|
||||||
|
obj['sn'] = a[3];
|
||||||
|
obj['deviceId'] = ab2str(a.sublist(4, 10)).toUpperCase();
|
||||||
|
obj['b'] = a[10];
|
||||||
|
obj['h'] = a[11];
|
||||||
|
obj['t'] = a[12];
|
||||||
|
obj['net'] = (a[13] & 1) == 1 ? '在线' : '离线';
|
||||||
|
obj['flag'] = (a[13] & 2) == 2 ? '异常' : '正常';
|
||||||
|
|
||||||
|
ByteData byteData = ByteData.sublistView(
|
||||||
|
Uint8List.fromList(a.sublist(14, 18).reversed.toList()));
|
||||||
|
obj['version'] = byteData.getUint32(0);
|
||||||
|
|
||||||
|
item['adData'] = obj;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isQuanShiDevice(name) {
|
||||||
|
return "$name".contains("S4-ZM-M94-4") ||
|
||||||
|
"$name".contains("S4-ZM-N94-4") ||
|
||||||
|
"$name".contains("MHT-SWES-D");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMHTSWES(name) {
|
||||||
|
return "$name".contains("MHT-") ||
|
||||||
|
"$name".contains("MHT-SWES-M") ||
|
||||||
|
"$name".contains("MHT-SWES-S");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ class MHTLoginController extends GetControllerEx<LoginModel> {
|
|||||||
"type": type,
|
"type": type,
|
||||||
"userName": account,
|
"userName": account,
|
||||||
"password": password,
|
"password": password,
|
||||||
|
'khCode':'mht',
|
||||||
};
|
};
|
||||||
String serviceAddress = ServiceConstant.service_address;
|
String serviceAddress = ServiceConstant.service_address;
|
||||||
String serviceName = ServiceConstant.server_service;
|
String serviceName = ServiceConstant.server_service;
|
||||||
@@ -273,16 +274,11 @@ class MHTLoginController extends GetControllerEx<LoginModel> {
|
|||||||
method: MyHttpMethod.post,
|
method: MyHttpMethod.post,
|
||||||
queryUrl: queryUrl,
|
queryUrl: queryUrl,
|
||||||
data: data);
|
data: data);
|
||||||
|
ef.log("微信登录授权开始");
|
||||||
if (apiResponse.code == HttpStatusCodes.ok) {
|
if (apiResponse.code == HttpStatusCodes.ok) {
|
||||||
ef.log("微信登录授权成功:${apiResponse}");
|
ef.log("微信登录授权成功:${apiResponse}");
|
||||||
UserInfoController userInfoController = Get.find();
|
UserInfoController userInfoController = Get.find();
|
||||||
userInfoController.model.user = UserModel.fromJson(apiResponse.data);
|
userInfoController.model.user = UserModel.fromJson(apiResponse.data);
|
||||||
userInfoController.model.login = 1;
|
|
||||||
String token = apiResponse.rawResponse.headers['token']!.first;
|
|
||||||
EasyDartModule.dio.token = token;
|
|
||||||
final box = GetStorage();
|
|
||||||
box.write('token', token); // 存储 token
|
|
||||||
box.write('user', userInfoController.model.user!.toJson()); // 存储用户信息
|
|
||||||
if (userInfoController.model.user!.phone == null ||
|
if (userInfoController.model.user!.phone == null ||
|
||||||
userInfoController.model.user!.phone!.isEmpty) {
|
userInfoController.model.user!.phone!.isEmpty) {
|
||||||
await Get.toNamed("/auth_bind_tel", arguments: {'code': 'mht'});
|
await Get.toNamed("/auth_bind_tel", arguments: {'code': 'mht'});
|
||||||
@@ -291,6 +287,12 @@ class MHTLoginController extends GetControllerEx<LoginModel> {
|
|||||||
userInfoController.model.user!.phone!.isEmpty) {
|
userInfoController.model.user!.phone!.isEmpty) {
|
||||||
userInfoController.model.login = 0;
|
userInfoController.model.login = 0;
|
||||||
}
|
}
|
||||||
|
userInfoController.model.login = 1;
|
||||||
|
String token = apiResponse.rawResponse.headers['token']!.first;
|
||||||
|
EasyDartModule.dio.token = token;
|
||||||
|
final box = GetStorage();
|
||||||
|
box.write('token', token); // 存储 token
|
||||||
|
box.write('user', userInfoController.model.user!.toJson()); // 存储用户信息
|
||||||
} else {
|
} else {
|
||||||
EasyDartModule.logger.error("[微信登录]:失败-》${apiResponse}");
|
EasyDartModule.logger.error("[微信登录]:失败-》${apiResponse}");
|
||||||
}
|
}
|
||||||
@@ -310,7 +312,7 @@ class MHTLoginController extends GetControllerEx<LoginModel> {
|
|||||||
int code = 0;
|
int code = 0;
|
||||||
requestWithLog(
|
requestWithLog(
|
||||||
logTitle: "注销账号",
|
logTitle: "注销账号",
|
||||||
method: MyHttpMethod.put,
|
method: MyHttpMethod.delete,
|
||||||
queryUrl: queryUrl,
|
queryUrl: queryUrl,
|
||||||
onSuccess: (res) {
|
onSuccess: (res) {
|
||||||
code = res.code!;
|
code = res.code!;
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ class MHTRegisterController extends GetControllerEx<RegisterModel> {
|
|||||||
"type": 1,
|
"type": 1,
|
||||||
"userName": model.register_phone!,
|
"userName": model.register_phone!,
|
||||||
"password": model.register_pd!,
|
"password": model.register_pd!,
|
||||||
"verify": model.register_code!
|
"verify": model.register_code!,
|
||||||
|
"khCode": "mht",
|
||||||
};
|
};
|
||||||
await requestWithLog(
|
await requestWithLog(
|
||||||
logTitle: "用户注册".tr,
|
logTitle: "用户注册".tr,
|
||||||
|
|||||||
Reference in New Issue
Block a user