调试协议
This commit is contained in:
parent
c84a03dad5
commit
87ac11f3f9
@ -40,7 +40,7 @@
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
|
||||
@ -241,11 +241,29 @@ class BlueManage{
|
||||
// }
|
||||
|
||||
// 听上报来的数据,参数来自前面扫描到的结果
|
||||
var allData = <int>[];
|
||||
_subScribeToCharacteristic(QualifiedCharacteristic characteristic) {
|
||||
_flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) {
|
||||
// code to handle incoming data
|
||||
print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
|
||||
CommandReciverManager.appDataReceive(data);
|
||||
var dataLen = data[8] * 256 + data[9];// 高16位用来指示后面数据块内容的长度
|
||||
if((data[0] != 0xEF)&&(data[1] != 0x01)&&(data[2] != 0xEE)&&(data[3] != 0x02)){
|
||||
// 分包
|
||||
allData.addAll(data);
|
||||
}else{
|
||||
allData = <int>[];
|
||||
// 初始化数组为空
|
||||
if(dataLen > (data.length - 12)){
|
||||
// 进来先添加,还有包等待接收
|
||||
allData.addAll(data);
|
||||
return;
|
||||
}else{
|
||||
// 不需要分包的直接赋值
|
||||
allData = data;
|
||||
}
|
||||
}
|
||||
|
||||
CommandReciverManager.appDataReceive(allData);
|
||||
}, onError: (dynamic error) {
|
||||
EasyLoading.dismiss();
|
||||
print("subscribeToCharacteristic error:$error");
|
||||
|
||||
81
star_lock/lib/blue/io_protocol/io_automaticPadlock.dart
Normal file
81
star_lock/lib/blue/io_protocol/io_automaticPadlock.dart
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
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;
|
||||
|
||||
//TODO:自动落锁开关
|
||||
class AutomaticPadlockCommand extends SenderProtocol {
|
||||
String? lockID;
|
||||
String? userID;
|
||||
int? autoLockFlag;
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? signKey;
|
||||
List<int>? privateKey;
|
||||
AutomaticPadlockCommand({
|
||||
this.lockID,
|
||||
this.userID,
|
||||
this.autoLockFlag,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.signKey,
|
||||
this.privateKey
|
||||
}) : super(CommandType.generalExtendedCommond);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
List<int> subData = [];
|
||||
List<int> ebcData = [];
|
||||
|
||||
// 指令类型
|
||||
int type = commandType!.typeValue;
|
||||
double typeDouble = type / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 子命令类型
|
||||
data.add(4);
|
||||
|
||||
//lockID 40
|
||||
int lockIDLength = utf8.encode(lockID!).length;
|
||||
subData.addAll(utf8.encode(lockID!));
|
||||
subData = getFixedLengthList(subData, 40 - lockIDLength);
|
||||
|
||||
//userID 要接受钥匙的用户的useid 20
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
print("openDoorUserId:${utf8.encode(userID!)} utf8.encode(userID!).length:${utf8.encode(userID!).length}");
|
||||
subData.addAll(utf8.encode(userID!));
|
||||
subData = getFixedLengthList(subData, 20 - userIDLength);
|
||||
|
||||
// autoLockFlag 0:不自动落锁,1:自动落锁
|
||||
subData.add(autoLockFlag!);
|
||||
|
||||
data.add(subData.length);
|
||||
data.addAll(subData);
|
||||
|
||||
print("data:$data data.length:${data.length} (data.length % 16):${(data.length % 16)}");
|
||||
if ((data.length % 16) != 0) {
|
||||
int add = (16 - data.length % 16);
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
print("${commandType!.typeName} SM4Data:$data");
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class AutomaticPadlockReply extends Reply {
|
||||
AutomaticPadlockReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
119
star_lock/lib/blue/io_protocol/io_checkingCardStatus.dart
Normal file
119
star_lock/lib/blue/io_protocol/io_checkingCardStatus.dart
Normal file
@ -0,0 +1,119 @@
|
||||
|
||||
//TODO:查询指纹状态
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_reply.dart';
|
||||
import '../io_sender.dart';
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../io_type.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import 'package:crypto/crypto.dart' as crypto;
|
||||
|
||||
class SenderCheckingCardStatusCommand extends SenderProtocol {
|
||||
|
||||
String? keyID;
|
||||
String? userID;
|
||||
int? role;
|
||||
int? cardCount;
|
||||
int? cardNo;
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? publicKey;
|
||||
List<int>? privateKey;
|
||||
|
||||
SenderCheckingCardStatusCommand({
|
||||
this.keyID,
|
||||
this.userID,
|
||||
this.role,
|
||||
this.cardCount,
|
||||
this.cardNo,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.publicKey,
|
||||
this.privateKey,
|
||||
}) : super(CommandType.generalExtendedCommond);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
List<int> subData = [];
|
||||
List<int> ebcData = [];
|
||||
|
||||
// 指令类型
|
||||
int type = commandType!.typeValue;
|
||||
double typeDouble = type / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 子命令类型
|
||||
data.add(20);
|
||||
|
||||
// keyID 40
|
||||
int keyIDLength = utf8.encode(keyID!).length;
|
||||
subData.addAll(utf8.encode(keyID!));
|
||||
subData = getFixedLengthList(subData, 40 - keyIDLength);
|
||||
|
||||
//userID 20
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
subData.addAll(utf8.encode(userID!));
|
||||
subData = getFixedLengthList(subData, 20 - userIDLength);
|
||||
|
||||
// role
|
||||
subData.add(role!);
|
||||
|
||||
// CardCount
|
||||
subData.add(cardCount!);
|
||||
|
||||
// CardNo
|
||||
subData.add(cardNo!);
|
||||
|
||||
if(needAuthor == 0){
|
||||
//AuthCodeLen 1
|
||||
subData.add(0);
|
||||
} else {
|
||||
List<int> authCodeData = [];
|
||||
|
||||
//authUserID
|
||||
authCodeData.addAll(utf8.encode(userID!));
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||
authCodeData.addAll(token!);
|
||||
|
||||
authCodeData.addAll(publicKey!);
|
||||
|
||||
print("${commandType!.typeValue}-authCodeData:$authCodeData");
|
||||
|
||||
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
||||
var authCode = crypto.md5.convert(authCodeData);
|
||||
|
||||
subData.add(authCode.bytes.length);
|
||||
subData.addAll(authCode.bytes);
|
||||
}
|
||||
|
||||
data.add(subData.length);
|
||||
data.addAll(subData);
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
int add = (16 - data.length % 16);
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
print("${commandType!.typeName} SM4Data:$data");
|
||||
// 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class SenderCheckingCardStatusReply extends Reply {
|
||||
SenderCheckingCardStatusReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
@ -57,6 +57,19 @@ class OpenLockCommand extends SenderProtocol {
|
||||
|
||||
// OpenTime 4
|
||||
int? d1 = openTime;
|
||||
// var testData = [];
|
||||
// testData.add((d1! & 0xff000000) >> 24);
|
||||
// testData.add((d1 & 0xff0000) >> 16);
|
||||
// testData.add((d1 & 0xff00) >> 8);
|
||||
// testData.add((d1 & 0xff));
|
||||
//
|
||||
// int value = (
|
||||
// (0xff & testData[(0)]) << 24 |
|
||||
// (0xff & testData[1]) << 16 |
|
||||
// (0xff & testData[2]) << 8 |
|
||||
// (0xFF & testData[3]));
|
||||
// print("d1:$d1 testData:$testData value:$value");
|
||||
|
||||
data.add((d1! & 0xff000000) >> 24);
|
||||
data.add((d1 & 0xff0000) >> 16);
|
||||
data.add((d1 & 0xff00) >> 8);
|
||||
|
||||
119
star_lock/lib/blue/io_protocol/io_queryingFingerprintStatus.dart
Normal file
119
star_lock/lib/blue/io_protocol/io_queryingFingerprintStatus.dart
Normal file
@ -0,0 +1,119 @@
|
||||
|
||||
//TODO:查询指纹状态
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_reply.dart';
|
||||
import '../io_sender.dart';
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../io_type.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import 'package:crypto/crypto.dart' as crypto;
|
||||
|
||||
class SenderQueryingFingerprintStatusCommand extends SenderProtocol {
|
||||
|
||||
String? keyID;
|
||||
String? userID;
|
||||
int? role;
|
||||
int? fingerCount;
|
||||
int? fingerNo;
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? publicKey;
|
||||
List<int>? privateKey;
|
||||
|
||||
SenderQueryingFingerprintStatusCommand({
|
||||
this.keyID,
|
||||
this.userID,
|
||||
this.role,
|
||||
this.fingerCount,
|
||||
this.fingerNo,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.publicKey,
|
||||
this.privateKey,
|
||||
}) : super(CommandType.generalExtendedCommond);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
List<int> subData = [];
|
||||
List<int> ebcData = [];
|
||||
|
||||
// 指令类型
|
||||
int type = commandType!.typeValue;
|
||||
double typeDouble = type / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 子命令类型
|
||||
data.add(30);
|
||||
|
||||
// keyID 40
|
||||
int keyIDLength = utf8.encode(keyID!).length;
|
||||
subData.addAll(utf8.encode(keyID!));
|
||||
subData = getFixedLengthList(subData, 40 - keyIDLength);
|
||||
|
||||
//userID 20
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
subData.addAll(utf8.encode(userID!));
|
||||
subData = getFixedLengthList(subData, 20 - userIDLength);
|
||||
|
||||
// role
|
||||
subData.add(role!);
|
||||
|
||||
// fingerCount
|
||||
subData.add(fingerCount!);
|
||||
|
||||
// FingerNo
|
||||
subData.add(fingerNo!);
|
||||
|
||||
if(needAuthor == 0){
|
||||
//AuthCodeLen 1
|
||||
subData.add(0);
|
||||
} else {
|
||||
List<int> authCodeData = [];
|
||||
|
||||
//authUserID
|
||||
authCodeData.addAll(utf8.encode(userID!));
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||
authCodeData.addAll(token!);
|
||||
|
||||
authCodeData.addAll(publicKey!);
|
||||
|
||||
print("${commandType!.typeValue}-authCodeData:$authCodeData");
|
||||
|
||||
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
||||
var authCode = crypto.md5.convert(authCodeData);
|
||||
|
||||
subData.add(authCode.bytes.length);
|
||||
subData.addAll(authCode.bytes);
|
||||
}
|
||||
|
||||
data.add(subData.length);
|
||||
data.addAll(subData);
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
int add = (16 - data.length % 16);
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
print("${commandType!.typeName} SM4Data:$data");
|
||||
// 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class SenderQueryingFingerprintStatusReply extends Reply {
|
||||
SenderQueryingFingerprintStatusReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
117
star_lock/lib/blue/io_protocol/io_referEventRecordNumber.dart
Normal file
117
star_lock/lib/blue/io_protocol/io_referEventRecordNumber.dart
Normal file
@ -0,0 +1,117 @@
|
||||
|
||||
//TODO:查询事件记录(序号、数量查询)
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_reply.dart';
|
||||
import '../io_sender.dart';
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../io_type.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import 'package:crypto/crypto.dart' as crypto;
|
||||
|
||||
class SenderReferEventRecordNumberCommand extends SenderProtocol {
|
||||
|
||||
String? keyID;
|
||||
String? userID;
|
||||
int? logsCount;
|
||||
int? logsNo;
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? publicKey;
|
||||
List<int>? privateKey;
|
||||
|
||||
SenderReferEventRecordNumberCommand({
|
||||
this.keyID,
|
||||
this.userID,
|
||||
this.logsCount,
|
||||
this.logsNo,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.publicKey,
|
||||
this.privateKey,
|
||||
}) : super(CommandType.generalExtendedCommond);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
List<int> subData = [];
|
||||
List<int> ebcData = [];
|
||||
|
||||
// 指令类型
|
||||
int type = commandType!.typeValue;
|
||||
double typeDouble = type / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 子命令类型
|
||||
data.add(40);
|
||||
|
||||
// keyID 40
|
||||
int keyIDLength = utf8.encode(keyID!).length;
|
||||
subData.addAll(utf8.encode(keyID!));
|
||||
subData = getFixedLengthList(subData, 40 - keyIDLength);
|
||||
|
||||
//userID 20
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
subData.addAll(utf8.encode(userID!));
|
||||
subData = getFixedLengthList(subData, 20 - userIDLength);
|
||||
|
||||
// logsCount
|
||||
subData.add(logsCount!);
|
||||
|
||||
// logsNo
|
||||
subData.add(logsNo!);
|
||||
|
||||
// token
|
||||
// subData.addAll(token!);
|
||||
|
||||
if(needAuthor == 0){
|
||||
//AuthCodeLen 1
|
||||
subData.add(0);
|
||||
} else {
|
||||
List<int> authCodeData = [];
|
||||
|
||||
//authUserID
|
||||
authCodeData.addAll(utf8.encode(userID!));
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||
authCodeData.addAll(token!);
|
||||
|
||||
authCodeData.addAll(publicKey!);
|
||||
|
||||
print("${commandType!.typeValue}-authCodeData:$authCodeData");
|
||||
|
||||
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
||||
var authCode = crypto.md5.convert(authCodeData);
|
||||
|
||||
subData.add(authCode.bytes.length);
|
||||
subData.addAll(authCode.bytes);
|
||||
}
|
||||
|
||||
data.add(subData.length);
|
||||
data.addAll(subData);
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
int add = (16 - data.length % 16);
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
print("${commandType!.typeName} SM4Data:$data");
|
||||
// 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class SenderReferEventRecordNumberReply extends Reply {
|
||||
SenderReferEventRecordNumberReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
|
||||
//TODO:查询事件记录(时间查询)
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_reply.dart';
|
||||
import '../io_sender.dart';
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../io_type.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import 'package:crypto/crypto.dart' as crypto;
|
||||
|
||||
class SenderReferEventRecordNumberTimeCommand extends SenderProtocol {
|
||||
|
||||
String? keyID;
|
||||
String? userID;
|
||||
int? logsCount;
|
||||
int? time;
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? publicKey;
|
||||
List<int>? privateKey;
|
||||
|
||||
SenderReferEventRecordNumberTimeCommand({
|
||||
this.keyID,
|
||||
this.userID,
|
||||
this.logsCount,
|
||||
this.time,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.publicKey,
|
||||
this.privateKey,
|
||||
}) : super(CommandType.generalExtendedCommond);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
List<int> subData = [];
|
||||
List<int> ebcData = [];
|
||||
|
||||
// 指令类型
|
||||
int type = commandType!.typeValue;
|
||||
double typeDouble = type / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 子命令类型
|
||||
data.add(41);
|
||||
|
||||
// keyID 40
|
||||
int keyIDLength = utf8.encode(keyID!).length;
|
||||
subData.addAll(utf8.encode(keyID!));
|
||||
subData = getFixedLengthList(subData, 40 - keyIDLength);
|
||||
|
||||
//userID 20
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
subData.addAll(utf8.encode(userID!));
|
||||
subData = getFixedLengthList(subData, 20 - userIDLength);
|
||||
|
||||
// logsCount
|
||||
subData.add(logsCount!);
|
||||
|
||||
// time
|
||||
subData.add((time! & 0xff000000) >> 24);
|
||||
subData.add((time! & 0xff0000) >> 16);
|
||||
subData.add((time! & 0xff00) >> 8);
|
||||
subData.add((time! & 0xff));
|
||||
|
||||
// token
|
||||
// subData.addAll(token!);
|
||||
|
||||
if(needAuthor == 0){
|
||||
//AuthCodeLen 1
|
||||
subData.add(0);
|
||||
} else {
|
||||
List<int> authCodeData = [];
|
||||
|
||||
//authUserID
|
||||
authCodeData.addAll(utf8.encode(userID!));
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||
authCodeData.addAll(token!);
|
||||
|
||||
authCodeData.addAll(publicKey!);
|
||||
|
||||
print("${commandType!.typeValue}-authCodeData:$authCodeData");
|
||||
|
||||
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
||||
var authCode = crypto.md5.convert(authCodeData);
|
||||
|
||||
subData.add(authCode.bytes.length);
|
||||
subData.addAll(authCode.bytes);
|
||||
}
|
||||
|
||||
data.add(subData.length);
|
||||
data.addAll(subData);
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
int add = (16 - data.length % 16);
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
print("${commandType!.typeName} SM4Data:$data");
|
||||
// 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class SenderReferEventRecordNumberTimeReply extends Reply {
|
||||
SenderReferEventRecordNumberTimeReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
@ -24,7 +24,7 @@ class TimingCommand extends SenderProtocol {
|
||||
this.needAuthor,
|
||||
this.signKey,
|
||||
this.privateKey
|
||||
}) : super(CommandType.openLock);
|
||||
}) : super(CommandType.calibrationTime);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
@ -52,6 +52,7 @@ class TimingCommand extends SenderProtocol {
|
||||
|
||||
// nowTime 4
|
||||
int? d1 = nowTime;
|
||||
print("timing d1:$d1");
|
||||
data.add((d1! & 0xff000000) >> 24);
|
||||
data.add((d1 & 0xff0000) >> 16);
|
||||
data.add((d1 & 0xff00) >> 8);
|
||||
|
||||
@ -14,9 +14,13 @@ import 'package:star_lock/blue/io_protocol/io_transferPermissions.dart';
|
||||
import '../tools/storage.dart';
|
||||
import 'io_protocol/io_addFingerprint.dart';
|
||||
import 'io_protocol/io_addUser.dart';
|
||||
import 'io_protocol/io_automaticPadlock.dart';
|
||||
import 'io_protocol/io_checkingCardStatus.dart';
|
||||
import 'io_protocol/io_getPrivateKey.dart';
|
||||
import 'io_protocol/io_getPublicKey.dart';
|
||||
import 'io_protocol/io_openLock.dart';
|
||||
import 'io_protocol/io_queryingFingerprintStatus.dart';
|
||||
import 'io_protocol/io_referEventRecordNumber.dart';
|
||||
import 'io_reply.dart';
|
||||
import 'io_protocol/io_senderCustomPasswords.dart';
|
||||
import 'io_type.dart';
|
||||
@ -32,15 +36,17 @@ class CommandReciverManager {
|
||||
if(data.isEmpty){
|
||||
return;
|
||||
}
|
||||
int data_size = data.length;
|
||||
int dataSize = data.length;
|
||||
// 当小于包头加起来13个字节
|
||||
if(data_size < 13){
|
||||
if(dataSize < 13){
|
||||
return;
|
||||
}
|
||||
// print("appDataReceiveData:$data"); // &&(data[4] == 0x11)
|
||||
|
||||
print("appDataReceiveData:$data"); // &&(data[4] == 0x11)
|
||||
if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)){
|
||||
var tmpType = (data[7] & 0x0f);// 包标识
|
||||
print("temType:$tmpType");
|
||||
|
||||
var dataLen = data[8] * 256 + data[9];// 高16位用来指示后面数据块内容的长度
|
||||
var oriLen = data[10] * 256 + data[11];// 低16位用来指示数据加密前的原长度
|
||||
print("dataLen:$dataLen oriLen:$oriLen");
|
||||
@ -162,6 +168,24 @@ class CommandReciverManager {
|
||||
reply = SenderCustomPasswordsReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
// 自动落锁开关
|
||||
reply = AutomaticPadlockReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case 20:
|
||||
{
|
||||
// 查询卡片状态
|
||||
reply = SenderCheckingCardStatusReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case 30:
|
||||
{
|
||||
// 查询指纹状态
|
||||
reply = SenderQueryingFingerprintStatusReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case 31:
|
||||
{
|
||||
// 注册指纹开始
|
||||
@ -180,6 +204,12 @@ class CommandReciverManager {
|
||||
reply = SenderAddFingerprintProcessReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case 40:
|
||||
{
|
||||
// 事件查询记录
|
||||
reply = SenderReferEventRecordNumberReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -4,12 +4,18 @@ import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
||||
|
||||
import 'io_protocol/io_addFingerprint.dart';
|
||||
import 'io_protocol/io_addUser.dart';
|
||||
import 'io_protocol/io_automaticPadlock.dart';
|
||||
import 'io_protocol/io_checkingCardStatus.dart';
|
||||
import 'io_protocol/io_editUser.dart';
|
||||
import 'io_protocol/io_factoryDataReset.dart';
|
||||
import 'io_protocol/io_getPrivateKey.dart';
|
||||
import 'io_protocol/io_getPublicKey.dart';
|
||||
import 'io_protocol/io_openLock.dart';
|
||||
import 'io_protocol/io_queryingFingerprintStatus.dart';
|
||||
import 'io_protocol/io_referEventRecordNumber.dart';
|
||||
import 'io_protocol/io_referEventRecordNumberTime.dart';
|
||||
import 'io_protocol/io_senderCustomPasswords.dart';
|
||||
import 'io_protocol/io_timing.dart';
|
||||
import 'io_protocol/io_transferPermissions.dart';
|
||||
import 'sender_data.dart';
|
||||
|
||||
@ -280,4 +286,148 @@ class IoSenderManage {
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
|
||||
//todo:校验时间
|
||||
static void senderTimingCommand({
|
||||
required String? lockID,
|
||||
required String? userID,
|
||||
required int? nowTime,
|
||||
required List<int>? token,
|
||||
required int? needAuthor,
|
||||
required List<int>? signKey,
|
||||
required List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: TimingCommand(
|
||||
lockID: lockID,
|
||||
userID: userID,
|
||||
nowTime: nowTime,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
signKey: signKey,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
|
||||
//todo:自动落锁
|
||||
static void senderAutomaticPadlockCommand({
|
||||
required String? lockID,
|
||||
required String? userID,
|
||||
required int? autoLockFlag,
|
||||
required List<int>? token,
|
||||
required int? needAuthor,
|
||||
required List<int>? signKey,
|
||||
required List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: AutomaticPadlockCommand(
|
||||
lockID: lockID,
|
||||
userID: userID,
|
||||
autoLockFlag: autoLockFlag,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
signKey: signKey,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
|
||||
//todo:事件记录(页数查询)
|
||||
static void senderReferEventRecordNumberCommand({
|
||||
required String? keyID,
|
||||
required String? userID,
|
||||
required int? logsCount,
|
||||
required int? logsNo,
|
||||
required List<int>? token,
|
||||
required int? needAuthor,
|
||||
required List<int>? publicKey,
|
||||
required List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: SenderReferEventRecordNumberCommand(
|
||||
keyID: keyID,
|
||||
userID: userID,
|
||||
logsCount: logsCount,
|
||||
logsNo: logsNo,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
publicKey: publicKey,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
|
||||
//todo:事件记录(时间查询)
|
||||
static void senderReferEventRecordNumberTimeCommand({
|
||||
required String? keyID,
|
||||
required String? userID,
|
||||
required int? logsCount,
|
||||
required int? time,
|
||||
required List<int>? token,
|
||||
required int? needAuthor,
|
||||
required List<int>? publicKey,
|
||||
required List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: SenderReferEventRecordNumberTimeCommand(
|
||||
keyID: keyID,
|
||||
userID: userID,
|
||||
logsCount: logsCount,
|
||||
time: time,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
publicKey: publicKey,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
|
||||
//todo:查询指纹状态
|
||||
static void senderQueryingFingerprintStatusCommand({
|
||||
required String? keyID,
|
||||
required String? userID,
|
||||
required int? role,
|
||||
required int? fingerCount,
|
||||
required int? fingerNo,
|
||||
required List<int>? token,
|
||||
required int? needAuthor,
|
||||
required List<int>? publicKey,
|
||||
required List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: SenderQueryingFingerprintStatusCommand(
|
||||
keyID: keyID,
|
||||
userID: userID,
|
||||
role: role,
|
||||
fingerCount: fingerCount,
|
||||
fingerNo: fingerNo,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
publicKey: publicKey,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
|
||||
//todo:查询卡片状态
|
||||
static void senderCheckingCardStatusCommand({
|
||||
required String? keyID,
|
||||
required String? userID,
|
||||
required int? role,
|
||||
required int? cardCount,
|
||||
required int? cardNo,
|
||||
required List<int>? token,
|
||||
required int? needAuthor,
|
||||
required List<int>? publicKey,
|
||||
required List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: SenderCheckingCardStatusCommand(
|
||||
keyID: keyID,
|
||||
userID: userID,
|
||||
role: role,
|
||||
cardCount: cardCount,
|
||||
cardNo: cardNo,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
publicKey: publicKey,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,168 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
import '../../../../blue/blue_manage.dart';
|
||||
import '../../../../blue/io_protocol/io_automaticPadlock.dart';
|
||||
import '../../../../blue/io_protocol/io_getLockStatu.dart';
|
||||
import '../../../../blue/io_reply.dart';
|
||||
import '../../../../blue/io_tool/io_manager.dart';
|
||||
import '../../../../blue/io_tool/io_tool.dart';
|
||||
import '../../../../blue/io_tool/manager_event_bus.dart';
|
||||
import '../../../../blue/sender_manage.dart';
|
||||
import '../../../../tools/storage.dart';
|
||||
import 'automaticBlocking_state.dart';
|
||||
|
||||
class AutomaticBlockingLogic extends BaseGetXController{
|
||||
final AutomaticBlockingState automaticBlockingState = AutomaticBlockingState();
|
||||
|
||||
// 获取解析后的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
void _initReplySubscription() {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if(reply is AutomaticPadlockReply) {
|
||||
_replyAutomaticPadlock(reply);
|
||||
}
|
||||
|
||||
// 获取锁状态
|
||||
if(reply is GetLockStatuReply) {
|
||||
_replyGetLockStatus(reply);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取锁状态数据解析
|
||||
Future<void> _replyGetLockStatus(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
|
||||
// 锁当前时间
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 校时数据解析
|
||||
Future<void> _replyAutomaticPadlock(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
// _getLockStatus();
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取锁状态
|
||||
Future<void> _getLockStatus() async {
|
||||
// 进来之后首先连接
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
IoSenderManage.senderGetLockStatu(
|
||||
lockID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 校验时间
|
||||
Future<void> sendTiming() async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
var signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
List<int> getSignKeyList = changeStringListToIntList(signKey!);
|
||||
|
||||
print("automaticBlockingState.isOpen.value:${automaticBlockingState.isOpen.value}");
|
||||
IoSenderManage.senderAutomaticPadlockCommand(
|
||||
lockID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
autoLockFlag:automaticBlockingState.isOpen.value ? 1 : 0,
|
||||
token:getTokenList,
|
||||
needAuthor:1,
|
||||
signKey:getSignKeyList,
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
print("onReady()");
|
||||
|
||||
_initReplySubscription();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
// TODO: implement onInit
|
||||
super.onInit();
|
||||
print("onInit()");
|
||||
|
||||
_getLockStatus();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ import '../../../../tools/commonItem.dart';
|
||||
import '../../../../tools/showBottomSheetTool.dart';
|
||||
import '../../../../tools/titleAppBar.dart';
|
||||
import '../../../../translations/trans_lib.dart';
|
||||
import 'automaticBlocking_logic.dart';
|
||||
|
||||
class AutomaticBlockingPage extends StatefulWidget {
|
||||
const AutomaticBlockingPage({Key? key}) : super(key: key);
|
||||
@ -20,6 +21,8 @@ class AutomaticBlockingPage extends StatefulWidget {
|
||||
|
||||
class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
|
||||
final TextEditingController _timeController = TextEditingController();
|
||||
final logic = Get.put(AutomaticBlockingLogic());
|
||||
final state = Get.find<AutomaticBlockingLogic>().automaticBlockingState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -28,16 +31,27 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
|
||||
appBar: TitleAppBar(
|
||||
barTitle: TranslationLoader.lanKeys!.automaticBlocking!.tr,
|
||||
haveBack: true,
|
||||
actionsList: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
TranslationLoader.lanKeys!.save!.tr,
|
||||
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||
),
|
||||
onPressed: () {
|
||||
logic.sendTiming();
|
||||
},
|
||||
),
|
||||
],
|
||||
backgroundColor: AppColors.mainColor),
|
||||
body: ListView(
|
||||
children: [
|
||||
CommonItem(
|
||||
Obx(() => CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.automaticBlocking!.tr,
|
||||
rightTitle: "",
|
||||
rightTitle: "${state.automaticBlockingTime}s",
|
||||
isHaveLine: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget:
|
||||
SizedBox(width: 60.w, height: 50.h, child: _switch())),
|
||||
SizedBox(width: 60.w, height: 50.h, child: _switch())),),
|
||||
Container(
|
||||
height: 10.h,
|
||||
),
|
||||
@ -49,11 +63,11 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
var list = [
|
||||
"5S",
|
||||
"10S",
|
||||
"15S",
|
||||
"30S",
|
||||
"60S",
|
||||
"5",
|
||||
"10",
|
||||
"15",
|
||||
"30",
|
||||
"60",
|
||||
TranslationLoader.lanKeys!.custom!.tr
|
||||
];
|
||||
ShowBottomSheetTool().showSingleRowPicker(
|
||||
@ -69,14 +83,20 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
|
||||
//adapter: PickerAdapter(),
|
||||
data: list,
|
||||
//选择事件的回调
|
||||
clickCallBack: (int index, var str) {});
|
||||
clickCallBack: (int index, var str) {
|
||||
if(index != 5){
|
||||
state.automaticBlockingTime.value = str.toString();
|
||||
}else{
|
||||
state.isCustomLockTime.value = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}),
|
||||
Container(
|
||||
height: 10.h,
|
||||
),
|
||||
Visibility(
|
||||
visible: true,
|
||||
Obx(() => Visibility(
|
||||
visible: state.isCustomLockTime.value,
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.only(
|
||||
@ -99,9 +119,9 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
|
||||
decoration: InputDecoration(
|
||||
//输入里面输入文字内边距设置
|
||||
contentPadding:
|
||||
const EdgeInsets.only(top: 12.0, bottom: 8.0),
|
||||
const EdgeInsets.only(top: 12.0, bottom: 8.0),
|
||||
hintText:
|
||||
"${TranslationLoader.lanKeys!.pleaseEnter!.tr}${TranslationLoader.lanKeys!.time!.tr}(S)",
|
||||
"${TranslationLoader.lanKeys!.pleaseEnter!.tr}${TranslationLoader.lanKeys!.time!.tr}(S)",
|
||||
hintStyle: TextStyle(fontSize: 24.sp),
|
||||
//不需要输入框下划线
|
||||
border: InputBorder.none,
|
||||
@ -113,7 +133,7 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
))),
|
||||
Container(
|
||||
padding: EdgeInsets.all(30.w),
|
||||
child: Row(
|
||||
@ -132,15 +152,14 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
|
||||
}
|
||||
|
||||
CupertinoSwitch _switch() {
|
||||
bool _isOn = false;
|
||||
return CupertinoSwitch(
|
||||
activeColor: CupertinoColors.activeBlue,
|
||||
trackColor: CupertinoColors.systemGrey5,
|
||||
thumbColor: CupertinoColors.white,
|
||||
value: _isOn,
|
||||
value: state.isOpen.value,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_isOn = value;
|
||||
state.isOpen.value = value;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class AutomaticBlockingState {
|
||||
var isOpen = false.obs;
|
||||
var automaticBlockingTime = "5".obs;
|
||||
var isCustomLockTime = false.obs;
|
||||
}
|
||||
@ -0,0 +1,183 @@
|
||||
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
|
||||
import '../../../../blue/blue_manage.dart';
|
||||
import '../../../../blue/io_protocol/io_getLockStatu.dart';
|
||||
import '../../../../blue/io_protocol/io_timing.dart';
|
||||
import '../../../../blue/io_reply.dart';
|
||||
import '../../../../blue/io_tool/io_manager.dart';
|
||||
import '../../../../blue/io_tool/io_tool.dart';
|
||||
import '../../../../blue/io_tool/manager_event_bus.dart';
|
||||
import '../../../../blue/sender_manage.dart';
|
||||
import '../../../../tools/baseGetXController.dart';
|
||||
import '../../../../tools/dateTool.dart';
|
||||
import '../../../../tools/storage.dart';
|
||||
import '../../../../tools/toast.dart';
|
||||
import 'lockTime_state.dart';
|
||||
|
||||
class LockTimeLogic extends BaseGetXController{
|
||||
final LockTimeState state = LockTimeState();
|
||||
|
||||
// 获取解析后的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
void _initReplySubscription() {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if(reply is TimingReply) {
|
||||
_replyTiming(reply);
|
||||
}
|
||||
|
||||
// 获取锁状态
|
||||
if(reply is GetLockStatuReply) {
|
||||
_replyGetLockStatus(reply);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取锁状态数据解析
|
||||
Future<void> _replyGetLockStatus(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
|
||||
// 锁当前时间
|
||||
var lockTime = reply.data.sublist(60, 64);
|
||||
|
||||
int value = (
|
||||
(0xff & lockTime[(0)]) << 24 |
|
||||
(0xff & lockTime[1]) << 16 |
|
||||
(0xff & lockTime[2]) << 8 |
|
||||
(0xFF & lockTime[3]));
|
||||
|
||||
String dataEime = DateTool().dateToString("${value}000");
|
||||
state.dateTime.value = dataEime;
|
||||
print("lockTime:$lockTime value:$value dataEime:$dataEime");
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 校时数据解析
|
||||
Future<void> _replyTiming(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
// _getLockStatus();
|
||||
Toast.show(msg:"锁时间更新成功");
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取锁状态
|
||||
Future<void> _getLockStatus() async {
|
||||
// 进来之后首先连接
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
IoSenderManage.senderGetLockStatu(
|
||||
lockID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 校验时间
|
||||
Future<void> sendTiming() async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
var signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
List<int> getSignKeyList = changeStringListToIntList(signKey!);
|
||||
|
||||
IoSenderManage.senderTimingCommand(
|
||||
lockID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
nowTime:DateTime.now().millisecondsSinceEpoch~/1000,
|
||||
token:getTokenList,
|
||||
needAuthor:1,
|
||||
signKey:getSignKeyList,
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
print("onReady()");
|
||||
|
||||
_initReplySubscription();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
// TODO: implement onInit
|
||||
super.onInit();
|
||||
print("onInit()");
|
||||
|
||||
_getLockStatus();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import '../../../../app_settings/app_colors.dart';
|
||||
import '../../../../tools/submitBtn.dart';
|
||||
import '../../../../tools/titleAppBar.dart';
|
||||
import '../../../../translations/trans_lib.dart';
|
||||
import 'lockTime_logic.dart';
|
||||
|
||||
class LockTimePage extends StatefulWidget {
|
||||
const LockTimePage({Key? key}) : super(key: key);
|
||||
@ -15,6 +16,9 @@ class LockTimePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _LockTimePageState extends State<LockTimePage> {
|
||||
final logic = Get.put(LockTimeLogic());
|
||||
final state = Get.find<LockTimeLogic>().state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -30,14 +34,14 @@ class _LockTimePageState extends State<LockTimePage> {
|
||||
SizedBox(
|
||||
height: 50.h,
|
||||
),
|
||||
Row(
|
||||
Obx(() => Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text("2023.07.10 11.47.33",
|
||||
Text(state.dateTime.value,
|
||||
style: TextStyle(
|
||||
fontSize: 26.sp, color: AppColors.blackColor)),
|
||||
],
|
||||
),
|
||||
),),
|
||||
SizedBox(
|
||||
height: 60.h,
|
||||
),
|
||||
@ -47,7 +51,10 @@ class _LockTimePageState extends State<LockTimePage> {
|
||||
fontSize: 32.sp,
|
||||
// margin: EdgeInsets.only(left: 03.w, right: 30.w, top: 20.w),
|
||||
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
|
||||
onClick: () {}),
|
||||
onClick: () {
|
||||
print("1111111");
|
||||
logic.sendTiming();
|
||||
}),
|
||||
SizedBox(
|
||||
height: 40.h,
|
||||
),
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class LockTimeState{
|
||||
var dateTime = "".obs;
|
||||
}
|
||||
@ -318,17 +318,12 @@ class LockDetailLogic extends BaseGetXController{
|
||||
List<int> getTokenList = changeStringListToIntList(token!);
|
||||
print("openDoorTokenPubToken:$getTokenList");
|
||||
|
||||
// String? userId = '';
|
||||
// final data = await Storage.getString('userLoginData');
|
||||
// if (data != null && data.isNotEmpty) {
|
||||
// userId = LoginEntity.fromJson(jsonDecode(data)).data!.userid.toString();
|
||||
// }
|
||||
// print("userId:$userId");
|
||||
print("millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch~/1000}");
|
||||
IoSenderManage.senderOpenLock(
|
||||
keyID: "1",
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
openTime: DateTime.now().millisecondsSinceEpoch,
|
||||
openTime: DateTime.now().millisecondsSinceEpoch~/1000,
|
||||
token: getTokenList,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyDataList,
|
||||
|
||||
@ -0,0 +1,140 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
|
||||
import '../../../blue/blue_manage.dart';
|
||||
import '../../../blue/io_protocol/io_referEventRecordNumber.dart';
|
||||
import '../../../blue/io_reply.dart';
|
||||
import '../../../blue/io_tool/io_manager.dart';
|
||||
import '../../../blue/io_tool/io_tool.dart';
|
||||
import '../../../blue/io_tool/manager_event_bus.dart';
|
||||
import '../../../blue/sender_manage.dart';
|
||||
import '../../../tools/baseGetXController.dart';
|
||||
import '../../../tools/storage.dart';
|
||||
import 'lockOperatingRecord_state.dart';
|
||||
|
||||
class LockOperatingRecordLogic extends BaseGetXController{
|
||||
LockOperatingRecordState state = LockOperatingRecordState();
|
||||
|
||||
// 获取解析后的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
void _initReplySubscription() {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if(reply is SenderReferEventRecordNumberReply) {
|
||||
_replyReferEventRecordNumber(reply);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 校时数据解析
|
||||
Future<void> _replyReferEventRecordNumber(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
// _getLockStatus();
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 查询事件记录(页数查询)
|
||||
Future<void> senderReferEventRecordNumber() async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
|
||||
|
||||
IoSenderManage.senderReferEventRecordNumberCommand(
|
||||
keyID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
logsCount:20,
|
||||
logsNo:1,
|
||||
token:getTokenList,
|
||||
needAuthor:1,
|
||||
publicKey:getPublicKeyList,
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 查询事件记录(时间查询)
|
||||
Future<void> senderReferEventRecordNumberTime() async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
|
||||
|
||||
IoSenderManage.senderReferEventRecordNumberTimeCommand(
|
||||
keyID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
logsCount:20,
|
||||
time:DateTime.now().millisecondsSinceEpoch~/1000,
|
||||
token:getTokenList,
|
||||
needAuthor:1,
|
||||
publicKey:getPublicKeyList,
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
print("onReady()");
|
||||
|
||||
_initReplySubscription();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
// TODO: implement onInit
|
||||
super.onInit();
|
||||
print("onInit()");
|
||||
|
||||
senderReferEventRecordNumberTime();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ import '../../../app_settings/app_colors.dart';
|
||||
import '../../../tools/jh_pop_menus.dart';
|
||||
import '../../../tools/titleAppBar.dart';
|
||||
import '../../../translations/trans_lib.dart';
|
||||
import 'lockOperatingRecord_logic.dart';
|
||||
|
||||
class LockOperatingRecordPage extends StatefulWidget {
|
||||
const LockOperatingRecordPage({Key? key}) : super(key: key);
|
||||
@ -20,6 +21,9 @@ class LockOperatingRecordPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _LockOperatingRecordPageState extends State<LockOperatingRecordPage> {
|
||||
final logic = Get.put(LockOperatingRecordLogic());
|
||||
final state = Get.find<LockOperatingRecordLogic>().state;
|
||||
|
||||
late KeyInfos keyInfo;
|
||||
late LockMainEntity lockMainEntity;
|
||||
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
class LockOperatingRecordState{
|
||||
|
||||
}
|
||||
@ -0,0 +1,181 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
|
||||
import '../../../../blue/blue_manage.dart';
|
||||
import '../../../../blue/io_protocol/io_checkingCardStatus.dart';
|
||||
import '../../../../blue/io_protocol/io_queryingFingerprintStatus.dart';
|
||||
import '../../../../blue/io_reply.dart';
|
||||
import '../../../../blue/io_tool/io_manager.dart';
|
||||
import '../../../../blue/io_tool/io_tool.dart';
|
||||
import '../../../../blue/io_tool/manager_event_bus.dart';
|
||||
import '../../../../blue/sender_manage.dart';
|
||||
import '../../../../tools/baseGetXController.dart';
|
||||
import '../../../../tools/storage.dart';
|
||||
import 'otherTypeKeyList_state.dart';
|
||||
|
||||
class OtherTypeKeyListLogic extends BaseGetXController{
|
||||
OtherTypeKeyListState state = OtherTypeKeyListState();
|
||||
|
||||
// 获取解析后的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
void _initReplySubscription() {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if(reply is SenderQueryingFingerprintStatusReply) {
|
||||
// 获取指纹状态
|
||||
_replyQueryingFingerprintStatus(reply);
|
||||
}
|
||||
|
||||
if(reply is SenderCheckingCardStatusReply) {
|
||||
_replyReferEventRecordNumber(reply);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取指纹状态
|
||||
Future<void> _replyQueryingFingerprintStatus(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
// _getLockStatus();
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取卡片状态
|
||||
Future<void> _replyReferEventRecordNumber(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
// _getLockStatus();
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取指纹状态
|
||||
Future<void> senderQueryingFingerprintStatus() async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
|
||||
|
||||
IoSenderManage.senderQueryingFingerprintStatusCommand(
|
||||
keyID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
role:0xff,
|
||||
fingerCount:20,
|
||||
fingerNo:1,
|
||||
token:getTokenList,
|
||||
needAuthor:1,
|
||||
publicKey:getPublicKeyList,
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 查询卡片状态
|
||||
Future<void> senderCheckingCardStatus() async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
|
||||
|
||||
IoSenderManage.senderCheckingCardStatusCommand(
|
||||
keyID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
role:0xff,
|
||||
cardCount:20,
|
||||
cardNo:1,
|
||||
token:getTokenList,
|
||||
needAuthor:1,
|
||||
publicKey:getPublicKeyList,
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
print("onReady()");
|
||||
|
||||
_initReplySubscription();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
// TODO: implement onInit
|
||||
super.onInit();
|
||||
print("onInit()");
|
||||
|
||||
// senderQueryingFingerprintStatus();
|
||||
senderCheckingCardStatus();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ import '../../../../app_settings/app_colors.dart';
|
||||
import '../../../../tools/submitBtn.dart';
|
||||
import '../../../../tools/titleAppBar.dart';
|
||||
import '../../../../translations/trans_lib.dart';
|
||||
import 'otherTypeKeyList_logic.dart';
|
||||
|
||||
class OtherTypeKeyListPage extends StatefulWidget {
|
||||
const OtherTypeKeyListPage({Key? key}) : super(key: key);
|
||||
@ -16,6 +17,9 @@ class OtherTypeKeyListPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _OtherTypeKeyListPageState extends State<OtherTypeKeyListPage> {
|
||||
final logic = Get.put(OtherTypeKeyListLogic());
|
||||
final state = Get.find<OtherTypeKeyListLogic>().state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var type = ModalRoute.of(context)?.settings.arguments as int;
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
class OtherTypeKeyListState{
|
||||
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
|
||||
import 'package:date_format/date_format.dart';
|
||||
|
||||
class DateTool {
|
||||
|
||||
String getNowDateYMDHM(){
|
||||
@ -21,4 +23,13 @@ class DateTool {
|
||||
// print("组合 $year-$month-$day $hour:$minute:$millisecond");
|
||||
return "$year.$month.$day $hour:$minute";
|
||||
}
|
||||
|
||||
String dateToString(String timeDate){
|
||||
int time = int.parse(timeDate);
|
||||
DateTime nowDate = DateTime.fromMillisecondsSinceEpoch(time);
|
||||
|
||||
String appointmentDate = formatDate(nowDate, [yyyy,'.',mm,'.',dd,' ',HH,':',nn]);
|
||||
|
||||
return appointmentDate;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user