Compare commits
4 Commits
develop_sk
...
develop_sk
| Author | SHA1 | Date | |
|---|---|---|---|
| b0506a8910 | |||
| 4fa076565f | |||
| 8a8c81b7d2 | |||
| 7e53ecfbf5 |
BIN
images/icon_device_not_selected.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
images/icon_device_selected.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
images/icon_main_drlock_1024.png
Normal file
|
After Width: | Height: | Size: 306 KiB |
BIN
images/mine/icon_message_checbox.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
images/mine/icon_message_close.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
images/mine/icon_message_readed.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
images/mine/icon_message_unread.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
@ -1185,5 +1185,6 @@
|
||||
"这是单次密码,只能使用一次": "这是单次密码,只能使用一次",
|
||||
"您好": "您好",
|
||||
"您的开门密码是": "您的开门密码是",
|
||||
"开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标": "开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标"
|
||||
"开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标": "开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标",
|
||||
"锁博士": "锁博士"
|
||||
}
|
||||
|
||||
@ -150,6 +150,7 @@ class AppColors {
|
||||
|
||||
static Color openPassageModeColor = const Color(0xFFEB2A3B); // 首页开启常开模式颜色(红色)
|
||||
static Color listTimeYellowColor = const Color(0xFFF3BA37); // 首页时间过期颜色(黄色)
|
||||
static Color messageTipsColor = const Color.fromRGBO(202, 220, 247, 1); //消息页面顶部提示条背景色
|
||||
|
||||
static Color get lockDetailBottomBtnUneable =>
|
||||
const Color(0xFF808080); // 首页时间灰色颜色(灰色)
|
||||
|
||||
74
lib/blue/io_protocol/io_readRegisterKey.dart
Normal file
@ -0,0 +1,74 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import '../io_reply.dart';
|
||||
import '../io_sender.dart';
|
||||
import '../io_type.dart';
|
||||
import 'package:crypto/crypto.dart' as crypto;
|
||||
|
||||
/// 读取注册密钥
|
||||
class SenderReadRegisterKeyCommand extends SenderProtocol {
|
||||
SenderReadRegisterKeyCommand({
|
||||
this.lockID,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.publicKey,
|
||||
this.privateKey,
|
||||
}) : super(CommandType.readRegisterKey);
|
||||
|
||||
String? lockID;
|
||||
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? publicKey;
|
||||
List<int>? privateKey;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SenderReadRegisterKeyCommand{ lockID: $lockID, token: $token, '
|
||||
'needAuthor: $needAuthor, publicKey: $publicKey, '
|
||||
'privateKey: $privateKey}';
|
||||
}
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = <int>[];
|
||||
List<int> ebcData = <int>[];
|
||||
|
||||
// 指令类型
|
||||
final int type = commandType!.typeValue;
|
||||
final double typeDouble = type / 256;
|
||||
final int type1 = typeDouble.toInt();
|
||||
final int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 锁id 40
|
||||
final int lockIDLength = utf8.encode(lockID!).length;
|
||||
data.addAll(utf8.encode(lockID!));
|
||||
data = getFixedLengthList(data, 40 - lockIDLength);
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
final int add = 16 - data.length % 16;
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
|
||||
printLog(data);
|
||||
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class SenderReadRegisterKeyCommandReply extends Reply {
|
||||
SenderReadRegisterKeyCommandReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
|
||||
final int status = data[6];
|
||||
errorWithStstus(status);
|
||||
}
|
||||
}
|
||||
106
lib/blue/io_protocol/io_sendAuthorizationCode.dart
Normal file
@ -0,0 +1,106 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import '../io_reply.dart';
|
||||
import '../io_sender.dart';
|
||||
import '../io_type.dart';
|
||||
import 'package:crypto/crypto.dart' as crypto;
|
||||
|
||||
/// 发送授权码
|
||||
class SenderAuthorizationCodeCommand extends SenderProtocol {
|
||||
SenderAuthorizationCodeCommand({
|
||||
this.lockID,
|
||||
this.uuid,
|
||||
this.key,
|
||||
this.mac,
|
||||
this.platform,
|
||||
this.utcTimeStamp,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.publicKey,
|
||||
this.privateKey,
|
||||
}) : super(CommandType.sendAuthorizationCode);
|
||||
|
||||
String? lockID;
|
||||
String? uuid;
|
||||
String? key;
|
||||
String? mac;
|
||||
int? platform; //0:锁通通;1:涂鸦智能
|
||||
int? utcTimeStamp;
|
||||
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? publicKey;
|
||||
List<int>? privateKey;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SenderAuthorizationCodeCommand{ lockID: $lockID, token: $token, '
|
||||
'needAuthor: $needAuthor, publicKey: $publicKey, '
|
||||
'privateKey: $privateKey}';
|
||||
}
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = <int>[];
|
||||
List<int> ebcData = <int>[];
|
||||
|
||||
// 指令类型
|
||||
final int type = commandType!.typeValue;
|
||||
final double typeDouble = type / 256;
|
||||
final int type1 = typeDouble.toInt();
|
||||
final int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 锁id 40
|
||||
final int lockIDLength = utf8.encode(lockID!).length;
|
||||
data.addAll(utf8.encode(lockID!));
|
||||
data = getFixedLengthList(data, 40 - lockIDLength);
|
||||
|
||||
// uuid 40
|
||||
final int uuidLength = utf8.encode(uuid!).length;
|
||||
data.addAll(utf8.encode(uuid!));
|
||||
data = getFixedLengthList(data, 40 - uuidLength);
|
||||
|
||||
// key 40
|
||||
final int keyLength = utf8.encode(key!).length;
|
||||
data.addAll(utf8.encode(key!));
|
||||
data = getFixedLengthList(data, 40 - keyLength);
|
||||
|
||||
// mac 40
|
||||
final int macLength = utf8.encode(mac!).length;
|
||||
data.addAll(utf8.encode(mac!));
|
||||
data = getFixedLengthList(data, 40 - macLength);
|
||||
|
||||
data.add(platform!);
|
||||
|
||||
data.add((utcTimeStamp! & 0xff000000) >> 24);
|
||||
data.add((utcTimeStamp! & 0xff0000) >> 16);
|
||||
data.add((utcTimeStamp! & 0xff00) >> 8);
|
||||
data.add(utcTimeStamp! & 0xff);
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
final int add = 16 - data.length % 16;
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
|
||||
printLog(data);
|
||||
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class SenderAuthorizationCodeCommandReply extends Reply {
|
||||
SenderAuthorizationCodeCommandReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
|
||||
final int status = data[6];
|
||||
errorWithStstus(status);
|
||||
}
|
||||
}
|
||||
@ -9,10 +9,10 @@ List<String> getDeviceType(DeviceType deviceType) {
|
||||
List<String> t = ['758824'];
|
||||
switch (deviceType) {
|
||||
case DeviceType.blue:
|
||||
t = ['758824', '75', '768824', '76','24'];
|
||||
t = ['758824', '75', '768824', '76', '24'];
|
||||
break;
|
||||
case DeviceType.gateway:
|
||||
t = ['758825','25'];
|
||||
t = ['758825', '25'];
|
||||
break;
|
||||
}
|
||||
return t;
|
||||
@ -53,6 +53,8 @@ enum CommandType {
|
||||
gatewayGetWifiList, //网关获取附近的wifi列表 0x30F6
|
||||
gatewayGetWifiListResult, //网关获取附近的wifi列表结果 0x30F7
|
||||
gatewayGetStatus, //获取网关状态 0x30F8
|
||||
readRegisterKey, //读取注册密钥 0x30A7
|
||||
sendAuthorizationCode, //发送授权码 0x30A6
|
||||
|
||||
generalExtendedCommond, // 通用扩展指令 = 0x3030
|
||||
gecChangeAdministratorPassword, // 通用扩展指令子命令-修改管理员密码 = 2
|
||||
@ -245,6 +247,16 @@ extension ExtensionCommandType on CommandType {
|
||||
type = CommandType.gatewayGetStatus;
|
||||
}
|
||||
break;
|
||||
case 0x30A6:
|
||||
{
|
||||
type = CommandType.sendAuthorizationCode;
|
||||
}
|
||||
break;
|
||||
case 0x30A7:
|
||||
{
|
||||
type = CommandType.readRegisterKey;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
type = CommandType.readStarLockStatusInfo;
|
||||
@ -353,6 +365,12 @@ extension ExtensionCommandType on CommandType {
|
||||
case CommandType.setLockCurrentVoicePacket:
|
||||
type = 0x30A5;
|
||||
break;
|
||||
case CommandType.sendAuthorizationCode:
|
||||
type = 0x30A6;
|
||||
break;
|
||||
case CommandType.readRegisterKey:
|
||||
type = 0x30A7;
|
||||
break;
|
||||
default:
|
||||
type = 0x300A;
|
||||
break;
|
||||
@ -492,6 +510,12 @@ extension ExtensionCommandType on CommandType {
|
||||
case 0x30A5:
|
||||
t = '设置锁当前语音包';
|
||||
break;
|
||||
case 0x30A6:
|
||||
t = '发送授权码';
|
||||
break;
|
||||
case 0x30A7:
|
||||
t = '读取注册密钥';
|
||||
break;
|
||||
default:
|
||||
t = '读星锁状态信息';
|
||||
break;
|
||||
|
||||
@ -16,10 +16,12 @@ import 'package:star_lock/blue/io_protocol/io_getDeviceModel.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_readAdminPassword.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_readRegisterKey.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_readSupportFunctionsNoParameters.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_readSupportFunctionsWithParameters.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_readVoicePackageFinalResult.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_referEventRecordTime.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_sendAuthorizationCode.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsNoParameters.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsWithParameters.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_setVoicePackageFinalResult.dart';
|
||||
@ -331,6 +333,18 @@ class CommandReciverManager {
|
||||
SetVoicePackageFinalResultReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case CommandType.readRegisterKey:
|
||||
{
|
||||
reply =
|
||||
SenderReadRegisterKeyCommandReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case CommandType.sendAuthorizationCode:
|
||||
{
|
||||
reply =
|
||||
SenderAuthorizationCodeCommandReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case CommandType.generalExtendedCommond:
|
||||
{
|
||||
// 子命令类型
|
||||
|
||||
@ -6,6 +6,8 @@ import 'package:star_lock/blue/io_protocol/io_deletUser.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_readAdminPassword.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_readRegisterKey.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_sendAuthorizationCode.dart';
|
||||
|
||||
import 'io_gateway/io_gateway_configuringWifi.dart';
|
||||
import 'io_gateway/io_gateway_getStatus.dart';
|
||||
@ -1109,10 +1111,7 @@ class IoSenderManage {
|
||||
|
||||
//ota 升级过程
|
||||
static void senderProcessOtaUpgradeCommand(
|
||||
{required int? index,
|
||||
required int? size,
|
||||
required List<int>? data,
|
||||
CommandSendCallBack? callBack}) {
|
||||
{required int? index, required int? size, required List<int>? data, CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: ProcessOtaUpgradeCommand(
|
||||
index: index,
|
||||
@ -1321,8 +1320,7 @@ class IoSenderManage {
|
||||
}
|
||||
|
||||
// 网关获取wifi列表
|
||||
static void gatewayGetWifiCommand(
|
||||
{required String? userID, CommandSendCallBack? callBack}) {
|
||||
static void gatewayGetWifiCommand({required String? userID, CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: GatewayGetWifiCommand(
|
||||
userID: userID,
|
||||
@ -1339,21 +1337,51 @@ class IoSenderManage {
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: GatewayConfiguringWifiCommand(
|
||||
ssid: ssid,
|
||||
password: password,
|
||||
gatewayConfigurationStr: gatewayConfigurationStr),
|
||||
ssid: ssid, password: password, gatewayConfigurationStr: gatewayConfigurationStr),
|
||||
isBeforeAddUser: true,
|
||||
callBack: callBack);
|
||||
}
|
||||
|
||||
// 获取网关状态
|
||||
static void gatewayGetStatusCommand(
|
||||
{required String? lockID,
|
||||
required String? userID,
|
||||
CommandSendCallBack? callBack}) {
|
||||
{required String? lockID, required String? userID, CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: GatewayGetStatusCommand(lockID: lockID, userID: userID),
|
||||
isBeforeAddUser: true,
|
||||
callBack: callBack);
|
||||
command: GatewayGetStatusCommand(lockID: lockID, userID: userID), isBeforeAddUser: true, callBack: callBack);
|
||||
}
|
||||
|
||||
// 读取注册密钥
|
||||
static void readRegisterKey({
|
||||
required String? lockID,
|
||||
CommandSendCallBack? callBack,
|
||||
}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: SenderReadRegisterKeyCommand(lockID: lockID),
|
||||
isBeforeAddUser: true,
|
||||
callBack: callBack,
|
||||
);
|
||||
}
|
||||
|
||||
// 发送授权码
|
||||
static void sendAuthorizationCode({
|
||||
required String? lockID,
|
||||
required String? uuid,
|
||||
required String? key,
|
||||
required String? mac,
|
||||
required int? platform,
|
||||
required int? utcTimeStamp,
|
||||
CommandSendCallBack? callBack,
|
||||
}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: SenderAuthorizationCodeCommand(
|
||||
lockID: lockID,
|
||||
uuid: uuid,
|
||||
key: key,
|
||||
mac: mac,
|
||||
platform: platform,
|
||||
utcTimeStamp: utcTimeStamp,
|
||||
),
|
||||
isBeforeAddUser: true,
|
||||
callBack: callBack,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ class F {
|
||||
case Flavor.sky:
|
||||
case Flavor.sky_dev:
|
||||
case Flavor.sky_pre:
|
||||
return '锁通通'.tr;
|
||||
return '锁博士'.tr;
|
||||
case Flavor.xhj:
|
||||
case Flavor.xhj_bundle:
|
||||
case Flavor.xhj_dev:
|
||||
@ -119,7 +119,7 @@ class F {
|
||||
case Flavor.sky:
|
||||
case Flavor.sky_dev:
|
||||
case Flavor.sky_pre:
|
||||
return '锁通通'.tr;
|
||||
return '锁博士'.tr;
|
||||
case Flavor.xhj:
|
||||
case Flavor.xhj_bundle:
|
||||
case Flavor.xhj_dev:
|
||||
|
||||
@ -52,6 +52,13 @@ class StarLockLoginLogic extends BaseGetXController {
|
||||
|
||||
Future<void> login() async {
|
||||
FocusScope.of(Get.context!).requestFocus(FocusNode()); //关闭键盘
|
||||
|
||||
// 添加邮箱格式验证
|
||||
if (!GetUtils.isEmail(state.emailOrPhone.value)) {
|
||||
showToast('请输入有效的邮箱地址');
|
||||
return;
|
||||
}
|
||||
|
||||
final LoginEntity entity = await ApiRepository.to.login(
|
||||
loginType: '1',
|
||||
password: state.pwd.value,
|
||||
|
||||
@ -88,30 +88,31 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.w),
|
||||
child: Center(child: Image.asset('images/icon_main_sky_1024.png', width: 110.w, height: 110.w))),
|
||||
child: Center(child: Image.asset('images/icon_main_drlock_1024.png', width: 110.w, height: 110.w))),
|
||||
SizedBox(height: 50.w),
|
||||
Obx(() => CommonItem(
|
||||
leftTitel: '你所在的国家/地区'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isPadding: false,
|
||||
isHaveRightWidget: true,
|
||||
isHaveDirection: true,
|
||||
rightWidget: Text(
|
||||
'${state.countryName} +${state.countryCode.value}',
|
||||
textAlign: TextAlign.end,
|
||||
style: TextStyle(fontSize: 22.sp, color: AppColors.darkGrayTextColor),
|
||||
),
|
||||
action: () async {
|
||||
final result = await Get.toNamed(Routers.selectCountryRegionPage);
|
||||
if (result != null) {
|
||||
result as Map<String, dynamic>;
|
||||
state.countryCode.value = result['code'];
|
||||
state.countryKey.value = result['countryName'];
|
||||
logic.checkIpAction();
|
||||
}
|
||||
},
|
||||
)),
|
||||
// Obx(() =>
|
||||
// CommonItem(
|
||||
// leftTitel: '你所在的国家/地区'.tr,
|
||||
// rightTitle: '',
|
||||
// isHaveLine: true,
|
||||
// isPadding: false,
|
||||
// isHaveRightWidget: true,
|
||||
// isHaveDirection: true,
|
||||
// rightWidget: Text(
|
||||
// '${state.countryName} +${state.countryCode.value}',
|
||||
// textAlign: TextAlign.end,
|
||||
// style: TextStyle(fontSize: 22.sp, color: AppColors.darkGrayTextColor),
|
||||
// ),
|
||||
// action: () async {
|
||||
// final result = await Get.toNamed(Routers.selectCountryRegionPage);
|
||||
// if (result != null) {
|
||||
// result as Map<String, dynamic>;
|
||||
// state.countryCode.value = result['code'];
|
||||
// state.countryKey.value = result['countryName'];
|
||||
// logic.checkIpAction();
|
||||
// }
|
||||
// },
|
||||
// )),
|
||||
LoginInput(
|
||||
focusNode: logic.state.emailOrPhoneFocusNode,
|
||||
controller: state.emailOrPhoneController,
|
||||
@ -126,12 +127,16 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
||||
height: 36.w,
|
||||
),
|
||||
),
|
||||
hintText: '请输入手机号或者邮箱'.tr,
|
||||
// hintText: '请输入手机号或者邮箱'.tr,
|
||||
hintText: '请输入邮箱'.tr,
|
||||
// keyboardType: TextInputType.number,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
// FilteringTextInputFormatter.allow(RegExp('[0-9]')),
|
||||
LengthLimitingTextInputFormatter(30),
|
||||
FilteringTextInputFormatter.singleLineFormatter
|
||||
FilteringTextInputFormatter.singleLineFormatter,
|
||||
// 添加邮箱格式限制
|
||||
FilteringTextInputFormatter.allow(RegExp(r'^[a-zA-Z0-9@._-]+$')),
|
||||
]),
|
||||
SizedBox(height: 10.h),
|
||||
LoginInput(
|
||||
|
||||
@ -30,7 +30,8 @@ class StarLockLoginState {
|
||||
RxString emailOrPhone = ''.obs;
|
||||
RxString pwd = ''.obs;
|
||||
RxBool canNext = false.obs;
|
||||
bool get isEmailOrPhone => emailOrPhone.value.isNotEmpty;
|
||||
// bool get isEmailOrPhone => emailOrPhone.value.isNotEmpty;
|
||||
bool get isEmailOrPhone => GetUtils.isEmail(emailOrPhone.value);
|
||||
bool get pwdIsOK => pwd.value.isNotEmpty;
|
||||
|
||||
TextEditingController emailOrPhoneController = TextEditingController();
|
||||
|
||||
@ -41,7 +41,7 @@ class _StarLockRegisterPageState extends State<StarLockRegisterPage> {
|
||||
child: ListView(
|
||||
padding: EdgeInsets.only(top: 40.h, left: 40.w, right: 40.w),
|
||||
children: <Widget>[
|
||||
topSelectCountryAndRegionWidget(),
|
||||
// topSelectCountryAndRegionWidget(),
|
||||
middleTFWidget(),
|
||||
Obx(() {
|
||||
return SubmitBtn(
|
||||
|
||||
@ -6,7 +6,7 @@ class StarLockRegisterState {
|
||||
StarLockRegisterState() {
|
||||
// 根据系统语言设置默认选中的tab
|
||||
final Locale? systemLocale = Get.deviceLocale;
|
||||
isIphoneType.value = systemLocale?.languageCode == 'zh';
|
||||
//isIphoneType.value = systemLocale?.languageCode == 'zh';
|
||||
|
||||
resetResend();
|
||||
}
|
||||
@ -24,7 +24,7 @@ class StarLockRegisterState {
|
||||
RxString surePwd = ''.obs;
|
||||
RxString verificationCode = ''.obs;
|
||||
RxString xWidth = ''.obs; // 滑动验证码滑动位置
|
||||
RxBool isIphoneType = true.obs;
|
||||
RxBool isIphoneType = false.obs;
|
||||
RxBool canSub = false.obs; // 是否能提交
|
||||
RxBool agree = false.obs;
|
||||
RxBool canSendCode = false.obs; // 是否能发送验证码
|
||||
|
||||
@ -69,6 +69,14 @@ FutureOr<void> main() async {
|
||||
String? token = await CallKitHandler.getVoipToken();
|
||||
print('获取到的VoIP Token: $token');
|
||||
}
|
||||
// 在 runApp 之前设置
|
||||
SystemChrome.setSystemUIOverlayStyle(
|
||||
const SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent, // 状态栏背景色(通常透明)
|
||||
statusBarIconBrightness: Brightness.dark, // Android: 黑色图标
|
||||
statusBarBrightness: Brightness.dark, // iOS: 状态栏内容为深色(影响时间等颜色)
|
||||
),
|
||||
);
|
||||
|
||||
runApp(MyApp(isLogin: isLogin));
|
||||
});
|
||||
|
||||
@ -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}';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
@ -35,27 +34,25 @@ class _LockDetailMainPageState extends State<LockDetailMainPage> {
|
||||
skyCall: () => Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: TitleAppBar(
|
||||
barTitle: F.navTitle,
|
||||
haveBack: true,
|
||||
backgroundColor: AppColors.mainColor),
|
||||
body: LockDetailPage(
|
||||
isOnlyOneData: isOnlyOneData,
|
||||
lockListInfoItemEntity: keyInfos),
|
||||
barTitle: F.navTitle,
|
||||
haveBack: true,
|
||||
backgroundColor: Colors.white,
|
||||
titleColor: Colors.black,
|
||||
iconColor: Colors.black,
|
||||
),
|
||||
body: LockDetailPage(isOnlyOneData: isOnlyOneData, lockListInfoItemEntity: keyInfos),
|
||||
// body: Container(),
|
||||
),
|
||||
xhjCall: () => Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: TitleAppBar(
|
||||
barTitle: F.sw(
|
||||
xhjCall: () => '星星锁'.tr, skyCall: () => keyInfos.lockAlias),
|
||||
barTitle: F.sw(xhjCall: () => '星星锁'.tr, skyCall: () => keyInfos.lockAlias),
|
||||
haveBack: true,
|
||||
backgroundColor: Colors.white,
|
||||
titleColor: AppColors.blackColor,
|
||||
iconColor: AppColors.blackColor,
|
||||
),
|
||||
body: LockDetailPage(
|
||||
isOnlyOneData: isOnlyOneData,
|
||||
lockListInfoItemEntity: keyInfos),
|
||||
body: LockDetailPage(isOnlyOneData: isOnlyOneData, lockListInfoItemEntity: keyInfos),
|
||||
// body: Container(),
|
||||
));
|
||||
}
|
||||
|
||||
@ -464,6 +464,44 @@ class _LockDetailPageState extends State<LockDetailPage> with TickerProviderStat
|
||||
Widget skWidget() {
|
||||
return ListView(
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible: widget.isOnlyOneData,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
Image.asset('images/icon_main_drlock_1024.png', width: 68.w, height: 68.w),
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
Text(
|
||||
F.title,
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
//实现回调函数
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routers.selectLockTypePage,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add_circle_outline_rounded,
|
||||
size: 48.sp,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: (state.keyInfos.value.keyType == XSConstantMacro.keyTypeTime ||
|
||||
state.keyInfos.value.keyType == XSConstantMacro.keyTypeLoop) && // 限时、循环
|
||||
|
||||
@ -1,40 +1,298 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/blue/blue_manage.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_getStarLockStatusInfo.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_readRegisterKey.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_sendAuthorizationCode.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/lockTime/getServerDatetime_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockSet/thirdPartyPlatform/third_party_platform_state.dart';
|
||||
import 'package:star_lock/network/api_repository.dart';
|
||||
import 'package:star_lock/network/start_company_api.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
|
||||
class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||
ThirdPartyPlatformState state = ThirdPartyPlatformState();
|
||||
|
||||
void savePlatFormSetting() {
|
||||
// showEasyLoading();
|
||||
showToast('功能待开放'.tr);
|
||||
// dismissEasyLoading();
|
||||
}
|
||||
|
||||
/// 查询TPP支持
|
||||
void getActivateInfo() async {
|
||||
final model = state.lockSetInfoData.value.lockBasicInfo?.model;
|
||||
if (model != null && model != '') {
|
||||
final response = await StartCompanyApi.to.getActivateInfo(model: model);
|
||||
if (response.errorCode!.codeIsSuccessful) {
|
||||
AppLog.log('${response.data}');
|
||||
}
|
||||
}
|
||||
}
|
||||
// 监听设备返回的数据
|
||||
StreamSubscription<Reply>? _replySubscription;
|
||||
|
||||
@override
|
||||
void onReady() async {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
getActivateInfo();
|
||||
await getActivateInfo();
|
||||
_initReplySubscription();
|
||||
getServerDatetime();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
dismissEasyLoading();
|
||||
// 安全地取消订阅
|
||||
_replySubscription?.cancel();
|
||||
_replySubscription = null;
|
||||
|
||||
// 添加额外的日志来跟踪清理过程
|
||||
AppLog.log('ThirdPartyPlatformLogic disposed, subscription cancelled');
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
// 安全地取消订阅
|
||||
_replySubscription?.cancel();
|
||||
_replySubscription = null;
|
||||
}
|
||||
|
||||
// 从服务器时间
|
||||
Future<void> getServerDatetime() async {
|
||||
final GetServerDatetimeEntity entity = await ApiRepository.to.getServerDatetimeData(isUnShowLoading: true);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
state.differentialTime = entity.data!.date! ~/ 1000 - DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
}
|
||||
}
|
||||
|
||||
int getUTCNetTime() {
|
||||
return DateTime.now().millisecondsSinceEpoch ~/ 1000 + state.differentialTime;
|
||||
}
|
||||
|
||||
void _initReplySubscription() {
|
||||
// 更严格的检查,避免重复初始化
|
||||
if (_replySubscription != null) {
|
||||
AppLog.log('订阅已存在,避免重复初始化');
|
||||
return;
|
||||
}
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
||||
AppLog.log('输出了listen:${_replySubscription.hashCode}');
|
||||
if (reply is SenderReadRegisterKeyCommandReply) {
|
||||
_handleReadRegisterKeyReply(reply);
|
||||
}
|
||||
|
||||
if (reply is GetStarLockStatuInfoReply) {
|
||||
_replyGetStarLockStatusInfo(reply);
|
||||
}
|
||||
if (reply is SenderAuthorizationCodeCommandReply) {
|
||||
_handleAuthorizationCodeReply(reply);
|
||||
}
|
||||
});
|
||||
AppLog.log('创建新订阅:${_replySubscription.hashCode}');
|
||||
}
|
||||
|
||||
// 获取星锁状态
|
||||
Future<void> _replyGetStarLockStatusInfo(Reply reply) async {
|
||||
final int status = reply.data[2];
|
||||
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
//成功
|
||||
// AppLog.log('获取锁状态成功');
|
||||
// 厂商名称
|
||||
int index = 3;
|
||||
final List<int> vendor = reply.data.sublist(index, index + 20);
|
||||
final String vendorStr = utf8String(vendor);
|
||||
state.lockInfo['vendor'] = vendorStr;
|
||||
// state.lockInfo["vendor"] = "XL";
|
||||
index = index + 20;
|
||||
// AppLog.log('厂商名称 vendorStr:$vendorStr');
|
||||
|
||||
// 锁设备类型
|
||||
final int product = reply.data[index];
|
||||
state.lockInfo['product'] = product;
|
||||
index = index + 1;
|
||||
// AppLog.log('锁设备类型 product:$product');
|
||||
|
||||
// 产品名称
|
||||
final List<int> model = reply.data.sublist(index, index + 20);
|
||||
final String modelStr = utf8String(model);
|
||||
state.lockInfo['model'] = modelStr;
|
||||
// state.lockInfo["model"] = "JL-BLE-01";
|
||||
index = index + 20;
|
||||
// AppLog.log('产品名称 mmodelStr:$modelStr');
|
||||
|
||||
// 软件版本
|
||||
final List<int> fwVersion = reply.data.sublist(index, index + 20);
|
||||
final String fwVersionStr = utf8String(fwVersion);
|
||||
state.lockInfo['fwVersion'] = fwVersionStr;
|
||||
index = index + 20;
|
||||
// AppLog.log('软件版本 fwVersionStr:$fwVersionStr');
|
||||
|
||||
// 硬件版本
|
||||
final List<int> hwVersion = reply.data.sublist(index, index + 20);
|
||||
final String hwVersionStr = utf8String(hwVersion);
|
||||
state.lockInfo['hwVersion'] = hwVersionStr;
|
||||
index = index + 20;
|
||||
// AppLog.log('硬件版本 hwVersionStr:$hwVersionStr');
|
||||
|
||||
// 厂商序列号
|
||||
final List<int> serialNum0 = reply.data.sublist(index, index + 16);
|
||||
final String serialNum0Str = utf8String(serialNum0);
|
||||
state.lockInfo['serialNum0'] = serialNum0Str;
|
||||
// state.lockInfo["serialNum0"] = "${DateTime.now().millisecondsSinceEpoch ~/ 10}";
|
||||
index = index + 16;
|
||||
// AppLog.log('厂商序列号 serialNum0Str:$serialNum0Str');
|
||||
final response = await StartCompanyApi.to.getAuthorizationCode(
|
||||
registerKey: state.registerKey.value,
|
||||
model: modelStr,
|
||||
serialNum0: serialNum0Str,
|
||||
platform: 1,
|
||||
);
|
||||
if (response.errorCode!.codeIsSuccessful) {
|
||||
BlueManage().blueSendData(
|
||||
BlueManage().connectDeviceName,
|
||||
(BluetoothConnectionState connectionState) async {
|
||||
if (connectionState == BluetoothConnectionState.connected) {
|
||||
IoSenderManage.sendAuthorizationCode(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
uuid: response.data?.extraParams?['uuid'],
|
||||
key: response.data?.authCode,
|
||||
mac: response.data?.extraParams?['mac'],
|
||||
platform: 1,
|
||||
utcTimeStamp: getUTCNetTime(),
|
||||
);
|
||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
}
|
||||
},
|
||||
isAddEquipment: true,
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
IoSenderManage.senderGetStarLockStatuInfo(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
utcTimeStamp: 0,
|
||||
unixTimeStamp: 0,
|
||||
isBeforeAddUser: false,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void savePlatFormSetting() {
|
||||
if (state.selectPlatFormIndex.value == 1) {
|
||||
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();
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
showToast('目前只支持切换至涂鸦智能协议'.tr);
|
||||
}
|
||||
}
|
||||
|
||||
/// 查询TPP支持
|
||||
Future<void> getActivateInfo() async {
|
||||
final model = state.lockSetInfoData.value.lockBasicInfo?.model;
|
||||
if (model != null && model != '') {
|
||||
final response = await StartCompanyApi.to.getTppSupport(model: model);
|
||||
if (response.errorCode!.codeIsSuccessful) {
|
||||
response.data?.forEach((element) {
|
||||
state.tppSupportList.add(element);
|
||||
});
|
||||
state.tppSupportList.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _handleReadRegisterKeyReply(SenderReadRegisterKeyCommandReply reply) {
|
||||
final int status = reply.data[6];
|
||||
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
// 提取 RegisterKey (从第7个字节开始,长度为40)
|
||||
final List<int> registerKeyBytes = reply.data.sublist(7, 47);
|
||||
final String registerKey = String.fromCharCodes(registerKeyBytes);
|
||||
|
||||
print('Register Key: $registerKey');
|
||||
state.registerKey.value = registerKey;
|
||||
if (registerKey.isNotEmpty) {
|
||||
_requestAuthorizationCode();
|
||||
}
|
||||
//成功
|
||||
cancelBlueConnetctToastTimer();
|
||||
dismissEasyLoading();
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _requestAuthorizationCode() async {
|
||||
showEasyLoading();
|
||||
showBlueConnetctToastTimer(action: () {
|
||||
dismissEasyLoading();
|
||||
});
|
||||
BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async {
|
||||
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
IoSenderManage.senderGetStarLockStatuInfo(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
utcTimeStamp: 0,
|
||||
unixTimeStamp: 0,
|
||||
isBeforeAddUser: false,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
} else if (deviceConnectionState == BluetoothConnectionState.disconnected) {
|
||||
//失败
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _handleAuthorizationCodeReply(SenderAuthorizationCodeCommandReply reply) {
|
||||
final int status = reply.data[6];
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
cancelBlueConnetctToastTimer();
|
||||
dismissEasyLoading();
|
||||
showToast('操作成功,请在24小时内用涂鸦APP添加门锁,否则将过期'.tr);
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,107 +45,123 @@ class _ThirdPartyPlatformPageState extends State<ThirdPartyPlatformPage> {
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return Stack(
|
||||
children: [
|
||||
// 1. 背景或空白区域(可选)
|
||||
Container(
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.all(16.w),
|
||||
),
|
||||
// 2. 顶部图标行:使用 Row 并排显示
|
||||
Positioned(
|
||||
top: 80.h,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 均匀分布
|
||||
children: [
|
||||
Image.asset(
|
||||
'images/other/tuya.png',
|
||||
height: 50.h,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Image.asset(
|
||||
'images/other/2.png', // 中间图标
|
||||
height: 80.h,
|
||||
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Image.asset(
|
||||
'images/other/matter.png',
|
||||
width: 110.w,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
],
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
minHeight: MediaQuery.of(context).size.height - 100.h,
|
||||
),
|
||||
Positioned(
|
||||
top: 220.h,
|
||||
left: 20.w,
|
||||
right: 20.w,
|
||||
child: Text(
|
||||
'第三方协议的支持依赖网络授权下载,打开功能开关时请保证手机数据网络的正常连接'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 20.sp,
|
||||
color: Colors.grey,
|
||||
fontWeight: FontWeight.w500,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 1. 背景或空白区域(可选)
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.all(16.w),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 320.h,
|
||||
bottom: 0,
|
||||
child: ListView.builder(
|
||||
itemCount: state.platFormSet.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
// 判断是否是最后一个元素(索引等于 itemCount - 1)
|
||||
final isLastItem = index == state.platFormSet.length - 1;
|
||||
|
||||
// 获取当前平台数据(假设 platFormSet 是 RxList<Platform>)
|
||||
final platform = state.platFormSet.value[index];
|
||||
return CommonItem(
|
||||
leftTitel: state.platFormSet.value[index],
|
||||
rightTitle: '',
|
||||
isHaveLine: !isLastItem,
|
||||
// 最后一个元素不显示分割线(取反)
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
Positioned(
|
||||
top: 30.h,
|
||||
left: 50.w,
|
||||
child: Image.asset(
|
||||
'images/other/tuya.png',
|
||||
height: 80.h,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 130.h,
|
||||
left: 150.w,
|
||||
right: 150.w,
|
||||
child: Image.asset(
|
||||
'images/other/2.png',
|
||||
height: 220.h,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
// 2. 顶部图标行:使用 Row 并排显示
|
||||
Positioned(
|
||||
top: 400.h,
|
||||
right: 50.w,
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
'images/other/matter.png',
|
||||
width: 280.w,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 530.h,
|
||||
left: 20.w,
|
||||
right: 20.w,
|
||||
child: Text(
|
||||
'第三方协议的支持依赖网络授权下载,打开功能开关时请保证手机数据网络的正常连接'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 20.sp,
|
||||
color: Colors.grey,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
action: () {
|
||||
setState(() {
|
||||
state.selectPlatFormIndex.value = index;
|
||||
});
|
||||
),
|
||||
),
|
||||
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 620.h,
|
||||
bottom: 0,
|
||||
child: ListView.builder(
|
||||
itemCount: state.platFormSet.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
// 判断是否是最后一个元素(索引等于 itemCount - 1)
|
||||
final isLastItem = index == state.platFormSet.length - 1;
|
||||
|
||||
// 获取当前平台数据(假设 platFormSet 是 RxList<Platform>)
|
||||
final platform = state.platFormSet.value[index];
|
||||
return CommonItem(
|
||||
leftTitel: state.platFormSet.value[index],
|
||||
rightTitle: '',
|
||||
isHaveLine: !isLastItem,
|
||||
// 最后一个元素不显示分割线(取反)
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
action: () {
|
||||
setState(() {
|
||||
state.selectPlatFormIndex.value = index;
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
),
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get/get_rx/get_rx.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockDetail/ActivateInfoResponse.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
|
||||
import 'package:star_lock/translations/app_dept.dart';
|
||||
|
||||
@ -11,15 +13,20 @@ class ThirdPartyPlatformState {
|
||||
}
|
||||
|
||||
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
|
||||
int differentialTime = 0;// 服务器时间即UTC+0时间
|
||||
|
||||
// 响应式字符串集合(自动触发 UI 更新)
|
||||
final RxList<String> platFormSet = List.of({
|
||||
'锁通通'.tr,
|
||||
'涂鸦智能'.tr,
|
||||
'Matter'.tr ,
|
||||
'Matter'.tr,
|
||||
}).obs;
|
||||
|
||||
RxInt selectPlatFormIndex = 0.obs;
|
||||
// 响应式字符串集合(自动触发 UI 更新)
|
||||
final RxList<TppSupportInfo> tppSupportList = RxList<TppSupportInfo>([]);
|
||||
|
||||
RxInt selectPlatFormIndex = 1.obs;
|
||||
RxString registerKey = ''.obs;
|
||||
|
||||
Map lockInfo = {};
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ class PasswordKeyDetailLogic extends BaseGetXController {
|
||||
'\n' +
|
||||
'有效期'.tr +
|
||||
':${startDateStr.toLocal().toString().substring(0, 16)} -- ${endDateStr.toLocal().toString().substring(0, 16)}\n\n' +
|
||||
'这是单次密码,只能使用一次\n';
|
||||
'${'这是单次密码,只能使用一次'.tr}\n';
|
||||
break;
|
||||
case 2:
|
||||
//永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效
|
||||
@ -309,8 +309,8 @@ class PasswordKeyDetailLogic extends BaseGetXController {
|
||||
':' +
|
||||
'永久'.tr +
|
||||
'\n' +
|
||||
'\n注:\n' +
|
||||
'必需在开始时间24小时内使用一次,否则将失效\n';
|
||||
'\n${'注:'.tr}\n' +
|
||||
'${'必需在开始时间24小时内使用一次,否则将失效'.tr}\n';
|
||||
break;
|
||||
case 3:
|
||||
//限期 3 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效
|
||||
@ -324,7 +324,7 @@ class PasswordKeyDetailLogic extends BaseGetXController {
|
||||
':${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}' +
|
||||
'\n' +
|
||||
'\n注:\n' +
|
||||
'必需在开始时间24小时内使用一次,否则将失效\n';
|
||||
'${'必需在开始时间24小时内使用一次,否则将失效'.tr}\n';
|
||||
break;
|
||||
case 4:
|
||||
//删除 4 在锁上使用后会删除之前在锁上使用过的密码
|
||||
@ -453,9 +453,10 @@ class PasswordKeyDetailLogic extends BaseGetXController {
|
||||
default:
|
||||
}
|
||||
// return '您好,您的密码是'.tr + ':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}';
|
||||
return '您好' +
|
||||
',\n您的开门密码是' +
|
||||
':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}\n\n开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标';
|
||||
return '您好'.tr +
|
||||
',\n${'您的开门密码是'.tr}' +
|
||||
':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}\n'
|
||||
'\n${'开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标'.tr}';
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -46,32 +46,24 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
} else if (state.widgetType.value == 1) {
|
||||
//限时
|
||||
// 鑫鸿佳不需要生效时间
|
||||
if (CommonDataManage().currentKeyInfo.vendor ==
|
||||
IoModelVendor.vendor_XHJ &&
|
||||
(CommonDataManage().currentKeyInfo.model ==
|
||||
IoModelVendor.model_XHJ_SYD ||
|
||||
CommonDataManage().currentKeyInfo.model ==
|
||||
IoModelVendor.model_XHJ_JL)) {
|
||||
if (endDate <=
|
||||
DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
|
||||
if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XHJ &&
|
||||
(CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XHJ_SYD ||
|
||||
CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XHJ_JL)) {
|
||||
if (endDate <= DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
|
||||
showToast('失效时间要大于当前时间'.tr);
|
||||
return;
|
||||
}
|
||||
//endDate 设置当天凌晨 0 点
|
||||
final DateTime now = DateTime.now();
|
||||
startDate =
|
||||
DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
|
||||
startDate = DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
|
||||
}
|
||||
|
||||
// 芯连需要生效时间
|
||||
if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XL &&
|
||||
(CommonDataManage().currentKeyInfo.model ==
|
||||
IoModelVendor.model_XL_BLE ||
|
||||
CommonDataManage().currentKeyInfo.model ==
|
||||
IoModelVendor.model_XL_WIFI)) {
|
||||
(CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_BLE ||
|
||||
CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_WIFI)) {
|
||||
//限时
|
||||
if (startDate <
|
||||
DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
|
||||
if (startDate < DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
|
||||
showToast('生效时间不能小于当前时间'.tr);
|
||||
return;
|
||||
}
|
||||
@ -91,12 +83,9 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
//循环
|
||||
// 芯连需要结束时间
|
||||
if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XL &&
|
||||
(CommonDataManage().currentKeyInfo.model ==
|
||||
IoModelVendor.model_XL_BLE ||
|
||||
CommonDataManage().currentKeyInfo.model ==
|
||||
IoModelVendor.model_XL_WIFI)) {
|
||||
if (endDate <
|
||||
DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
|
||||
(CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_BLE ||
|
||||
CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_WIFI)) {
|
||||
if (endDate < DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
|
||||
showToast('结束时间不能小于当前时间'.tr);
|
||||
return;
|
||||
}
|
||||
@ -166,10 +155,8 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
//是否为永久
|
||||
if (state.isPermanent.value == false) {
|
||||
getKeyType = '3';
|
||||
getEffectiveDateTime =
|
||||
DateTool().dateToTimestamp(state.customBeginTime.value, 1).toString();
|
||||
getFailureDateTime =
|
||||
DateTool().dateToTimestamp(state.customEndTime.value, 1).toString();
|
||||
getEffectiveDateTime = DateTool().dateToTimestamp(state.customBeginTime.value, 1).toString();
|
||||
getFailureDateTime = DateTool().dateToTimestamp(state.customEndTime.value, 1).toString();
|
||||
}
|
||||
final PasswordKeyEntity entity = await ApiRepository.to.addPasswordKey(
|
||||
lockId: lockId,
|
||||
@ -184,8 +171,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
ApmHelper.instance.trackEvent('add_password', {
|
||||
'lock_name': BlueManage().connectDeviceName,
|
||||
'account':
|
||||
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'date': DateTool().getNowDateWithType(1),
|
||||
'add_password_result': '成功',
|
||||
});
|
||||
@ -202,8 +188,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
} else {
|
||||
ApmHelper.instance.trackEvent('add_password', {
|
||||
'lock_name': BlueManage().connectDeviceName,
|
||||
'account':
|
||||
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'date': DateTool().getNowDateWithType(1),
|
||||
'add_password_result': '${entity.errorMsg}',
|
||||
});
|
||||
@ -230,8 +215,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
showToast('请输入密码'.tr);
|
||||
return;
|
||||
}
|
||||
final PasswordKeyEntity entity =
|
||||
await ApiRepository.to.checkKeyboardpwdName(
|
||||
final PasswordKeyEntity entity = await ApiRepository.to.checkKeyboardpwdName(
|
||||
lockId: state.keyInfo.value.lockId.toString(),
|
||||
keyboardPwdName: state.nameController.text,
|
||||
keyboardPwd: state.pwdController.text,
|
||||
@ -246,16 +230,11 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
|
||||
void _initReplySubscription() {
|
||||
_replySubscription =
|
||||
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
||||
// 设置自定义密码
|
||||
if ((reply is SenderCustomPasswordsReply) &&
|
||||
(state.ifCurrentScreen.value == true)) {
|
||||
if ((reply is SenderCustomPasswordsReply) && (state.ifCurrentScreen.value == true)) {
|
||||
BuglyTool.uploadException(
|
||||
message: '添加密码结果,解析数据',
|
||||
detail: '添加密码结果,解析数据:${reply.data}',
|
||||
eventStr: '添加密码事件结果',
|
||||
upload: true);
|
||||
message: '添加密码结果,解析数据', detail: '添加密码结果,解析数据:${reply.data}', eventStr: '添加密码事件结果', upload: true);
|
||||
|
||||
final int status = reply.data[2];
|
||||
switch (status) {
|
||||
@ -305,20 +284,14 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
final List<String> saveStrList = changeIntListToStringList(token);
|
||||
Storage.setStringList(saveBlueToken, saveStrList);
|
||||
|
||||
final List<String>? privateKey =
|
||||
await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList =
|
||||
changeStringListToIntList(privateKey!);
|
||||
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 List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
final List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
||||
|
||||
int startDate =
|
||||
DateTool().dateToTimestamp(state.customBeginTime.value, 1);
|
||||
int endDate =
|
||||
DateTool().dateToTimestamp(state.customEndTime.value, 1);
|
||||
int startDate = DateTool().dateToTimestamp(state.customBeginTime.value, 1);
|
||||
int endDate = DateTool().dateToTimestamp(state.customEndTime.value, 1);
|
||||
//非永久 须有时限
|
||||
if (state.isPermanent.value == true) {
|
||||
startDate = 0;
|
||||
@ -367,8 +340,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
int endDate = DateTool().dateToTimestamp(state.customEndTime.value, 1);
|
||||
//非永久 须有时限
|
||||
if (state.isPermanent.value == false) {
|
||||
if (startDate <
|
||||
DateTool().dateToTimestamp(DateTool().getNowDateWithType(2), 1)) {
|
||||
if (startDate < DateTool().dateToTimestamp(DateTool().getNowDateWithType(2), 1)) {
|
||||
showToast('生效时间需晚于当前时间'.tr);
|
||||
return;
|
||||
}
|
||||
@ -382,8 +354,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
endDate = 0;
|
||||
}
|
||||
|
||||
if (state.pwdController.text.length < 6 ||
|
||||
state.pwdController.text.length > 9) {
|
||||
if (state.pwdController.text.length < 6 || state.pwdController.text.length > 9) {
|
||||
showToast('请输入6-9位数字'.tr);
|
||||
return;
|
||||
}
|
||||
@ -396,8 +367,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
final List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
||||
|
||||
final List<String>? privateKey =
|
||||
await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
@ -424,8 +394,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
final String getMobile = (await Storage.getMobile())!;
|
||||
ApmHelper.instance.trackEvent('add_password', {
|
||||
'lock_name': BlueManage().connectDeviceName,
|
||||
'account':
|
||||
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'date': DateTool().getNowDateWithType(1),
|
||||
'add_password_result': '添加自定义密码超时',
|
||||
});
|
||||
@ -439,17 +408,13 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
dismissEasyLoading();
|
||||
state.sureBtnState.value = 0;
|
||||
});
|
||||
BlueManage().blueSendData(BlueManage().connectDeviceName,
|
||||
(BluetoothConnectionState deviceConnectionState) async {
|
||||
BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async {
|
||||
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
||||
final List<String>? signKey =
|
||||
await Storage.getStringList(saveBlueSignKey);
|
||||
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
final List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
||||
|
||||
final List<String>? privateKey =
|
||||
await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList =
|
||||
changeStringListToIntList(privateKey!);
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
final List<int> getTokenList = changeStringListToIntList(token!);
|
||||
@ -469,13 +434,11 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
token: getTokenList);
|
||||
} else if (deviceConnectionState ==
|
||||
BluetoothConnectionState.disconnected) {
|
||||
} else if (deviceConnectionState == BluetoothConnectionState.disconnected) {
|
||||
final String getMobile = (await Storage.getMobile())!;
|
||||
ApmHelper.instance.trackEvent('add_password', {
|
||||
'lock_name': BlueManage().connectDeviceName,
|
||||
'account':
|
||||
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'date': DateTool().getNowDateWithType(1),
|
||||
'add_password_result': '添加自定义密码断开',
|
||||
});
|
||||
@ -517,17 +480,11 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
'\n' +
|
||||
'有效期'.tr +
|
||||
':${startDateStr.toLocal().toString().substring(0, 16)} -- ${endDateStr.toLocal().toString().substring(0, 16)}\n\n' +
|
||||
'这是单次密码,只能使用一次\n';
|
||||
'${'这是单次密码,只能使用一次'.tr}\n';
|
||||
break;
|
||||
case 0:
|
||||
//永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'永久'.tr +
|
||||
'\n' +
|
||||
'\n注:\n' +
|
||||
'必需在开始时间24小时内使用一次,否则将失效\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '永久'.tr + '\n' + '\n注:\n' + '${'必需在开始时间24小时内使用一次,否则将失效'.tr}\n';
|
||||
break;
|
||||
case 1:
|
||||
//限期 3 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效
|
||||
@ -540,15 +497,14 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
'有效期'.tr +
|
||||
':${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}' +
|
||||
'\n' +
|
||||
'\n注:\n' +
|
||||
'必需在开始时间24小时内使用一次,否则将失效\n';
|
||||
'\n${'注:'.tr}\n' +
|
||||
'${'必需在开始时间24小时内使用一次,否则将失效'.tr}\n';
|
||||
break;
|
||||
case 3:
|
||||
//自定义
|
||||
if (state.isPermanent.value == false) {
|
||||
useDateStr = '类型'.tr +
|
||||
':' +
|
||||
'自定义-限时\n${'有效期'.tr}:${state.customBeginTime.value} -- ${state.customEndTime.value}';
|
||||
useDateStr =
|
||||
'类型'.tr + ':' + '自定义-限时\n${'有效期'.tr}:${state.customBeginTime.value} -- ${state.customEndTime.value}';
|
||||
} else {
|
||||
useDateStr = '类型:自定义-永久'.tr;
|
||||
}
|
||||
@ -559,171 +515,51 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
break;
|
||||
case 4:
|
||||
//周未循环 5 在周未开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周末'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周末'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 6:
|
||||
//每日循环 6 每天开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'每日'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '每日'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 7:
|
||||
//工作日循环 7 工作日开始和结束时间指定的时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'工作日'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '工作日'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 8:
|
||||
//周一循环 8 每周一开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周一'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周一'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 9:
|
||||
//周二循环 9 每周二开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周二'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周二'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 10:
|
||||
//周三循环 10 每周三开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周三'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周三'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 11:
|
||||
//周四循环 11 每周四开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周四'.tr +
|
||||
' $starHour:00 -$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周四'.tr + ' $starHour:00 -$endHour:00' + '\n';
|
||||
break;
|
||||
case 12:
|
||||
//周五循环 12 每周五开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周五'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周五'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 13:
|
||||
//周六循环 13 每周六开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周六'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周六'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
case 14:
|
||||
//周日循环 14 每周日开始和结束时间指定时间段内有效
|
||||
useDateStr = '\n' +
|
||||
'类型'.tr +
|
||||
':' +
|
||||
'循环'.tr +
|
||||
'\n' +
|
||||
'\n' +
|
||||
'周日'.tr +
|
||||
' $starHour:00-$endHour:00' +
|
||||
'\n';
|
||||
useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周日'.tr + ' $starHour:00-$endHour:00' + '\n';
|
||||
break;
|
||||
default:
|
||||
}
|
||||
// return '您好,您的密码是'.tr + ':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}';
|
||||
return '您好' +
|
||||
',\n您的开门密码是' +
|
||||
':${state.getPwdStr.value}\n$useDateStr\n${'密码名字'.tr}:${state.pwdNameStr}\n\n开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标';
|
||||
// switch (getPwdType) {
|
||||
// case 0:
|
||||
// // 永久 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效
|
||||
// useDateStr = '类型'.tr + ':' + '永久';
|
||||
// break;
|
||||
// case 1:
|
||||
// //限时 在开始和结束时间内有效,必需在开始时间24小时内使用一次,否则将失效
|
||||
// useDateStr = '类型'.tr +
|
||||
// ':' +
|
||||
// '限时\n${'有效期'.tr}:${state.beginTime.value} -- ${state.endTime.value}';
|
||||
// break;
|
||||
// case 2:
|
||||
// //单次 只能在开始时间后6小时内使用一次
|
||||
// useDateStr = '类型'.tr +
|
||||
// ':' +
|
||||
// '单次\n${'有效期'.tr}:${state.beginTime.value} -- ${state.endTime.value}';
|
||||
// break;
|
||||
// case 3:
|
||||
// //自定义
|
||||
// if (state.isPermanent.value == false) {
|
||||
// useDateStr = '类型'.tr +
|
||||
// ':' +
|
||||
// '自定义-限时\n${'有效期'.tr}:${state.customBeginTime.value} -- ${state.customEndTime.value}';
|
||||
// } else {
|
||||
// useDateStr = '类型:自定义-永久'.tr;
|
||||
// }
|
||||
// break;
|
||||
// case 4:
|
||||
// //周未循环 在周未开始和结束时间指定时间段内有效
|
||||
// useDateStr = '类型'.tr +
|
||||
// ':' +
|
||||
// '循环\n${state.loopModeStr.value} ${state.loopEffectiveDate.value}:00-${state.loopFailureDate.value}';
|
||||
// break;
|
||||
// case 5:
|
||||
// //删除 4 在锁上使用后会删除之前在锁上使用过的密码
|
||||
// useDateStr = '类型:清空';
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// }
|
||||
// return '${'您好,您的密码是'.tr}:${state.getPwdStr.value}\n$useDateStr\n${'密码名字'.tr}:${state.pwdNameStr}';
|
||||
|
||||
return '您好'.tr +
|
||||
',\n${'您的开门密码是'.tr}' +
|
||||
':${state.getPwdStr.value}\n$useDateStr\n${'密码名字'.tr}:${state.pwdNameStr}\n'
|
||||
'\n${'开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标'.tr}';
|
||||
}
|
||||
|
||||
String addSpaces(String input) {
|
||||
|
||||
@ -36,13 +36,13 @@ class _LockListGroupViewState extends State<LockListGroupView> {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
color: widget.backgroundColor ?? Colors.white,
|
||||
height: 80.h,
|
||||
child: Row(
|
||||
children: _buildExpandRowList(),
|
||||
),
|
||||
),
|
||||
// Container(
|
||||
// color: widget.backgroundColor ?? Colors.white,
|
||||
// height: 80.h,
|
||||
// child: Row(
|
||||
// children: _buildExpandRowList(),
|
||||
// ),
|
||||
// ),
|
||||
ClipRect(
|
||||
child: AnimatedAlign(
|
||||
heightFactor: _isExpanded ? 1.0 : 0.0,
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/flavors.dart';
|
||||
import 'package:star_lock/main/lockMian/lockList/lockList_state.dart';
|
||||
|
||||
import '../../../appRouters.dart';
|
||||
@ -14,8 +16,7 @@ import 'lockListGroup_view.dart';
|
||||
import 'lockList_logic.dart';
|
||||
|
||||
class LockListPage extends StatefulWidget {
|
||||
const LockListPage({required this.lockListInfoGroupEntity, Key? key})
|
||||
: super(key: key);
|
||||
const LockListPage({required this.lockListInfoGroupEntity, Key? key}) : super(key: key);
|
||||
final LockListInfoGroupEntity lockListInfoGroupEntity;
|
||||
|
||||
@override
|
||||
@ -30,41 +31,84 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
void initState() {
|
||||
super.initState();
|
||||
logic = Get.put(LockListLogic(widget.lockListInfoGroupEntity));
|
||||
state = Get
|
||||
.find<LockListLogic>()
|
||||
.state;
|
||||
state = Get.find<LockListLogic>().state;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Obx(() => Scaffold(
|
||||
body: ListView.separated(
|
||||
itemCount: logic.groupDataListFiltered.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final GroupList itemData = logic.groupDataListFiltered[index];
|
||||
return _buildLockExpandedList(context, index, itemData, key: ValueKey(itemData.groupId));
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1,
|
||||
color: AppColors.greyLineColor,
|
||||
);
|
||||
}),
|
||||
));
|
||||
return Obx(
|
||||
() => Scaffold(
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
Image.asset('images/icon_main_drlock_1024.png', width: 68.w, height: 68.w),
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
Text(
|
||||
F.title,
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
//实现回调函数
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routers.selectLockTypePage,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add_circle_outline_rounded,
|
||||
size: 48.sp,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
itemCount: logic.groupDataListFiltered.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final GroupList itemData = logic.groupDataListFiltered[index];
|
||||
return _buildLockExpandedList(context, index, itemData, key: ValueKey(itemData.groupId));
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1,
|
||||
color: AppColors.greyLineColor,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//设备多层级列表
|
||||
Widget _buildLockExpandedList(BuildContext context, int index,
|
||||
GroupList itemData, {Key? key}) {
|
||||
final List<LockListInfoItemEntity> lockItemList =
|
||||
itemData.lockList ?? <LockListInfoItemEntity>[];
|
||||
Widget _buildLockExpandedList(BuildContext context, int index, GroupList itemData, {Key? key}) {
|
||||
final List<LockListInfoItemEntity> lockItemList = itemData.lockList ?? <LockListInfoItemEntity>[];
|
||||
return LockListGroupView(
|
||||
key: key,
|
||||
onTap: () {
|
||||
//是否选中组
|
||||
if (itemData.isChecked) {} else {}
|
||||
if (itemData.isChecked) {
|
||||
} else {}
|
||||
setState(() {});
|
||||
},
|
||||
typeImgList: const <dynamic>[],
|
||||
@ -103,39 +147,36 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
),
|
||||
child: lockInfoListItem(keyInfo, isLast, () {
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusWaitIneffective)) {
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusWaitIneffective)) {
|
||||
logic.showToast('您的钥匙未生效'.tr);
|
||||
return;
|
||||
}
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLong ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLong ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen)) {
|
||||
logic.showToast('您的钥匙已冻结'.tr);
|
||||
return;
|
||||
}
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusExpired)) {
|
||||
logic.showToast('您的钥匙已过期'.tr);
|
||||
return;
|
||||
}
|
||||
Get.toNamed(Routers.lockDetailMainPage,
|
||||
arguments: <String, Object>{
|
||||
// "lockMainEntity": widget.lockMainEntity,
|
||||
'keyInfo': keyInfo,
|
||||
'isOnlyOneData': false,
|
||||
});
|
||||
Get.toNamed(Routers.lockDetailMainPage, arguments: <String, Object>{
|
||||
// "lockMainEntity": widget.lockMainEntity,
|
||||
'keyInfo': keyInfo,
|
||||
'isOnlyOneData': false,
|
||||
});
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget lockInfoListItem(LockListInfoItemEntity keyInfo, bool isLast,
|
||||
Function() action) {
|
||||
Widget lockInfoListItem(LockListInfoItemEntity keyInfo, bool isLast, Function() action) {
|
||||
return GestureDetector(
|
||||
onTap: action,
|
||||
child: Container(
|
||||
@ -144,16 +185,12 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
? EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w, bottom: 20.w)
|
||||
: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w),
|
||||
decoration: BoxDecoration(
|
||||
color: (((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusWaitIneffective ||
|
||||
keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusFrozen ||
|
||||
keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusExpired)) ||
|
||||
(keyInfo.keyType == XSConstantMacro.keyTypeLong &&
|
||||
keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen))
|
||||
color: (((keyInfo.keyType == XSConstantMacro.keyTypeTime || keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusWaitIneffective ||
|
||||
keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen ||
|
||||
keyInfo.keyStatus == XSConstantMacro.keyStatusExpired)) ||
|
||||
(keyInfo.keyType == XSConstantMacro.keyTypeLong &&
|
||||
keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen))
|
||||
? AppColors.greyBackgroundColor
|
||||
: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20.w),
|
||||
@ -193,8 +230,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
SizedBox(width: 2.w),
|
||||
Text(
|
||||
'${keyInfo.electricQuantity!}%',
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
),
|
||||
SizedBox(width: 30.w),
|
||||
],
|
||||
@ -211,10 +247,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
borderRadius: BorderRadius.circular(5.w),
|
||||
color: AppColors.openPassageModeColor,
|
||||
),
|
||||
child: Text('常开模式开启'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp,
|
||||
color: AppColors.appBarIconColor)),
|
||||
child: Text('常开模式开启'.tr, style: TextStyle(fontSize: 18.sp, color: AppColors.appBarIconColor)),
|
||||
),
|
||||
],
|
||||
)),
|
||||
@ -226,8 +259,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
SizedBox(width: 30.w),
|
||||
Text(
|
||||
'远程开锁'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
),
|
||||
],
|
||||
)),
|
||||
@ -241,15 +273,13 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
padding: EdgeInsets.only(right: 5.w, left: 5.w),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5.w),
|
||||
color:
|
||||
DateTool().compareTimeIsOvertime(keyInfo.endDate!)
|
||||
color: DateTool().compareTimeIsOvertime(keyInfo.endDate!)
|
||||
? AppColors.listTimeYellowColor
|
||||
: AppColors.mainColor,
|
||||
),
|
||||
child: Text(logic.getKeyEffective(keyInfo),
|
||||
style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
// child: Text(logic.compareTimeIsOvertime(keyInfo.endDate!) ? "已过期" : "余${logic.compareTimeGetDaysFromNow(keyInfo.endDate!)}天", style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
),
|
||||
child: Text(logic.getKeyEffective(keyInfo), style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
// child: Text(logic.compareTimeIsOvertime(keyInfo.endDate!) ? "已过期" : "余${logic.compareTimeGetDaysFromNow(keyInfo.endDate!)}天", style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
@ -258,13 +288,8 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
children: <Widget>[
|
||||
SizedBox(width: 30.w),
|
||||
Text(
|
||||
"${logic.getUseKeyTypeStr(keyInfo.startDate, keyInfo.endDate,
|
||||
keyInfo.keyType)}/${keyInfo.isLockOwner == 1
|
||||
? '超级管理员'.tr
|
||||
: (keyInfo.keyRight == 1 ? "授权管理员".tr : "普通用户"
|
||||
.tr)}",
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
"${logic.getUseKeyTypeStr(keyInfo.startDate, keyInfo.endDate, keyInfo.keyType)}/${keyInfo.isLockOwner == 1 ? '超级管理员'.tr : (keyInfo.keyRight == 1 ? "授权管理员".tr : "普通用户".tr)}",
|
||||
style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -286,13 +311,10 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
@override
|
||||
void dispose() {
|
||||
Get.delete<LockListLogic>();
|
||||
|
||||
/// 取消路由订阅
|
||||
AppRouteObserver().routeObserver.unsubscribe(this);
|
||||
super
|
||||
.
|
||||
dispose
|
||||
(
|
||||
);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 从上级界面进入 当前界面即将出现
|
||||
|
||||
@ -23,8 +23,11 @@ import 'package:star_lock/tools/submitBtn.dart';
|
||||
import '../../../appRouters.dart';
|
||||
import '../../../baseWidget.dart';
|
||||
import '../../../flavors.dart';
|
||||
import '../../../mine/addLock/selectLockType/selectLockType_logic.dart';
|
||||
import '../../../mine/message/messageList/messageList_page.dart';
|
||||
import '../../../mine/mine/starLockMine_page.dart';
|
||||
import '../../../tools/EasyRefreshTool.dart';
|
||||
import '../../../tools/commonDataManage.dart';
|
||||
import '../../../tools/eventBusEventManage.dart';
|
||||
import '../../../tools/storage.dart';
|
||||
import '../../../tools/titleAppBar.dart';
|
||||
@ -34,8 +37,7 @@ import '../lockList/lockList_page.dart';
|
||||
import 'lockMain_logic.dart';
|
||||
|
||||
class StarLockMainPage extends StatefulWidget {
|
||||
StarLockMainPage({Key? key, this.showAppBar = true, this.showDrawer = true})
|
||||
: super(key: key);
|
||||
StarLockMainPage({Key? key, this.showAppBar = true, this.showDrawer = true}) : super(key: key);
|
||||
bool showAppBar;
|
||||
bool showDrawer;
|
||||
|
||||
@ -48,16 +50,15 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
final LockMainLogic logic = Get.put(LockMainLogic());
|
||||
final LockMainState state = Get.find<LockMainLogic>().state;
|
||||
|
||||
Future<void> getHttpData(
|
||||
{bool clearScanDevices = false, bool isUnShowLoading = false}) async {
|
||||
LockListInfoGroupEntity? lockListInfoGroupEntity =
|
||||
await Storage.getLockMainListData();
|
||||
final SelectLockTypeLogic logicType = Get.put(SelectLockTypeLogic());
|
||||
|
||||
Future<void> getHttpData({bool clearScanDevices = false, bool isUnShowLoading = false}) async {
|
||||
LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData();
|
||||
if (lockListInfoGroupEntity != null) {
|
||||
await logic.loadMainDataLogic(lockListInfoGroupEntity);
|
||||
setState(() {});
|
||||
}
|
||||
lockListInfoGroupEntity =
|
||||
(await logic.getStarLockInfo(isUnShowLoading: isUnShowLoading)).data;
|
||||
lockListInfoGroupEntity = (await logic.getStarLockInfo(isUnShowLoading: isUnShowLoading)).data;
|
||||
if (lockListInfoGroupEntity != null) {
|
||||
await logic.loadMainDataLogic(lockListInfoGroupEntity);
|
||||
setState(() {});
|
||||
@ -89,7 +90,8 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<LockMainLogic>(builder: (LockMainLogic logic) {
|
||||
Widget child = EasyRefreshTool(
|
||||
Widget child = Obx(
|
||||
() => EasyRefreshTool(
|
||||
onRefresh: () {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
// 更新状态的代码
|
||||
@ -98,37 +100,44 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
});
|
||||
},
|
||||
// child: getDataReturnUI(state.dataLength.value));
|
||||
child: getDataReturnUI(state.dataLength.value));
|
||||
child: getDataReturnUI(state.dataLength.value),
|
||||
),
|
||||
);
|
||||
if (widget.showAppBar || widget.showDrawer) {
|
||||
child = Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F5F5),
|
||||
appBar: widget.showAppBar
|
||||
? TitleAppBar(
|
||||
barTitle: F.navTitle,
|
||||
haveBack: false,
|
||||
haveOtherLeftWidget: true,
|
||||
leftWidget: Builder(
|
||||
builder: (BuildContext context) => IconButton(
|
||||
icon: Image.asset(
|
||||
'images/main/mainLeft_menu_icon.png',
|
||||
color: Colors.white,
|
||||
width: 44.w,
|
||||
height: 44.w,
|
||||
),
|
||||
onPressed: () {
|
||||
Scaffold.of(context).openDrawer();
|
||||
},
|
||||
)),
|
||||
backgroundColor: AppColors.mainColor,
|
||||
)
|
||||
: null,
|
||||
drawer: widget.showDrawer
|
||||
? Drawer(
|
||||
width: 1.sw / 3 * 2,
|
||||
child: const StarLockMinePage(),
|
||||
)
|
||||
: null,
|
||||
backgroundColor: Colors.white,
|
||||
body: child,
|
||||
bottomNavigationBar: Obx(
|
||||
() => BottomNavigationBar(
|
||||
backgroundColor: Colors.white,
|
||||
items: <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(
|
||||
icon: ImageIcon(
|
||||
AssetImage(state.selectedIndex.value == 0
|
||||
? 'images/icon_device_selected'
|
||||
'.png'
|
||||
: 'images/icon_device_not_selected.png'),
|
||||
), // 使用本地图片
|
||||
label: '设备',
|
||||
),
|
||||
const BottomNavigationBarItem(
|
||||
icon: Icon(Icons.notifications),
|
||||
label: '消息',
|
||||
),
|
||||
const BottomNavigationBarItem(
|
||||
icon: Icon(Icons.person),
|
||||
label: '我的',
|
||||
),
|
||||
],
|
||||
onTap: (index) {
|
||||
state.selectedIndex.value = index;
|
||||
},
|
||||
currentIndex: state.selectedIndex.value,
|
||||
selectedItemColor: AppColors.mainColor,
|
||||
unselectedItemColor: Colors.grey,
|
||||
showUnselectedLabels: true, // 显示未选中项的标签
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
child = F.sw(
|
||||
@ -149,41 +158,52 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
Widget getDataReturnUI(int type) {
|
||||
Widget returnWidget;
|
||||
|
||||
if (type == 1) {
|
||||
type = F.sw(skyCall: () => 1, xhjCall: () => 2);
|
||||
}
|
||||
switch (type) {
|
||||
case 0:
|
||||
// 显示无数据模式
|
||||
returnWidget = unHaveData();
|
||||
break;
|
||||
case 1:
|
||||
// 只有一条数据
|
||||
Storage.setBool(ifIsDemoModeOrNot, false);
|
||||
returnWidget = LockDetailPage(
|
||||
isOnlyOneData: true,
|
||||
lockListInfoItemEntity:
|
||||
state.lockListInfoGroupEntity.value.groupList![0].lockList![0]);
|
||||
break;
|
||||
case 2:
|
||||
// 有多条数据
|
||||
Storage.setBool(ifIsDemoModeOrNot, false);
|
||||
returnWidget = F.sw(
|
||||
skyCall: () => LockListPage(
|
||||
lockListInfoGroupEntity: state.lockListInfoGroupEntity.value),
|
||||
xhjCall: () => LockListXHJPage(
|
||||
lockListInfoGroupEntity: state.lockListInfoGroupEntity.value));
|
||||
break;
|
||||
default:
|
||||
returnWidget = NoData();
|
||||
break;
|
||||
if (state.selectedIndex.value == 0) {
|
||||
if (type == 1) {
|
||||
type = F.sw(skyCall: () => 1, xhjCall: () => 2);
|
||||
}
|
||||
switch (type) {
|
||||
case 0:
|
||||
// 显示无数据模式
|
||||
returnWidget = MainBg(child: unHaveData());
|
||||
break;
|
||||
case 1:
|
||||
// 只有一条数据
|
||||
Storage.setBool(ifIsDemoModeOrNot, false);
|
||||
returnWidget = MainBg(child: LockDetailPage(
|
||||
isOnlyOneData: true,
|
||||
lockListInfoItemEntity: state.lockListInfoGroupEntity.value.groupList![0].lockList![0]));
|
||||
break;
|
||||
case 2:
|
||||
// 有多条数据
|
||||
Storage.setBool(ifIsDemoModeOrNot, false);
|
||||
returnWidget = F.sw(
|
||||
skyCall: () => MainBg(child: LockListPage(lockListInfoGroupEntity: state.lockListInfoGroupEntity.value)),
|
||||
xhjCall: () => MainBg(child: LockListXHJPage(lockListInfoGroupEntity: state.lockListInfoGroupEntity.value)));
|
||||
break;
|
||||
default:
|
||||
returnWidget = MainBg(child: NoData());
|
||||
break;
|
||||
}
|
||||
} else if (state.selectedIndex.value == 1) {
|
||||
returnWidget = MainBg(child: MessageListPage());
|
||||
} else {
|
||||
returnWidget = MainBg(child: StarLockMinePage());
|
||||
}
|
||||
return returnWidget;
|
||||
}
|
||||
|
||||
//鑫泓佳背景
|
||||
Widget XHJBg({required Widget child}) {
|
||||
return Container();
|
||||
//背景
|
||||
Widget MainBg({required Widget child}) {
|
||||
return Container(
|
||||
child: child,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('images/lockMain_bg.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget unHaveData() {
|
||||
@ -192,6 +212,48 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 10.h,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
Image.asset('images/icon_main_drlock_1024.png', width: 68.w, height: 68.w),
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
Text(
|
||||
F.title,
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
//实现回调函数
|
||||
// Navigator.pushNamed(
|
||||
// context,
|
||||
// Routers.selectLockTypePage,
|
||||
// );
|
||||
|
||||
// 跳转到扫描设备页
|
||||
CommonDataManage().seletLockType = 0;
|
||||
logicType.getNearByLimits();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add_circle_outline_rounded,
|
||||
size: 48.sp,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 160.h,
|
||||
),
|
||||
@ -211,10 +273,14 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
),
|
||||
onTap: () {
|
||||
//实现回调函数
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routers.selectLockTypePage,
|
||||
);
|
||||
// Navigator.pushNamed(
|
||||
// context,
|
||||
// Routers.selectLockTypePage,
|
||||
// );
|
||||
|
||||
// 跳转到扫描设备页
|
||||
CommonDataManage().seletLockType = 0;
|
||||
logicType.getNearByLimits();
|
||||
},
|
||||
)),
|
||||
],
|
||||
@ -288,13 +354,9 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
late StreamSubscription _teamEvent;
|
||||
|
||||
void _initLoadDataAction() {
|
||||
_teamEvent = eventBus
|
||||
.on<RefreshLockListInfoDataEvent>()
|
||||
.listen((RefreshLockListInfoDataEvent event) {
|
||||
_teamEvent = eventBus.on<RefreshLockListInfoDataEvent>().listen((RefreshLockListInfoDataEvent event) {
|
||||
logic.pageNo = 1;
|
||||
getHttpData(
|
||||
clearScanDevices: event.clearScanDevices,
|
||||
isUnShowLoading: event.isUnShowLoading);
|
||||
getHttpData(clearScanDevices: event.clearScanDevices, isUnShowLoading: event.isUnShowLoading);
|
||||
});
|
||||
}
|
||||
|
||||
@ -304,8 +366,7 @@ class _StarLockMainPageState extends State<StarLockMainPage>
|
||||
ByteData byteData = await rootBundle.load(assetPath);
|
||||
|
||||
// 将 ByteData 转换为 Uint8List
|
||||
Uint8List uint8List =
|
||||
Uint8List.sublistView(byteData); //byteData.buffer.asUint8List();
|
||||
Uint8List uint8List = Uint8List.sublistView(byteData); //byteData.buffer.asUint8List();
|
||||
|
||||
// 返回字节数组
|
||||
return uint8List.toList();
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import '../entity/lockListInfo_entity.dart';
|
||||
|
||||
class LockMainState {
|
||||
|
||||
// 0是无数据 1是有一条数据 2是有很多条数据
|
||||
RxInt dataLength = 100.obs;
|
||||
Rx<LockListInfoGroupEntity> lockListInfoGroupEntity = LockListInfoGroupEntity().obs;
|
||||
@ -13,5 +11,6 @@ class LockMainState {
|
||||
// 网络连接状态 0没有网络 1有网络
|
||||
RxInt networkConnectionStatus = 0.obs;
|
||||
|
||||
// late Timer timer;
|
||||
}
|
||||
RxInt selectedIndex = 0.obs;
|
||||
// late Timer timer;
|
||||
}
|
||||
|
||||
@ -29,6 +29,38 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
final MessageListLogic logic = Get.put(MessageListLogic());
|
||||
final MessageListState state = Get.find<MessageListLogic>().state;
|
||||
|
||||
// 修改 _showCheckboxes 状态变量为可观察状态
|
||||
final RxBool _showCheckboxes = false.obs;
|
||||
|
||||
// 添加选中状态
|
||||
final RxList<bool> _selectedItems = <bool>[].obs;
|
||||
|
||||
// 添加控制通知横幅显示的状态
|
||||
bool showNotificationBanner = true;
|
||||
|
||||
// 添加设置状态变量
|
||||
final RxBool _pushNotificationEnabled = false.obs;
|
||||
|
||||
// 删除方法
|
||||
void deleteSelectedMessages() {
|
||||
final List<MessageItemEntity> selectedMessages = [];
|
||||
for (int i = 0; i < state.itemDataList.value.length; i++) {
|
||||
if (_selectedItems[i]) {
|
||||
selectedMessages.add(state.itemDataList.value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 调用删除接口
|
||||
//logic.deletMessageDataRequest(selectedMessages);
|
||||
|
||||
// 清空选中状态
|
||||
_selectedItems.clear();
|
||||
_selectedItems.addAll(
|
||||
List.generate(state.itemDataList.value.length, (index) => false));
|
||||
_showCheckboxes.value = false;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void getHttpData() {
|
||||
logic.messageListDataRequest().then((MessageListEntity value) {
|
||||
setState(() {});
|
||||
@ -39,38 +71,60 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
// 获取当前消息推送设置状态
|
||||
_loadPushNotificationStatus();
|
||||
|
||||
getHttpData();
|
||||
}
|
||||
|
||||
// 加载消息推送状态
|
||||
void _loadPushNotificationStatus() async {
|
||||
final bool? enabled = await Storage.getBool('push_notification_enabled');
|
||||
_pushNotificationEnabled.value = enabled ?? false;
|
||||
}
|
||||
|
||||
//添加以时间分组的方法
|
||||
Map<String, List<MessageItemEntity>> _groupMessagesByDate() {
|
||||
Map<String, List<MessageItemEntity>> grouped = {};
|
||||
state.itemDataList.forEach((item) {
|
||||
String date = DateTool().dateToYMDString(item.createdAt!.toString());
|
||||
if (!grouped.containsKey(date)) {
|
||||
grouped[date] = [];
|
||||
}
|
||||
grouped[date]!.add(item);
|
||||
});
|
||||
return grouped;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.mainBackgroundColor,
|
||||
appBar: widget.showAppBar
|
||||
? TitleAppBar(
|
||||
barTitle: '消息'.tr,
|
||||
haveBack: true,
|
||||
actionsList: <Widget>[
|
||||
TextButton(
|
||||
child: Text(
|
||||
'清空'.tr,
|
||||
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||
),
|
||||
onPressed: () async {
|
||||
final bool? isDemoMode =
|
||||
await Storage.getBool(ifIsDemoModeOrNot);
|
||||
if (isDemoMode == false) {
|
||||
ShowTipView().showIosTipWithContentDialog('是否清空?'.tr,
|
||||
barTitle: '消息'.tr,
|
||||
haveBack: true,
|
||||
actionsList: <Widget>[
|
||||
TextButton(
|
||||
child: Text(
|
||||
'清空'.tr,
|
||||
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||
),
|
||||
onPressed: () async {
|
||||
final bool? isDemoMode =
|
||||
await Storage.getBool(ifIsDemoModeOrNot);
|
||||
if (isDemoMode == false) {
|
||||
ShowTipView().showIosTipWithContentDialog('是否清空?'.tr,
|
||||
() async {
|
||||
logic.deletAllMessageDataRequest();
|
||||
});
|
||||
} else {
|
||||
logic.showToast('演示模式'.tr);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
backgroundColor: AppColors.mainColor)
|
||||
} else {
|
||||
logic.showToast('演示模式'.tr);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
backgroundColor: AppColors.mainColor)
|
||||
: null,
|
||||
body: EasyRefreshTool(onRefresh: () {
|
||||
logic.pageNo = 1;
|
||||
@ -80,116 +134,354 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
}, child: Obx(() {
|
||||
return state.itemDataList.value.isEmpty
|
||||
? NoData()
|
||||
: SlidableAutoCloseBehavior(
|
||||
: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: showNotificationBanner ? 100 : 70,
|
||||
child: Column(children: [
|
||||
showNotificationBanner
|
||||
? Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: 10, right: 10),
|
||||
color: AppColors.messageTipsColor,
|
||||
height: 30,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('开启消息通知开关,及时获取通知',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 20.sp)),
|
||||
Row(children: [
|
||||
!_pushNotificationEnabled.value
|
||||
? GestureDetector(child: Text('去开启',
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontSize: 20.sp)),
|
||||
onTap: (){
|
||||
|
||||
}) : SizedBox.shrink(),
|
||||
SizedBox(width: 10),
|
||||
InkWell(
|
||||
child: Image.asset(
|
||||
'images/mine/icon_message_close.png',
|
||||
width: 24.w,
|
||||
height: 24.w),
|
||||
onTap: () {
|
||||
// 可以通过控制一个状态变量来隐藏整个通知栏
|
||||
setState(() {
|
||||
showNotificationBanner =
|
||||
false;
|
||||
});
|
||||
}),
|
||||
])
|
||||
]))
|
||||
: SizedBox.shrink(),
|
||||
Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: 15.w, right: 24.w, top: 20.h),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('告警',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 30.sp)),
|
||||
// 点击多选可以进行删除
|
||||
// GestureDetector(
|
||||
// onTap: () {
|
||||
// // 没有多选删除的 api接口,无法使用
|
||||
// // if (_showCheckboxes.value) {
|
||||
// // deleteSelectedMessages();
|
||||
// // } else {
|
||||
// // setState(() {
|
||||
// // _showCheckboxes.value =
|
||||
// // !_showCheckboxes.value;
|
||||
// // });
|
||||
// // }
|
||||
// },
|
||||
// child: _showCheckboxes.value
|
||||
// ? Text('删除',
|
||||
// style: TextStyle(
|
||||
// fontSize: 24.sp,
|
||||
// color: Colors.red))
|
||||
// : Image.asset(
|
||||
// 'images/mine/icon_message_checbox.png',
|
||||
// width: 30.w,
|
||||
// height: 30.h),
|
||||
// )
|
||||
]),
|
||||
)
|
||||
]))),
|
||||
Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: showNotificationBanner ? 80 : 50),
|
||||
child: ListView.builder(
|
||||
itemCount: state.itemDataList.value.length,
|
||||
itemBuilder: (BuildContext c, int index) {
|
||||
final MessageItemEntity messageItemEntity =
|
||||
state.itemDataList.value[index];
|
||||
return Slidable(
|
||||
key: ValueKey(messageItemEntity.id),
|
||||
endActionPane: ActionPane(
|
||||
extentRatio: 0.2,
|
||||
motion: const ScrollMotion(),
|
||||
children: <Widget>[
|
||||
SlidableAction(
|
||||
onPressed: (BuildContext context) {
|
||||
logic.deletMessageDataRequest(
|
||||
messageItemEntity.id!, () {
|
||||
logic.pageNo = 1;
|
||||
getHttpData();
|
||||
});
|
||||
},
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
label: '删除'.tr,
|
||||
padding: EdgeInsets.only(left: 5.w, right: 5.w),
|
||||
),
|
||||
],
|
||||
itemCount: _buildGroupedListItems().length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var item = _buildGroupedListItems()[index];
|
||||
|
||||
if (item is String) {
|
||||
// 日期标题
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 16.w, vertical: 10.h),
|
||||
color: AppColors.mainBackgroundColor,
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: item.substring(8, 10),
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 36.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' ',
|
||||
),
|
||||
TextSpan(
|
||||
text: item.substring(5, 7),
|
||||
style: TextStyle(
|
||||
color: Colors.grey, fontSize: 20.sp, fontWeight: FontWeight.w400),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: _messageListItem(messageItemEntity, () {
|
||||
Get.toNamed(Routers.messageDetailPage,
|
||||
arguments: <String, MessageItemEntity>{
|
||||
'messageItemEntity': messageItemEntity
|
||||
});
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
} else if (item is MessageItemEntity) {
|
||||
// 消息项
|
||||
return _messageListItem(item, () {
|
||||
Get.toNamed(Routers.messageDetailPage,
|
||||
arguments: <String, MessageItemEntity>{
|
||||
'messageItemEntity': item
|
||||
});
|
||||
});
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
// 构建分组列表
|
||||
List<dynamic> _buildGroupedListItems() {
|
||||
List<dynamic> items = [];
|
||||
Map<String, List<MessageItemEntity>> grouped = _groupMessagesByDate();
|
||||
|
||||
grouped.forEach((date, messages) {
|
||||
items.add(date); // 添加日期标题
|
||||
items.addAll(messages.map((message) => message)); // 添加该日期下的所有消息
|
||||
});
|
||||
|
||||
// 初始化选中状态
|
||||
if (_selectedItems.length != state.itemDataList.value.length) {
|
||||
_selectedItems.clear();
|
||||
_selectedItems.addAll(
|
||||
List.generate(state.itemDataList.value.length, (index) => false));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
Widget _messageListItem(
|
||||
MessageItemEntity messageItemEntity, Function() action) {
|
||||
final int index = state.itemDataList.value.indexOf(messageItemEntity);
|
||||
|
||||
// 查找当前消息在其所属日期分组中的位置
|
||||
Map<String, List<MessageItemEntity>> grouped = _groupMessagesByDate();
|
||||
bool isLastInGroupSimple = false;
|
||||
|
||||
// 确定当前消息属于哪个日期分组
|
||||
for (var entry in grouped.entries) {
|
||||
int messageIndex = entry.value.indexWhere((msg) => msg.id == messageItemEntity.id);
|
||||
if (messageIndex != -1) {
|
||||
// 如果是该分组的最后一条消息
|
||||
isLastInGroupSimple = messageIndex == entry.value.length - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: action,
|
||||
child: Container(
|
||||
height: 90.h,
|
||||
width: 1.sw,
|
||||
margin: EdgeInsets.only(bottom: 2.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.w),
|
||||
),
|
||||
child: Container(
|
||||
width: 1.sw,
|
||||
margin: EdgeInsets.only(left: 20.w, right: 20.w),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
if (messageItemEntity.readAt! == 0)
|
||||
onTap: () {
|
||||
// 如果是多选模式,切换选中状态
|
||||
if (_showCheckboxes.value) {
|
||||
_selectedItems[index] = !_selectedItems[index];
|
||||
setState(() {});
|
||||
} else {
|
||||
// 否则跳转到详情页
|
||||
action();
|
||||
}
|
||||
},
|
||||
child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 10),
|
||||
transform: Matrix4.translationValues(0, 20, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
messageItemEntity.readAt! == 0
|
||||
? 'images/mine/icon_message_unread.png'
|
||||
: 'images/mine/icon_message_readed.png',
|
||||
width: 18.w,
|
||||
height: 18.h),
|
||||
// 添加竖线,根据是否是分组最后一条消息来决定是否显示
|
||||
if (!isLastInGroupSimple)
|
||||
Container(
|
||||
width: 10.w,
|
||||
height: 10.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.circular(5.w),
|
||||
),
|
||||
width: 0.5,
|
||||
height: 190.h,
|
||||
color: AppColors.placeholderTextColor,
|
||||
)
|
||||
else
|
||||
Container(),
|
||||
if (messageItemEntity.readAt! == 0)
|
||||
SizedBox(width: 5.w)
|
||||
else
|
||||
Container(),
|
||||
Flexible(
|
||||
child: Text(
|
||||
messageItemEntity.data!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 22.sp,
|
||||
color: messageItemEntity.readAt! == 0
|
||||
? AppColors.blackColor
|
||||
: AppColors.placeholderTextColor),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Expanded(
|
||||
child: Slidable(
|
||||
key: Key(messageItemEntity.id.toString()), // 为每个item添加唯一key
|
||||
endActionPane: ActionPane(
|
||||
motion: const ScrollMotion(),
|
||||
children: [
|
||||
SlidableAction(
|
||||
onPressed: (context) {
|
||||
// 删除单条消息
|
||||
logic.deletMessageDataRequest(
|
||||
messageItemEntity.id!, () {
|
||||
logic.pageNo = 1;
|
||||
getHttpData();
|
||||
});
|
||||
},
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
icon: Icons.delete,
|
||||
label: '删除',
|
||||
),
|
||||
],
|
||||
), child: Container(
|
||||
width: 1.sw,
|
||||
margin: EdgeInsets.all(20.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.w),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
// Image.asset('images/mine/icon_mine_gatewaySignal_strong.png', width: 40.w, height: 40.w,),
|
||||
// SizedBox(width: 10.w,),
|
||||
Text(
|
||||
DateTool().dateToYMDHNString(
|
||||
messageItemEntity.createdAt!.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp,
|
||||
color: messageItemEntity.readAt! == 0
|
||||
? AppColors.blackColor
|
||||
: AppColors.placeholderTextColor)),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 20.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
child: Container(
|
||||
width: 1.sw,
|
||||
margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 8.h),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
// SizedBox(height: 4.h),
|
||||
// Row(
|
||||
// children: <Widget>[
|
||||
// Flexible(
|
||||
// child: Text(
|
||||
// // 调用请求标题
|
||||
// '远程开门请求',
|
||||
// maxLines: 1,
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// style: TextStyle(
|
||||
// fontSize: 22.sp,
|
||||
// color: messageItemEntity.readAt! == 0
|
||||
// ? AppColors.blackColor
|
||||
// : AppColors.placeholderTextColor),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(height: 4.h),
|
||||
Wrap(
|
||||
children: <Widget>[
|
||||
// if (messageItemEntity.readAt! == 0)
|
||||
// Container(
|
||||
// width: 10.w,
|
||||
// height: 10.w,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.red,
|
||||
// borderRadius: BorderRadius.circular(5.w),
|
||||
// ),
|
||||
// )
|
||||
// else
|
||||
// Container(),
|
||||
// if (messageItemEntity.readAt! == 0)
|
||||
// SizedBox(width: 5.w)
|
||||
// else
|
||||
// Container(),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 4.h),
|
||||
child: Text(
|
||||
DateTool().dateToHnString(messageItemEntity.createdAt!.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 20.sp,
|
||||
color: messageItemEntity.readAt! == 0
|
||||
? AppColors.blackColor
|
||||
: AppColors.placeholderTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 1,
|
||||
height: 10,
|
||||
margin: EdgeInsets.only(left: 5.w, right: 5.w, top: 10.h),
|
||||
color: messageItemEntity.readAt! == 0
|
||||
? AppColors.blackColor
|
||||
: AppColors.placeholderTextColor,
|
||||
),
|
||||
Container(transform: Matrix4.translationValues(0, -18, 0),
|
||||
child: Text(' ${messageItemEntity.data!}',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 20.sp,
|
||||
color: messageItemEntity.readAt! == 0
|
||||
? AppColors.blackColor
|
||||
: AppColors.placeholderTextColor,
|
||||
),
|
||||
)),
|
||||
Container(transform: Matrix4.translationValues(0, -8, 0), child: GestureDetector(
|
||||
child: Text('点击查看', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.sp, color: AppColors.mainColor),),
|
||||
),alignment: Alignment.centerRight,)
|
||||
],
|
||||
),
|
||||
// SizedBox(height: 5.h),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// children: <Widget>[
|
||||
// // Image.asset('images/mine/icon_mine_gatewaySignal_strong.png', width: 40.w, height: 40.w,),
|
||||
// // SizedBox(width: 10.w,),
|
||||
// Text(
|
||||
// DateTool().dateToHnString(messageItemEntity
|
||||
// .createdAt!
|
||||
// .toString()),
|
||||
// style: TextStyle(
|
||||
// fontSize: 18.sp,
|
||||
// color: messageItemEntity.readAt! == 0
|
||||
// ? AppColors.blackColor
|
||||
// : AppColors.placeholderTextColor)),
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(width: 20.h),
|
||||
]))))),
|
||||
// 显示选中状态的复选框
|
||||
if (_showCheckboxes.value)
|
||||
Checkbox(
|
||||
value: _selectedItems[index],
|
||||
activeColor: Colors.blue,
|
||||
onChanged: (val) {
|
||||
_selectedItems[index] = val!;
|
||||
setState(() {});
|
||||
},
|
||||
)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,22 +1,34 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
|
||||
import 'package:star_lock/flavors.dart';
|
||||
import 'package:star_lock/mine/mine/starLockMine_state.dart';
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
import 'package:star_lock/tools/wechat/customer_tool.dart';
|
||||
|
||||
import '../../appRouters.dart';
|
||||
import '../../app_settings/app_colors.dart';
|
||||
import '../../baseWidget.dart';
|
||||
import '../../tools/commonItem.dart';
|
||||
import '../../tools/customNetworkImage.dart';
|
||||
import '../../tools/showTipView.dart';
|
||||
import '../../tools/submitBtn.dart';
|
||||
import '../../tools/wechat/wechatManageTool.dart';
|
||||
import '../../tools/wechat/wx_push_miniProgram/wx_push_miniProgram.dart';
|
||||
import '../../translations/app_dept.dart';
|
||||
import '../../translations/current_locale_tool.dart';
|
||||
import '../mineSet/mineSet/mineSet_logic.dart';
|
||||
import '../mineSet/mineSet/mineSet_state.dart';
|
||||
import 'starLockMine_logic.dart';
|
||||
|
||||
class StarLockMinePage extends StatefulWidget {
|
||||
const StarLockMinePage({Key? key}) : super(key: key);
|
||||
const StarLockMinePage({Key? key, this.showAppBar = true, this.showAbout = true}) : super(key: key);
|
||||
final bool showAppBar;
|
||||
final bool showAbout;
|
||||
|
||||
@override
|
||||
State<StarLockMinePage> createState() => StarLockMinePageState();
|
||||
@ -27,199 +39,237 @@ GlobalKey<StarLockMinePageState> starLockMineKey = GlobalKey();
|
||||
class StarLockMinePageState extends State<StarLockMinePage> with BaseWidget {
|
||||
final StarLockMineLogic logic = Get.put(StarLockMineLogic());
|
||||
final StarLockMineState state = Get.find<StarLockMineLogic>().state;
|
||||
late final MineSetState stateSet;
|
||||
late final MineSetLogic logicSet;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
// 确保 MineSetLogic 存在
|
||||
if (!Get.isRegistered<MineSetLogic>()) {
|
||||
Get.put(MineSetLogic());
|
||||
}
|
||||
logicSet = Get.find<MineSetLogic>();
|
||||
stateSet = logicSet.state;
|
||||
logicSet.userSettingsInfoRequest();
|
||||
|
||||
logic.getUserInfoRequest();
|
||||
|
||||
// 初始化时检查推送权限状态
|
||||
_checkNotificationPermission();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFFFFFFF),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
topWidget(),
|
||||
bottomListWidget(),
|
||||
SizedBox(
|
||||
height: 80.h,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
WechatManageTool.getAppInfo(() {
|
||||
WxPushWeChatMiniProgramTool.pushWeChatMiniProgram(
|
||||
F.wechatAppInfo.wechatAppId, F.wechatAppInfo.universalLink);
|
||||
});
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 20.w, right: 20.w),
|
||||
child: Image.asset(
|
||||
'images/mine/icon_mine_wan_miniprogram.png',
|
||||
// width: 400.w,
|
||||
// height: 151.h,
|
||||
fit: BoxFit.fill,
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(child: Container(
|
||||
margin: EdgeInsets.only(bottom: 20.h),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 20.h,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget topWidget() {
|
||||
return Container(
|
||||
height: 380.h,
|
||||
width: 1.sw,
|
||||
color: AppColors.mainColor,
|
||||
// color: Colors.red,
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Image.asset(
|
||||
'images/mine/icon_mine_topBg.png',
|
||||
width: 400.w,
|
||||
height: 380.h,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
Center(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 120.h,
|
||||
topWidget(),
|
||||
SizedBox(
|
||||
height: 20.h,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
GestureDetector(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 15.h),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.minePersonInfoPage);
|
||||
},
|
||||
child: Obx(() => SizedBox(
|
||||
width: 105.w,
|
||||
height: 105.w,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(52.5.w),
|
||||
child: CustomNetworkImage(
|
||||
url: state.userHeadUrl.value,
|
||||
defaultUrl: 'images/controls_user.png',
|
||||
width: 105.w,
|
||||
height: 105.h,
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20.h,
|
||||
),
|
||||
Obx(() => GestureDetector(
|
||||
onTap: () {
|
||||
if (!state.isVip.value) {
|
||||
// if (CommonDataManage().currentKeyInfo.isLockOwner !=
|
||||
// 1) {
|
||||
// logic.showToast('请先添加锁');
|
||||
// } else {
|
||||
Get.toNamed(Routers.advancedFeaturesWebPage,
|
||||
arguments: <String, int>{
|
||||
'webBuyType': XSConstantMacro.webBuyTypeVip,
|
||||
});
|
||||
// }
|
||||
} else {
|
||||
Get.toNamed(
|
||||
Routers.valueAddedServicesHighFunctionPage);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
state.userNickName.value.isNotEmpty
|
||||
? state.userNickName.value
|
||||
: (state.userMobile.value.isNotEmpty
|
||||
? state.userMobile.value
|
||||
: state.userEmail.value),
|
||||
style: TextStyle(
|
||||
fontSize: 22.sp,
|
||||
color: Colors.white,
|
||||
)),
|
||||
SizedBox(
|
||||
width: 5.w,
|
||||
),
|
||||
if (!state.isVip.value)
|
||||
Image.asset(
|
||||
'images/mine/icon_mine_noPlus.png',
|
||||
width: 20.w,
|
||||
height: 20.w,
|
||||
)
|
||||
else
|
||||
Image.asset(
|
||||
'images/mine/icon_mine_isPlus.png',
|
||||
width: 20.w,
|
||||
height: 20.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Icons.person,
|
||||
size: 32.sp,
|
||||
),
|
||||
))
|
||||
],
|
||||
SizedBox(width: 15.w),
|
||||
Text(
|
||||
'个人信息'.tr,
|
||||
style: TextStyle(fontSize: 28.sp),
|
||||
),
|
||||
const Spacer(),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: Colors.grey[400],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20.h,
|
||||
),
|
||||
bottomListWidget(),
|
||||
SizedBox(
|
||||
height: 20.h,
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 15.h),
|
||||
child: getListDataView(),
|
||||
)])))));
|
||||
}
|
||||
|
||||
Widget topWidget() {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.minePersonInfoPage);
|
||||
},
|
||||
child: Obx(
|
||||
() => SizedBox(
|
||||
width: 68.w,
|
||||
height: 68.w,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(52.5.w),
|
||||
child: CustomNetworkImage(
|
||||
url: state.userHeadUrl.value,
|
||||
defaultUrl: 'images/controls_user.png',
|
||||
width: 68.w,
|
||||
height: 68.h,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 20.w),
|
||||
Obx(
|
||||
() => GestureDetector(
|
||||
onTap: () {
|
||||
if (!state.isVip.value) {
|
||||
Get.toNamed(Routers.advancedFeaturesWebPage, arguments: <String, int>{
|
||||
'webBuyType': XSConstantMacro.webBuyTypeVip,
|
||||
});
|
||||
// }
|
||||
} else {
|
||||
Get.toNamed(Routers.valueAddedServicesHighFunctionPage);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
state.userNickName.value.isNotEmpty
|
||||
? state.userNickName.value
|
||||
: (state.userMobile.value.isNotEmpty ? state.userMobile.value : state.userEmail.value),
|
||||
style: TextStyle(
|
||||
fontSize: 22.sp,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 5.w,
|
||||
),
|
||||
if (!state.isVip.value)
|
||||
Image.asset(
|
||||
'images/mine/icon_mine_noPlus.png',
|
||||
width: 20.w,
|
||||
height: 20.w,
|
||||
)
|
||||
else
|
||||
Image.asset(
|
||||
'images/mine/icon_mine_isPlus.png',
|
||||
width: 20.w,
|
||||
height: 20.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// const Spacer(),
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(10.r),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 10.h),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// if (F.isSKY && Get.locale!.languageCode == 'zh')
|
||||
// GestureDetector(
|
||||
// onTap: () {
|
||||
// Get.back();
|
||||
// WechatManageTool.getAppInfo(CustomerTool.openCustomerService);
|
||||
// },
|
||||
// child: Image.asset(
|
||||
// 'images/mine/icon_mine_main_supportStaff.png',
|
||||
// width: 34.w,
|
||||
// height: 34.w,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: 20.w,
|
||||
// ),
|
||||
// GestureDetector(
|
||||
// onTap: () {
|
||||
// Get.back();
|
||||
// Get.toNamed(Routers.messageListPage);
|
||||
// },
|
||||
// child: Image.asset(
|
||||
// 'images/mine/icon_mine_main_message.png',
|
||||
// width: 36.w,
|
||||
// height: 36.w,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// )
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget bottomListWidget() {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 60.w,
|
||||
top: 50.h,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.w),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.w),
|
||||
child: Column(
|
||||
children: [
|
||||
mineItem('images/mine/icon_mine_main_addLock.png', '添加设备'.tr, () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.selectLockTypePage);
|
||||
}),
|
||||
// mineItem('images/mine/icon_mine_main_gateway.png',
|
||||
// TranslationLoader.lanKeys!.gateway!.tr, () {
|
||||
// Navigator.pushNamed(context, Routers.gatewayListPage);
|
||||
// mineItem('images/mine/icon_mine_main_set.png', '设置'.tr, () {
|
||||
// Get.back();
|
||||
// Get.toNamed(Routers.mineSetPage);
|
||||
// }),
|
||||
mineItem('images/mine/icon_mine_main_message.png', '消息'.tr, () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.messageListPage);
|
||||
// Toast.show(msg: "功能暂未开放");
|
||||
// SizedBox(height: 20.h),
|
||||
mineItem('images/mine/icon_mine_main_vip.png', '增值服务'.tr, () async {
|
||||
final bool? isVip = await Storage.getBool(saveIsVip);
|
||||
if (isVip == null || !isVip) {
|
||||
// vip状态是和账号绑定,这里判断用户打开的某个锁是不是LockOwner没意义
|
||||
// if (CommonDataManage().currentKeyInfo.isLockOwner != 1) {
|
||||
// logic.showToast('请先添加锁'.tr);
|
||||
// } else {
|
||||
//刷新购买状态
|
||||
Get.toNamed(Routers.advancedFeaturesWebPage, arguments: <String, int>{
|
||||
'webBuyType': XSConstantMacro.webBuyTypeVip,
|
||||
})?.then((value) => logic.getUserInfoRequest());
|
||||
// }
|
||||
} else {
|
||||
Get.toNamed(Routers.valueAddedServicesHighFunctionPage);
|
||||
}
|
||||
}),
|
||||
//删除“客服”行
|
||||
// mineItem('images/mine/icon_mine_main_supportStaff.png',
|
||||
// TranslationLoader.lanKeys!.supportStaff!.tr, () {
|
||||
// Navigator.pushNamed(context, Routers.supportStaffPage);
|
||||
// }),
|
||||
mineItem('images/mine/icon_mine_main_set.png', '设置'.tr, () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.mineSetPage);
|
||||
}),
|
||||
//上架审核
|
||||
// if (F.isLite)
|
||||
// Container()
|
||||
// else
|
||||
mineItem('images/mine/icon_mine_main_vip.png', '增值服务'.tr, () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.valueAddedServicesPage);
|
||||
}),
|
||||
// if (F.isLite)
|
||||
// Container()
|
||||
// else
|
||||
mineItem('images/mine/icon_mine_main_shoppingcart.png', '配件商城'.tr,
|
||||
() {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.lockMallPage);
|
||||
}),
|
||||
if (F.isSKY && Get.locale!.languageCode == 'zh')
|
||||
mineItem('images/mine/icon_mine_main_supportStaff.png', '客服'.tr,
|
||||
() {
|
||||
Get.back();
|
||||
WechatManageTool.getAppInfo(CustomerTool.openCustomerService);
|
||||
}),
|
||||
SizedBox(height: 20.h),
|
||||
mineItem('images/mine/icon_mine_main_about.png', '关于'.tr, () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.aboutPage);
|
||||
@ -229,71 +279,435 @@ class StarLockMinePageState extends State<StarLockMinePage> with BaseWidget {
|
||||
);
|
||||
}
|
||||
|
||||
// Widget keyBottomWidget() {
|
||||
// return Column(
|
||||
// children: <Widget>[
|
||||
// SubmitBtn(
|
||||
// btnName: '退出'.tr,
|
||||
// borderRadius: 20.w,
|
||||
// fontSize: 32.sp,
|
||||
// margin: EdgeInsets.only(left: 60.w, right: 60.w),
|
||||
// padding: EdgeInsets.only(top: 15.w, bottom: 15.w),
|
||||
// onClick: () {}),
|
||||
// Container(
|
||||
// padding: EdgeInsets.only(right: 30.w),
|
||||
// // color: Colors.red,
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.end,
|
||||
// children: <Widget>[
|
||||
// TextButton(
|
||||
// child: Text(
|
||||
// '删除账号'.tr,
|
||||
// style: TextStyle(
|
||||
// color: AppColors.mainColor, fontWeight: FontWeight.w500),
|
||||
// ),
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: 30.h,
|
||||
// )
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
|
||||
Widget mineItem(
|
||||
String lockTypeIcon, String lockTypeTitle, Function() action) {
|
||||
Widget mineItem(String lockTypeIcon, String lockTypeTitle, Function() action) {
|
||||
return GestureDetector(
|
||||
onTap: action,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Center(
|
||||
child: Container(
|
||||
// height: 80.h,
|
||||
width: 330.w,
|
||||
padding: EdgeInsets.all(20.h),
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Image.asset(
|
||||
lockTypeIcon,
|
||||
width: 28.w,
|
||||
height: 28.w,
|
||||
),
|
||||
SizedBox(width: 15.w),
|
||||
Text(
|
||||
lockTypeTitle,
|
||||
style: TextStyle(fontSize: 22.sp),
|
||||
),
|
||||
],
|
||||
),
|
||||
Image.asset(
|
||||
lockTypeIcon,
|
||||
width: 28.w,
|
||||
height: 28.w,
|
||||
),
|
||||
SizedBox(width: 15.w),
|
||||
Text(
|
||||
lockTypeTitle,
|
||||
style: TextStyle(fontSize: 28.sp),
|
||||
),
|
||||
const Spacer(),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: Colors.grey[400],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget getListDataView() {
|
||||
// 检测系统语言是否为中文
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
/* 2024-01-12 会议确定去掉“提示音、触摸开锁” by DaisyWu
|
||||
CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.prompTone!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: true,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: SizedBox(
|
||||
width: 60.w,
|
||||
height: 50.h,
|
||||
child: Obx(() => _isPrompToneSwitch()))),
|
||||
CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.touchUnlock!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: true,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: SizedBox(
|
||||
width: 60.w,
|
||||
height: 50.h,
|
||||
child: Obx(() => _isTouchUnlockSwitch()))),
|
||||
*/
|
||||
F.sw(
|
||||
skyCall: () => const SizedBox(),
|
||||
xhjCall: () => CommonItem(
|
||||
leftTitel: '个人信息'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.minePersonInfoPage);
|
||||
})),
|
||||
CommonItem(
|
||||
leftTitel: '消息推送'.tr,
|
||||
rightTitle: '',
|
||||
isHaveRightWidget: true,
|
||||
isHaveLine: F.sw(
|
||||
skyCall: () => F.appFlavor == Flavor.sky, xhjCall: () => true),
|
||||
rightWidget: SizedBox(
|
||||
width: 60.w,
|
||||
height: 50.h,
|
||||
child: Obx(_isPushNotificationSwitch)
|
||||
)),
|
||||
// if (F.appFlavor == Flavor.sky)
|
||||
Visibility(
|
||||
visible: stateSet.currentLanguageCode == 'zh_CN',
|
||||
child: CommonItem(
|
||||
leftTitel: '微信公众号推送'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: SizedBox(
|
||||
width: 60.w,
|
||||
height: 50.h,
|
||||
child: Obx(_isWechatPublicAccountPushSwitch),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
CommonItem(
|
||||
leftTitel: '锁用户管理'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.lockUserManageLisPage);
|
||||
}),
|
||||
CommonItem(
|
||||
leftTitel: '授权管理员'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.authorizedAdministratorListPage);
|
||||
}),
|
||||
//by DaisyWu 新增--批量授权
|
||||
if (!F.isProductionEnv)
|
||||
CommonItem(
|
||||
leftTitel: '批量授权'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.authorityManagementPage);
|
||||
// Toast.show(msg: "功能暂未开放");
|
||||
}),
|
||||
CommonItem(
|
||||
leftTitel: '网关'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.gatewayListPage);
|
||||
}),
|
||||
CommonItem(
|
||||
leftTitel: '锁分组'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.lockGroupListPage);
|
||||
}),
|
||||
CommonItem(
|
||||
leftTitel: '转移智能锁'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.transferSmartLockPage);
|
||||
}),
|
||||
//暂无网关屏蔽
|
||||
// CommonItem(
|
||||
// leftTitel: '转移网关'.tr,
|
||||
// rightTitle: '',
|
||||
// isHaveLine: true,
|
||||
// isHaveDirection: true,
|
||||
// action: () {
|
||||
// Get.toNamed(Routers.selectGetewayListPage);
|
||||
// }),
|
||||
SizedBox(
|
||||
height: 10.h,
|
||||
),
|
||||
|
||||
// AppLog.log('state.currentLanguageName: ${state.currentLanguageName} state.currentLanguage.value: ${state.currentLanguage.value}');
|
||||
CommonItem(
|
||||
leftTitel: '多语言'.tr,
|
||||
rightTitle: stateSet.currentLanguageName,
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () async {
|
||||
// Get.toNamed(Routers.mineMultiLanguagePage);
|
||||
await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) {
|
||||
setState(() {
|
||||
if (value.containsKey('currentLanguage')) {
|
||||
stateSet.currentLanguage.value = value['currentLanguage'];
|
||||
}
|
||||
});
|
||||
});
|
||||
}),
|
||||
/* 2024-01-12 会议确定去掉“锁屏” by DaisyWu
|
||||
Obx(() => CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.lockScreen!.tr,
|
||||
rightTitle: (state.lockScreen.value == 1
|
||||
? TranslationLoader.lanKeys!.opened!.tr
|
||||
: TranslationLoader.lanKeys!.closed!.tr),
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Navigator.pushNamed(context, Routers.lockScreenPage,
|
||||
arguments: {'isOn': state.lockScreen.value}).then((value) {
|
||||
logic.userSettingsInfoRequest();
|
||||
});
|
||||
})),
|
||||
*/
|
||||
Obx(() => CommonItem(
|
||||
leftTitel: '隐藏无效开锁权限'.tr,
|
||||
rightTitle:
|
||||
(stateSet.hideExpiredAccessFlag.value == 1 ? '已开启'.tr : '已关闭'.tr),
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Navigator.pushNamed(
|
||||
context, Routers.hideInvalidUnlockPermissionsPage,
|
||||
arguments: <String, int>{
|
||||
'isOn': stateSet.hideExpiredAccessFlag.value
|
||||
}).then((Object? value) {
|
||||
logicSet.userSettingsInfoRequest();
|
||||
});
|
||||
})),
|
||||
otherItem(
|
||||
leftTitle: 'APP开锁时需手机连网的锁'.tr,
|
||||
isHaveLine: true,
|
||||
action: () {
|
||||
Navigator.pushNamed(
|
||||
context, Routers.aPPUnlockNeedMobileNetworkingLockPage);
|
||||
}),
|
||||
if (!F.isSKY)
|
||||
CommonItem(
|
||||
leftTitel: '增值服务'.tr,
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.valueAddedServicesPage);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 10.h,
|
||||
),
|
||||
CommonItem(
|
||||
leftTitel: 'Amazon Alexa'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.amazonAlexaPage, arguments: <String, dynamic>{
|
||||
'isAmazonAlexa': stateSet.isAmazonAlexa.value,
|
||||
'amazonAlexaData': stateSet.amazonAlexaData.value
|
||||
});
|
||||
}),
|
||||
CommonItem(
|
||||
leftTitel: 'Google Home'.tr,
|
||||
rightTitle: '',
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.googleHomePage, arguments: <String, dynamic>{
|
||||
'isGoogleHome': stateSet.isGoogleHome.value,
|
||||
'googleHomeData': stateSet.googleHomeData.value
|
||||
})?.then((Object? value) {
|
||||
logicSet.userSettingsInfoRequest();
|
||||
});
|
||||
}),
|
||||
// if (!F.isProductionEnv)
|
||||
// CommonItem(
|
||||
// leftTitel: '小米IOT平台'.tr,
|
||||
// rightTitle: '',
|
||||
// isHaveLine: widget.showAbout,
|
||||
// isHaveDirection: true,
|
||||
// action: () {
|
||||
// logic.showToast('功能暂未开放'.tr);
|
||||
// }),
|
||||
if (!F.isSKY)
|
||||
CommonItem(
|
||||
leftTitel: '客服'.tr,
|
||||
isHaveLine: widget.showAbout,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
WechatManageTool.getAppInfo(CustomerTool.openCustomerService);
|
||||
},
|
||||
),
|
||||
if (widget.showAbout)
|
||||
CommonItem(
|
||||
leftTitel: '关于'.tr,
|
||||
isHaveLine: false,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.back();
|
||||
Get.toNamed(Routers.aboutPage);
|
||||
},
|
||||
),
|
||||
// CommonItem(leftTitel:TranslationLoader.lanKeys!.valueAddedServices!.tr, rightTitle:"", isHaveDirection: true, action: (){
|
||||
//
|
||||
// }),
|
||||
SizedBox(
|
||||
height: F.sw(skyCall: () => 50.h, xhjCall: () => 0.0),
|
||||
),
|
||||
// CommonItem(leftTitel:TranslationLoader.lanKeys!.about!.tr, rightTitle:"", isHaveLine: true, isHaveDirection: true, action: (){
|
||||
//
|
||||
// }),
|
||||
// SizedBox(height: 10.h,),
|
||||
// CommonItem(leftTitel:TranslationLoader.lanKeys!.userAgreement!.tr, rightTitle:"", isHaveLine: true, isHaveDirection: true, action: (){
|
||||
//
|
||||
// }),
|
||||
// CommonItem(leftTitel:TranslationLoader.lanKeys!.privacyPolicy!.tr, rightTitle:"", isHaveLine: true, isHaveDirection: true, action: (){
|
||||
//
|
||||
// }),
|
||||
// CommonItem(leftTitel:TranslationLoader.lanKeys!.personalInformationCollectionList!.tr, rightTitle:"", isHaveLine: true, isHaveDirection: true, action: (){
|
||||
//
|
||||
// }),
|
||||
// CommonItem(leftTitel:TranslationLoader.lanKeys!.applicationPermissionDescription!.tr, rightTitle:"", isHaveLine: true, isHaveDirection: true, action: (){
|
||||
//
|
||||
// }),
|
||||
// CommonItem(leftTitel:TranslationLoader.lanKeys!.thirdPartyInformationSharingList!.tr, rightTitle:"", isHaveLine: true, isHaveDirection: true, action: (){
|
||||
//
|
||||
// }),
|
||||
F.sw(skyCall: keyBottomWidget, xhjCall: () => const SizedBox())
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//微信公众号推送开关
|
||||
CupertinoSwitch _isWechatPublicAccountPushSwitch() {
|
||||
return CupertinoSwitch(
|
||||
activeColor: CupertinoColors.activeBlue,
|
||||
trackColor: CupertinoColors.systemGrey5,
|
||||
thumbColor: CupertinoColors.white,
|
||||
value: stateSet.isWechatPublicAccountPush.value,
|
||||
onChanged: (bool value) {
|
||||
stateSet.isWechatPublicAccountPush.value =
|
||||
!stateSet.isWechatPublicAccountPush.value;
|
||||
logicSet.setMpWechatPushSwitchRequest(context);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
CupertinoSwitch _isPushNotificationSwitch() {
|
||||
return CupertinoSwitch(
|
||||
activeColor: CupertinoColors.activeBlue,
|
||||
trackColor: CupertinoColors.systemGrey5,
|
||||
thumbColor: CupertinoColors.white,
|
||||
value: stateSet.isPushNotification.value,
|
||||
onChanged: (bool value) async {
|
||||
// stateSet.isPushNotification.value = !stateSet.isPushNotification.value;
|
||||
openAppSettings();
|
||||
final PermissionStatus newStatus = await Permission.notification.status;
|
||||
stateSet.isPushNotification.value = newStatus.isGranted;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _checkNotificationPermission() async {
|
||||
final PermissionStatus status = await Permission.notification.status;
|
||||
stateSet.isPushNotification.value = status.isGranted;
|
||||
}
|
||||
|
||||
Widget otherItem(
|
||||
{String? leftTitle,
|
||||
bool? isHaveLine,
|
||||
Function()? action,
|
||||
double? allHeight}) {
|
||||
return GestureDetector(
|
||||
onTap: action,
|
||||
child: Container(
|
||||
width: 1.sw,
|
||||
padding:
|
||||
EdgeInsets.only(left: 20.w, top: 15.h, bottom: 15.h, right: 10.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isHaveLine!
|
||||
? Border(
|
||||
bottom: BorderSide(
|
||||
color: AppColors.greyLineColor, // 设置边框颜色
|
||||
width: 2.0.h, // 设置边框宽度
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Text(leftTitle!, style: TextStyle(fontSize: 22.sp))),
|
||||
SizedBox(width: 10.w),
|
||||
if (CurrentLocaleTool.getCurrentLocaleString() ==
|
||||
ExtensionLanguageType.fromLanguageType(LanguageType.hebrew)
|
||||
.toString() ||
|
||||
CurrentLocaleTool.getCurrentLocaleString() ==
|
||||
ExtensionLanguageType.fromLanguageType(LanguageType.arabic)
|
||||
.toString())
|
||||
Image.asset(
|
||||
'images/icon_left_grey.png',
|
||||
width: 21.w,
|
||||
height: 21.w,
|
||||
)
|
||||
else
|
||||
Image.asset(
|
||||
'images/icon_right_grey.png',
|
||||
width: 12.w,
|
||||
height: 21.w,
|
||||
),
|
||||
SizedBox(width: 5.w),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget keyBottomWidget() {
|
||||
return Padding(
|
||||
padding: F.sw(
|
||||
skyCall: () => EdgeInsets.zero,
|
||||
xhjCall: () => EdgeInsets.symmetric(horizontal: 15.w)),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SubmitBtn(
|
||||
btnName: '退出'.tr,
|
||||
isDelete: true,
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
onClick: () {
|
||||
//退出登录
|
||||
ShowTipView().showIosTipWithContentDialog(
|
||||
'确定要退出吗?'.tr, () async {
|
||||
await logicSet.userLogoutRequest();
|
||||
// showLoginOutAlertTipDialog();
|
||||
});
|
||||
}),
|
||||
Container(
|
||||
height: 0.5.h,
|
||||
color: Colors.grey,
|
||||
padding: EdgeInsets.only(left: 30.w, top: 30.h),
|
||||
// color: Colors.red,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
TextButton(
|
||||
child: Text(
|
||||
'删除账号'.tr,
|
||||
style: TextStyle(
|
||||
color: AppColors.darkGrayTextColor, fontSize: 18.sp),
|
||||
),
|
||||
onPressed: () {
|
||||
ShowTipView().showIosTipWithContentDialog(
|
||||
'删除账号后,你的所有信息及相关记录都会从平台彻底删除,且不可恢复,是否删除?'.tr, () {
|
||||
//安全验证
|
||||
Get.toNamed(Routers.safeVerifyPage);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30.h,
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -10,28 +10,48 @@ import 'package:star_lock/talk/starChart/entity/star_chart_register_node_entity.
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
|
||||
class StartCompanyApi extends BaseProvider {
|
||||
// 星图url
|
||||
// 星启url
|
||||
String _startChartHost = 'https://company.skychip.top';
|
||||
|
||||
static StartCompanyApi get to => Get.put(StartCompanyApi());
|
||||
|
||||
// 设置星图host
|
||||
// 设置星启host
|
||||
set startChartHost(String value) {
|
||||
_startChartHost = value;
|
||||
}
|
||||
|
||||
// 获取星图host
|
||||
// 获取星启host
|
||||
String get startChartHost => _startChartHost;
|
||||
|
||||
// ttp查询
|
||||
Future<ActivateInfoResponse> getActivateInfo({
|
||||
Future<TppSupportResponse> getTppSupport({
|
||||
required String model,
|
||||
}) async {
|
||||
final response = await post(
|
||||
_startChartHost + getTppSupportURL.toUrl,
|
||||
jsonEncode(<String, dynamic>{
|
||||
'model': model,
|
||||
}),
|
||||
isUnShowLoading: true,
|
||||
isUserBaseUrl: false,
|
||||
);
|
||||
return TppSupportResponse.fromJson(response.body);
|
||||
}
|
||||
|
||||
// 获取授权码
|
||||
Future<ActivateInfoResponse> getAuthorizationCode({
|
||||
required String registerKey,
|
||||
required String model,
|
||||
required String serialNum0,
|
||||
required int platform,
|
||||
}) async {
|
||||
final response = await post(
|
||||
_startChartHost + getActivateInfoURL.toUrl,
|
||||
jsonEncode(<String, dynamic>{
|
||||
'register_key': registerKey,
|
||||
'platform': platform,
|
||||
'model': model,
|
||||
|
||||
'serial_num0': serialNum0,
|
||||
}),
|
||||
isUnShowLoading: true,
|
||||
isUserBaseUrl: false,
|
||||
|
||||
@ -67,7 +67,7 @@ class CommonItem extends StatelessWidget {
|
||||
),
|
||||
child: Text(
|
||||
leftTitel!,
|
||||
style: leftTitleStyle ?? TextStyle(fontSize: 22.sp),
|
||||
style: leftTitleStyle ?? TextStyle(fontSize: 28.sp),
|
||||
overflow: TextOverflow.ellipsis, // 超出部分显示省略号
|
||||
maxLines: 3, // 最多显示2行
|
||||
),
|
||||
|
||||
@ -194,6 +194,45 @@ class DateTool {
|
||||
return appointmentDate;
|
||||
}
|
||||
|
||||
/// 将时间戳传化为月
|
||||
String dateToMMString(String? timestamp) {
|
||||
timestamp ??= '0';
|
||||
int time = int.parse(timestamp);
|
||||
if (timestamp.length == 10) {
|
||||
time = time * 1000;
|
||||
}
|
||||
final DateTime nowDate = DateTime.fromMillisecondsSinceEpoch(time);
|
||||
final String appointmentDate =
|
||||
formatDate(nowDate, <String>[mm]);
|
||||
return appointmentDate;
|
||||
}
|
||||
|
||||
/// 将时间戳传化为日
|
||||
String dateToDDString(String? timestamp) {
|
||||
timestamp ??= '0';
|
||||
int time = int.parse(timestamp);
|
||||
if (timestamp.length == 10) {
|
||||
time = time * 1000;
|
||||
}
|
||||
final DateTime nowDate = DateTime.fromMillisecondsSinceEpoch(time);
|
||||
final String appointmentDate =
|
||||
formatDate(nowDate, <String>[dd]);
|
||||
return appointmentDate;
|
||||
}
|
||||
|
||||
/// 将时间戳传化为时分
|
||||
String dateToHnString(String? timestamp) {
|
||||
timestamp ??= '0';
|
||||
int time = int.parse(timestamp);
|
||||
if (timestamp.length == 10) {
|
||||
time = time * 1000;
|
||||
}
|
||||
final DateTime nowDate = DateTime.fromMillisecondsSinceEpoch(time);
|
||||
final String appointmentDate =
|
||||
formatDate(nowDate, <String>[HH, ':', nn]);
|
||||
return appointmentDate;
|
||||
}
|
||||
|
||||
/// 将时间戳传化为年月日 (年-月-日 时:分)
|
||||
String dateIntToYMDHNString(int? time) {
|
||||
time ??= 0;
|
||||
|
||||
@ -261,7 +261,7 @@ dependencies:
|
||||
|
||||
jverify: 3.0.0
|
||||
#<cn>
|
||||
umeng_common_sdk: 1.2.8
|
||||
# umeng_common_sdk: 1.2.8
|
||||
#</cn>
|
||||
#<com>
|
||||
firebase_analytics: 11.3.0
|
||||
@ -323,6 +323,7 @@ flutter:
|
||||
- images/
|
||||
- images/tabbar/
|
||||
- images/guide/
|
||||
- images/other/
|
||||
- images/main/
|
||||
- images/main/addFingerprint/
|
||||
- images/mine/
|
||||
|
||||