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",
"请开启蓝牙":"Please turn on Bluetooth",
"请选择有效日":"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_easyloading/flutter_easyloading.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/io_protocol/io_otaUpgrade.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_tool/io_tool.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/lockSet/lockSet_logic.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockEscalation/version_entity.dart';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/commonDataManage.dart';
import 'package:star_lock/tools/showTipView.dart';
@ -34,17 +34,8 @@ class LockEscalationLogic extends BaseGetXController {
int otaIndex = 0;
Uint8List? otaBin;
int startSecond = 0;
Map? headJson = null;
//
Future<void> setLockSetGeneralSetting() async {
// var entity = await ApiRepository.to.getLockVersionInfoData(
// lockId: state.getKeyInfosData.value.lockId.toString(),
// );
// if(entity.errorCode!.codeIsSuccessful){
//
// }
}
Map? headJson;
FwVersionEntity? entity;
//
Future<void> otaUpdate() async {
@ -58,6 +49,10 @@ class LockEscalationLogic extends BaseGetXController {
}
final File file = File(result.files.single.path!);
final Uint8List data = await file.readAsBytes();
stateUpData(data);
}
Future<void> stateUpData(Uint8List data) async {
headJson = await getHeadFile(data);
if (headJson is! Map) {
return;
@ -69,10 +64,10 @@ class LockEscalationLogic extends BaseGetXController {
final String md5Str = md5.convert(otaBin!).toString();
headJson!['fwMd5'] = md5Str;
ShowTipView().showIosTipWithContentDialog('未避免异常情况,请在门打开时升级'.tr, () async {
blueOTAUpgrade(headJson!, [0, 0, 0, 0]);
blueOTAUpgrade(headJson!, <int>[0, 0, 0, 0]);
EasyLoading.show(
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,
(BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) {
final privateKey = await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final signKey = await Storage.getStringList(saveBlueSignKey);
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
final List<String>? signKey =
await Storage.getStringList(saveBlueSignKey);
final List<int> signKeyDataList = changeStringListToIntList(signKey!);
final String uid = await Storage.getUid() ?? '';
BlueManage().writeCharacteristicWithResponse(OTAUpgradeCommand(
@ -236,17 +234,47 @@ class LockEscalationLogic extends BaseGetXController {
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
void onReady() {
super.onReady();
setLockSetGeneralSetting();
checkUpData();
}
@override
void onInit() {
super.onInit();
_replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((reply) {
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
if (reply is OTAUpgradeReply) {
if (reply.status == 0x00) {
//

View File

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

View File

@ -1,6 +1,9 @@
import 'package:get/get.dart';
class LockEscalationState {
var otaUpdateIng = false.obs;
var otaProgress = 0.00.obs;
RxBool otaUpdateIng = false.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 getNoticeTemplateURL = '/key/getNoticeTemplate'; //
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() =>
post(appGetAppInfoURL.toUrl, jsonEncode(<String, int>{}),
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 {

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/face/addFace/addFace_entity.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/msgNotification/coerceOpenDoor/coerceFingerprintList/coerceFingerprintList_entity.dart';
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/msgNotification/msgNotification_entity.dart';
@ -2154,8 +2155,15 @@ class ApiRepository {
//
Future<GetAppInfo> getAppInfo() async {
final Response<dynamic> res =
await apiProvider.getAppInfo();
final Response<dynamic> res = await apiProvider.getAppInfo();
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);
}
}