fix: 调整第三方平台设置
This commit is contained in:
parent
4f1b1dd02f
commit
e1011688de
@ -46,7 +46,7 @@ class BlueManage {
|
||||
StreamSubscription<BluetoothConnectionState>? _connectionStateSubscription;
|
||||
|
||||
StreamSubscription<int>? _mtuSubscription;
|
||||
int? _mtuSize = 20;
|
||||
int? _mtuSize = 30;
|
||||
|
||||
// 当前连接设备的名字
|
||||
String connectDeviceName = '';
|
||||
@ -813,30 +813,33 @@ class BlueManage {
|
||||
|
||||
/// 写入蓝牙特征值,并等待响应
|
||||
Future<void> writeCharacteristicWithResponse(List<int> value) async {
|
||||
// 如果MTU还是默认值,尝试重新请求
|
||||
if (_mtuSize == 23 && bluetoothConnectDevice != null) {
|
||||
try {
|
||||
if (Platform.isAndroid) {
|
||||
await bluetoothConnectDevice!.requestMtu(512);
|
||||
}
|
||||
} catch (e) {
|
||||
AppLog.log('重新请求MTU失败: $e');
|
||||
}
|
||||
}
|
||||
final List<BluetoothService> services = await bluetoothConnectDevice!.discoverServices();
|
||||
for (final BluetoothService service in services) {
|
||||
if (service.uuid == _serviceIdConnect) {
|
||||
for (final BluetoothCharacteristic characteristic in service.characteristics) {
|
||||
if (characteristic.characteristicUuid == _characteristicIdWrite) {
|
||||
try {
|
||||
_initGetMtuSubscription();
|
||||
// 如果MTU还是默认值,尝试重新请求
|
||||
if ((_mtuSize == 23 || _mtuSize == 20) && bluetoothConnectDevice != null) {
|
||||
try {
|
||||
if (Platform.isAndroid) {
|
||||
await bluetoothConnectDevice!.requestMtu(512);
|
||||
}
|
||||
} catch (e) {
|
||||
AppLog.log('重新请求MTU失败: $e');
|
||||
}
|
||||
}
|
||||
// 添加重试机制
|
||||
int retryCount = 0;
|
||||
const int maxRetries = 3;
|
||||
const int retryDelayMs = 500;
|
||||
|
||||
final List<int> valueList = value;
|
||||
AppLog.log('发送数据时当前的mtuSize是:${_mtuSize}');
|
||||
final List subData = splitList(valueList, _mtuSize!);
|
||||
|
||||
|
||||
for (int i = 0; i < subData.length; i++) {
|
||||
// 对每个数据包都应用重试逻辑
|
||||
bool packetSent = false;
|
||||
|
||||
@ -1,24 +1,109 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class ActivateInfoResponse {
|
||||
ActivateInfoResponse({
|
||||
this.description,
|
||||
this.errorCode,
|
||||
this.data, // 现在是一个 List<ActivateInfo>
|
||||
this.data, // 现在是一个 List<ActivateInfo>
|
||||
this.errorMsg,
|
||||
});
|
||||
|
||||
ActivateInfoResponse.fromJson(dynamic json) {
|
||||
description = json['description'];
|
||||
errorCode = json['errorCode'];
|
||||
// 修改这里:如果 json['data'] 是列表,则解析为 List<ActivateInfo>;否则为空列表
|
||||
data = json['data'] != null
|
||||
? (json['data'] as List).map((item) => ActivateInfo.fromJson(item)).toList()
|
||||
: [];
|
||||
// 修改这里:直接解析为单个 ActivateInfo 对象
|
||||
data = json['data'] != null ? ActivateInfo.fromJson(json['data']) : null;
|
||||
errorMsg = json['errorMsg'];
|
||||
}
|
||||
|
||||
String? description;
|
||||
int? errorCode;
|
||||
List<ActivateInfo>? data; // 改为 List<ActivateInfo>
|
||||
ActivateInfo? data; // 改为 List<ActivateInfo>
|
||||
String? errorMsg;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['description'] = description;
|
||||
map['errorCode'] = errorCode;
|
||||
if (data != null) {
|
||||
// 修改这里:将单个 ActivateInfo 对象转换为 JSON
|
||||
map['data'] = data!.toJson();
|
||||
}
|
||||
map['errorMsg'] = errorMsg;
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ActivateInfoResponse{description: $description, errorCode: $errorCode, data: $data, errorMsg: $errorMsg}';
|
||||
}
|
||||
}
|
||||
|
||||
class ActivateInfo {
|
||||
String? authCode;
|
||||
String? activatedAt;
|
||||
Map<String, dynamic>? extraParams; // 修改为 Map 类型
|
||||
|
||||
ActivateInfo({
|
||||
this.authCode,
|
||||
this.activatedAt,
|
||||
this.extraParams,
|
||||
});
|
||||
|
||||
ActivateInfo.fromJson(dynamic json) {
|
||||
authCode = json['auth_code'] ?? '';
|
||||
activatedAt = json['activated_at'] ?? '';
|
||||
// 修改这里:将 extraParams 解析为 Map 对象
|
||||
if (json['extra_params'] != null) {
|
||||
if (json['extra_params'] is Map) {
|
||||
extraParams = json['extra_params'];
|
||||
} else if (json['extra_params'] is String) {
|
||||
// 如果是字符串,尝试解析为 JSON 对象
|
||||
try {
|
||||
extraParams = jsonDecode(json['extra_params']);
|
||||
} catch (e) {
|
||||
// 解析失败则设为 null 或空 map
|
||||
extraParams = {};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
extraParams = {};
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['authCode'] = authCode;
|
||||
map['activatedAt'] = activatedAt;
|
||||
map['extraParams'] = extraParams;
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ActivateInfo{authCode: $authCode, activatedAt: $activatedAt, extraParams: $extraParams}';
|
||||
}
|
||||
}
|
||||
|
||||
class TppSupportResponse {
|
||||
TppSupportResponse({
|
||||
this.description,
|
||||
this.errorCode,
|
||||
this.data, // 现在是一个 List<ActivateInfo>
|
||||
this.errorMsg,
|
||||
});
|
||||
|
||||
TppSupportResponse.fromJson(dynamic json) {
|
||||
description = json['description'];
|
||||
errorCode = json['errorCode'];
|
||||
// 修改这里:如果 json['data'] 是列表,则解析为 List<ActivateInfo>;否则为空列表
|
||||
data = json['data'] != null ? (json['data'] as List).map((item) => TppSupportInfo.fromJson(item)).toList() : [];
|
||||
errorMsg = json['errorMsg'];
|
||||
}
|
||||
|
||||
String? description;
|
||||
int? errorCode;
|
||||
List<TppSupportInfo>? data; // 改为 List<ActivateInfo>
|
||||
String? errorMsg;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
@ -35,33 +120,28 @@ class ActivateInfoResponse {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ActivateInfoResponse{description: $description, errorCode: $errorCode, data: $data, errorMsg: $errorMsg}';
|
||||
return 'TppSupportResponse{description: $description, errorCode: $errorCode, data: $data, errorMsg: $errorMsg}';
|
||||
}
|
||||
}
|
||||
|
||||
class ActivateInfo {
|
||||
String? platformName;
|
||||
class TppSupportInfo {
|
||||
int? platform;
|
||||
String? platformName;
|
||||
|
||||
ActivateInfo({
|
||||
this.platformName,
|
||||
TppSupportInfo({
|
||||
this.platform,
|
||||
this.platformName,
|
||||
});
|
||||
|
||||
ActivateInfo.fromJson(dynamic json) {
|
||||
platformName = json['platformName'] ?? '';
|
||||
platform = json['platform'] ?? '';
|
||||
TppSupportInfo.fromJson(dynamic json) {
|
||||
platform = json['platform'] as int? ?? -1;
|
||||
platformName = json['platform_name'] as String? ?? '';
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['platformName'] = platformName;
|
||||
map['platform'] = platform;
|
||||
map['platform_name'] = platformName;
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ActivateInfo{platformName: $platformName, platform: $platform}';
|
||||
}
|
||||
}
|
||||
|
||||
@ -658,6 +658,7 @@ class LockDetailLogic extends BaseGetXController {
|
||||
if (list.isEmpty) {
|
||||
return;
|
||||
}
|
||||
AppLog.log('list:${list}');
|
||||
final KeyOperationRecordEntity entity =
|
||||
await ApiRepository.to.lockRecordUploadData(lockId: state.keyInfos.value.lockId.toString(), records: list);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
|
||||
@ -29,7 +29,24 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
super.onReady();
|
||||
await getActivateInfo();
|
||||
_initReplySubscription();
|
||||
getServerDatetime();
|
||||
await getServerDatetime();
|
||||
showEasyLoading();
|
||||
showBlueConnetctToastTimer(action: () {
|
||||
dismissEasyLoading();
|
||||
});
|
||||
BlueManage().blueSendData(
|
||||
BlueManage().connectDeviceName,
|
||||
(BluetoothConnectionState connectionState) async {
|
||||
if (connectionState == BluetoothConnectionState.connected) {
|
||||
IoSenderManage.readRegisterKey(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
);
|
||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -57,6 +74,7 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
Future<void> getServerDatetime() async {
|
||||
final GetServerDatetimeEntity entity = await ApiRepository.to.getServerDatetimeData(isUnShowLoading: true);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
state.serverTime = entity.data!.date! ~/ 1000;
|
||||
state.differentialTime = entity.data!.date! ~/ 1000 - DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
}
|
||||
}
|
||||
@ -72,7 +90,6 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
return;
|
||||
}
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
||||
AppLog.log('输出了listen:${_replySubscription.hashCode}');
|
||||
if (reply is SenderReadRegisterKeyCommandReply) {
|
||||
_handleReadRegisterKeyReply(reply);
|
||||
}
|
||||
@ -158,7 +175,7 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
uuid: response.data?.extraParams?['uuid'],
|
||||
key: response.data?.authCode,
|
||||
mac: response.data?.extraParams?['mac'],
|
||||
platform: 1,
|
||||
platform: state.selectPlatFormIndex.value,
|
||||
utcTimeStamp: getUTCNetTime(),
|
||||
);
|
||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||
@ -191,25 +208,11 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
|
||||
void savePlatFormSetting() {
|
||||
if (state.selectPlatFormIndex.value == 1 || state.selectPlatFormIndex.value == 0) {
|
||||
showEasyLoading();
|
||||
showBlueConnetctToastTimer(action: () {
|
||||
dismissEasyLoading();
|
||||
});
|
||||
BlueManage().blueSendData(
|
||||
BlueManage().connectDeviceName,
|
||||
(BluetoothConnectionState connectionState) async {
|
||||
if (connectionState == BluetoothConnectionState.connected) {
|
||||
IoSenderManage.readRegisterKey(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
);
|
||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
}
|
||||
},
|
||||
);
|
||||
if (state.registerKey.isNotEmpty) {
|
||||
_requestAuthorizationCode();
|
||||
}
|
||||
} else {
|
||||
showToast('目前只支持切换至涂鸦智能协议'.tr);
|
||||
showToast('目前只支持切换至涂鸦智能、锁通通协议'.tr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,15 +235,14 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
final platform = reply.data[7];
|
||||
// 提取 RegisterKey (从第7个字节开始,长度为40)
|
||||
final List<int> registerKeyBytes = reply.data.sublist(7, 47);
|
||||
final List<int> registerKeyBytes = reply.data.sublist(8, 48);
|
||||
final String registerKey = String.fromCharCodes(registerKeyBytes);
|
||||
|
||||
state.selectPlatFormIndex.value = platform;
|
||||
print('platform: $platform');
|
||||
print('Register Key: $registerKey');
|
||||
state.registerKey.value = registerKey;
|
||||
if (registerKey.isNotEmpty) {
|
||||
_requestAuthorizationCode();
|
||||
}
|
||||
//成功
|
||||
cancelBlueConnetctToastTimer();
|
||||
dismissEasyLoading();
|
||||
@ -265,8 +267,8 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
IoSenderManage.senderGetStarLockStatuInfo(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
utcTimeStamp: 0,
|
||||
unixTimeStamp: 0,
|
||||
utcTimeStamp: state.serverTime,
|
||||
unixTimeStamp: getLocalTime2(),
|
||||
isBeforeAddUser: false,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
@ -278,6 +280,18 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
});
|
||||
}
|
||||
|
||||
int getLocalTime() {
|
||||
final DateTime now = DateTime.now();
|
||||
final Duration timeZoneOffset = now.timeZoneOffset;
|
||||
return state.differentialTime + timeZoneOffset.inSeconds;
|
||||
}
|
||||
|
||||
int getLocalTime2() {
|
||||
final DateTime now = DateTime.now();
|
||||
final Duration timeZoneOffset = now.timeZoneOffset;
|
||||
return state.serverTime + timeZoneOffset.inSeconds;
|
||||
}
|
||||
|
||||
void _handleAuthorizationCodeReply(SenderAuthorizationCodeCommandReply reply) {
|
||||
final int status = reply.data[6];
|
||||
switch (status) {
|
||||
@ -285,7 +299,12 @@ class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
//成功
|
||||
cancelBlueConnetctToastTimer();
|
||||
dismissEasyLoading();
|
||||
showToast('操作成功,请在24小时内用涂鸦APP添加门锁,否则将过期'.tr);
|
||||
if (state.selectPlatFormIndex.value == 1) {
|
||||
showSuccess('操作成功,请尽快用"涂鸦”APP配置,如不使用请关闭该设置支持'.tr);
|
||||
} else if (state.selectPlatFormIndex.value == 0) {
|
||||
showSuccess('操作成功'.tr);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
|
||||
@ -128,25 +128,27 @@ class _ThirdPartyPlatformPageState extends State<ThirdPartyPlatformPage> {
|
||||
// 最后一个元素不显示分割线(取反)
|
||||
isHaveDirection: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: Radio<String>(
|
||||
// Radio 的值:使用平台的唯一标识(如 id)
|
||||
value: platform,
|
||||
// 当前选中的值:与 selectPlatFormIndex 关联的 id
|
||||
groupValue: state.platFormSet.value[state.selectPlatFormIndex.value],
|
||||
// 选中颜色(可选,默认主题色)
|
||||
activeColor: AppColors.mainColor,
|
||||
// 点击 Radio 时回调(更新选中索引)
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
setState(() {
|
||||
// 找到当前选中平台的索引(根据 id 匹配)
|
||||
final newIndex = state.platFormSet.value.indexWhere((p) => p == value);
|
||||
if (newIndex != -1) {
|
||||
state.selectPlatFormIndex.value = newIndex;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
rightWidget: Obx(
|
||||
() => Radio<String>(
|
||||
// Radio 的值:使用平台的唯一标识(如 id)
|
||||
value: platform,
|
||||
// 当前选中的值:与 selectPlatFormIndex 关联的 id
|
||||
groupValue: state.platFormSet.value[state.selectPlatFormIndex.value],
|
||||
// 选中颜色(可选,默认主题色)
|
||||
activeColor: AppColors.mainColor,
|
||||
// 点击 Radio 时回调(更新选中索引)
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
setState(() {
|
||||
// 找到当前选中平台的索引(根据 id 匹配)
|
||||
final newIndex = state.platFormSet.value.indexWhere((p) => p == value);
|
||||
if (newIndex != -1) {
|
||||
state.selectPlatFormIndex.value = newIndex;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
action: () {
|
||||
setState(() {
|
||||
|
||||
@ -13,7 +13,7 @@ class ThirdPartyPlatformState {
|
||||
}
|
||||
|
||||
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
|
||||
int differentialTime = 0;// 服务器时间即UTC+0时间
|
||||
int differentialTime = 0; // 服务器时间即UTC+0时间
|
||||
|
||||
// 响应式字符串集合(自动触发 UI 更新)
|
||||
final RxList<String> platFormSet = List.of({
|
||||
@ -25,8 +25,11 @@ class ThirdPartyPlatformState {
|
||||
// 响应式字符串集合(自动触发 UI 更新)
|
||||
final RxList<TppSupportInfo> tppSupportList = RxList<TppSupportInfo>([]);
|
||||
|
||||
RxInt selectPlatFormIndex = 1.obs;
|
||||
RxInt selectPlatFormIndex = (-1).obs;
|
||||
RxBool openNumber = false.obs;
|
||||
RxString registerKey = ''.obs;
|
||||
|
||||
Map lockInfo = {};
|
||||
|
||||
int serverTime = 0; // 服务器时间即UTC+0时间
|
||||
}
|
||||
|
||||
@ -305,6 +305,8 @@ abstract class Api {
|
||||
'/lockSetting/updateLockSetting'; // 设置语音包
|
||||
final String reportBuyRequestURL =
|
||||
'/service/reportBuyRequest'; // 上报增值服务购买请求
|
||||
final String getActivateInfoURL =
|
||||
final String getTppSupportURL =
|
||||
'/api/authCode/getTppSupport'; // 查询ttp
|
||||
final String getActivateInfoURL =
|
||||
'/api/authCode/getActivateInfo'; // 查询ttp
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user