app-starlock/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart

418 lines
15 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:star_lock/apm/apm_helper.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/date_time_extensions.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_state.dart';
import 'package:star_lock/main/lockDetail/lockOperatingRecord/lockOperatingRecordGetLastRecordTime_entity.dart';
import 'package:star_lock/tools/commonDataManage.dart';
import 'package:star_lock/tools/dateTool.dart';
import 'package:star_lock/tools/eventBusEventManage.dart';
import '../../../blue/blue_manage.dart';
import '../../../blue/io_protocol/io_referEventRecordTime.dart';
import '../../../blue/io_reply.dart';
import '../../../blue/io_tool/io_tool.dart';
import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart';
import '../../../network/api_repository.dart';
import '../../../tools/baseGetXController.dart';
import '../../../tools/bugly/bugly_tool.dart';
import '../../../tools/storage.dart';
import '../lockOperatingRecord/keyOperationRecord_entity.dart';
class DoorLockLogLogic extends BaseGetXController {
final DoorLockLogState state = DoorLockLogState();
// 获取解析后的数据
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
if (reply is SenderReferEventRecordTimeReply &&
state.ifCurrentScreen.value == true) {
_replyReferEventRecordTime(reply);
}
});
}
// 根据时间查解析数据
Future<void> _replyReferEventRecordTime(Reply reply) async {
BuglyTool.uploadException(
message: '查询锁记录结果,解析数据',
detail: '查询锁记录结果,解析数据:${reply.data}',
eventStr: '查询锁记录事件结果',
upload: true);
state.isLockReceiveResponse = true;
cancelBlueConnetctToastTimer();
final int status = reply.data[2];
switch (status) {
case 0x00:
dismissEasyLoading();
cancelBlueConnetctToastTimer();
//成功
final int dataLength = (reply.data[5] << 8) + reply.data[6];
AppLog.log("dataLength:$dataLength");
// var dataLength = reply.data[5];
if (dataLength > 0) {
reply.data.removeRange(0, 7);
// 把得到的数据按8位分割成数组 然后塞进一个新的数组里面
if (reply.data.length < 17) {
return;
}
final List<List<int>> getList = splitList(reply.data, 17);
// AppLog.log("getList:$getList");
final List uploadList = [];
for (int i = 0; i < getList.length; i++) {
final List<int> indexList = getList[i];
try {
// AppLog.log("indexList:$indexList");
final Map indexMap = {};
indexMap['type'] = indexList[0].toString();
final int userNo = (indexList[1] * 256) + indexList[2];
indexMap['user'] = userNo.toString();
// AppLog.log('userNouserNouserNouserNo:$userNo');
final List<int> passwordData = indexList.sublist(7, 17);
final String password = utf8String(passwordData);
indexMap['password'] = password.toString();
// AppLog.log('passwordpasswordpassword:$password');
indexMap['success'] = '1';
final int time = (0xff & indexList[3]) << 24 |
(0xff & indexList[4]) << 16 |
(0xff & indexList[5]) << 8 |
(0xFF & indexList[6]);
final int operateDate = time * 1000;
final int serverTime = state.currentDate;
if (DateTime.fromMillisecondsSinceEpoch(operateDate).isAfter(
DateTime.fromMillisecondsSinceEpoch(serverTime * 1000))) {
// AppLog.log('operateDate:$operateDate state.currentDate:${state.currentDate}');
continue;
}
indexMap['date'] = '$operateDate';
uploadList.add(indexMap);
} catch (e) {
AppLog.log('操作记录:$indexList,解析失败,跳过该跳记录,进行下一条记录解析。');
}
}
if (dataLength == state.logCountPage) {
state.ifHaveNext = true;
} else {
state.ifHaveNext = false;
}
lockRecordUploadData(uploadList);
} else {
showToast('暂无最新记录'.tr);
}
break;
case 0x06:
//无权限 需要鉴权
break;
default:
//失败
dismissEasyLoading();
cancelBlueConnetctToastTimer();
break;
}
}
// 查询事件记录(时间查询)
Future<void> senderReferEventRecordTime() async {
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final List<String>? token = await Storage.getStringList(saveBlueToken);
final List<int> getTokenList = changeStringListToIntList(token!);
final List<String>? publicKey =
await Storage.getStringList(saveBluePublicKey);
final List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
final String command = SenderReferEventRecordTimeCommand(
keyID: BlueManage().connectDeviceName,
userID: await Storage.getUid(),
logsCount: state.logCountPage,
// time:DateTime.now().millisecondsSinceEpoch~/1000,
time: state.operateDate,
currentDate: state.currentDate,
token: getTokenList,
needAuthor: 1,
publicKey: getPublicKeyList,
privateKey: getPrivateKeyList,
).toString();
showEasyLoading();
showBlueConnetctToastTimer(action: () async {
dismissEasyLoading();
final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('check_doorLockLog', {
'lockName': state.keyInfos.value.lockName!,
'account':
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1),
'open_lock_result': '超时',
});
BuglyTool.uploadException(
message: '查询锁记录超时-查询锁记录失败',
detail: '添加密码超时,查询锁记录失败--senderReferEventRecordTimeCommand:$command',
eventStr: '查询锁记录事件超时',
upload: true);
});
BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionStateState) async {
if (connectionStateState == BluetoothConnectionState.connected) {
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
final List<String>? token = await Storage.getStringList(saveBlueToken);
final List<int> getTokenList = changeStringListToIntList(token!);
final List<String>? publicKey =
await Storage.getStringList(saveBluePublicKey);
final List<int> getPublicKeyList =
changeStringListToIntList(publicKey!);
IoSenderManage.senderReferEventRecordTimeCommand(
keyID: BlueManage().connectDeviceName,
userID: await Storage.getUid(),
logsCount: state.logCountPage,
// time:DateTime.now().millisecondsSinceEpoch~/1000,
time: state.operateDate,
currentDate: state.currentDate,
token: getTokenList,
needAuthor: 1,
publicKey: getPublicKeyList,
privateKey: getPrivateKeyList,
);
} else if (connectionStateState ==
BluetoothConnectionState.disconnected) {
if (state.ifCurrentScreen.value == true) {
showBlueConnetctToast();
}
cancelBlueConnetctToastTimer();
final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('check_doorLockLog', {
'lockName': state.keyInfos.value.lockName!,
'account':
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1),
'open_lock_result': '断开连接',
});
BuglyTool.uploadException(
message: '查询锁记录超时-查询锁记录失败',
detail:
'添加密码超时,查询锁记录失败--senderReferEventRecordTimeCommand:$command',
eventStr: '查询锁记录事件断开连接',
upload: true);
}
});
}
//请求操作记录列表(门锁日志)
Future<void> mockNetworkDataRequest({required bool isRefresh}) async {
// 如果是下拉刷新,清空已有数据
if (isRefresh) {
state.lockLogItemList.clear();
pageNo = 1;
}
final DoorLockLogEntity entity = await ApiRepository.to.lockEventList(
lockId: state.keyInfos.value.lockId!,
lockEventType: state.dropdownValue.value,
pageNo: pageNo,
pageSize: 1000,
startDate: state.startDate.value,
endDate: state.endDate.value);
if (entity.errorCode!.codeIsSuccessful) {
// 更新数据列表
state.lockLogItemList.addAll(entity.data!.itemList!);
state.lockLogItemList.refresh();
state.weekEventList.addAll(entity.data!.itemList!);
state.weekEventList.refresh();
// 更新页码
pageNo++;
}
}
/// 刷新门锁日志列表
StreamSubscription? _getDoorLockLogListRefreshUIEvent;
void _getDoorLockLogListRefreshUIAction() {
_getDoorLockLogListRefreshUIEvent = eventBus
.on<DoorLockLogListRefreshUI>()
.listen((DoorLockLogListRefreshUI event) {
state.currentSelectDate.value = event.getDoorLockLogTime;
// 设置startDate为当天的0点
state.startDate.value = DateTime(
state.currentSelectDate.value.year,
state.currentSelectDate.value.month,
state.currentSelectDate.value.day)
.millisecondsSinceEpoch;
// 设置endDate为下一天的0点然后减去1毫秒
state.endDate.value = DateTime(
state.currentSelectDate.value.year,
state.currentSelectDate.value.month,
state.currentSelectDate.value.day + 1)
.subtract(const Duration(milliseconds: 1))
.millisecondsSinceEpoch;
pageNo = 1;
mockNetworkDataRequest(isRefresh: true);
});
}
// 查询锁记录最后时间
Future<void> getLockRecordLastUploadDataTime() async {
final LockOperatingRecordGetLastRecordTimeEntity entity =
await ApiRepository.to.getLockRecordLastUploadDataTime(
lockId: state.keyInfos.value.lockId.toString());
if (entity.errorCode!.codeIsSuccessful) {
state.operateDate = entity.data!.operateDate! ~/ 1000;
state.currentDate = entity.data!.currentDate! ~/ 1000;
// AppLog.log('entity.data!.currentDate!:${entity.data!.currentDate!} currentDate:${state.currentDate}');
senderReferEventRecordTime();
}
}
// 操作记录上传
Future<void> lockRecordUploadData(List list) async {
// AppLog.log('上传数据:$list');
// 无数据时不上传
if (list.isEmpty) {
return;
}
final KeyOperationRecordEntity entity = await ApiRepository.to
.lockRecordUploadData(
lockId: state.keyInfos.value.lockId.toString(), records: list);
final String getMobile = (await Storage.getMobile())!;
if (entity.errorCode!.codeIsSuccessful) {
showToast('操作成功'.tr, something: () async {
dismissEasyLoading();
if (state.ifHaveNext == true) {
showEasyLoading();
getLockRecordLastUploadDataTime();
} else {
ApmHelper.instance.trackEvent('check_doorLockLog', {
'lockName': state.keyInfos.value.lockName!,
'account':
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1),
'open_lock_result': '成功',
});
mockNetworkDataRequest(isRefresh: true);
}
});
} else {
ApmHelper.instance.trackEvent('check_doorLockLog', {
'lockName': state.keyInfos.value.lockName!,
'account':
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1),
'open_lock_result': '上传数据接口失败',
});
dismissEasyLoading();
}
}
//清空操作记录
Future<void> clearOperationRecordRequest() async {
final KeyOperationRecordEntity entity = await ApiRepository.to
.clearOperationRecord(
CommonDataManage().currentKeyInfo.lockId.toString());
if (entity.errorCode!.codeIsSuccessful) {
showToast('清除数据成功'.tr, something: () {
pageNo = 1;
mockNetworkDataRequest(isRefresh: true);
});
}
}
@override
Future<void> onReady() async {
super.onReady();
// 获取是否是演示模式 演示模式不获取接口
final bool? isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) {
// _initReplySubscription();
// mockNetworkDataRequest(isRefresh: true);
_getDoorLockLogListRefreshUIAction();
}
}
@override
Future<void> onInit() async {
_setWeekRange();
super.onInit();
// 获取是否是演示模式 演示模式不获取接口
final bool? isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) {
mockNetworkDataRequest(isRefresh: true);
// getLockRecordLastUploadDataTime();
_initReplySubscription();
}
}
void _setWeekRange() {
final now = DateTime.now();
// 计算当前日期是星期几1=周一7=周日)
int weekday = now.weekday; // 1-7
// 计算距离本周一有多少天(向后推)
// 周一: 0天, 周二: 1天, ..., 周日: 6天
int daysToSubtract = weekday - 1; // 减去1因为周一就是基准
// 当前周的周一 00:00:00.000
DateTime startOfWeek = DateTime(now.year, now.month, now.day)
.subtract(Duration(days: daysToSubtract));
// 当前周的周日 23:59:59.999
DateTime endOfWeek = startOfWeek
.add(Duration(days: 6)) // 加6天到周日
.add(Duration(hours: 23, minutes: 59, seconds: 59, milliseconds: 999));
// 更新响应式变量
state.startDate.value = startOfWeek.millisecondsSinceEpoch;
state.endDate.value = endOfWeek.millisecondsSinceEpoch;
}
// 可选:提供一个方法来刷新周范围(比如切换周)
void refreshWeek() {
_setWeekRange();
}
@override
Future<void> onClose() async {
super.onClose();
//获取是否是演示模式 演示模式不获取接口
final bool? isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) {
_replySubscription.cancel();
_getDoorLockLogListRefreshUIEvent?.cancel();
}
}
}