442 lines
16 KiB
Dart
442 lines
16 KiB
Dart
import 'dart:async';
|
||
import 'dart:convert';
|
||
|
||
import 'package:EasyDartModule/EasyDartModule.dart';
|
||
import 'package:easydevice/easydevice.dart';
|
||
import 'package:ef/ef.dart';
|
||
import 'package:json_annotation/json_annotation.dart';
|
||
import 'package:vbvs_app/common/color/ServiceConstant.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/MyUtils.dart';
|
||
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
|
||
import 'package:vbvs_app/controller/person/person_controller.dart';
|
||
import 'package:vbvs_app/model/BleDeviceData.dart';
|
||
import 'package:vbvs_app/model/api_response.dart';
|
||
|
||
part 'blueteeth_bind_controller.g.dart';
|
||
|
||
@JsonSerializable()
|
||
class BlueteethBindModel {
|
||
int? read = 1;
|
||
double? singal = -70;
|
||
|
||
@JsonKey(ignore: true)
|
||
List<BleDeviceData>? devicelist = []; //蓝牙扫描
|
||
@JsonKey(ignore: true)
|
||
List<BleDeviceData>? betDevicelist = []; //网络状态
|
||
@JsonKey(ignore: true)
|
||
List? blelist = []; //蓝牙扫描的原始数据
|
||
|
||
List bindArr = ["", "", ""];
|
||
String connectedWifiName = "";
|
||
int connectedRssi = 0;
|
||
String deviceName = "";
|
||
|
||
bool? deviceIndex0 = true;
|
||
bool? deviceIndex1 = false;
|
||
bool? deviceIndex2 = false;
|
||
|
||
bool wifiPassShow = false;
|
||
String? wifiPass;
|
||
|
||
BlueteethBindModel();
|
||
|
||
factory BlueteethBindModel.fromJson(Map<String, dynamic> json) {
|
||
try {
|
||
return _$BlueteethBindModelFromJson(json);
|
||
} catch (e) {
|
||
return BlueteethBindModel();
|
||
}
|
||
}
|
||
|
||
Map<String, dynamic> toJson() => _$BlueteethBindModelToJson(this);
|
||
}
|
||
|
||
class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
|
||
BlueteethBindController() {
|
||
attr = GetModel(BlueteethBindModel()).obs;
|
||
}
|
||
|
||
Timer? _statusTimer;
|
||
|
||
THapp? currentDevice;
|
||
RxInt wifiStatus = 0.obs; //wifi连接状态 0:未连接 1:已连接
|
||
RxList wifiList = [].obs;
|
||
RxMap connect_wifi = {}.obs;
|
||
RxString scanMac = "".obs;
|
||
|
||
RxString currentDeviceMac = "".obs; //当前选中的设备mac地址
|
||
RxString? cid = "".obs;
|
||
|
||
RxString search = "".obs; //搜索关键字
|
||
|
||
RxBool bluetoothStatus = false.obs; //蓝牙开启状态
|
||
RxInt connectStatus = 0.obs; //当前wifi连接状态 0:未连接 1:已连接
|
||
RxInt blueConnectFlag = 0.obs; //当前蓝牙连接状态 0.正在连接 1.未连接 2.已连接
|
||
RxInt netType = 0.obs; //当前网络类型 0.正在检测 1.wifi 2.4g设备 3.未知
|
||
RxInt wifiConnectStatus = 1.obs; //获取wifi状态 0.正在检测 1.已检测完
|
||
|
||
RxMap selectWifi = {}.obs; //正在连接wifi信息
|
||
|
||
int returnPage = 0; //0返回首页 1.返回设备列表
|
||
|
||
// 安全展示 TopSlideNotification
|
||
void safeShowNotification(String msg) {
|
||
try {
|
||
final ctx = Get.context;
|
||
if (ctx != null && ctx.mounted) {
|
||
TopSlideNotification.show(
|
||
ctx,
|
||
text: msg,
|
||
textColor: themeController.currentColor.sc9,
|
||
);
|
||
} else {
|
||
print("TopSlideNotification 未显示:context 不可用或未挂载");
|
||
}
|
||
} catch (e, stack) {
|
||
// print("TopSlideNotification 显示异常: $e\n$stack");
|
||
}
|
||
}
|
||
|
||
// 启动每10秒获取设备状态
|
||
void startStatusPolling() {
|
||
updateDeviceStatus().then((res) {
|
||
if (res.code == HttpStatusCodes.ok) {
|
||
updateAll();
|
||
} else {
|
||
safeShowNotification(res.msg ?? "获取设备状态异常");
|
||
EasyDartModule.logger.info("获取设备状态异常: $res");
|
||
DailyLogUtils.writeLog("获取设备状态异常: $res");
|
||
}
|
||
});
|
||
|
||
if (_statusTimer == null) {
|
||
_statusTimer = Timer.periodic(Duration(seconds: 2), (timer) {
|
||
updateDeviceStatus().then((res) {
|
||
if (res.code == HttpStatusCodes.ok) {
|
||
updateAll();
|
||
} else {
|
||
safeShowNotification(res.msg ?? "获取设备状态异常");
|
||
EasyDartModule.logger.info("获取设备状态异常: $res");
|
||
DailyLogUtils.writeLog("获取设备状态异常: $res");
|
||
}
|
||
}).catchError((e, stack) {
|
||
print("updateDeviceStatus 执行异常: $e\n$stack");
|
||
safeShowNotification("设备状态请求失败");
|
||
EasyDartModule.logger.info("设备状态异常: $e");
|
||
DailyLogUtils.writeLog("设备状态异常: $e");
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
void stopStatusPolling() {
|
||
_statusTimer?.cancel();
|
||
_statusTimer = null;
|
||
}
|
||
|
||
// Future<ApiResponse> updateDeviceStatus() async {
|
||
// try {
|
||
// String serviceAddress = ServiceConstant.service_address;
|
||
// String serviceName = ServiceConstant.server_service;
|
||
// String serviceApi = ServiceConstant.get_bluetooth_device_status;
|
||
// String queryUrl = "$serviceAddress$serviceName$serviceApi";
|
||
|
||
// if (model.devicelist != null && model.devicelist!.isNotEmpty) {
|
||
// final macParams = model.devicelist!
|
||
// .map((device) => "mac=${Uri.encodeQueryComponent(device.mac!)}")
|
||
// .join("&");
|
||
|
||
// if (queryUrl.contains('?')) {
|
||
// queryUrl += '&$macParams';
|
||
// } else {
|
||
// queryUrl += '?$macParams';
|
||
// }
|
||
// String? language = "";
|
||
// if (languageController.selectLanguage != null) {
|
||
// language = languageController.selectLanguage.value!.language_code;
|
||
// }
|
||
// if (language != null && language.isNotEmpty) {
|
||
// if (queryUrl.contains("?")) {
|
||
// queryUrl += "&lang=$language";
|
||
// } else {
|
||
// queryUrl += "?lang=$language";
|
||
// }
|
||
// }
|
||
|
||
// var response = await EasyDartModule.dio.get(queryUrl);
|
||
// var responseData =
|
||
// response.data is String ? jsonDecode(response.data) : response.data;
|
||
// ApiResponse res =
|
||
// ApiResponse.fromJson(responseData, (object) => object);
|
||
// if (res.code != HttpStatusCodes.ok) return res;
|
||
|
||
// if (response.data['data'] != null && response.data['data'] is List) {
|
||
// List<dynamic> responseList = response.data['data'];
|
||
|
||
// // 构建 mac -> 设备的映射
|
||
// Map<String, BleDeviceData> deviceMap = {
|
||
// for (var d in model.devicelist!)
|
||
// if (d.mac != null) d.mac!.toLowerCase(): d,
|
||
// };
|
||
|
||
// // 用于记录已经设置过主从关系的 mac,避免重复
|
||
// Set<String> processedMacs = {};
|
||
|
||
// for (var item in responseList) {
|
||
// String mac = item['mac'].toLowerCase();
|
||
// String? bindMac = item['bindMac']?.toLowerCase();
|
||
// bool? bind = item['bind'];
|
||
|
||
// if (!deviceMap.containsKey(mac)) continue;
|
||
|
||
// BleDeviceData currentDevice = deviceMap[mac]!;
|
||
// currentDevice.bind = bind;
|
||
|
||
// if (bindMac != null && deviceMap.containsKey(bindMac)) {
|
||
// final isMutualBind = responseList.any((e) =>
|
||
// e['mac']?.toString().toLowerCase() == bindMac &&
|
||
// e['bindMac']?.toString().toLowerCase() == mac);
|
||
|
||
// if (isMutualBind) {
|
||
// if (processedMacs.contains(mac) ||
|
||
// processedMacs.contains(bindMac)) {
|
||
// continue;
|
||
// }
|
||
|
||
// final masterMac = (mac.compareTo(bindMac) < 0) ? mac : bindMac;
|
||
// final slaveMac = (mac.compareTo(bindMac) < 0) ? bindMac : mac;
|
||
|
||
// if (deviceMap.containsKey(masterMac) &&
|
||
// deviceMap.containsKey(slaveMac)) {
|
||
// deviceMap[masterMac]!.slave = deviceMap[slaveMac];
|
||
// processedMacs.add(masterMac);
|
||
// processedMacs.add(slaveMac);
|
||
// }
|
||
// } else {
|
||
// if (!processedMacs.contains(mac)) {
|
||
// BleDeviceData masterDevice = deviceMap[bindMac]!;
|
||
// masterDevice.slave = currentDevice;
|
||
// processedMacs.add(mac);
|
||
// processedMacs.add(bindMac);
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// // 获取所有被作为 slave 的 mac,用于排除掉
|
||
// final Set<String> allSlaveMacs = {
|
||
// for (var d in deviceMap.values)
|
||
// if (d.slave?.mac != null) d.slave!.mac!.toLowerCase()
|
||
// };
|
||
|
||
// // 构造最终列表,只保留主设备和未被作为 slave 的独立设备
|
||
// final List<BleDeviceData> finalList = deviceMap.values.where((d) {
|
||
// final mac = d.mac?.toLowerCase();
|
||
// if (mac == null) return false;
|
||
// if (d.slave != null) return true; // 主设备
|
||
// return !allSlaveMacs.contains(mac); // 不是别人 slave 的独立设备
|
||
// }).toList();
|
||
|
||
// model.betDevicelist = finalList;
|
||
// } else {
|
||
// model.betDevicelist = [];
|
||
// }
|
||
|
||
// updateAll();
|
||
// return res;
|
||
// }
|
||
// } catch (e) {
|
||
// print("获取设备状态异常: $e");
|
||
// EasyDartModule.logger.info("获取设备状态异常: $e");
|
||
// DailyLogUtils.writeLog("获取设备状态异常: $e");
|
||
// return ApiResponse(code: -1, msg: "请求失败".tr);
|
||
// }
|
||
|
||
// return ApiResponse(code: -1, msg: "未知错误".tr);
|
||
// }
|
||
|
||
Future<ApiResponse> updateDeviceStatus() async {
|
||
try {
|
||
String serviceAddress = ServiceConstant.service_address;
|
||
String serviceName = ServiceConstant.server_service;
|
||
String serviceApi = ServiceConstant.get_bluetooth_device_status;
|
||
String queryUrl = "$serviceAddress$serviceName$serviceApi";
|
||
|
||
if (model.devicelist != null && model.devicelist!.isNotEmpty) {
|
||
final macParams = model.devicelist!
|
||
.map((device) => "mac=${Uri.encodeQueryComponent(device.mac!)}")
|
||
.join("&");
|
||
|
||
if (queryUrl.contains('?')) {
|
||
queryUrl += '&$macParams';
|
||
} else {
|
||
queryUrl += '?$macParams';
|
||
}
|
||
String? language = "";
|
||
if (languageController.selectLanguage != null) {
|
||
language = languageController.selectLanguage.value!.language_code;
|
||
}
|
||
if (language != null && language.isNotEmpty) {
|
||
if (queryUrl.contains("?")) {
|
||
queryUrl += "&lang=$language";
|
||
} else {
|
||
queryUrl += "?lang=$language";
|
||
}
|
||
}
|
||
|
||
var response = await EasyDartModule.dio.get(queryUrl);
|
||
var responseData =
|
||
response.data is String ? jsonDecode(response.data) : response.data;
|
||
ApiResponse res =
|
||
ApiResponse.fromJson(responseData, (object) => object);
|
||
if (res.code != HttpStatusCodes.ok) return res;
|
||
|
||
if (response.data['data'] != null && response.data['data'] is List) {
|
||
List<dynamic> responseList = response.data['data'];
|
||
Map<String, BleDeviceData> deviceMap = {
|
||
for (var d in model.devicelist!)
|
||
if (d.mac != null) d.mac!: d
|
||
};
|
||
|
||
List<String> slaveMacsToRemove = [];
|
||
|
||
for (var item in responseList) {
|
||
String mac = item['mac'];
|
||
String? bindMac = item['bindMac'];
|
||
bool? bind = item['bind'];
|
||
|
||
if (deviceMap.containsKey(mac)) {
|
||
BleDeviceData currentDevice = deviceMap[mac]!;
|
||
currentDevice.bind = bind;
|
||
if (bindMac != null && deviceMap.containsKey(bindMac)) {
|
||
BleDeviceData masterDevice = deviceMap[bindMac]!;
|
||
masterDevice.slave = currentDevice;
|
||
slaveMacsToRemove.add(mac);
|
||
}
|
||
}
|
||
}
|
||
|
||
model.devicelist!
|
||
.removeWhere((device) => slaveMacsToRemove.contains(device.mac));
|
||
model.betDevicelist = model.devicelist!;
|
||
} else {
|
||
model.betDevicelist = [];
|
||
}
|
||
|
||
updateAll();
|
||
return res;
|
||
}
|
||
} catch (e) {
|
||
print("获取设备状态异常: $e");
|
||
EasyDartModule.logger.info("获取设备状态异常: $e");
|
||
DailyLogUtils.writeLog("获取设备状态异常: $e");
|
||
return ApiResponse(code: -1, msg: "请求失败".tr);
|
||
}
|
||
|
||
return ApiResponse(code: -1, msg: "未知错误".tr);
|
||
}
|
||
|
||
Future<ApiResponse> bindDeviceAndMAC(BleDeviceData d) async {
|
||
try {
|
||
ApiResponse apiResponse = ApiResponse(code: -1, msg: "蓝牙绑定.绑定失败".tr);
|
||
String serviceAddress = ServiceConstant.service_address;
|
||
String serviceName = ServiceConstant.server_service;
|
||
String serviceApi = ServiceConstant.device_bind;
|
||
String queryUrl = "$serviceAddress$serviceName$serviceApi";
|
||
String? language = "";
|
||
if (languageController.selectLanguage != null) {
|
||
language = languageController.selectLanguage.value!.language_code;
|
||
}
|
||
if (language != null && language.isNotEmpty) {
|
||
if (queryUrl.contains("?")) {
|
||
queryUrl += "&lang=$language";
|
||
} else {
|
||
queryUrl += "?lang=$language";
|
||
}
|
||
}
|
||
//todo 双人版的话根据slave取到mac
|
||
var data = {
|
||
"deviceType": 1,
|
||
"mac": d.mac,
|
||
};
|
||
var response =
|
||
await EasyDartModule.dio.post(queryUrl, data: jsonEncode(data));
|
||
if (response != null) {
|
||
var responseData =
|
||
response.data is String ? jsonDecode(response.data) : response.data;
|
||
ApiResponse res =
|
||
ApiResponse.fromJson(responseData, (object) => object);
|
||
MyUtils.formatResponse(res, "绑定成功.绑定成功".tr, "绑定成功.绑定成功".tr);
|
||
if (res.code == HttpStatusCodes.ok) {
|
||
PersonController personController = Get.find();
|
||
personController.currentPersonId.value = res.data['id'];
|
||
return res;
|
||
} else {
|
||
return res;
|
||
}
|
||
} else {
|
||
return ApiResponse(code: -1, msg: "服务器.失败".tr);
|
||
}
|
||
} catch (e) {
|
||
EasyDartModule.logger.info("蓝牙绑定.绑定异常: $e");
|
||
DailyLogUtils.writeLog("蓝牙绑定.绑定异常: $e");
|
||
}
|
||
return ApiResponse(code: -1, msg: "未知错误".tr);
|
||
}
|
||
|
||
@override
|
||
void onClose() {
|
||
stopStatusPolling();
|
||
super.onClose();
|
||
}
|
||
|
||
bindDevice(Map<String, dynamic> map) {}
|
||
|
||
Future<ApiResponse> bindDeviceByScan(String mac) async {
|
||
try {
|
||
ApiResponse apiResponse = ApiResponse(code: -1, msg: "蓝牙绑定.绑定失败".tr);
|
||
String serviceAddress = ServiceConstant.service_address;
|
||
String serviceName = ServiceConstant.server_service;
|
||
String serviceApi = ServiceConstant.device_bind;
|
||
String queryUrl = "$serviceAddress$serviceName$serviceApi";
|
||
String? language = "";
|
||
if (languageController.selectLanguage != null) {
|
||
language = languageController.selectLanguage.value!.language_code;
|
||
}
|
||
if (language != null && language.isNotEmpty) {
|
||
if (queryUrl.contains("?")) {
|
||
queryUrl += "&lang=$language";
|
||
} else {
|
||
queryUrl += "?lang=$language";
|
||
}
|
||
}
|
||
var data = {
|
||
"deviceType": 1,
|
||
"mac": mac,
|
||
};
|
||
var response =
|
||
await EasyDartModule.dio.post(queryUrl, data: jsonEncode(data));
|
||
if (response != null) {
|
||
var responseData =
|
||
response.data is String ? jsonDecode(response.data) : response.data;
|
||
ApiResponse res =
|
||
ApiResponse.fromJson(responseData, (object) => object);
|
||
MyUtils.formatResponse(res, "绑定成功.绑定成功".tr, "绑定成功.绑定成功".tr);
|
||
if (res.code == HttpStatusCodes.ok) {
|
||
return res;
|
||
}
|
||
apiResponse.msg = res.msg ?? apiResponse.msg;
|
||
} else {
|
||
return ApiResponse(code: -1, msg: "服务器.失败".tr);
|
||
}
|
||
return apiResponse;
|
||
} catch (e) {
|
||
EasyDartModule.logger.info("蓝牙绑定.绑定异常: $e");
|
||
DailyLogUtils.writeLog("蓝牙绑定.绑定异常: $e");
|
||
}
|
||
return ApiResponse(code: -1, msg: "未知错误".tr);
|
||
}
|
||
}
|