feat: 新增常见问题页面及升级固件相关逻辑

This commit is contained in:
wuyaxi 2025-07-15 10:01:52 +08:00
parent fa270b77e0
commit a733840c5e
5 changed files with 341 additions and 133 deletions

View File

@ -41,6 +41,7 @@ import 'package:star_lock/main/lockDetail/palm/palmList/palmList_page.dart';
import 'package:star_lock/main/lockDetail/passwordKey/passwordKeyDetailChangeDate/passwordKeyDetailChangeDate_page.dart';
import 'package:star_lock/main/lockMian/lockMain/xhj/lockMain_xhj_page.dart';
import 'package:star_lock/mine/about/webviewShow_page.dart';
import 'package:star_lock/mine/addLock/lockAddFaq/lockAddFaq_page.dart';
import 'package:star_lock/mine/addLock/lockResetConfirm/lockResetConfirm_page.dart';
import 'package:star_lock/mine/mine/safeVerify/safeVerify_page.dart';
import 'package:star_lock/mine/minePersonInfo/minePersonInfoEmail/mineBindPhoneOrEmail_page.dart';
@ -516,6 +517,7 @@ abstract class Routers {
static const String starChartTalkView = '/starChartTalkView'; //
static const String h264WebView = '/h264WebView'; //
static const String lockResetConfirmPage = '/LockResetConfirmPage'; //
static const String lockAddFaqPage = '/LockAddFaqPage';
}
abstract class AppRouters {
@ -1191,5 +1193,9 @@ abstract class AppRouters {
name: Routers.lockResetConfirmPage,
page: () => const LockResetConfirmPage(),
),
GetPage<dynamic>(
name: Routers.lockAddFaqPage,
page: () => const LockAddFaqPage(),
),
];
}

View File

@ -0,0 +1,23 @@
import 'dart:io';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/mine/addLock/nearbyLock/nearbyLock_logic.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/widget/permission/permission_dialog.dart';
class LockAddFaqLogic extends BaseGetXController {
// OTA升级
void startOtaUpgrade() async {
//
if (!Platform.isIOS) {
final bool storageRequest = await PermissionDialog.requestStorage();
if (!storageRequest) {
return;
}
}
//
final NearbyLockLogic upgradeLogic = NearbyLockLogic();
upgradeLogic.otaUpdate();
}
}

View File

@ -0,0 +1,248 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/mine/addLock/lockAddFaq/lockAddFaq_logic.dart';
import '../../../app_settings/app_colors.dart';
import '../../../tools/titleAppBar.dart';
class LockAddFaqPage extends StatefulWidget {
const LockAddFaqPage({Key? key}) : super(key: key);
@override
State<LockAddFaqPage> createState() => _LockAddFaqPageState();
}
class _LockAddFaqPageState extends State<LockAddFaqPage> {
final LockAddFaqLogic logic = Get.put(LockAddFaqLogic());
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: TitleAppBar(
barTitle: '常见问题'.tr,
haveBack: true,
backgroundColor: AppColors.mainColor,
),
body: ListView(
padding: EdgeInsets.all(20.w),
children: [
// 1
_buildFaqItem(
icon: Icons.bluetooth,
title: '蓝牙未开启或未授权'.tr,
description: '请确保手机蓝牙已开启并授权App使用蓝牙权限。'.tr,
solution: '检查手机设置中的蓝牙权限确保已授权给App。'.tr,
),
SizedBox(height: 20.h),
// 2
_buildFaqItem(
icon: Icons.refresh,
title: '未重置锁'.tr,
description: '请先将锁重置为出厂状态,重置方法详见上一步指引。'.tr,
solution: '找到锁上的重置按钮,长按直到听到"滴"声或看到指示灯闪烁。'.tr,
),
SizedBox(height: 20.h),
// 3
_buildFaqItem(
icon: Icons.battery_alert,
title: '锁电量过低'.tr,
description: '锁电量过低可能导致无法正常连接和添加。'.tr,
solution: '请更换电池后重试。'.tr,
),
SizedBox(height: 20.h),
// 4
_buildFaqItem(
icon: Icons.signal_wifi_off,
title: '距离过远'.tr,
description: '请确保手机与锁的距离在有效范围内。'.tr,
solution: '将手机靠近锁距离保持在1米以内。'.tr,
),
SizedBox(height: 20.h),
// 5
_buildFaqItem(
icon: Icons.person_off,
title: '锁已被其他用户添加'.tr,
description: '如果锁已被其他用户添加,需要先解除绑定。'.tr,
solution: '请联系锁的管理员解除绑定,或使用管理员权限重置锁。'.tr,
),
SizedBox(height: 30.h),
//
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: ElevatedButton.icon(
onPressed: logic.startOtaUpgrade,
icon: const Icon(Icons.system_update_alt, color: Colors.white),
label: Text(
'尝试升级固件'.tr,
style: TextStyle(
color: Colors.white,
fontSize: 20.sp,
fontWeight: FontWeight.w500,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.mainColor,
padding: EdgeInsets.symmetric(vertical: 15.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.w),
),
elevation: 2,
),
),
),
SizedBox(height: 20.h),
//
Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.orange[50],
borderRadius: BorderRadius.circular(12.w),
border: Border.all(color: Colors.orange[200]!),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.info_outline,
color: Colors.orange[700], size: 20.w),
SizedBox(width: 8.w),
Text(
'升级说明'.tr,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.orange[700],
),
),
],
),
SizedBox(height: 8.h),
Text(
'如果以上方法都无法解决问题,可以尝试升级锁的固件。升级前请确保:'.tr,
style: TextStyle(
fontSize: 14.sp,
color: Colors.orange[800],
),
),
SizedBox(height: 8.h),
Text(
'• 锁电量充足\n• 已获取正确的固件文件\n• 升级过程中不要断开连接'.tr,
style: TextStyle(
fontSize: 14.sp,
color: Colors.orange[800],
height: 1.4,
),
),
],
),
),
],
),
);
}
Widget _buildFaqItem({
required IconData icon,
required String title,
required String description,
required String solution,
}) {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(12.w),
border: Border.all(color: Colors.grey[200]!),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 40.w,
height: 40.w,
decoration: BoxDecoration(
color: AppColors.mainColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(20.w),
),
child: Icon(
icon,
color: AppColors.mainColor,
size: 26.w,
),
),
SizedBox(width: 12.w),
Expanded(
child: Text(
title,
style: TextStyle(
fontSize: 20.sp,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
),
],
),
SizedBox(height: 12.h),
Text(
description,
style: TextStyle(
fontSize: 16.sp,
color: Colors.black54,
height: 1.4,
),
),
SizedBox(height: 8.h),
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: AppColors.mainColor.withOpacity(0.05),
borderRadius: BorderRadius.circular(8.w),
border: Border.all(color: AppColors.mainColor.withOpacity(0.2)),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
Icons.lightbulb_outline,
color: AppColors.mainColor,
size: 18.w,
),
SizedBox(width: 8.w),
Expanded(
child: Text(
solution,
style: TextStyle(
fontSize: 14.sp,
color: AppColors.mainColor,
fontWeight: FontWeight.w500,
height: 1.4,
),
),
),
],
),
),
],
),
);
}
}

View File

@ -337,17 +337,15 @@ class NearbyLockLogic extends BaseGetXController {
// 'featureSettingValue': state.featureSettingValue,
// 'featureSettingParams': state.featureSettingParams,
// });
Get.toNamed(Routers.saveLockPage,
arguments: <String, Object?>{
'addressInfo': {},
'pwdTimestamp': state.timestampValue * 1000,
'lockInfo': state.lockInfo,
'featureValue': state.featureValue,
'featureSettingValue': state.featureSettingValue,
'featureSettingParams': state.featureSettingParams,
'isFromMap': 0,
});
Get.toNamed(Routers.saveLockPage, arguments: <String, Object?>{
'addressInfo': {},
'pwdTimestamp': state.timestampValue * 1000,
'lockInfo': state.lockInfo,
'featureValue': state.featureValue,
'featureSettingValue': state.featureSettingValue,
'featureSettingParams': state.featureSettingParams,
'isFromMap': 0,
});
break;
case 0x06:
@ -575,12 +573,12 @@ class NearbyLockLogic extends BaseGetXController {
void startOTAData() {
state.otaUpdateIng.value = true;
state.oTAProgressDialog = true;
Get.dialog(
OTAProgressDialog(
logic: this,
),
barrierDismissible: false)
.then((dynamic value) => state.oTAProgressDialog = false);
// Get.dialog(
// OTAProgressDialog(
// logic: this,
// ),
// barrierDismissible: false)
// .then((dynamic value) => state.oTAProgressDialog = false);
}
// ata

View File

@ -4,6 +4,7 @@ import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/flavors.dart';
import 'package:star_lock/mine/addLock/nearbyLock/nearbyLock_state.dart';
import '../../../app_settings/app_colors.dart';
@ -52,7 +53,49 @@ class _NearbyLockPageState extends State<NearbyLockPage> with RouteAware {
SizedBox(width: 30.w)
]),
),
body: Obx(listView),
body: Stack(
children: [
Obx(listView),
Positioned(
left: 16.w,
bottom: 64.h,
child: GestureDetector(
onTap: () {
Get.toNamed(Routers.lockAddFaqPage);
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.w),
boxShadow: const <BoxShadow>[
BoxShadow(
color: Colors.black12,
blurRadius: 8,
offset: Offset(0, 2),
),
],
),
child: Row(
children: [
Icon(Icons.help_outline,
color: AppColors.mainColor, size: 20.w),
SizedBox(width: 6.w),
Text(
'找不到锁?点此查看。'.tr,
style: TextStyle(
color: AppColors.mainColor,
fontSize: 20.sp,
fontWeight: FontWeight.w500,
),
),
],
),
),
),
),
],
),
);
}
@ -81,24 +124,7 @@ class _NearbyLockPageState extends State<NearbyLockPage> with RouteAware {
},
),
),
Padding(
padding: EdgeInsets.only(left: 15.w, bottom: 10.h),
child: TextButton(
onPressed: () async {
bool skip = false;
if (!state.otaState.value) {
skip = await Get.dialog(
const _TipDialog(),
);
}
state.otaState.value = skip;
},
child: Text(
state.otaState.value ? '点击返回设备配对'.tr : '无法连接?尝试升级'.tr,
style: TextStyle(fontSize: 22.sp),
),
),
),
// "无法连接?尝试升级"
],
);
}
@ -164,9 +190,7 @@ class _NearbyLockPageState extends State<NearbyLockPage> with RouteAware {
),
Expanded(child: SizedBox(width: 20.w)),
Image.asset(
state.otaState.value
? 'images/ota_upgrade_icon.png'
: 'images/main/icon_main_addLock.png',
'images/main/icon_main_addLock.png',
width: 36.w,
height: 36.w,
color: AppColors.mainColor,
@ -205,7 +229,6 @@ class _NearbyLockPageState extends State<NearbyLockPage> with RouteAware {
@override
void didPop() {
super.didPop();
EasyLoading.isShow ? EasyLoading.dismiss() : null;
state.ifCurrentScreen.value = false;
logic.cancelBlueConnetctToastTimer();
@ -216,7 +239,6 @@ class _NearbyLockPageState extends State<NearbyLockPage> with RouteAware {
@override
void didPopNext() {
super.didPopNext();
state.ifCurrentScreen.value = true;
logic.startScanBlueList();
}
@ -225,97 +247,8 @@ class _NearbyLockPageState extends State<NearbyLockPage> with RouteAware {
@override
void didPushNext() {
super.didPushNext();
if (!logic.state.otaState.value) {
state.ifCurrentScreen.value = false;
logic.cancelBlueConnetctToastTimer();
logic.stopScanBlueList();
}
}
}
class _TipDialog extends StatelessWidget {
const _TipDialog({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CupertinoAlertDialog(
title: Text(
'固件升级提示'.tr,
),
content: Text('请先获取固件文件到手机本地,再选择升级'.tr),
actions: <Widget>[
TextButton(
onPressed: Get.back,
child: Text(
'取消'.tr,
style: TextStyle(fontSize: 22.sp, color: AppColors.blackColor),
),
),
TextButton(
onPressed: () async {
Get.back(result: true);
},
child: Text(
'确定'.tr,
style: TextStyle(fontSize: 22.sp, color: AppColors.blackColor),
),
),
],
);
}
}
class OTAProgressDialog extends StatelessWidget {
NearbyLockLogic logic;
OTAProgressDialog({required this.logic, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Obx(() {
return CupertinoAlertDialog(
title: Text(
'固件升级中'.tr,
),
content: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 20.h, bottom: 10.h),
child: Text(
'传输期间请勿离开当前页面'.tr,
style: TextStyle(fontSize: 20.sp, color: AppColors.blackColor),
),
),
Row(
children: <Widget>[
Text(
'传输中'.tr,
style: TextStyle(fontSize: 18.sp, color: AppColors.mainColor),
),
SizedBox(
width: 15.w,
),
Expanded(
child: LinearProgressIndicator(
value: logic.state.otaProgress.value,
color: AppColors.mainColor,
)),
],
),
],
),
actions: <Widget>[
TextButton(
onPressed: () {
logic.closeOTADAta();
},
child: Text(
'取消升级'.tr,
style: TextStyle(fontSize: 22.sp, color: AppColors.blackColor),
),
),
],
);
});
state.ifCurrentScreen.value = false;
logic.cancelBlueConnetctToastTimer();
logic.stopScanBlueList();
}
}