Compare commits

...

4 Commits

Author SHA1 Message Date
b0506a8910 1.取消用手机号码登陆
2.添加设备页直接跳到扫描设备页
2025-10-31 13:42:25 +08:00
4fa076565f 1.底部新增消息入口
2.将设置移出到个人中心页面
3.注册页面默认邮箱注册
2025-10-31 09:02:03 +08:00
8a8c81b7d2 消息列表优化 2025-10-29 18:10:34 +08:00
7e53ecfbf5 fix: 增加drlock 分支 2025-10-16 14:31:19 +08:00
40 changed files with 2290 additions and 938 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -1185,5 +1185,6 @@
"这是单次密码,只能使用一次": "这是单次密码,只能使用一次", "这是单次密码,只能使用一次": "这是单次密码,只能使用一次",
"您好": "您好", "您好": "您好",
"您的开门密码是": "您的开门密码是", "您的开门密码是": "您的开门密码是",
"开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标": "开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标" "开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标": "开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标",
"锁博士": "锁博士"
} }

View File

@ -150,6 +150,7 @@ class AppColors {
static Color openPassageModeColor = const Color(0xFFEB2A3B); // () static Color openPassageModeColor = const Color(0xFFEB2A3B); // ()
static Color listTimeYellowColor = const Color(0xFFF3BA37); // () static Color listTimeYellowColor = const Color(0xFFF3BA37); // ()
static Color messageTipsColor = const Color.fromRGBO(202, 220, 247, 1); //
static Color get lockDetailBottomBtnUneable => static Color get lockDetailBottomBtnUneable =>
const Color(0xFF808080); // () const Color(0xFF808080); // ()

View 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);
}
}

View 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; //01
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);
}
}

View File

@ -9,10 +9,10 @@ List<String> getDeviceType(DeviceType deviceType) {
List<String> t = ['758824']; List<String> t = ['758824'];
switch (deviceType) { switch (deviceType) {
case DeviceType.blue: case DeviceType.blue:
t = ['758824', '75', '768824', '76','24']; t = ['758824', '75', '768824', '76', '24'];
break; break;
case DeviceType.gateway: case DeviceType.gateway:
t = ['758825','25']; t = ['758825', '25'];
break; break;
} }
return t; return t;
@ -53,6 +53,8 @@ enum CommandType {
gatewayGetWifiList, //wifi列表 0x30F6 gatewayGetWifiList, //wifi列表 0x30F6
gatewayGetWifiListResult, //wifi列表结果 0x30F7 gatewayGetWifiListResult, //wifi列表结果 0x30F7
gatewayGetStatus, // 0x30F8 gatewayGetStatus, // 0x30F8
readRegisterKey, // 0x30A7
sendAuthorizationCode, // 0x30A6
generalExtendedCommond, // = 0x3030 generalExtendedCommond, // = 0x3030
gecChangeAdministratorPassword, // - = 2 gecChangeAdministratorPassword, // - = 2
@ -245,6 +247,16 @@ extension ExtensionCommandType on CommandType {
type = CommandType.gatewayGetStatus; type = CommandType.gatewayGetStatus;
} }
break; break;
case 0x30A6:
{
type = CommandType.sendAuthorizationCode;
}
break;
case 0x30A7:
{
type = CommandType.readRegisterKey;
}
break;
default: default:
{ {
type = CommandType.readStarLockStatusInfo; type = CommandType.readStarLockStatusInfo;
@ -353,6 +365,12 @@ extension ExtensionCommandType on CommandType {
case CommandType.setLockCurrentVoicePacket: case CommandType.setLockCurrentVoicePacket:
type = 0x30A5; type = 0x30A5;
break; break;
case CommandType.sendAuthorizationCode:
type = 0x30A6;
break;
case CommandType.readRegisterKey:
type = 0x30A7;
break;
default: default:
type = 0x300A; type = 0x300A;
break; break;
@ -492,6 +510,12 @@ extension ExtensionCommandType on CommandType {
case 0x30A5: case 0x30A5:
t = '设置锁当前语音包'; t = '设置锁当前语音包';
break; break;
case 0x30A6:
t = '发送授权码';
break;
case 0x30A7:
t = '读取注册密钥';
break;
default: default:
t = '读星锁状态信息'; t = '读星锁状态信息';
break; break;

View File

@ -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_otaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart'; import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_readAdminPassword.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_readSupportFunctionsNoParameters.dart';
import 'package:star_lock/blue/io_protocol/io_readSupportFunctionsWithParameters.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_readVoicePackageFinalResult.dart';
import 'package:star_lock/blue/io_protocol/io_referEventRecordTime.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_setSupportFunctionsNoParameters.dart';
import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsWithParameters.dart'; import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsWithParameters.dart';
import 'package:star_lock/blue/io_protocol/io_setVoicePackageFinalResult.dart'; import 'package:star_lock/blue/io_protocol/io_setVoicePackageFinalResult.dart';
@ -331,6 +333,18 @@ class CommandReciverManager {
SetVoicePackageFinalResultReply.parseData(commandType, data); SetVoicePackageFinalResultReply.parseData(commandType, data);
} }
break; break;
case CommandType.readRegisterKey:
{
reply =
SenderReadRegisterKeyCommandReply.parseData(commandType, data);
}
break;
case CommandType.sendAuthorizationCode:
{
reply =
SenderAuthorizationCodeCommandReply.parseData(commandType, data);
}
break;
case CommandType.generalExtendedCommond: case CommandType.generalExtendedCommond:
{ {
// //

View File

@ -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_otaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart'; import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_readAdminPassword.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_configuringWifi.dart';
import 'io_gateway/io_gateway_getStatus.dart'; import 'io_gateway/io_gateway_getStatus.dart';
@ -1109,10 +1111,7 @@ class IoSenderManage {
//ota //ota
static void senderProcessOtaUpgradeCommand( static void senderProcessOtaUpgradeCommand(
{required int? index, {required int? index, required int? size, required List<int>? data, CommandSendCallBack? callBack}) {
required int? size,
required List<int>? data,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData( CommandSenderManager().managerSendData(
command: ProcessOtaUpgradeCommand( command: ProcessOtaUpgradeCommand(
index: index, index: index,
@ -1321,8 +1320,7 @@ class IoSenderManage {
} }
// wifi列表 // wifi列表
static void gatewayGetWifiCommand( static void gatewayGetWifiCommand({required String? userID, CommandSendCallBack? callBack}) {
{required String? userID, CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData( CommandSenderManager().managerSendData(
command: GatewayGetWifiCommand( command: GatewayGetWifiCommand(
userID: userID, userID: userID,
@ -1339,21 +1337,51 @@ class IoSenderManage {
CommandSendCallBack? callBack}) { CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData( CommandSenderManager().managerSendData(
command: GatewayConfiguringWifiCommand( command: GatewayConfiguringWifiCommand(
ssid: ssid, ssid: ssid, password: password, gatewayConfigurationStr: gatewayConfigurationStr),
password: password,
gatewayConfigurationStr: gatewayConfigurationStr),
isBeforeAddUser: true, isBeforeAddUser: true,
callBack: callBack); callBack: callBack);
} }
// //
static void gatewayGetStatusCommand( static void gatewayGetStatusCommand(
{required String? lockID, {required String? lockID, required String? userID, CommandSendCallBack? callBack}) {
required String? userID,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData( CommandSenderManager().managerSendData(
command: GatewayGetStatusCommand(lockID: lockID, userID: userID), command: GatewayGetStatusCommand(lockID: lockID, userID: userID), isBeforeAddUser: true, callBack: callBack);
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,
);
} }
} }

View File

@ -97,7 +97,7 @@ class F {
case Flavor.sky: case Flavor.sky:
case Flavor.sky_dev: case Flavor.sky_dev:
case Flavor.sky_pre: case Flavor.sky_pre:
return '通通'.tr; return '博士'.tr;
case Flavor.xhj: case Flavor.xhj:
case Flavor.xhj_bundle: case Flavor.xhj_bundle:
case Flavor.xhj_dev: case Flavor.xhj_dev:
@ -119,7 +119,7 @@ class F {
case Flavor.sky: case Flavor.sky:
case Flavor.sky_dev: case Flavor.sky_dev:
case Flavor.sky_pre: case Flavor.sky_pre:
return '通通'.tr; return '博士'.tr;
case Flavor.xhj: case Flavor.xhj:
case Flavor.xhj_bundle: case Flavor.xhj_bundle:
case Flavor.xhj_dev: case Flavor.xhj_dev:

View File

@ -52,6 +52,13 @@ class StarLockLoginLogic extends BaseGetXController {
Future<void> login() async { Future<void> login() async {
FocusScope.of(Get.context!).requestFocus(FocusNode()); // FocusScope.of(Get.context!).requestFocus(FocusNode()); //
//
if (!GetUtils.isEmail(state.emailOrPhone.value)) {
showToast('请输入有效的邮箱地址');
return;
}
final LoginEntity entity = await ApiRepository.to.login( final LoginEntity entity = await ApiRepository.to.login(
loginType: '1', loginType: '1',
password: state.pwd.value, password: state.pwd.value,

View File

@ -88,30 +88,31 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
children: <Widget>[ children: <Widget>[
Container( Container(
padding: EdgeInsets.all(10.w), 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), SizedBox(height: 50.w),
Obx(() => CommonItem( // Obx(() =>
leftTitel: '你所在的国家/地区'.tr, // CommonItem(
rightTitle: '', // leftTitel: '你所在的国家/地区'.tr,
isHaveLine: true, // rightTitle: '',
isPadding: false, // isHaveLine: true,
isHaveRightWidget: true, // isPadding: false,
isHaveDirection: true, // isHaveRightWidget: true,
rightWidget: Text( // isHaveDirection: true,
'${state.countryName} +${state.countryCode.value}', // rightWidget: Text(
textAlign: TextAlign.end, // '${state.countryName} +${state.countryCode.value}',
style: TextStyle(fontSize: 22.sp, color: AppColors.darkGrayTextColor), // textAlign: TextAlign.end,
), // style: TextStyle(fontSize: 22.sp, color: AppColors.darkGrayTextColor),
action: () async { // ),
final result = await Get.toNamed(Routers.selectCountryRegionPage); // action: () async {
if (result != null) { // final result = await Get.toNamed(Routers.selectCountryRegionPage);
result as Map<String, dynamic>; // if (result != null) {
state.countryCode.value = result['code']; // result as Map<String, dynamic>;
state.countryKey.value = result['countryName']; // state.countryCode.value = result['code'];
logic.checkIpAction(); // state.countryKey.value = result['countryName'];
} // logic.checkIpAction();
}, // }
)), // },
// )),
LoginInput( LoginInput(
focusNode: logic.state.emailOrPhoneFocusNode, focusNode: logic.state.emailOrPhoneFocusNode,
controller: state.emailOrPhoneController, controller: state.emailOrPhoneController,
@ -126,12 +127,16 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
height: 36.w, height: 36.w,
), ),
), ),
hintText: '请输入手机号或者邮箱'.tr, // hintText: '请输入手机号或者邮箱'.tr,
hintText: '请输入邮箱'.tr,
// keyboardType: TextInputType.number, // keyboardType: TextInputType.number,
keyboardType: TextInputType.emailAddress,
inputFormatters: <TextInputFormatter>[ inputFormatters: <TextInputFormatter>[
// FilteringTextInputFormatter.allow(RegExp('[0-9]')), // FilteringTextInputFormatter.allow(RegExp('[0-9]')),
LengthLimitingTextInputFormatter(30), LengthLimitingTextInputFormatter(30),
FilteringTextInputFormatter.singleLineFormatter FilteringTextInputFormatter.singleLineFormatter,
//
FilteringTextInputFormatter.allow(RegExp(r'^[a-zA-Z0-9@._-]+$')),
]), ]),
SizedBox(height: 10.h), SizedBox(height: 10.h),
LoginInput( LoginInput(

View File

@ -30,7 +30,8 @@ class StarLockLoginState {
RxString emailOrPhone = ''.obs; RxString emailOrPhone = ''.obs;
RxString pwd = ''.obs; RxString pwd = ''.obs;
RxBool canNext = false.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; bool get pwdIsOK => pwd.value.isNotEmpty;
TextEditingController emailOrPhoneController = TextEditingController(); TextEditingController emailOrPhoneController = TextEditingController();

View File

@ -41,7 +41,7 @@ class _StarLockRegisterPageState extends State<StarLockRegisterPage> {
child: ListView( child: ListView(
padding: EdgeInsets.only(top: 40.h, left: 40.w, right: 40.w), padding: EdgeInsets.only(top: 40.h, left: 40.w, right: 40.w),
children: <Widget>[ children: <Widget>[
topSelectCountryAndRegionWidget(), // topSelectCountryAndRegionWidget(),
middleTFWidget(), middleTFWidget(),
Obx(() { Obx(() {
return SubmitBtn( return SubmitBtn(

View File

@ -6,7 +6,7 @@ class StarLockRegisterState {
StarLockRegisterState() { StarLockRegisterState() {
// tab // tab
final Locale? systemLocale = Get.deviceLocale; final Locale? systemLocale = Get.deviceLocale;
isIphoneType.value = systemLocale?.languageCode == 'zh'; //isIphoneType.value = systemLocale?.languageCode == 'zh';
resetResend(); resetResend();
} }
@ -24,7 +24,7 @@ class StarLockRegisterState {
RxString surePwd = ''.obs; RxString surePwd = ''.obs;
RxString verificationCode = ''.obs; RxString verificationCode = ''.obs;
RxString xWidth = ''.obs; // RxString xWidth = ''.obs; //
RxBool isIphoneType = true.obs; RxBool isIphoneType = false.obs;
RxBool canSub = false.obs; // RxBool canSub = false.obs; //
RxBool agree = false.obs; RxBool agree = false.obs;
RxBool canSendCode = false.obs; // RxBool canSendCode = false.obs; //

View File

@ -69,6 +69,14 @@ FutureOr<void> main() async {
String? token = await CallKitHandler.getVoipToken(); String? token = await CallKitHandler.getVoipToken();
print('获取到的VoIP Token: $token'); print('获取到的VoIP Token: $token');
} }
// runApp
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent, //
statusBarIconBrightness: Brightness.dark, // Android:
statusBarBrightness: Brightness.dark, // iOS:
),
);
runApp(MyApp(isLogin: isLogin)); runApp(MyApp(isLogin: isLogin));
}); });

View File

@ -1,24 +1,109 @@
import 'dart:convert';
class ActivateInfoResponse { class ActivateInfoResponse {
ActivateInfoResponse({ ActivateInfoResponse({
this.description, this.description,
this.errorCode, this.errorCode,
this.data, // List<ActivateInfo> this.data, // List<ActivateInfo>
this.errorMsg, this.errorMsg,
}); });
ActivateInfoResponse.fromJson(dynamic json) { ActivateInfoResponse.fromJson(dynamic json) {
description = json['description']; description = json['description'];
errorCode = json['errorCode']; errorCode = json['errorCode'];
// json['data'] List<ActivateInfo> // ActivateInfo
data = json['data'] != null data = json['data'] != null ? ActivateInfo.fromJson(json['data']) : null;
? (json['data'] as List).map((item) => ActivateInfo.fromJson(item)).toList()
: [];
errorMsg = json['errorMsg']; errorMsg = json['errorMsg'];
} }
String? description; String? description;
int? errorCode; 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; String? errorMsg;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -35,33 +120,28 @@ class ActivateInfoResponse {
@override @override
String toString() { String toString() {
return 'ActivateInfoResponse{description: $description, errorCode: $errorCode, data: $data, errorMsg: $errorMsg}'; return 'TppSupportResponse{description: $description, errorCode: $errorCode, data: $data, errorMsg: $errorMsg}';
} }
} }
class ActivateInfo { class TppSupportInfo {
String? platformName;
int? platform; int? platform;
String? platformName;
ActivateInfo({ TppSupportInfo({
this.platformName,
this.platform, this.platform,
this.platformName,
}); });
ActivateInfo.fromJson(dynamic json) { TppSupportInfo.fromJson(dynamic json) {
platformName = json['platformName'] ?? ''; platform = json['platform'] as int? ?? -1;
platform = json['platform'] ?? ''; platformName = json['platform_name'] as String? ?? '';
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final map = <String, dynamic>{}; final map = <String, dynamic>{};
map['platformName'] = platformName;
map['platform'] = platform; map['platform'] = platform;
map['platform_name'] = platformName;
return map; return map;
} }
@override
String toString() {
return 'ActivateInfo{platformName: $platformName, platform: $platform}';
}
} }

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -35,27 +34,25 @@ class _LockDetailMainPageState extends State<LockDetailMainPage> {
skyCall: () => Scaffold( skyCall: () => Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
appBar: TitleAppBar( appBar: TitleAppBar(
barTitle: F.navTitle, barTitle: F.navTitle,
haveBack: true, haveBack: true,
backgroundColor: AppColors.mainColor), backgroundColor: Colors.white,
body: LockDetailPage( titleColor: Colors.black,
isOnlyOneData: isOnlyOneData, iconColor: Colors.black,
lockListInfoItemEntity: keyInfos), ),
body: LockDetailPage(isOnlyOneData: isOnlyOneData, lockListInfoItemEntity: keyInfos),
// body: Container(), // body: Container(),
), ),
xhjCall: () => Scaffold( xhjCall: () => Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
appBar: TitleAppBar( appBar: TitleAppBar(
barTitle: F.sw( barTitle: F.sw(xhjCall: () => '星星锁'.tr, skyCall: () => keyInfos.lockAlias),
xhjCall: () => '星星锁'.tr, skyCall: () => keyInfos.lockAlias),
haveBack: true, haveBack: true,
backgroundColor: Colors.white, backgroundColor: Colors.white,
titleColor: AppColors.blackColor, titleColor: AppColors.blackColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
), ),
body: LockDetailPage( body: LockDetailPage(isOnlyOneData: isOnlyOneData, lockListInfoItemEntity: keyInfos),
isOnlyOneData: isOnlyOneData,
lockListInfoItemEntity: keyInfos),
// body: Container(), // body: Container(),
)); ));
} }

View File

@ -464,6 +464,44 @@ class _LockDetailPageState extends State<LockDetailPage> with TickerProviderStat
Widget skWidget() { Widget skWidget() {
return ListView( return ListView(
children: <Widget>[ 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( Visibility(
visible: (state.keyInfos.value.keyType == XSConstantMacro.keyTypeTime || visible: (state.keyInfos.value.keyType == XSConstantMacro.keyTypeTime ||
state.keyInfos.value.keyType == XSConstantMacro.keyTypeLoop) && // state.keyInfos.value.keyType == XSConstantMacro.keyTypeLoop) && //

View File

@ -1,40 +1,298 @@
import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/app_settings/app_settings.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/main/lockDetail/lockSet/thirdPartyPlatform/third_party_platform_state.dart';
import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/network/start_company_api.dart'; import 'package:star_lock/network/start_company_api.dart';
import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/storage.dart';
class ThirdPartyPlatformLogic extends BaseGetXController { class ThirdPartyPlatformLogic extends BaseGetXController {
ThirdPartyPlatformState state = ThirdPartyPlatformState(); ThirdPartyPlatformState state = ThirdPartyPlatformState();
void savePlatFormSetting() { //
// showEasyLoading(); StreamSubscription<Reply>? _replySubscription;
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}');
}
}
}
@override @override
void onReady() async { void onReady() async {
// TODO: implement onReady
super.onReady(); super.onReady();
getActivateInfo(); await getActivateInfo();
_initReplySubscription();
getServerDatetime();
} }
@override @override
void dispose() { void dispose() {
dismissEasyLoading(); dismissEasyLoading();
//
_replySubscription?.cancel();
_replySubscription = null;
//
AppLog.log('ThirdPartyPlatformLogic disposed, subscription cancelled');
super.dispose(); 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 (740)
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;
}
}
} }

View File

@ -45,107 +45,123 @@ class _ThirdPartyPlatformPageState extends State<ThirdPartyPlatformPage> {
} }
Widget _buildBody() { Widget _buildBody() {
return Stack( return SingleChildScrollView(
children: [ child: Container(
// 1. decoration: BoxDecoration(
Container(
color: Colors.white, color: Colors.white,
padding: EdgeInsets.all(16.w),
), ),
// 2. 使 Row constraints: BoxConstraints(
Positioned( minHeight: MediaQuery.of(context).size.height - 100.h,
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,
),
],
),
), ),
Positioned( child: Stack(
top: 220.h, children: [
left: 20.w, // 1.
right: 20.w, Container(
child: Text( color: Colors.white,
'第三方协议的支持依赖网络授权下载,打开功能开关时请保证手机数据网络的正常连接'.tr, padding: EdgeInsets.all(16.w),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.sp,
color: Colors.grey,
fontWeight: FontWeight.w500,
), ),
), Positioned(
), top: 30.h,
left: 50.w,
Positioned( child: Image.asset(
left: 0, 'images/other/tuya.png',
right: 0, height: 80.h,
top: 320.h, fit: BoxFit.cover,
bottom: 0, ),
child: ListView.builder( ),
itemCount: state.platFormSet.length, Positioned(
itemBuilder: (BuildContext context, int index) { top: 130.h,
// itemCount - 1 left: 150.w,
final isLastItem = index == state.platFormSet.length - 1; right: 150.w,
child: Image.asset(
// platFormSet RxList<Platform> 'images/other/2.png',
final platform = state.platFormSet.value[index]; height: 220.h,
return CommonItem( fit: BoxFit.contain,
leftTitel: state.platFormSet.value[index], ),
rightTitle: '', ),
isHaveLine: !isLastItem, // 2. 使 Row
// 线 Positioned(
isHaveDirection: false, top: 400.h,
isHaveRightWidget: true, right: 50.w,
rightWidget: Radio<String>( child: Column(
// Radio 使 id children: [
value: platform, Image.asset(
// selectPlatFormIndex id 'images/other/matter.png',
groupValue: state.platFormSet.value[state.selectPlatFormIndex.value], width: 280.w,
// fit: BoxFit.contain,
activeColor: AppColors.mainColor, ),
// Radio ],
onChanged: (value) { ),
if (value != null) { ),
setState(() { Positioned(
// id top: 530.h,
final newIndex = state.platFormSet.value.indexWhere((p) => p == value); left: 20.w,
if (newIndex != -1) { right: 20.w,
state.selectPlatFormIndex.value = newIndex; 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(), ),
), ],
), ),
], ),
); );
} }
} }

View File

@ -1,6 +1,8 @@
import 'dart:ui'; import 'dart:ui';
import 'package:get/get.dart'; 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/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import 'package:star_lock/translations/app_dept.dart'; import 'package:star_lock/translations/app_dept.dart';
@ -11,15 +13,20 @@ class ThirdPartyPlatformState {
} }
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs; Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
int differentialTime = 0;// UTC+0
// UI // UI
final RxList<String> platFormSet = List.of({ final RxList<String> platFormSet = List.of({
'锁通通'.tr, '锁通通'.tr,
'涂鸦智能'.tr, '涂鸦智能'.tr,
'Matter'.tr , 'Matter'.tr,
}).obs; }).obs;
RxInt selectPlatFormIndex = 0.obs; // UI
final RxList<TppSupportInfo> tppSupportList = RxList<TppSupportInfo>([]);
RxInt selectPlatFormIndex = 1.obs;
RxString registerKey = ''.obs;
Map lockInfo = {};
} }

View File

@ -300,7 +300,7 @@ class PasswordKeyDetailLogic extends BaseGetXController {
'\n' + '\n' +
'有效期'.tr + '有效期'.tr +
':${startDateStr.toLocal().toString().substring(0, 16)} -- ${endDateStr.toLocal().toString().substring(0, 16)}\n\n' + ':${startDateStr.toLocal().toString().substring(0, 16)} -- ${endDateStr.toLocal().toString().substring(0, 16)}\n\n' +
'这是单次密码,只能使用一次\n'; '${'这是单次密码,只能使用一次'.tr}\n';
break; break;
case 2: case 2:
// 2 24使 // 2 24使
@ -309,8 +309,8 @@ class PasswordKeyDetailLogic extends BaseGetXController {
':' + ':' +
'永久'.tr + '永久'.tr +
'\n' + '\n' +
'\n注:\n' + '\n${'注:'.tr}\n' +
'必需在开始时间24小时内使用一次否则将失效\n'; '${'必需在开始时间24小时内使用一次否则将失效'.tr}\n';
break; break;
case 3: case 3:
// 3 24使 // 3 24使
@ -324,7 +324,7 @@ class PasswordKeyDetailLogic extends BaseGetXController {
':${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}' + ':${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}' +
'\n' + '\n' +
'\n注:\n' + '\n注:\n' +
'必需在开始时间24小时内使用一次否则将失效\n'; '${'必需在开始时间24小时内使用一次否则将失效'.tr}\n';
break; break;
case 4: case 4:
// 4 使使 // 4 使使
@ -453,9 +453,10 @@ class PasswordKeyDetailLogic extends BaseGetXController {
default: default:
} }
// return '您好,您的密码是'.tr + ':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}'; // return '您好,您的密码是'.tr + ':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}';
return '您好' + return '您好'.tr +
',\n您的开门密码是' + ',\n${'您的开门密码是'.tr}' +
':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}\n\n开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标'; ':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}\n'
'\n${'开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标'.tr}';
} }
@override @override

View File

@ -46,32 +46,24 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
} else if (state.widgetType.value == 1) { } else if (state.widgetType.value == 1) {
// //
// 鸿 // 鸿
if (CommonDataManage().currentKeyInfo.vendor == if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XHJ &&
IoModelVendor.vendor_XHJ && (CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XHJ_SYD ||
(CommonDataManage().currentKeyInfo.model == CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XHJ_JL)) {
IoModelVendor.model_XHJ_SYD || if (endDate <= DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
CommonDataManage().currentKeyInfo.model ==
IoModelVendor.model_XHJ_JL)) {
if (endDate <=
DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
showToast('失效时间要大于当前时间'.tr); showToast('失效时间要大于当前时间'.tr);
return; return;
} }
//endDate 0 //endDate 0
final DateTime now = DateTime.now(); final DateTime now = DateTime.now();
startDate = startDate = DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
} }
// //
if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XL && if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XL &&
(CommonDataManage().currentKeyInfo.model == (CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_BLE ||
IoModelVendor.model_XL_BLE || CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_WIFI)) {
CommonDataManage().currentKeyInfo.model ==
IoModelVendor.model_XL_WIFI)) {
// //
if (startDate < if (startDate < DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
showToast('生效时间不能小于当前时间'.tr); showToast('生效时间不能小于当前时间'.tr);
return; return;
} }
@ -91,12 +83,9 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
// //
// //
if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XL && if (CommonDataManage().currentKeyInfo.vendor == IoModelVendor.vendor_XL &&
(CommonDataManage().currentKeyInfo.model == (CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_BLE ||
IoModelVendor.model_XL_BLE || CommonDataManage().currentKeyInfo.model == IoModelVendor.model_XL_WIFI)) {
CommonDataManage().currentKeyInfo.model == if (endDate < DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
IoModelVendor.model_XL_WIFI)) {
if (endDate <
DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) {
showToast('结束时间不能小于当前时间'.tr); showToast('结束时间不能小于当前时间'.tr);
return; return;
} }
@ -166,10 +155,8 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
// //
if (state.isPermanent.value == false) { if (state.isPermanent.value == false) {
getKeyType = '3'; getKeyType = '3';
getEffectiveDateTime = getEffectiveDateTime = DateTool().dateToTimestamp(state.customBeginTime.value, 1).toString();
DateTool().dateToTimestamp(state.customBeginTime.value, 1).toString(); getFailureDateTime = DateTool().dateToTimestamp(state.customEndTime.value, 1).toString();
getFailureDateTime =
DateTool().dateToTimestamp(state.customEndTime.value, 1).toString();
} }
final PasswordKeyEntity entity = await ApiRepository.to.addPasswordKey( final PasswordKeyEntity entity = await ApiRepository.to.addPasswordKey(
lockId: lockId, lockId: lockId,
@ -184,8 +171,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
ApmHelper.instance.trackEvent('add_password', { ApmHelper.instance.trackEvent('add_password', {
'lock_name': BlueManage().connectDeviceName, 'lock_name': BlueManage().connectDeviceName,
'account': 'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1), 'date': DateTool().getNowDateWithType(1),
'add_password_result': '成功', 'add_password_result': '成功',
}); });
@ -202,8 +188,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
} else { } else {
ApmHelper.instance.trackEvent('add_password', { ApmHelper.instance.trackEvent('add_password', {
'lock_name': BlueManage().connectDeviceName, 'lock_name': BlueManage().connectDeviceName,
'account': 'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1), 'date': DateTool().getNowDateWithType(1),
'add_password_result': '${entity.errorMsg}', 'add_password_result': '${entity.errorMsg}',
}); });
@ -230,8 +215,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
showToast('请输入密码'.tr); showToast('请输入密码'.tr);
return; return;
} }
final PasswordKeyEntity entity = final PasswordKeyEntity entity = await ApiRepository.to.checkKeyboardpwdName(
await ApiRepository.to.checkKeyboardpwdName(
lockId: state.keyInfo.value.lockId.toString(), lockId: state.keyInfo.value.lockId.toString(),
keyboardPwdName: state.nameController.text, keyboardPwdName: state.nameController.text,
keyboardPwd: state.pwdController.text, keyboardPwd: state.pwdController.text,
@ -246,16 +230,11 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
late StreamSubscription<Reply> _replySubscription; late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() { void _initReplySubscription() {
_replySubscription = _replySubscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
// //
if ((reply is SenderCustomPasswordsReply) && if ((reply is SenderCustomPasswordsReply) && (state.ifCurrentScreen.value == true)) {
(state.ifCurrentScreen.value == true)) {
BuglyTool.uploadException( BuglyTool.uploadException(
message: '添加密码结果,解析数据', message: '添加密码结果,解析数据', detail: '添加密码结果,解析数据:${reply.data}', eventStr: '添加密码事件结果', upload: true);
detail: '添加密码结果,解析数据:${reply.data}',
eventStr: '添加密码事件结果',
upload: true);
final int status = reply.data[2]; final int status = reply.data[2];
switch (status) { switch (status) {
@ -305,20 +284,14 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
final List<String> saveStrList = changeIntListToStringList(token); final List<String> saveStrList = changeIntListToStringList(token);
Storage.setStringList(saveBlueToken, saveStrList); Storage.setStringList(saveBlueToken, saveStrList);
final List<String>? privateKey = final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
await Storage.getStringList(saveBluePrivateKey); final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
final List<String>? signKey = final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
await Storage.getStringList(saveBlueSignKey); final List<int> signKeyDataList = changeStringListToIntList(signKey!);
final List<int> signKeyDataList =
changeStringListToIntList(signKey!);
int startDate = int startDate = DateTool().dateToTimestamp(state.customBeginTime.value, 1);
DateTool().dateToTimestamp(state.customBeginTime.value, 1); int endDate = DateTool().dateToTimestamp(state.customEndTime.value, 1);
int endDate =
DateTool().dateToTimestamp(state.customEndTime.value, 1);
// //
if (state.isPermanent.value == true) { if (state.isPermanent.value == true) {
startDate = 0; startDate = 0;
@ -367,8 +340,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
int endDate = DateTool().dateToTimestamp(state.customEndTime.value, 1); int endDate = DateTool().dateToTimestamp(state.customEndTime.value, 1);
// //
if (state.isPermanent.value == false) { if (state.isPermanent.value == false) {
if (startDate < if (startDate < DateTool().dateToTimestamp(DateTool().getNowDateWithType(2), 1)) {
DateTool().dateToTimestamp(DateTool().getNowDateWithType(2), 1)) {
showToast('生效时间需晚于当前时间'.tr); showToast('生效时间需晚于当前时间'.tr);
return; return;
} }
@ -382,8 +354,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
endDate = 0; endDate = 0;
} }
if (state.pwdController.text.length < 6 || if (state.pwdController.text.length < 6 || state.pwdController.text.length > 9) {
state.pwdController.text.length > 9) {
showToast('请输入6-9位数字'.tr); showToast('请输入6-9位数字'.tr);
return; return;
} }
@ -396,8 +367,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey); final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
final List<int> signKeyDataList = changeStringListToIntList(signKey!); final List<int> signKeyDataList = changeStringListToIntList(signKey!);
final List<String>? privateKey = final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!); final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final List<String>? token = await Storage.getStringList(saveBlueToken); final List<String>? token = await Storage.getStringList(saveBlueToken);
@ -424,8 +394,7 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
final String getMobile = (await Storage.getMobile())!; final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('add_password', { ApmHelper.instance.trackEvent('add_password', {
'lock_name': BlueManage().connectDeviceName, 'lock_name': BlueManage().connectDeviceName,
'account': 'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1), 'date': DateTool().getNowDateWithType(1),
'add_password_result': '添加自定义密码超时', 'add_password_result': '添加自定义密码超时',
}); });
@ -439,17 +408,13 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
dismissEasyLoading(); dismissEasyLoading();
state.sureBtnState.value = 0; state.sureBtnState.value = 0;
}); });
BlueManage().blueSendData(BlueManage().connectDeviceName, BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async {
(BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) { if (deviceConnectionState == BluetoothConnectionState.connected) {
final List<String>? signKey = final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
await Storage.getStringList(saveBlueSignKey);
final List<int> signKeyDataList = changeStringListToIntList(signKey!); final List<int> signKeyDataList = changeStringListToIntList(signKey!);
final List<String>? privateKey = final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
await Storage.getStringList(saveBluePrivateKey); final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
final List<String>? token = await Storage.getStringList(saveBlueToken); final List<String>? token = await Storage.getStringList(saveBlueToken);
final List<int> getTokenList = changeStringListToIntList(token!); final List<int> getTokenList = changeStringListToIntList(token!);
@ -469,13 +434,11 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
signKey: signKeyDataList, signKey: signKeyDataList,
privateKey: getPrivateKeyList, privateKey: getPrivateKeyList,
token: getTokenList); token: getTokenList);
} else if (deviceConnectionState == } else if (deviceConnectionState == BluetoothConnectionState.disconnected) {
BluetoothConnectionState.disconnected) {
final String getMobile = (await Storage.getMobile())!; final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('add_password', { ApmHelper.instance.trackEvent('add_password', {
'lock_name': BlueManage().connectDeviceName, 'lock_name': BlueManage().connectDeviceName,
'account': 'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1), 'date': DateTool().getNowDateWithType(1),
'add_password_result': '添加自定义密码断开', 'add_password_result': '添加自定义密码断开',
}); });
@ -517,17 +480,11 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
'\n' + '\n' +
'有效期'.tr + '有效期'.tr +
':${startDateStr.toLocal().toString().substring(0, 16)} -- ${endDateStr.toLocal().toString().substring(0, 16)}\n\n' + ':${startDateStr.toLocal().toString().substring(0, 16)} -- ${endDateStr.toLocal().toString().substring(0, 16)}\n\n' +
'这是单次密码,只能使用一次\n'; '${'这是单次密码,只能使用一次'.tr}\n';
break; break;
case 0: case 0:
// 2 24使 // 2 24使
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '永久'.tr + '\n' + '\n注:\n' + '${'必需在开始时间24小时内使用一次否则将失效'.tr}\n';
'类型'.tr +
':' +
'永久'.tr +
'\n' +
'\n注:\n' +
'必需在开始时间24小时内使用一次否则将失效\n';
break; break;
case 1: case 1:
// 3 24使 // 3 24使
@ -540,15 +497,14 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
'有效期'.tr + '有效期'.tr +
':${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}' + ':${startDateStr.toLocal().toString().substring(0, 16)}-${endDateStr.toLocal().toString().substring(0, 16)}' +
'\n' + '\n' +
'\n注:\n' + '\n${'注:'.tr}\n' +
'必需在开始时间24小时内使用一次否则将失效\n'; '${'必需在开始时间24小时内使用一次否则将失效'.tr}\n';
break; break;
case 3: case 3:
// //
if (state.isPermanent.value == false) { if (state.isPermanent.value == false) {
useDateStr = '类型'.tr + useDateStr =
':' + '类型'.tr + ':' + '自定义-限时\n${'有效期'.tr}:${state.customBeginTime.value} -- ${state.customEndTime.value}';
'自定义-限时\n${'有效期'.tr}:${state.customBeginTime.value} -- ${state.customEndTime.value}';
} else { } else {
useDateStr = '类型:自定义-永久'.tr; useDateStr = '类型:自定义-永久'.tr;
} }
@ -559,171 +515,51 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
break; break;
case 4: case 4:
// 5 // 5
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周末'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周末'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 6: case 6:
// 6 // 6
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '每日'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'每日'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 7: case 7:
// 7 // 7
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '工作日'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'工作日'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 8: case 8:
// 8 // 8
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周一'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周一'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 9: case 9:
// 9 // 9
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周二'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周二'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 10: case 10:
// 10 // 10
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周三'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周三'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 11: case 11:
// 11 // 11
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周四'.tr + ' $starHour:00 -$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周四'.tr +
' $starHour:00 -$endHour:00' +
'\n';
break; break;
case 12: case 12:
// 12 // 12
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周五'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周五'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 13: case 13:
// 13 // 13
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周六'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周六'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
case 14: case 14:
// 14 // 14
useDateStr = '\n' + useDateStr = '\n' + '类型'.tr + ':' + '循环'.tr + '\n' + '\n' + '周日'.tr + ' $starHour:00-$endHour:00' + '\n';
'类型'.tr +
':' +
'循环'.tr +
'\n' +
'\n' +
'周日'.tr +
' $starHour:00-$endHour:00' +
'\n';
break; break;
default: default:
} }
// return '您好,您的密码是'.tr + ':${state.itemData.value.keyboardPwd}\n$useDateStr\n${'密码名字'.tr}:${state.itemData.value.keyboardPwdName}';
return '您好' + return '您好'.tr +
',\n您的开门密码是' + ',\n${'您的开门密码是'.tr}' +
':${state.getPwdStr.value}\n$useDateStr\n${'密码名字'.tr}:${state.pwdNameStr}\n\n开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标'; ':${state.getPwdStr.value}\n$useDateStr\n${'密码名字'.tr}:${state.pwdNameStr}\n'
// switch (getPwdType) { '\n${'开锁时,先激活锁键盘,再输入密码,以#号结束,#号键在键盘右下角,有可能是其他图标'.tr}';
// 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}';
} }
String addSpaces(String input) { String addSpaces(String input) {

View File

@ -36,13 +36,13 @@ class _LockListGroupViewState extends State<LockListGroupView> {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Container( // Container(
color: widget.backgroundColor ?? Colors.white, // color: widget.backgroundColor ?? Colors.white,
height: 80.h, // height: 80.h,
child: Row( // child: Row(
children: _buildExpandRowList(), // children: _buildExpandRowList(),
), // ),
), // ),
ClipRect( ClipRect(
child: AnimatedAlign( child: AnimatedAlign(
heightFactor: _isExpanded ? 1.0 : 0.0, heightFactor: _isExpanded ? 1.0 : 0.0,

View File

@ -1,7 +1,9 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/flavors.dart';
import 'package:star_lock/main/lockMian/lockList/lockList_state.dart'; import 'package:star_lock/main/lockMian/lockList/lockList_state.dart';
import '../../../appRouters.dart'; import '../../../appRouters.dart';
@ -14,8 +16,7 @@ import 'lockListGroup_view.dart';
import 'lockList_logic.dart'; import 'lockList_logic.dart';
class LockListPage extends StatefulWidget { class LockListPage extends StatefulWidget {
const LockListPage({required this.lockListInfoGroupEntity, Key? key}) const LockListPage({required this.lockListInfoGroupEntity, Key? key}) : super(key: key);
: super(key: key);
final LockListInfoGroupEntity lockListInfoGroupEntity; final LockListInfoGroupEntity lockListInfoGroupEntity;
@override @override
@ -30,41 +31,84 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
void initState() { void initState() {
super.initState(); super.initState();
logic = Get.put(LockListLogic(widget.lockListInfoGroupEntity)); logic = Get.put(LockListLogic(widget.lockListInfoGroupEntity));
state = Get state = Get.find<LockListLogic>().state;
.find<LockListLogic>()
.state;
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Obx(() => Scaffold( return Obx(
body: ListView.separated( () => Scaffold(
itemCount: logic.groupDataListFiltered.length, body: SafeArea(
itemBuilder: (BuildContext context, int index) { child: Column(
final GroupList itemData = logic.groupDataListFiltered[index]; children: [
return _buildLockExpandedList(context, index, itemData, key: ValueKey(itemData.groupId)); Row(
}, children: [
shrinkWrap: true, SizedBox(
physics: const AlwaysScrollableScrollPhysics(), width: 20.w,
separatorBuilder: (BuildContext context, int index) { ),
return const Divider( Image.asset('images/icon_main_drlock_1024.png', width: 68.w, height: 68.w),
height: 1, SizedBox(
color: AppColors.greyLineColor, 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, Widget _buildLockExpandedList(BuildContext context, int index, GroupList itemData, {Key? key}) {
GroupList itemData, {Key? key}) { final List<LockListInfoItemEntity> lockItemList = itemData.lockList ?? <LockListInfoItemEntity>[];
final List<LockListInfoItemEntity> lockItemList =
itemData.lockList ?? <LockListInfoItemEntity>[];
return LockListGroupView( return LockListGroupView(
key: key, key: key,
onTap: () { onTap: () {
// //
if (itemData.isChecked) {} else {} if (itemData.isChecked) {
} else {}
setState(() {}); setState(() {});
}, },
typeImgList: const <dynamic>[], typeImgList: const <dynamic>[],
@ -103,39 +147,36 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
), ),
child: lockInfoListItem(keyInfo, isLast, () { child: lockInfoListItem(keyInfo, isLast, () {
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime || if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) && keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
(keyInfo.keyStatus == (keyInfo.keyStatus == XSConstantMacro.keyStatusWaitIneffective)) {
XSConstantMacro.keyStatusWaitIneffective)) {
logic.showToast('您的钥匙未生效'.tr); logic.showToast('您的钥匙未生效'.tr);
return; return;
} }
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime || if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
keyInfo.keyType == XSConstantMacro.keyTypeLong || keyInfo.keyType == XSConstantMacro.keyTypeLong ||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) && keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
(keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen)) { (keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen)) {
logic.showToast('您的钥匙已冻结'.tr); logic.showToast('您的钥匙已冻结'.tr);
return; return;
} }
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime || if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) && keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
(keyInfo.keyStatus == XSConstantMacro.keyStatusExpired)) { (keyInfo.keyStatus == XSConstantMacro.keyStatusExpired)) {
logic.showToast('您的钥匙已过期'.tr); logic.showToast('您的钥匙已过期'.tr);
return; return;
} }
Get.toNamed(Routers.lockDetailMainPage, Get.toNamed(Routers.lockDetailMainPage, arguments: <String, Object>{
arguments: <String, Object>{ // "lockMainEntity": widget.lockMainEntity,
// "lockMainEntity": widget.lockMainEntity, 'keyInfo': keyInfo,
'keyInfo': keyInfo, 'isOnlyOneData': false,
'isOnlyOneData': false, });
});
}), }),
); );
}), }),
); );
} }
Widget lockInfoListItem(LockListInfoItemEntity keyInfo, bool isLast, Widget lockInfoListItem(LockListInfoItemEntity keyInfo, bool isLast, Function() action) {
Function() action) {
return GestureDetector( return GestureDetector(
onTap: action, onTap: action,
child: Container( 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, bottom: 20.w)
: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w), : EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w),
decoration: BoxDecoration( decoration: BoxDecoration(
color: (((keyInfo.keyType == XSConstantMacro.keyTypeTime || color: (((keyInfo.keyType == XSConstantMacro.keyTypeTime || keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
keyInfo.keyType == XSConstantMacro.keyTypeLoop) && (keyInfo.keyStatus == XSConstantMacro.keyStatusWaitIneffective ||
(keyInfo.keyStatus == keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen ||
XSConstantMacro.keyStatusWaitIneffective || keyInfo.keyStatus == XSConstantMacro.keyStatusExpired)) ||
keyInfo.keyStatus == (keyInfo.keyType == XSConstantMacro.keyTypeLong &&
XSConstantMacro.keyStatusFrozen || keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen))
keyInfo.keyStatus ==
XSConstantMacro.keyStatusExpired)) ||
(keyInfo.keyType == XSConstantMacro.keyTypeLong &&
keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen))
? AppColors.greyBackgroundColor ? AppColors.greyBackgroundColor
: Colors.white, : Colors.white,
borderRadius: BorderRadius.circular(20.w), borderRadius: BorderRadius.circular(20.w),
@ -193,8 +230,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
SizedBox(width: 2.w), SizedBox(width: 2.w),
Text( Text(
'${keyInfo.electricQuantity!}%', '${keyInfo.electricQuantity!}%',
style: TextStyle( style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
), ),
SizedBox(width: 30.w), SizedBox(width: 30.w),
], ],
@ -211,10 +247,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
borderRadius: BorderRadius.circular(5.w), borderRadius: BorderRadius.circular(5.w),
color: AppColors.openPassageModeColor, color: AppColors.openPassageModeColor,
), ),
child: Text('常开模式开启'.tr, child: Text('常开模式开启'.tr, style: TextStyle(fontSize: 18.sp, color: AppColors.appBarIconColor)),
style: TextStyle(
fontSize: 18.sp,
color: AppColors.appBarIconColor)),
), ),
], ],
)), )),
@ -226,8 +259,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
SizedBox(width: 30.w), SizedBox(width: 30.w),
Text( Text(
'远程开锁'.tr, '远程开锁'.tr,
style: TextStyle( style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
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), padding: EdgeInsets.only(right: 5.w, left: 5.w),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.w), borderRadius: BorderRadius.circular(5.w),
color: color: DateTool().compareTimeIsOvertime(keyInfo.endDate!)
DateTool().compareTimeIsOvertime(keyInfo.endDate!)
? AppColors.listTimeYellowColor ? AppColors.listTimeYellowColor
: AppColors.mainColor, : AppColors.mainColor,
), ),
child: Text(logic.getKeyEffective(keyInfo), child: Text(logic.getKeyEffective(keyInfo), style: TextStyle(fontSize: 18.sp, color: Colors.white)
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.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>[ children: <Widget>[
SizedBox(width: 30.w), SizedBox(width: 30.w),
Text( Text(
"${logic.getUseKeyTypeStr(keyInfo.startDate, keyInfo.endDate, "${logic.getUseKeyTypeStr(keyInfo.startDate, keyInfo.endDate, keyInfo.keyType)}/${keyInfo.isLockOwner == 1 ? '超级管理员'.tr : (keyInfo.keyRight == 1 ? "授权管理员".tr : "普通用户".tr)}",
keyInfo.keyType)}/${keyInfo.isLockOwner == 1 style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
? '超级管理员'.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 @override
void dispose() { void dispose() {
Get.delete<LockListLogic>(); Get.delete<LockListLogic>();
/// ///
AppRouteObserver().routeObserver.unsubscribe(this); AppRouteObserver().routeObserver.unsubscribe(this);
super super.dispose();
.
dispose
(
);
} }
/// ///

View File

@ -23,8 +23,11 @@ import 'package:star_lock/tools/submitBtn.dart';
import '../../../appRouters.dart'; import '../../../appRouters.dart';
import '../../../baseWidget.dart'; import '../../../baseWidget.dart';
import '../../../flavors.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 '../../../mine/mine/starLockMine_page.dart';
import '../../../tools/EasyRefreshTool.dart'; import '../../../tools/EasyRefreshTool.dart';
import '../../../tools/commonDataManage.dart';
import '../../../tools/eventBusEventManage.dart'; import '../../../tools/eventBusEventManage.dart';
import '../../../tools/storage.dart'; import '../../../tools/storage.dart';
import '../../../tools/titleAppBar.dart'; import '../../../tools/titleAppBar.dart';
@ -34,8 +37,7 @@ import '../lockList/lockList_page.dart';
import 'lockMain_logic.dart'; import 'lockMain_logic.dart';
class StarLockMainPage extends StatefulWidget { class StarLockMainPage extends StatefulWidget {
StarLockMainPage({Key? key, this.showAppBar = true, this.showDrawer = true}) StarLockMainPage({Key? key, this.showAppBar = true, this.showDrawer = true}) : super(key: key);
: super(key: key);
bool showAppBar; bool showAppBar;
bool showDrawer; bool showDrawer;
@ -48,16 +50,15 @@ class _StarLockMainPageState extends State<StarLockMainPage>
final LockMainLogic logic = Get.put(LockMainLogic()); final LockMainLogic logic = Get.put(LockMainLogic());
final LockMainState state = Get.find<LockMainLogic>().state; final LockMainState state = Get.find<LockMainLogic>().state;
Future<void> getHttpData( final SelectLockTypeLogic logicType = Get.put(SelectLockTypeLogic());
{bool clearScanDevices = false, bool isUnShowLoading = false}) async {
LockListInfoGroupEntity? lockListInfoGroupEntity = Future<void> getHttpData({bool clearScanDevices = false, bool isUnShowLoading = false}) async {
await Storage.getLockMainListData(); LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData();
if (lockListInfoGroupEntity != null) { if (lockListInfoGroupEntity != null) {
await logic.loadMainDataLogic(lockListInfoGroupEntity); await logic.loadMainDataLogic(lockListInfoGroupEntity);
setState(() {}); setState(() {});
} }
lockListInfoGroupEntity = lockListInfoGroupEntity = (await logic.getStarLockInfo(isUnShowLoading: isUnShowLoading)).data;
(await logic.getStarLockInfo(isUnShowLoading: isUnShowLoading)).data;
if (lockListInfoGroupEntity != null) { if (lockListInfoGroupEntity != null) {
await logic.loadMainDataLogic(lockListInfoGroupEntity); await logic.loadMainDataLogic(lockListInfoGroupEntity);
setState(() {}); setState(() {});
@ -89,7 +90,8 @@ class _StarLockMainPageState extends State<StarLockMainPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GetBuilder<LockMainLogic>(builder: (LockMainLogic logic) { return GetBuilder<LockMainLogic>(builder: (LockMainLogic logic) {
Widget child = EasyRefreshTool( Widget child = Obx(
() => EasyRefreshTool(
onRefresh: () { onRefresh: () {
SchedulerBinding.instance.addPostFrameCallback((_) { 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)); child: getDataReturnUI(state.dataLength.value),
),
);
if (widget.showAppBar || widget.showDrawer) { if (widget.showAppBar || widget.showDrawer) {
child = Scaffold( child = Scaffold(
backgroundColor: const Color(0xFFF5F5F5), backgroundColor: Colors.white,
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,
body: child, 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( child = F.sw(
@ -149,41 +158,52 @@ class _StarLockMainPageState extends State<StarLockMainPage>
Widget getDataReturnUI(int type) { Widget getDataReturnUI(int type) {
Widget returnWidget; Widget returnWidget;
if (type == 1) { if (state.selectedIndex.value == 0) {
type = F.sw(skyCall: () => 1, xhjCall: () => 2); if (type == 1) {
} type = F.sw(skyCall: () => 1, xhjCall: () => 2);
switch (type) { }
case 0: switch (type) {
// case 0:
returnWidget = unHaveData(); //
break; returnWidget = MainBg(child: unHaveData());
case 1: break;
// case 1:
Storage.setBool(ifIsDemoModeOrNot, false); //
returnWidget = LockDetailPage( Storage.setBool(ifIsDemoModeOrNot, false);
isOnlyOneData: true, returnWidget = MainBg(child: LockDetailPage(
lockListInfoItemEntity: isOnlyOneData: true,
state.lockListInfoGroupEntity.value.groupList![0].lockList![0]); lockListInfoItemEntity: state.lockListInfoGroupEntity.value.groupList![0].lockList![0]));
break; break;
case 2: case 2:
// //
Storage.setBool(ifIsDemoModeOrNot, false); Storage.setBool(ifIsDemoModeOrNot, false);
returnWidget = F.sw( returnWidget = F.sw(
skyCall: () => LockListPage( skyCall: () => MainBg(child: LockListPage(lockListInfoGroupEntity: state.lockListInfoGroupEntity.value)),
lockListInfoGroupEntity: state.lockListInfoGroupEntity.value), xhjCall: () => MainBg(child: LockListXHJPage(lockListInfoGroupEntity: state.lockListInfoGroupEntity.value)));
xhjCall: () => LockListXHJPage( break;
lockListInfoGroupEntity: state.lockListInfoGroupEntity.value)); default:
break; returnWidget = MainBg(child: NoData());
default: break;
returnWidget = NoData(); }
break; } else if (state.selectedIndex.value == 1) {
returnWidget = MainBg(child: MessageListPage());
} else {
returnWidget = MainBg(child: StarLockMinePage());
} }
return returnWidget; return returnWidget;
} }
// //
Widget XHJBg({required Widget child}) { Widget MainBg({required Widget child}) {
return Container(); return Container(
child: child,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('images/lockMain_bg.jpg'),
fit: BoxFit.cover,
),
),
);
} }
Widget unHaveData() { Widget unHaveData() {
@ -192,6 +212,48 @@ class _StarLockMainPageState extends State<StarLockMainPage>
Column( Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ 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( SizedBox(
height: 160.h, height: 160.h,
), ),
@ -211,10 +273,14 @@ class _StarLockMainPageState extends State<StarLockMainPage>
), ),
onTap: () { onTap: () {
// //
Navigator.pushNamed( // Navigator.pushNamed(
context, // context,
Routers.selectLockTypePage, // Routers.selectLockTypePage,
); // );
//
CommonDataManage().seletLockType = 0;
logicType.getNearByLimits();
}, },
)), )),
], ],
@ -288,13 +354,9 @@ class _StarLockMainPageState extends State<StarLockMainPage>
late StreamSubscription _teamEvent; late StreamSubscription _teamEvent;
void _initLoadDataAction() { void _initLoadDataAction() {
_teamEvent = eventBus _teamEvent = eventBus.on<RefreshLockListInfoDataEvent>().listen((RefreshLockListInfoDataEvent event) {
.on<RefreshLockListInfoDataEvent>()
.listen((RefreshLockListInfoDataEvent event) {
logic.pageNo = 1; logic.pageNo = 1;
getHttpData( getHttpData(clearScanDevices: event.clearScanDevices, isUnShowLoading: event.isUnShowLoading);
clearScanDevices: event.clearScanDevices,
isUnShowLoading: event.isUnShowLoading);
}); });
} }
@ -304,8 +366,7 @@ class _StarLockMainPageState extends State<StarLockMainPage>
ByteData byteData = await rootBundle.load(assetPath); ByteData byteData = await rootBundle.load(assetPath);
// ByteData Uint8List // ByteData Uint8List
Uint8List uint8List = Uint8List uint8List = Uint8List.sublistView(byteData); //byteData.buffer.asUint8List();
Uint8List.sublistView(byteData); //byteData.buffer.asUint8List();
// //
return uint8List.toList(); return uint8List.toList();

View File

@ -1,11 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../entity/lockListInfo_entity.dart'; import '../entity/lockListInfo_entity.dart';
class LockMainState { class LockMainState {
// 0 1 2 // 0 1 2
RxInt dataLength = 100.obs; RxInt dataLength = 100.obs;
Rx<LockListInfoGroupEntity> lockListInfoGroupEntity = LockListInfoGroupEntity().obs; Rx<LockListInfoGroupEntity> lockListInfoGroupEntity = LockListInfoGroupEntity().obs;
@ -13,5 +11,6 @@ class LockMainState {
// 0 1 // 0 1
RxInt networkConnectionStatus = 0.obs; RxInt networkConnectionStatus = 0.obs;
// late Timer timer; RxInt selectedIndex = 0.obs;
// late Timer timer;
} }

View File

@ -29,6 +29,38 @@ class _MessageListPageState extends State<MessageListPage>
final MessageListLogic logic = Get.put(MessageListLogic()); final MessageListLogic logic = Get.put(MessageListLogic());
final MessageListState state = Get.find<MessageListLogic>().state; 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() { void getHttpData() {
logic.messageListDataRequest().then((MessageListEntity value) { logic.messageListDataRequest().then((MessageListEntity value) {
setState(() {}); setState(() {});
@ -39,38 +71,60 @@ class _MessageListPageState extends State<MessageListPage>
void initState() { void initState() {
super.initState(); super.initState();
//
_loadPushNotificationStatus();
getHttpData(); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: AppColors.mainBackgroundColor, backgroundColor: AppColors.mainBackgroundColor,
appBar: widget.showAppBar appBar: widget.showAppBar
? TitleAppBar( ? TitleAppBar(
barTitle: '消息'.tr, barTitle: '消息'.tr,
haveBack: true, haveBack: true,
actionsList: <Widget>[ actionsList: <Widget>[
TextButton( TextButton(
child: Text( child: Text(
'清空'.tr, '清空'.tr,
style: TextStyle(color: Colors.white, fontSize: 24.sp), style: TextStyle(color: Colors.white, fontSize: 24.sp),
), ),
onPressed: () async { onPressed: () async {
final bool? isDemoMode = final bool? isDemoMode =
await Storage.getBool(ifIsDemoModeOrNot); await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) { if (isDemoMode == false) {
ShowTipView().showIosTipWithContentDialog('是否清空?'.tr, ShowTipView().showIosTipWithContentDialog('是否清空?'.tr,
() async { () async {
logic.deletAllMessageDataRequest(); logic.deletAllMessageDataRequest();
}); });
} else { } else {
logic.showToast('演示模式'.tr); logic.showToast('演示模式'.tr);
} }
}, },
), ),
], ],
backgroundColor: AppColors.mainColor) backgroundColor: AppColors.mainColor)
: null, : null,
body: EasyRefreshTool(onRefresh: () { body: EasyRefreshTool(onRefresh: () {
logic.pageNo = 1; logic.pageNo = 1;
@ -80,116 +134,354 @@ class _MessageListPageState extends State<MessageListPage>
}, child: Obx(() { }, child: Obx(() {
return state.itemDataList.value.isEmpty return state.itemDataList.value.isEmpty
? NoData() ? 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( child: ListView.builder(
itemCount: state.itemDataList.value.length, itemCount: _buildGroupedListItems().length,
itemBuilder: (BuildContext c, int index) { itemBuilder: (BuildContext context, int index) {
final MessageItemEntity messageItemEntity = var item = _buildGroupedListItems()[index];
state.itemDataList.value[index];
return Slidable( if (item is String) {
key: ValueKey(messageItemEntity.id), //
endActionPane: ActionPane( return Container(
extentRatio: 0.2, padding: EdgeInsets.symmetric(
motion: const ScrollMotion(), horizontal: 16.w, vertical: 10.h),
children: <Widget>[ color: AppColors.mainBackgroundColor,
SlidableAction( child: RichText(
onPressed: (BuildContext context) { text: TextSpan(
logic.deletMessageDataRequest( children: [
messageItemEntity.id!, () { TextSpan(
logic.pageNo = 1; text: item.substring(8, 10),
getHttpData(); style: TextStyle(
}); color: Colors.black,
}, fontSize: 36.sp,
backgroundColor: Colors.red, fontWeight: FontWeight.w600,
foregroundColor: Colors.white, ),
label: '删除'.tr, ),
padding: EdgeInsets.only(left: 5.w, right: 5.w), 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( Widget _messageListItem(
MessageItemEntity messageItemEntity, Function() action) { 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( return GestureDetector(
onTap: action, onTap: () {
child: Container( //
height: 90.h, if (_showCheckboxes.value) {
width: 1.sw, _selectedItems[index] = !_selectedItems[index];
margin: EdgeInsets.only(bottom: 2.h), setState(() {});
decoration: BoxDecoration( } else {
color: Colors.white, //
borderRadius: BorderRadius.circular(10.w), action();
), }
child: Container( },
width: 1.sw, child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
margin: EdgeInsets.only(left: 20.w, right: 20.w), Container(
child: Column( padding: EdgeInsets.only(left: 10),
mainAxisAlignment: MainAxisAlignment.center, transform: Matrix4.translationValues(0, 20, 0),
children: <Widget>[ child: Column(
Row( children: [
children: <Widget>[ Image.asset(
if (messageItemEntity.readAt! == 0) messageItemEntity.readAt! == 0
? 'images/mine/icon_message_unread.png'
: 'images/mine/icon_message_readed.png',
width: 18.w,
height: 18.h),
// 线
if (!isLastInGroupSimple)
Container( Container(
width: 10.w, width: 0.5,
height: 10.w, height: 190.h,
decoration: BoxDecoration( color: AppColors.placeholderTextColor,
color: Colors.red,
borderRadius: BorderRadius.circular(5.w),
),
) )
else ],
Container(), )),
if (messageItemEntity.readAt! == 0) Expanded(
SizedBox(width: 5.w) child: Slidable(
else key: Key(messageItemEntity.id.toString()), // item添加唯一key
Container(), endActionPane: ActionPane(
Flexible( motion: const ScrollMotion(),
child: Text( children: [
messageItemEntity.data!, SlidableAction(
maxLines: 1, onPressed: (context) {
overflow: TextOverflow.ellipsis, //
style: TextStyle( logic.deletMessageDataRequest(
fontSize: 22.sp, messageItemEntity.id!, () {
color: messageItemEntity.readAt! == 0 logic.pageNo = 1;
? AppColors.blackColor getHttpData();
: AppColors.placeholderTextColor), });
), },
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),
), ),
], child: Container(
), width: 1.sw,
SizedBox(height: 10.h), margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 8.h),
Row( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
// Image.asset('images/mine/icon_mine_gatewaySignal_strong.png', width: 40.w, height: 40.w,), // SizedBox(height: 4.h),
// SizedBox(width: 10.w,), // Row(
Text( // children: <Widget>[
DateTool().dateToYMDHNString( // Flexible(
messageItemEntity.createdAt!.toString()), // child: Text(
style: TextStyle( // //
fontSize: 18.sp, // '远程开门请求',
color: messageItemEntity.readAt! == 0 // maxLines: 1,
? AppColors.blackColor // overflow: TextOverflow.ellipsis,
: AppColors.placeholderTextColor)), // style: TextStyle(
], // fontSize: 22.sp,
), // color: messageItemEntity.readAt! == 0
SizedBox(width: 20.h), // ? 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(() {});
},
)
]));
} }
} }

View File

@ -1,22 +1,34 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart'; import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import 'package:star_lock/flavors.dart'; import 'package:star_lock/flavors.dart';
import 'package:star_lock/mine/mine/starLockMine_state.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 'package:star_lock/tools/wechat/customer_tool.dart';
import '../../appRouters.dart'; import '../../appRouters.dart';
import '../../app_settings/app_colors.dart'; import '../../app_settings/app_colors.dart';
import '../../baseWidget.dart'; import '../../baseWidget.dart';
import '../../tools/commonItem.dart';
import '../../tools/customNetworkImage.dart'; import '../../tools/customNetworkImage.dart';
import '../../tools/showTipView.dart';
import '../../tools/submitBtn.dart'; import '../../tools/submitBtn.dart';
import '../../tools/wechat/wechatManageTool.dart'; import '../../tools/wechat/wechatManageTool.dart';
import '../../tools/wechat/wx_push_miniProgram/wx_push_miniProgram.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'; import 'starLockMine_logic.dart';
class StarLockMinePage extends StatefulWidget { 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 @override
State<StarLockMinePage> createState() => StarLockMinePageState(); State<StarLockMinePage> createState() => StarLockMinePageState();
@ -27,199 +39,237 @@ GlobalKey<StarLockMinePageState> starLockMineKey = GlobalKey();
class StarLockMinePageState extends State<StarLockMinePage> with BaseWidget { class StarLockMinePageState extends State<StarLockMinePage> with BaseWidget {
final StarLockMineLogic logic = Get.put(StarLockMineLogic()); final StarLockMineLogic logic = Get.put(StarLockMineLogic());
final StarLockMineState state = Get.find<StarLockMineLogic>().state; final StarLockMineState state = Get.find<StarLockMineLogic>().state;
late final MineSetState stateSet;
late final MineSetLogic logicSet;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// MineSetLogic
if (!Get.isRegistered<MineSetLogic>()) {
Get.put(MineSetLogic());
}
logicSet = Get.find<MineSetLogic>();
stateSet = logicSet.state;
logicSet.userSettingsInfoRequest();
logic.getUserInfoRequest(); logic.getUserInfoRequest();
//
_checkNotificationPermission();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: const Color(0xFFFFFFFF), body: SafeArea(
body: Column( child: SingleChildScrollView(child: Container(
children: <Widget>[ margin: EdgeInsets.only(bottom: 20.h),
topWidget(), padding: EdgeInsets.symmetric(horizontal: 20.w),
bottomListWidget(), child: Column(
SizedBox( children: <Widget>[
height: 80.h, SizedBox(
), height: 20.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,
), ),
), topWidget(),
), SizedBox(
], height: 20.h,
), ),
); Container(
} decoration: BoxDecoration(
color: Colors.white,
Widget topWidget() { borderRadius: BorderRadius.circular(10.r),
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,
), ),
GestureDetector( padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 15.h),
child: GestureDetector(
onTap: () { onTap: () {
Get.back(); Get.back();
Get.toNamed(Routers.minePersonInfoPage); Get.toNamed(Routers.minePersonInfoPage);
}, },
child: Obx(() => SizedBox( child: Row(
width: 105.w, children: <Widget>[
height: 105.w, Icon(
child: ClipRRect( Icons.person,
borderRadius: BorderRadius.circular(52.5.w), size: 32.sp,
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,
),
],
),
), ),
)) 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() { Widget bottomListWidget() {
return Container( return Container(
padding: EdgeInsets.only( width: double.infinity,
left: 60.w, decoration: BoxDecoration(
top: 50.h, color: Colors.white,
borderRadius: BorderRadius.circular(10.w),
), ),
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.w),
child: Column( child: Column(
children: [ children: [
mineItem('images/mine/icon_mine_main_addLock.png', '添加设备'.tr, () { // mineItem('images/mine/icon_mine_main_set.png', '设置'.tr, () {
Get.back(); // Get.back();
Get.toNamed(Routers.selectLockTypePage); // Get.toNamed(Routers.mineSetPage);
}),
// mineItem('images/mine/icon_mine_main_gateway.png',
// TranslationLoader.lanKeys!.gateway!.tr, () {
// Navigator.pushNamed(context, Routers.gatewayListPage);
// }), // }),
mineItem('images/mine/icon_mine_main_message.png', '消息'.tr, () { // SizedBox(height: 20.h),
Get.back(); mineItem('images/mine/icon_mine_main_vip.png', '增值服务'.tr, () async {
Get.toNamed(Routers.messageListPage); final bool? isVip = await Storage.getBool(saveIsVip);
// Toast.show(msg: "功能暂未开放"); 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);
}
}), }),
// SizedBox(height: 20.h),
// 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);
}),
mineItem('images/mine/icon_mine_main_about.png', '关于'.tr, () { mineItem('images/mine/icon_mine_main_about.png', '关于'.tr, () {
Get.back(); Get.back();
Get.toNamed(Routers.aboutPage); Get.toNamed(Routers.aboutPage);
@ -229,71 +279,435 @@ class StarLockMinePageState extends State<StarLockMinePage> with BaseWidget {
); );
} }
// Widget keyBottomWidget() { Widget mineItem(String lockTypeIcon, String lockTypeTitle, Function() action) {
// 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) {
return GestureDetector( return GestureDetector(
onTap: action, onTap: action,
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Center( Image.asset(
child: Container( lockTypeIcon,
// height: 80.h, width: 28.w,
width: 330.w, height: 28.w,
padding: EdgeInsets.all(20.h), ),
color: Colors.white, SizedBox(width: 15.w),
child: Row( Text(
children: <Widget>[ lockTypeTitle,
Image.asset( style: TextStyle(fontSize: 28.sp),
lockTypeIcon, ),
width: 28.w, const Spacer(),
height: 28.w, Icon(
), Icons.arrow_forward_ios_rounded,
SizedBox(width: 15.w), color: Colors.grey[400],
Text( )
lockTypeTitle, ],
style: TextStyle(fontSize: 22.sp), ),
), );
], }
),
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( Container(
height: 0.5.h, padding: EdgeInsets.only(left: 30.w, top: 30.h),
color: Colors.grey, // 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,
) )
], ],
), ),

View File

@ -305,6 +305,8 @@ abstract class Api {
'/lockSetting/updateLockSetting'; // '/lockSetting/updateLockSetting'; //
final String reportBuyRequestURL = final String reportBuyRequestURL =
'/service/reportBuyRequest'; // '/service/reportBuyRequest'; //
final String getActivateInfoURL = final String getTppSupportURL =
'/api/authCode/getTppSupport'; // ttp '/api/authCode/getTppSupport'; // ttp
final String getActivateInfoURL =
'/api/authCode/getActivateInfo'; // ttp
} }

View File

@ -10,28 +10,48 @@ import 'package:star_lock/talk/starChart/entity/star_chart_register_node_entity.
import 'package:star_lock/tools/storage.dart'; import 'package:star_lock/tools/storage.dart';
class StartCompanyApi extends BaseProvider { class StartCompanyApi extends BaseProvider {
// url // url
String _startChartHost = 'https://company.skychip.top'; String _startChartHost = 'https://company.skychip.top';
static StartCompanyApi get to => Get.put(StartCompanyApi()); static StartCompanyApi get to => Get.put(StartCompanyApi());
// host // host
set startChartHost(String value) { set startChartHost(String value) {
_startChartHost = value; _startChartHost = value;
} }
// host // host
String get startChartHost => _startChartHost; String get startChartHost => _startChartHost;
// ttp查询 // ttp查询
Future<ActivateInfoResponse> getActivateInfo({ Future<TppSupportResponse> getTppSupport({
required String model, 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 { }) async {
final response = await post( final response = await post(
_startChartHost + getActivateInfoURL.toUrl, _startChartHost + getActivateInfoURL.toUrl,
jsonEncode(<String, dynamic>{ jsonEncode(<String, dynamic>{
'register_key': registerKey,
'platform': platform,
'model': model, 'model': model,
'serial_num0': serialNum0,
}), }),
isUnShowLoading: true, isUnShowLoading: true,
isUserBaseUrl: false, isUserBaseUrl: false,

View File

@ -67,7 +67,7 @@ class CommonItem extends StatelessWidget {
), ),
child: Text( child: Text(
leftTitel!, leftTitel!,
style: leftTitleStyle ?? TextStyle(fontSize: 22.sp), style: leftTitleStyle ?? TextStyle(fontSize: 28.sp),
overflow: TextOverflow.ellipsis, // overflow: TextOverflow.ellipsis, //
maxLines: 3, // 2 maxLines: 3, // 2
), ),

View File

@ -194,6 +194,45 @@ class DateTool {
return appointmentDate; 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) { String dateIntToYMDHNString(int? time) {
time ??= 0; time ??= 0;

View File

@ -261,7 +261,7 @@ dependencies:
jverify: 3.0.0 jverify: 3.0.0
#<cn> #<cn>
umeng_common_sdk: 1.2.8 # umeng_common_sdk: 1.2.8
#</cn> #</cn>
#<com> #<com>
firebase_analytics: 11.3.0 firebase_analytics: 11.3.0
@ -323,6 +323,7 @@ flutter:
- images/ - images/
- images/tabbar/ - images/tabbar/
- images/guide/ - images/guide/
- images/other/
- images/main/ - images/main/
- images/main/addFingerprint/ - images/main/addFingerprint/
- images/mine/ - images/mine/