feat:完成云 OTA 升级

This commit is contained in:
anfe 2024-05-31 14:28:52 +08:00
parent f2e439b3be
commit 1be9cfab22
10 changed files with 160 additions and 40 deletions

View File

@ -856,5 +856,6 @@
"视频事件":"Video event", "视频事件":"Video event",
"请开启蓝牙":"Please turn on Bluetooth", "请开启蓝牙":"Please turn on Bluetooth",
"请选择有效日":"Please select the effective day", "请选择有效日":"Please select the effective day",
"公司名字长度不能小于 6 ": "The length of the company name cannot be less than 6" "公司名字长度不能小于 6 ": "The length of the company name cannot be less than 6",
"已是最新版本": "It is the latest version"
} }

View File

@ -885,5 +885,6 @@
"视频事件":"视频事件", "视频事件":"视频事件",
"请开启蓝牙":"请开启蓝牙", "请开启蓝牙":"请开启蓝牙",
"请选择有效日":"请选择有效日", "请选择有效日":"请选择有效日",
"公司名字长度不能小于 6 ": "公司名字长度不能小于 6 " "公司名字长度不能小于 6 ": "公司名字长度不能小于 6 ",
"已是最新版本": "已是最新版本"
} }

View File

@ -855,5 +855,6 @@
"视频事件": "视频事件", "视频事件": "视频事件",
"请开启蓝牙": "请开启蓝牙", "请开启蓝牙": "请开启蓝牙",
"请选择有效日": "请选择有效日", "请选择有效日": "请选择有效日",
"公司名字长度不能小于 6 ": "公司名字长度不能小于 6 " "公司名字长度不能小于 6 ": "公司名字长度不能小于 6 ",
"已是最新版本": "已是最新版本"
} }

View File

@ -8,15 +8,15 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:http/http.dart' as http;
import 'package:star_lock/blue/blue_manage.dart'; import 'package:star_lock/blue/blue_manage.dart';
import 'package:star_lock/blue/io_protocol/io_otaUpgrade.dart'; import 'package:star_lock/blue/io_protocol/io_otaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart'; import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart';
import 'package:star_lock/blue/io_reply.dart'; import 'package:star_lock/blue/io_reply.dart';
import 'package:star_lock/blue/io_tool/io_tool.dart'; import 'package:star_lock/blue/io_tool/io_tool.dart';
import 'package:star_lock/blue/io_tool/manager_event_bus.dart'; import 'package:star_lock/blue/io_tool/manager_event_bus.dart';
import 'package:star_lock/blue/sender_manage.dart'; import 'package:star_lock/main/lockDetail/lockSet/lockEscalation/version_entity.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSet_logic.dart'; import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/commonDataManage.dart'; import 'package:star_lock/tools/commonDataManage.dart';
import 'package:star_lock/tools/showTipView.dart'; import 'package:star_lock/tools/showTipView.dart';
@ -34,17 +34,8 @@ class LockEscalationLogic extends BaseGetXController {
int otaIndex = 0; int otaIndex = 0;
Uint8List? otaBin; Uint8List? otaBin;
int startSecond = 0; int startSecond = 0;
Map? headJson = null; Map? headJson;
FwVersionEntity? entity;
//
Future<void> setLockSetGeneralSetting() async {
// var entity = await ApiRepository.to.getLockVersionInfoData(
// lockId: state.getKeyInfosData.value.lockId.toString(),
// );
// if(entity.errorCode!.codeIsSuccessful){
//
// }
}
// //
Future<void> otaUpdate() async { Future<void> otaUpdate() async {
@ -58,6 +49,10 @@ class LockEscalationLogic extends BaseGetXController {
} }
final File file = File(result.files.single.path!); final File file = File(result.files.single.path!);
final Uint8List data = await file.readAsBytes(); final Uint8List data = await file.readAsBytes();
stateUpData(data);
}
Future<void> stateUpData(Uint8List data) async {
headJson = await getHeadFile(data); headJson = await getHeadFile(data);
if (headJson is! Map) { if (headJson is! Map) {
return; return;
@ -69,10 +64,10 @@ class LockEscalationLogic extends BaseGetXController {
final String md5Str = md5.convert(otaBin!).toString(); final String md5Str = md5.convert(otaBin!).toString();
headJson!['fwMd5'] = md5Str; headJson!['fwMd5'] = md5Str;
ShowTipView().showIosTipWithContentDialog('未避免异常情况,请在门打开时升级'.tr, () async { ShowTipView().showIosTipWithContentDialog('未避免异常情况,请在门打开时升级'.tr, () async {
blueOTAUpgrade(headJson!, [0, 0, 0, 0]); blueOTAUpgrade(headJson!, <int>[0, 0, 0, 0]);
EasyLoading.show( EasyLoading.show(
status: '设备连接中...'.tr, maskType: EasyLoadingMaskType.black); status: '设备连接中...'.tr, maskType: EasyLoadingMaskType.black);
Future.delayed(const Duration(seconds: 4), EasyLoading.dismiss); Future<void>.delayed(const Duration(seconds: 4), EasyLoading.dismiss);
}); });
} }
@ -81,9 +76,12 @@ class LockEscalationLogic extends BaseGetXController {
BlueManage().blueSendData(BlueManage().connectDeviceName, BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState deviceConnectionState) async { (BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) { if (deviceConnectionState == BluetoothConnectionState.connected) {
final privateKey = await Storage.getStringList(saveBluePrivateKey); final List<String>? privateKey =
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!); await Storage.getStringList(saveBluePrivateKey);
final signKey = await Storage.getStringList(saveBlueSignKey); final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
final List<String>? signKey =
await Storage.getStringList(saveBlueSignKey);
final List<int> signKeyDataList = changeStringListToIntList(signKey!); final List<int> signKeyDataList = changeStringListToIntList(signKey!);
final String uid = await Storage.getUid() ?? ''; final String uid = await Storage.getUid() ?? '';
BlueManage().writeCharacteristicWithResponse(OTAUpgradeCommand( BlueManage().writeCharacteristicWithResponse(OTAUpgradeCommand(
@ -236,17 +234,47 @@ class LockEscalationLogic extends BaseGetXController {
return bin; return bin;
} }
//
Future<void> checkUpData() async {
final String model = CommonDataManage().currentKeyInfo.model ?? '';
String currentVersion = CommonDataManage().currentKeyInfo.fwVersion ?? '';
if (currentVersion.split('.').length >= 3) {
currentVersion = currentVersion.split('.')[0] +
'.' +
currentVersion.split('.')[1] +
'.' +
currentVersion.split('.')[2];
}
state.showVersion.value = currentVersion;
entity = await ApiRepository.to
.getFwVersion(model: model, currentVersion: currentVersion);
state.isShowUpDataBtn.value = entity?.data?.isUpdate == 1;
state.showNewVersion.value = entity?.data?.version??'';
}
//
Future<void> downloadTheFile() async {
if (entity?.data?.downloadUrl == null) {
return;
}
final String url = entity!.data!.downloadUrl!;
final http.Response response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
stateUpData(response.bodyBytes);
}
}
@override @override
void onReady() { void onReady() {
super.onReady(); super.onReady();
setLockSetGeneralSetting(); checkUpData();
} }
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
_replySubscription = _replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((reply) { EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
if (reply is OTAUpgradeReply) { if (reply is OTAUpgradeReply) {
if (reply.status == 0x00) { if (reply.status == 0x00) {
// //

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/tools/commonDataManage.dart';
import '../../../../app_settings/app_colors.dart'; import '../../../../app_settings/app_colors.dart';
import '../../../../tools/submitBtn.dart'; import '../../../../tools/submitBtn.dart';
@ -63,29 +64,46 @@ class _LockEscalationPageState extends State<LockEscalationPage> {
SizedBox( SizedBox(
width: 10.w, width: 10.w,
), ),
Text( Obx(() {
// TranslationLoader.lanKeys!.haveNewVersion!.tr, if (logic.state.isShowUpDataBtn.value) {
"未发现新版本", return Text(
style: TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600), TranslationLoader.lanKeys!.haveNewVersion!.tr + logic.state.showNewVersion.value,
) style:
TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600),
);
} else {
return Text(
'已是最新版本'.tr,
style:
TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600),
);
}
})
], ],
), ),
SizedBox( SizedBox(
height: 30.h, height: 30.h,
), ),
Text( Obx(() {
"${TranslationLoader.lanKeys!.currentVersion!.tr}1.0.0", return Text(
style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor), '${TranslationLoader.lanKeys!.currentVersion!.tr}${logic.state.showVersion.value}',
), style:
TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
);
}),
SizedBox( SizedBox(
height: 40.h, height: 40.h,
), ),
Obx(() { Obx(() {
return !logic.state.otaUpdateIng.value final bool show = !logic.state.otaUpdateIng.value &&
logic.state.isShowUpDataBtn.value;
return show
? SubmitBtn( ? SubmitBtn(
btnName: TranslationLoader.lanKeys!.upgrade!.tr, btnName: TranslationLoader.lanKeys!.upgrade!.tr,
onClick: () {}) onClick: () {
: SizedBox(); logic.downloadTheFile();
})
: const SizedBox();
}), }),
SizedBox( SizedBox(
height: 10.h, height: 10.h,

View File

@ -1,6 +1,9 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
class LockEscalationState { class LockEscalationState {
var otaUpdateIng = false.obs; RxBool otaUpdateIng = false.obs;
var otaProgress = 0.00.obs; RxDouble otaProgress = 0.00.obs;
RxBool isShowUpDataBtn = false.obs;
RxString showVersion = '1.0.0'.obs;
RxString showNewVersion = '1.0.0'.obs;
} }

View File

@ -0,0 +1,48 @@
class FwVersionEntity {
FwVersionEntity({this.errorCode, this.description, this.errorMsg, this.data});
FwVersionEntity.fromJson(Map<String, dynamic> json) {
errorCode = json['errorCode'];
description = json['description'];
errorMsg = json['errorMsg'];
if (json['data'] is Map) {
data = Data.fromJson(json['data']);
}
}
int? errorCode;
String? description;
String? errorMsg;
Data? data;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['errorCode'] = errorCode;
data['description'] = description;
data['errorMsg'] = errorMsg;
data['data'] = this.data;
return data;
}
}
class Data {
Data.fromJson(Map<String, dynamic> json) {
isUpdate = json['isUpdate'];
downloadUrl = json['downloadUrl'];
description = json['description'];
}
int? isUpdate;
String? downloadUrl;
String? description;
String? version;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['isUpdate'] = isUpdate;
data['downloadUrl'] = downloadUrl;
data['description'] = description;
data['version'] = version;
return data;
}
}

View File

@ -240,4 +240,5 @@ abstract class Api {
final String lockDataUploadUrl = '/lockRecords/lockDataUpload'; // final String lockDataUploadUrl = '/lockRecords/lockDataUpload'; //
final String getNoticeTemplateURL = '/key/getNoticeTemplate'; // final String getNoticeTemplateURL = '/key/getNoticeTemplate'; //
final String appGetAppInfoURL = '/app/getAppInfo'; //APP基本信息 final String appGetAppInfoURL = '/app/getAppInfo'; //APP基本信息
final String appGetFwVersionURL = '/app/getFwVersion'; //
} }

View File

@ -2127,6 +2127,17 @@ class ApiProvider extends BaseProvider {
Future<Response<dynamic>> getAppInfo() => Future<Response<dynamic>> getAppInfo() =>
post(appGetAppInfoURL.toUrl, jsonEncode(<String, int>{}), post(appGetAppInfoURL.toUrl, jsonEncode(<String, int>{}),
isShowErrMsg: false); isShowErrMsg: false);
// App固件信息
Future<Response<dynamic>> getFwVersion(String model, String currentVersion) =>
post(
appGetFwVersionURL.toUrl,
jsonEncode(<String, dynamic>{
'model': model,
'currentVersion': currentVersion,
}),
isUnShowLoading: true,
);
} }
extension ExtensionString on String { extension ExtensionString on String {

View File

@ -9,6 +9,7 @@ import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/ma
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendLockGroupListEntity.dart'; import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendLockGroupListEntity.dart';
import 'package:star_lock/main/lockDetail/face/addFace/addFace_entity.dart'; import 'package:star_lock/main/lockDetail/face/addFace/addFace_entity.dart';
import 'package:star_lock/main/lockDetail/lockSet/basicInformation/basicInformation/KeyDetailEntity.dart'; import 'package:star_lock/main/lockDetail/lockSet/basicInformation/basicInformation/KeyDetailEntity.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockEscalation/version_entity.dart';
import 'package:star_lock/main/lockDetail/messageWarn/lockUser/lockUser_entity.dart'; import 'package:star_lock/main/lockDetail/messageWarn/lockUser/lockUser_entity.dart';
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/coerceOpenDoor/coerceFingerprintList/coerceFingerprintList_entity.dart'; import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/coerceOpenDoor/coerceFingerprintList/coerceFingerprintList_entity.dart';
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/msgNotification/msgNotification_entity.dart'; import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/msgNotification/msgNotification_entity.dart';
@ -2154,8 +2155,15 @@ class ApiRepository {
// //
Future<GetAppInfo> getAppInfo() async { Future<GetAppInfo> getAppInfo() async {
final Response<dynamic> res = final Response<dynamic> res = await apiProvider.getAppInfo();
await apiProvider.getAppInfo();
return GetAppInfo.fromJson(res.body); return GetAppInfo.fromJson(res.body);
} }
//
Future<FwVersionEntity> getFwVersion(
{required String model, required String currentVersion}) async {
final Response<dynamic> res =
await apiProvider.getFwVersion(model, currentVersion);
return FwVersionEntity.fromJson(res.body);
}
} }