Merge branch 'develop_liyi' into 'develop'

Develop liyi

See merge request StarlockTeam/app-starlock!21
This commit is contained in:
李仪 2025-04-18 05:49:51 +00:00
commit 88b66be9a1
35 changed files with 764 additions and 697 deletions

View File

@ -1,86 +1,87 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>play</title> <title>play</title>
</head> </head>
<style> <style>
html { html {
margin: 0; margin: 0;
padding: 0; padding: 0;
overflow: hidden; /* 防止滚动条出现 */ overflow: hidden;
/* 防止滚动条出现 */
} }
body { body {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
margin: 0; margin: 0;
padding: 0; padding: 0;
background-color: white; background-color: white;
overflow: hidden; /* 防止滚动条出现 */ overflow: hidden;
/* 防止滚动条出现 */
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
#player { #player {
object-fit:cover; object-fit: cover;
height: 56vh; height: 56vh;
transform: rotate(-90deg); transform: rotate(-90deg);
} }
</style> </style>
<body> <body>
<video autoplay muted poster="images/loader-thumb.jpg" <video autoplay muted poster="images/loader-thumb.jpg" id="player">
id="player"> </video>
</video> <script src="jmuxer.min.js"></script>
<script src="jmuxer.min.js"></script> <script>
<script>
if (typeof JMuxer === 'undefined') { if (typeof JMuxer === 'undefined') {
console.error("JMuxer is not defined. Check if jmuxer.min.js is loaded correctly."); console.error("JMuxer is not defined. Check if jmuxer.min.js is loaded correctly.");
} else { } else {
console.log("JMuxer loaded successfully."); console.log("JMuxer loaded successfully.");
}
let jmuxer;
window.onload = function() {
try {
jmuxer = new JMuxer({
node: 'player',
mode: 'video',
debug: false,
webgl: true, // 启用WebGL加速
webglOptions: {
preserveDrawingBuffer: false,
antialias: false
},
flushingTime: 0, // 禁用自动刷新
clearBuffer: false, // 保留解码缓存
fps:20,
onReady: () => {
console.log('播放器初始化完成');
// 通知Flutter端准备就绪
window.Flutter.postMessage('ready');
}
});
jmuxer.reset();
console.log("JMuxer initialized.");
} catch (e) {
console.error("Error initializing JMuxer:", e);
} }
}; let jmuxer;
window.onload = function () {
try {
jmuxer = new JMuxer({
node: 'player',
// Feed data from Flutter mode: 'video',
function feedDataFromFlutter(data) { debug: false,
const buffer = new Uint8Array(data); readfpsfromtrack: true,
jmuxer.feed({ flushingTime: 0, // 立即刷新
video: buffer, clearBuffer: true, // 丢弃延迟帧
fps: 25, // 强制指定帧率
onReady: () => {
console.log('播放器初始化完成');
// 通知Flutter端准备就绪
window.Flutter.postMessage('ready');
},
onMissingVideoFrames: (missingFrames) => {
// console.log('Missing video frames:', missingFrames);
},
}); });
} } catch (e) {
console.error("Error initializing JMuxer:", e);
}
};
// Feed data from Flutter
function feedDataFromFlutter(data) {
const buffer = new Uint8Array(data);
jmuxer.feed({
video: buffer,
duration: 40 // 每帧持续时间40ms25fps
});
}
// Optional: notify Flutter // Optional: notify Flutter
@ -92,11 +93,27 @@
} }
} }
// Function to return to Flutter page // Function to return to Flutter page
function returnToFlutter() { function returnToFlutter() {
notifyFlutter("Returning to Flutter page"); notifyFlutter("Returning to Flutter page");
} }
</script>
// 添加清理方法
function cleanupJMuxer() {
if (jmuxer) {
try {
jmuxer.destroy();
jmuxer = null;
console.log('JMuxer cleaned up successfully');
window.Flutter.postMessage('cleanup_complete');
} catch (e) {
console.error('Error cleaning up JMuxer:', e);
window.Flutter.postMessage('cleanup_error');
}
}
}
</script>
</body> </body>
</html> </html>

View File

@ -173,9 +173,9 @@
"接收人信息": "收件人", "接收人信息": "收件人",
"转移网关": "傳輸網關", "转移网关": "傳輸網關",
"锁屏": "屏幕鎖定", "锁屏": "屏幕鎖定",
"已关闭": "關閉", "已关闭": "關閉",
"已开启": "", "已开启": "已開啟",
"开启": "開", "开启": "開",
"确定要开启重置键?": "繼續啟用Reset掣", "确定要开启重置键?": "繼續啟用Reset掣",
"确定要关闭重置键?": "繼續禁用Reset掣", "确定要关闭重置键?": "繼續禁用Reset掣",
"隐藏无效开锁权限": "隱藏無效訪問權限", "隐藏无效开锁权限": "隱藏無效訪問權限",

View File

@ -172,9 +172,9 @@
"接收人信息": "收件人", "接收人信息": "收件人",
"转移网关": "傳輸網關", "转移网关": "傳輸網關",
"锁屏": "屏幕鎖定", "锁屏": "屏幕鎖定",
"已关闭": "關", "已关闭": "",
"已开启": "開啟", "已开启": "開啟",
"开启": "開", "开启": "",
"确定要开启重置键?": "是否繼續啟用重置按鈕?", "确定要开启重置键?": "是否繼續啟用重置按鈕?",
"确定要关闭重置键?": "是否繼續禁用重置按鈕?", "确定要关闭重置键?": "是否繼續禁用重置按鈕?",
"隐藏无效开锁权限": "隱藏無效訪問", "隐藏无效开锁权限": "隱藏無效訪問",

View File

@ -1,19 +1,21 @@
import 'dart:io'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/apm/apm_helper.dart'; import 'package:star_lock/apm/apm_helper.dart';
import 'package:jverify/jverify.dart';
import 'package:star_lock/appRouters.dart'; import 'package:star_lock/appRouters.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/blue_manage.dart';
import 'package:star_lock/blue/io_tool/manager_event_bus.dart';
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart'; import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import 'package:star_lock/login/login/entity/LoginEntity.dart'; import 'package:star_lock/login/login/entity/LoginEntity.dart';
import 'package:star_lock/mine/mine/starLockMine_state.dart'; import 'package:star_lock/mine/mine/starLockMine_state.dart';
import 'package:star_lock/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_entity.dart'; import 'package:star_lock/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_entity.dart';
import 'package:star_lock/network/start_chart_api.dart'; import 'package:star_lock/network/start_chart_api.dart';
import 'package:star_lock/talk/starChart/entity/star_chart_register_node_entity.dart'; import 'package:star_lock/talk/starChart/entity/star_chart_register_node_entity.dart';
import 'package:star_lock/tools/appFirstEnterHandle.dart';
import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/translations/current_locale_tool.dart';
import '../../main/lockMian/lockMain/lockMain_logic.dart'; import '../../main/lockMian/lockMain/lockMain_logic.dart';
import '../../mine/mine/starLockMine_logic.dart'; import '../../mine/mine/starLockMine_logic.dart';
@ -143,7 +145,7 @@ class StarLockLoginLogic extends BaseGetXController {
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
if (state.countryName != entity.data!.name) { if (state.countryName != entity.data!.name) {
ShowTipView().showSureAlertDialog( ShowTipView().showSureAlertDialog(
'国家地区的选择将影响数据安全,你当前选择的是'+state.countryName+'请确认后再继续'.tr, '国家地区的选择将影响数据安全,你当前选择的是' + state.countryName + '请确认后再继续'.tr,
tipTitle: '确认国家或地区'.tr, tipTitle: '确认国家或地区'.tr,
sureStr: '我知道了'.tr); sureStr: '我知道了'.tr);
} }
@ -175,20 +177,43 @@ class StarLockLoginLogic extends BaseGetXController {
state.canNext.value = state.pwdIsOK && state.isEmailOrPhone; state.canNext.value = state.pwdIsOK && state.isEmailOrPhone;
} }
late StreamSubscription _agreePrivacySubscription;
void _initEventListen() {
_agreePrivacySubscription = eventBus
.on<AgreePrivacyAgreement>()
.listen((AgreePrivacyAgreement event) async {
/// ip如果属于国内才进行初始化
final CheckIPEntity entity = await ApiRepository.to.checkIpAction(ip: '');
String currentLanguage =
CurrentLocaleTool.getCurrentLocaleString(); //
// ip是国内的且选的是中文才初始化一键登录
if (entity.data!.abbreviation?.toLowerCase() == 'cn' &&
currentLanguage == 'zh_CN') {
//
await JverifyOneClickLoginManage();
state.isCheckVerifyEnable.value =
await JverifyOneClickLoginManage().checkVerifyEnable();
AppLog.log('一键登录初始化认证结果:${state.isCheckVerifyEnable.value}');
}
});
}
@override @override
Future<void> onInit() async { Future<void> onInit() async {
_initEventListen();
super.onInit(); super.onInit();
} }
@override @override
void onClose() { void onClose() {
//
_agreePrivacySubscription.cancel();
state.onClose(); state.onClose();
super.onClose(); super.onClose();
} }
// //
Future<void> flushedDeviceInfo() async { Future<void> flushedDeviceInfo() async {
XSConstantMacro().getDeviceInfoData().then((Map<String, dynamic> data) { XSConstantMacro().getDeviceInfoData().then((Map<String, dynamic> data) {
state.deviceInfoMap.value = data; state.deviceInfoMap.value = data;

View File

@ -10,19 +10,23 @@ import 'package:path/path.dart' as path;
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:star_lock/flavors.dart'; import 'package:star_lock/flavors.dart';
import 'package:star_lock/login/login/starLock_login_logic.dart'; import 'package:star_lock/login/login/starLock_login_logic.dart';
import 'package:star_lock/login/register/entity/checkIP_entity.dart';
import 'package:star_lock/mine/about/debug/debug_tool.dart'; import 'package:star_lock/mine/about/debug/debug_tool.dart';
import 'package:star_lock/network/api_provider.dart'; import 'package:star_lock/network/api_provider.dart';
import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/network/start_chart_api.dart'; import 'package:star_lock/network/start_chart_api.dart';
import 'package:star_lock/talk/starChart/handle/impl/debug_Info_model.dart'; import 'package:star_lock/talk/starChart/handle/impl/debug_Info_model.dart';
import 'package:star_lock/talk/starChart/status/appLifecycle_observer.dart'; import 'package:star_lock/talk/starChart/status/appLifecycle_observer.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/bugly/bugly_tool.dart'; import 'package:star_lock/tools/bugly/bugly_tool.dart';
import 'package:star_lock/tools/device_info_service.dart'; import 'package:star_lock/tools/device_info_service.dart';
import 'package:star_lock/tools/eventBusEventManage.dart';
import 'package:star_lock/tools/jverify_one_click_login.dart'; import 'package:star_lock/tools/jverify_one_click_login.dart';
import 'package:star_lock/tools/platform_info_services.dart'; import 'package:star_lock/tools/platform_info_services.dart';
import 'package:star_lock/tools/push/notification_service.dart'; import 'package:star_lock/tools/push/notification_service.dart';
import 'package:star_lock/tools/push/xs_jPhush.dart'; import 'package:star_lock/tools/push/xs_jPhush.dart';
import 'package:star_lock/tools/storage.dart'; import 'package:star_lock/tools/storage.dart';
import 'package:star_lock/translations/current_locale_tool.dart';
import 'package:star_lock/translations/trans_lib.dart'; import 'package:star_lock/translations/trans_lib.dart';
import 'apm/apm_helper.dart'; import 'apm/apm_helper.dart';
@ -102,10 +106,20 @@ Future<void> privacySDKInitialization() async {
await jpushProvider.initJPushService(); await jpushProvider.initJPushService();
NotificationService().init(); // NotificationService().init(); //
// /// ip如果属于国内才进行初始化
final StarLockLoginLogic loginLogic = Get.put(StarLockLoginLogic()); final CheckIPEntity entity = await ApiRepository.to.checkIpAction(ip: '');
JverifyOneClickLoginManage(); if (entity.errorCode!.codeIsSuccessful) {
loginLogic.oneClickLoginAction(); String currentLanguage =
loginLogic.state.isCheckVerifyEnable.value = CurrentLocaleTool.getCurrentLocaleString(); //
await JverifyOneClickLoginManage().checkVerifyEnable(); // ip是国内的且选的是中文才初始化一键登录
if (entity.data!.abbreviation?.toLowerCase() == 'cn' &&
currentLanguage == 'zh_CN') {
//
final StarLockLoginLogic loginLogic = Get.put(StarLockLoginLogic());
await JverifyOneClickLoginManage();
loginLogic.state.isCheckVerifyEnable.value =
await JverifyOneClickLoginManage().checkVerifyEnable();
eventBus.fire(AgreePrivacyAgreement());
}
}
} }

View File

@ -80,7 +80,7 @@ class AddICCardLogic extends BaseGetXController {
final List<int> token = reply.data.sublist(5, 9); final List<int> token = reply.data.sublist(5, 9);
final List<String> saveStrList = changeIntListToStringList(token); final List<String> saveStrList = changeIntListToStringList(token);
Storage.setStringList(saveBlueToken, saveStrList); Storage.setStringList(saveBlueToken, saveStrList);
// AppLog.log('添加卡token:$token'); AppLog.log('添加卡token:$token');
IoSenderManage.senderAddCardWithTimeCycleCoercionCommand( IoSenderManage.senderAddCardWithTimeCycleCoercionCommand(
keyID: '1', keyID: '1',
@ -107,6 +107,14 @@ class AddICCardLogic extends BaseGetXController {
token: token, token: token,
isBeforeAddUser: false); isBeforeAddUser: false);
break; break;
case 0xFE:
case 12:
//
state.ifAddState.value = false;
showToast('管理员已满'.tr, something: () {
Get.back();
});
break;
default: default:
// //
state.ifAddState.value = false; state.ifAddState.value = false;
@ -146,6 +154,7 @@ class AddICCardLogic extends BaseGetXController {
Get.close(1); Get.close(1);
break; break;
case 0xFE: case 0xFE:
case 0x12:
// //
showToast('管理员已满'.tr); showToast('管理员已满'.tr);
Get.close(1); Get.close(1);

View File

@ -28,6 +28,7 @@ class CardListLogic extends BaseGetXController {
// //
late StreamSubscription<Reply> _replySubscription; late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() { void _initReplySubscription() {
_replySubscription = _replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) { EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
@ -69,11 +70,15 @@ class CardListLogic extends BaseGetXController {
userID: (await Storage.getUid())!, userID: (await Storage.getUid())!,
cardNo: state.deletCardNo, cardNo: state.deletCardNo,
useCountLimit: 0xffff, useCountLimit: 0xffff,
operate: state.isDeletAll == true ? 3 : 2, // 0: 1 2: 3 operate: state.isDeletAll == true ? 3 : 2,
// 0: 1 2: 3
isAdmin: 0, isAdmin: 0,
isForce: 0, // isForce: 0,
isRound: 0, // //
weekRound: 0, // isRound: 0,
//
weekRound: 0,
//
startDate: 0x11223344, startDate: 0x11223344,
endDate: 0x11223344, endDate: 0x11223344,
startTime: '0', startTime: '0',
@ -116,11 +121,15 @@ class CardListLogic extends BaseGetXController {
userID: (await Storage.getUid())!, userID: (await Storage.getUid())!,
cardNo: state.deletCardNo, cardNo: state.deletCardNo,
useCountLimit: 0xffff, useCountLimit: 0xffff,
operate: state.isDeletAll == true ? 3 : 2, // 0: 1 2: 3 operate: state.isDeletAll == true ? 3 : 2,
// 0: 1 2: 3
isAdmin: 0, isAdmin: 0,
isForce: 0, // isForce: 0,
isRound: 0, // //
weekRound: 0, // isRound: 0,
//
weekRound: 0,
//
startDate: 0x11223344, startDate: 0x11223344,
endDate: 0x11223344, endDate: 0x11223344,
startTime: '0', startTime: '0',
@ -193,6 +202,7 @@ class CardListLogic extends BaseGetXController {
// //
late StreamSubscription _teamEvent; late StreamSubscription _teamEvent;
void _initRefreshAction() { void _initRefreshAction() {
_teamEvent = eventBus _teamEvent = eventBus
.on<OtherTypeRefreshListEvent>() .on<OtherTypeRefreshListEvent>()
@ -240,6 +250,7 @@ class CardListLogic extends BaseGetXController {
_initRefreshAction(); _initRefreshAction();
} }
await getICCardListData(isRefresh: true);
} }
@override @override

View File

@ -31,24 +31,24 @@ class _CardListPageState extends State<CardListPage> with RouteAware {
final CardListLogic logic = Get.put(CardListLogic()); final CardListLogic logic = Get.put(CardListLogic());
final CardListState state = Get.find<CardListLogic>().state; final CardListState state = Get.find<CardListLogic>().state;
Future<void> getHttpData({required bool isRefresh}) async { // Future<void> logic.getICCardListData({required bool isRefresh}) async {
final bool? isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); // final bool? isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) { // if (isDemoMode == false) {
logic // logic
.getICCardListData(isRefresh: isRefresh) // .getICCardListData(isRefresh: isRefresh)
.then((FingerprintListDataEntity value) { // .then((FingerprintListDataEntity value) {
if (mounted) { // if (mounted) {
setState(() {}); // setState(() {});
} // }
}); // });
} // }
} // }
@override @override
void initState() { void initState() {
super.initState(); super.initState();
getHttpData(isRefresh: true); // logic.getICCardListData(isRefresh: true);
} }
@override @override
@ -92,17 +92,17 @@ class _CardListPageState extends State<CardListPage> with RouteAware {
), ),
body: EasyRefreshTool( body: EasyRefreshTool(
onRefresh: () { onRefresh: () {
getHttpData(isRefresh: true); logic.getICCardListData(isRefresh: true);
}, },
onLoad: () { onLoad: () {
getHttpData(isRefresh: false); logic.getICCardListData(isRefresh: false);
}, },
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
KeySearchWidget( KeySearchWidget(
editingController: state.searchController, editingController: state.searchController,
onSubmittedAction: () { onSubmittedAction: () {
getHttpData(isRefresh: true); logic.getICCardListData(isRefresh: true);
}, },
), ),
SizedBox(height: 20.h), SizedBox(height: 20.h),
@ -115,10 +115,10 @@ class _CardListPageState extends State<CardListPage> with RouteAware {
'fromType': 1 // 1 2 'fromType': 1 // 1 2
})! })!
.then((value) { .then((value) {
getHttpData(isRefresh: true); logic.getICCardListData(isRefresh: true);
}); });
// if (data != null) { // if (data != null) {
// getHttpData(isRefresh: true); // logic.getICCardListData(isRefresh: true);
// } // }
}, },
), ),
@ -180,9 +180,9 @@ class _CardListPageState extends State<CardListPage> with RouteAware {
arguments: <String, FingerprintItemData>{ arguments: <String, FingerprintItemData>{
'fingerprintItemData': fingerprintItemData, 'fingerprintItemData': fingerprintItemData,
})! })!
.then((value) => getHttpData(isRefresh: true)); .then((value) => logic.getICCardListData(isRefresh: true));
// if (data != null) { // if (data != null) {
// getHttpData(isRefresh: true); // logic.getICCardListData(isRefresh: true);
// } // }
}), }),
); );

View File

@ -54,7 +54,7 @@ class AddFaceLogic extends BaseGetXController {
// //
state.maxRegCount.value = reply.data[11]; state.maxRegCount.value = reply.data[11];
// AppLog.log('人脸开始state.maxRegCount.value:${state.maxRegCount.value}'); AppLog.log('人脸开始state.maxRegCount.value:${state.maxRegCount.value}');
break; break;
case 0x06: case 0x06:
// //
@ -89,6 +89,12 @@ class AddFaceLogic extends BaseGetXController {
isBeforeAddUser: false isBeforeAddUser: false
); );
break; break;
case 0xFE:
case 12:
//
showToast('管理员已满'.tr);
Get.close(1);
break;
default: default:
// //
state.ifAddState.value = false; state.ifAddState.value = false;
@ -112,9 +118,9 @@ class AddFaceLogic extends BaseGetXController {
Get.close(1); Get.close(1);
break; break;
case 0xFE: case 0xFE:
case 12:
// //
showToast('管理员已满'.tr); showToast('管理员已满'.tr);
state.ifAddState.value = false;
Get.close(1); Get.close(1);
break; break;
case 0xFD: case 0xFD:
@ -138,7 +144,7 @@ class AddFaceLogic extends BaseGetXController {
// //
// //
state.regIndex.value = reply.data[6]; state.regIndex.value = reply.data[6];
// AppLog.log('注册人脸过程state.regIndex.value:${state.regIndex.value}'); AppLog.log('注册人脸过程state.regIndex.value:${state.regIndex.value}');
break; break;
} }

View File

@ -22,6 +22,7 @@ class FaceListLogic extends BaseGetXController {
// //
late StreamSubscription<Reply> _replySubscription; late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() { void _initReplySubscription() {
_replySubscription = _replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) { EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
@ -77,11 +78,15 @@ class FaceListLogic extends BaseGetXController {
userID: (await Storage.getUid())!, userID: (await Storage.getUid())!,
faceNo: state.deletFaceNo, faceNo: state.deletFaceNo,
useCountLimit: 0xffff, useCountLimit: 0xffff,
operate: state.isDeletAll == true ? 3 : 2, // 0: 1 2: 3 operate: state.isDeletAll == true ? 3 : 2,
// 0: 1 2: 3
isAdmin: 0, isAdmin: 0,
isForce: 0, // isForce: 0,
isRound: 0, // //
weekRound: 0, // isRound: 0,
//
weekRound: 0,
//
startDate: 0x11223344, startDate: 0x11223344,
endDate: 0x11223344, endDate: 0x11223344,
startTime: '0', startTime: '0',
@ -277,11 +282,15 @@ class FaceListLogic extends BaseGetXController {
userID: (await Storage.getUid())!, userID: (await Storage.getUid())!,
faceNo: state.deletFaceNo, faceNo: state.deletFaceNo,
useCountLimit: 0xffff, useCountLimit: 0xffff,
operate: state.isDeletAll == true ? 3 : 2, // 0: 1 2: 3 operate: state.isDeletAll == true ? 3 : 2,
// 0: 1 2: 3
isAdmin: 0, isAdmin: 0,
isForce: 0, // isForce: 0,
isRound: 0, // //
weekRound: 0, // isRound: 0,
//
weekRound: 0,
//
startDate: 0x11223344, startDate: 0x11223344,
endDate: 0x11223344, endDate: 0x11223344,
startTime: '0', startTime: '0',
@ -348,8 +357,8 @@ class FaceListLogic extends BaseGetXController {
lockId: state.lockId.value, lockId: state.lockId.value,
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
showToast('删除成功'.tr, something: () { showToast('删除成功'.tr, something: () async {
getFaceListData(isRefresh: true); await getFaceListData(isRefresh: true);
}); });
} }
} }
@ -366,8 +375,8 @@ class FaceListLogic extends BaseGetXController {
lockId: state.lockId.value, lockId: state.lockId.value,
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
showToast('重置成功'.tr, something: () { showToast('重置成功'.tr, something: () async{
getFaceListData(isRefresh: true); await getFaceListData(isRefresh: true);
}); });
} }
} }
@ -403,11 +412,12 @@ class FaceListLogic extends BaseGetXController {
// //
late StreamSubscription _teamEvent; late StreamSubscription _teamEvent;
void _initRefreshAction() { void _initRefreshAction() {
_teamEvent = eventBus _teamEvent = eventBus
.on<OtherTypeRefreshListEvent>() .on<OtherTypeRefreshListEvent>()
.listen((OtherTypeRefreshListEvent event) { .listen((OtherTypeRefreshListEvent event) async {
getFaceListData(isRefresh: true); await getFaceListData(isRefresh: true);
}); });
} }
@ -434,6 +444,7 @@ class FaceListLogic extends BaseGetXController {
// senderCheckingUserInfoCount(); // senderCheckingUserInfoCount();
} }
getFaceListData(isRefresh: true);
} }
@override @override

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -31,24 +30,6 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
final FaceListLogic logic = Get.put(FaceListLogic()); final FaceListLogic logic = Get.put(FaceListLogic());
final FaceListState state = Get.find<FaceListLogic>().state; final FaceListState state = Get.find<FaceListLogic>().state;
Future<void> getHttpData({required bool isRefresh}) async {
final bool? isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) {
logic.getFaceListData(isRefresh: isRefresh).then((FingerprintListDataEntity value) {
if (mounted) {
setState(() {});
}
});
}
}
@override
void initState() {
super.initState();
getHttpData(isRefresh: true);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -92,17 +73,17 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
), ),
body: EasyRefreshTool( body: EasyRefreshTool(
onRefresh: () { onRefresh: () {
getHttpData(isRefresh: true); logic.getFaceListData(isRefresh: true);
}, },
onLoad: () { onLoad: () {
getHttpData(isRefresh: false); logic.getFaceListData(isRefresh: false);
}, },
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
KeySearchWidget( KeySearchWidget(
editingController: state.searchController, editingController: state.searchController,
onSubmittedAction: () { onSubmittedAction: () {
getHttpData(isRefresh: true); logic.getFaceListData(isRefresh: true);
}, },
), ),
SizedBox( SizedBox(
@ -110,14 +91,15 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
), ),
Expanded(child: _buildMainUI()), Expanded(child: _buildMainUI()),
AddBottomWhiteBtn( AddBottomWhiteBtn(
btnName: btnName: '添加人脸'.tr,
'添加人脸'.tr,
onClick: () async { onClick: () async {
await Get.toNamed(Routers.addFaceTypePage, arguments: <String, int>{ await Get.toNamed(Routers.addFaceTypePage,
arguments: <String, int>{
'lockId': state.lockId.value, 'lockId': state.lockId.value,
'fromType': 1 // 1 2 'fromType': 1 // 1 2
})!.then((value) { })!
getHttpData(isRefresh: true); .then((value) {
logic.getFaceListData(isRefresh: true);
}); });
}, },
), ),
@ -154,9 +136,11 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
logic.getKeyType(getFaceItemData), logic.getKeyType(getFaceItemData),
logic.getKeyDateType(getFaceItemData), () async { logic.getKeyDateType(getFaceItemData), () async {
await Get.toNamed(Routers.faceDetailPage, await Get.toNamed(Routers.faceDetailPage,
arguments: <String, FingerprintItemData>{ arguments: <String, FingerprintItemData>{
'faceItemData': getFaceItemData, 'faceItemData': getFaceItemData,
})!.then((value) => getHttpData(isRefresh: true)); })!
.then((value) =>
logic.getFaceListData(isRefresh: true));
}), }),
); );
} }

View File

@ -105,6 +105,14 @@ class AddFingerprintLogic extends BaseGetXController {
token: token, token: token,
isBeforeAddUser: false); isBeforeAddUser: false);
break; break;
case 0xFE:
case 12:
//
state.ifAddState.value = false;
showToast('管理员已满'.tr, something: () {
Get.back();
});
break;
default: default:
// //
state.ifAddState.value = false; state.ifAddState.value = false;
@ -132,10 +140,12 @@ class AddFingerprintLogic extends BaseGetXController {
Get.close(1); Get.close(1);
break; break;
case 0xFE: case 0xFE:
// case 12:
showToast('管理员已满'.tr); //
state.ifAddState.value = false; state.ifAddState.value = false;
Get.close(1); showToast('管理员已满'.tr, something: () {
Get.back();
});
break; break;
case 0xFD: case 0xFD:
// //

View File

@ -404,8 +404,8 @@ class FingerprintListLogic extends BaseGetXController {
void _initRefreshAction() { void _initRefreshAction() {
_teamEvent = eventBus _teamEvent = eventBus
.on<OtherTypeRefreshListEvent>() .on<OtherTypeRefreshListEvent>()
.listen((OtherTypeRefreshListEvent event) { .listen((OtherTypeRefreshListEvent event) async {
getFingerprintsListData(isRefresh: true); await getFingerprintsListData(isRefresh: true);
}); });
} }
@ -460,7 +460,7 @@ class FingerprintListLogic extends BaseGetXController {
if (isDemoMode == false) { if (isDemoMode == false) {
_initReplySubscription(); _initReplySubscription();
_initRefreshAction(); // _initRefreshAction();
getFingerprintsListData(isRefresh: true); getFingerprintsListData(isRefresh: true);
} }
} }

View File

@ -7,6 +7,7 @@ import 'package:get/get.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/apm/apm_helper.dart'; import 'package:star_lock/apm/apm_helper.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart'; import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import 'package:star_lock/login/login/entity/LoginEntity.dart'; import 'package:star_lock/login/login/entity/LoginEntity.dart';
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
@ -285,7 +286,7 @@ class LockDetailLogic extends BaseGetXController {
final List<int> publicKeyData = final List<int> publicKeyData =
state.keyInfos.value.bluetooth!.publicKey!.cast<int>(); state.keyInfos.value.bluetooth!.publicKey!.cast<int>();
final List<String> saveStrList = changeIntListToStringList(publicKeyData); final List<String> saveStrList = changeIntListToStringList(publicKeyData);
await Storage.setStringList(saveBluePublicKey, saveStrList); await Storage.setStringList(saveBluePublicKey, saveStrList);
// //
final List<int> privateKeyData = final List<int> privateKeyData =
@ -298,7 +299,7 @@ class LockDetailLogic extends BaseGetXController {
final List<int> signKeyData = final List<int> signKeyData =
state.keyInfos.value.bluetooth!.signKey!.cast<int>(); state.keyInfos.value.bluetooth!.signKey!.cast<int>();
final List<String> saveSignKeyList = changeIntListToStringList(signKeyData); final List<String> saveSignKeyList = changeIntListToStringList(signKeyData);
await Storage.setStringList(saveBlueSignKey, saveSignKeyList); await Storage.setStringList(saveBlueSignKey, saveSignKeyList);
final bool ifHaveKey = await Storage.ifHaveKey(saveBlueToken); final bool ifHaveKey = await Storage.ifHaveKey(saveBlueToken);
if (!ifHaveKey) { if (!ifHaveKey) {
@ -814,7 +815,7 @@ class LockDetailLogic extends BaseGetXController {
} }
}); });
eventBus state.DetailLockInfo = eventBus
.on<PassCurrentLockInformationEvent>() .on<PassCurrentLockInformationEvent>()
.listen((PassCurrentLockInformationEvent event) { .listen((PassCurrentLockInformationEvent event) {
if (event.lockSetInfoData.lockSettingInfo != null && if (event.lockSetInfoData.lockSettingInfo != null &&
@ -838,5 +839,12 @@ class LockDetailLogic extends BaseGetXController {
state.keyInfos.refresh(); state.keyInfos.refresh();
} }
}); });
state.SuccessfulDistributionNetworkEvent = eventBus
.on<SuccessfulDistributionNetwork>()
.listen((SuccessfulDistributionNetwork event) {
//
requestDeviceNetworkInfo();
});
} }
} }

View File

@ -89,7 +89,6 @@ class _LockDetailPageState extends State<LockDetailPage>
AppRouteObserver().routeObserver.subscribe(this, ModalRoute.of(context)!); AppRouteObserver().routeObserver.subscribe(this, ModalRoute.of(context)!);
state.isOpenLockNeedOnline.refresh(); state.isOpenLockNeedOnline.refresh();
logic.requestDeviceNetworkInfo();
} }
StreamSubscription? _lockRefreshLockDetailInfoDataEvent; StreamSubscription? _lockRefreshLockDetailInfoDataEvent;
@ -1024,7 +1023,7 @@ class _LockDetailPageState extends State<LockDetailPage>
Widget widget = getBottomWidget()[index]; Widget widget = getBottomWidget()[index];
return widget; return widget;
}, },
physics: const NeverScrollableScrollPhysics(), // physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
) )

View File

@ -14,6 +14,8 @@ class LockDetailState {
late StreamSubscription<Reply> replySubscription; late StreamSubscription<Reply> replySubscription;
StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent; StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent;
StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription; StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription;
StreamSubscription? DetailLockInfo;
StreamSubscription? SuccessfulDistributionNetworkEvent;
String lockNetToken = '0'; String lockNetToken = '0';
int differentialTime = 0;// int differentialTime = 0;//

View File

@ -62,18 +62,15 @@ class ConfiguringWifiLogic extends BaseGetXController {
peerId: peerId, peerId: peerId,
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
// peerID
StartChartManage().lockNetworkInfo = DeviceNetworkInfo(
wifiName: wifiName,
networkMac: networkMac,
secretKey: secretKey,
peerId: peerId,
);
await _getUploadLockSet(); await _getUploadLockSet();
showToast('配网成功'.tr, something: () async {
eventBus
.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
// peerID
StartChartManage().lockNetworkInfo = DeviceNetworkInfo(
wifiName: wifiName,
networkMac: networkMac,
secretKey: secretKey,
peerId: peerId,
);
});
} }
} }
@ -107,8 +104,11 @@ class ConfiguringWifiLogic extends BaseGetXController {
// WIFI配网结果 // WIFI配网结果
Future<void> _replySenderConfiguringWifiResult(Reply reply) async { Future<void> _replySenderConfiguringWifiResult(Reply reply) async {
final int status = reply.data[2]; final int status = reply.data[2];
state.sureBtnState.value = 0; // state.sureBtnState.value = 0;
state.isLoading.value = false;
// loading超时定时器
state.loadingTimer?.cancel();
state.loadingTimer = null;
switch (status) { switch (status) {
case 0x00: case 0x00:
@ -135,21 +135,23 @@ class ConfiguringWifiLogic extends BaseGetXController {
// //
await Storage.saveLockNetWorkInfo(jsonMap); await Storage.saveLockNetWorkInfo(jsonMap);
// //
updateNetworkInfo( updateNetworkInfo(
peerId: peerId ?? '', peerId: peerId ?? '',
wifiName: wifiName ?? '', wifiName: wifiName ?? '',
secretKey: secretKey ?? '', secretKey: secretKey ?? '',
deviceMac: deviceMac ?? '', deviceMac: deviceMac ?? '',
networkMac: networkMac ?? ''); networkMac: networkMac ?? '');
break; break;
default: default:
// //
dismissEasyLoading(); dismissEasyLoading(); // loading
cancelBlueConnetctToastTimer();
if (state.loadingTimer != null) { if (state.loadingTimer != null) {
state.loadingTimer!.cancel(); state.loadingTimer!.cancel();
state.loadingTimer = null; state.loadingTimer = null;
} }
cancelBlueConnetctToastTimer();
showToast('配网失败'.tr); showToast('配网失败'.tr);
state.isLoading.value = false; state.isLoading.value = false;
break; break;
@ -165,7 +167,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
// wifi // wifi
Future<void> senderConfiguringWifiAction() async { Future<void> senderConfiguringWifiAction() async {
AppLog.log('开始配网${EasyLoading.isShow}'); AppLog.log('开始配网${EasyLoading.isShow}');
EasyLoading.show();
if (state.isLoading.isTrue) { if (state.isLoading.isTrue) {
AppLog.log('正在配网中请勿重复点击'); AppLog.log('正在配网中请勿重复点击');
return; return;
@ -179,10 +181,10 @@ class ConfiguringWifiLogic extends BaseGetXController {
showToast('请输入WiFi密码'.tr); showToast('请输入WiFi密码'.tr);
return; return;
} }
if (state.sureBtnState.value == 1) { // if (state.sureBtnState.value == 1) {
return; // return;
} // }
state.sureBtnState.value = 1; // state.sureBtnState.value = 1;
final GetGatewayConfigurationEntity entity = final GetGatewayConfigurationEntity entity =
await ApiRepository.to.getGatewayConfigurationNotLoading(timeout: 60); await ApiRepository.to.getGatewayConfigurationNotLoading(timeout: 60);
@ -219,9 +221,13 @@ class ConfiguringWifiLogic extends BaseGetXController {
// //
state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}"; state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
} }
showEasyLoading();
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
state.isLoading.value = false;
});
AppLog.log('获取到配网信息===开始发送蓝牙指令${EasyLoading.isShow}'); //
BlueManage().blueSendData( BlueManage().blueSendData(
BlueManage().connectDeviceName, BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async { (BluetoothConnectionState connectionState) async {
@ -231,31 +237,19 @@ class ConfiguringWifiLogic extends BaseGetXController {
password: state.wifiPWDController.text, password: state.wifiPWDController.text,
gatewayConfigurationStr: state.getGatewayConfigurationStr, gatewayConfigurationStr: state.getGatewayConfigurationStr,
); );
} else if (connectionState == BluetoothConnectionState.disconnected) {
dismissEasyLoading();
cancelBlueConnetctToastTimer();
state.isLoading.value = false;
// state.sureBtnState.value = 0;
if (state.ifCurrentScreen.value == true) {
showBlueConnetctToast();
}
} }
}, },
isAddEquipment: true, isAddEquipment: false,
); );
state.loadingTimer ??= Timer.periodic(Duration(milliseconds: 100), (timer) {
if (!EasyLoading.isShow) {
EasyLoading.show();
}
});
state.isLoading.value = true; state.isLoading.value = true;
// 15
Future.delayed(const Duration(seconds: 15), () {
if (state.isLoading.isTrue) {
EasyLoading.dismiss();
state.isLoading.value = false;
state.sureBtnState.value = 0;
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
showToast('配网失败'.tr);
}
});
AppLog.log('发送方法执行完毕${EasyLoading.isShow}');
} }
// //
@ -314,7 +308,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
getWifiLockServiceIpAndPort(); getWifiLockServiceIpAndPort();
_initReplySubscription(); _initReplySubscription();
getDevicesStatusAction(); // getDevicesStatusAction();
} }
@override @override
@ -330,13 +324,13 @@ class ConfiguringWifiLogic extends BaseGetXController {
void _replyGatewayGetStatusReply(GatewayGetStatusReply reply) { void _replyGatewayGetStatusReply(GatewayGetStatusReply reply) {
final int status = reply.data[2]; final int status = reply.data[2];
//
dismissEasyLoading();
cancelBlueConnetctToastTimer();
switch (status) { switch (status) {
case 0x00: case 0x00:
// //
// state.sureBtnState.value = 0; // state.sureBtnState.value = 0;
cancelBlueConnetctToastTimer();
dismissEasyLoading();
final GetGatewayInfoModel gatewayModel = GetGatewayInfoModel(); final GetGatewayInfoModel gatewayModel = GetGatewayInfoModel();
// MAC地址 // MAC地址
@ -387,28 +381,17 @@ class ConfiguringWifiLogic extends BaseGetXController {
} }
} }
void _replyStatusInfo(reply) {}
// //
Future<void> _getUploadLockSet() async { Future<void> _getUploadLockSet() async {
showEasyLoading(); showEasyLoading();
showBlueConnetctToastTimer(action: () { showBlueConnetctToastTimer(action: () {
dismissEasyLoading(); dismissEasyLoading();
}); });
BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async {
if (connectionState == BluetoothConnectionState.connected) {
final List<String>? token = await Storage.getStringList(saveBlueToken);
final List<int> getTokenList = changeStringListToIntList(token!);
_uploadLockSet(getTokenList); final List<String>? token = await Storage.getStringList(saveBlueToken);
} else if (connectionState == BluetoothConnectionState.disconnected) { final List<int> getTokenList = changeStringListToIntList(token!);
cancelBlueConnetctToastTimer();
if (state.ifCurrentScreen.value == true) { await _uploadLockSet(getTokenList);
showBlueConnetctToast();
}
}
});
} }
// //
@ -432,15 +415,15 @@ class ConfiguringWifiLogic extends BaseGetXController {
// //
Future<void> _replyUpdataLockSetReply(Reply reply) async { Future<void> _replyUpdataLockSetReply(Reply reply) async {
final int status = reply.data[2]; final int status = reply.data[2];
dismissEasyLoading(); // loading
cancelBlueConnetctToastTimer();
switch (status) { switch (status) {
case 0x00: case 0x00:
// await _lockDataUpload(
dismissEasyLoading();
cancelBlueConnetctToastTimer();
_lockDataUpload(
uploadType: 1, uploadType: 1,
recordType: 0, recordType: 0,
records: reply.data.sublist(7, reply.data.length)); records: reply.data.sublist(7, reply.data.length));
break; break;
case 0x06: case 0x06:
// //
@ -469,30 +452,18 @@ class ConfiguringWifiLogic extends BaseGetXController {
records: records, records: records,
isUnShowLoading: true); isUnShowLoading: true);
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
await Future.delayed((Duration(seconds: 1))); showToast('配网成功'.tr, something: () {
if (state.pageName.value == 'lockSet') { state.isLoading.value = false;
Get.close(2); if (state.pageName.value == 'lockSet') {
} else { Get.close(2);
Get.offAllNamed(Routers.starLockMain); } else {
} Get.offAllNamed(Routers.starLockMain);
dismissEasyLoading(); }
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
}
}
@override eventBus
void dispose() { .fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
dismissEasyLoading(); eventBus.fire(SuccessfulDistributionNetwork());
// TODO: implement dispose });
super.dispose();
state.isLoading.value = false;
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
} }
} }
} }

View File

@ -1,4 +1,3 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart';
@ -17,51 +16,59 @@ import '../../../../tools/eventBusEventManage.dart';
import '../../../../tools/storage.dart'; import '../../../../tools/storage.dart';
import 'normallyOpenMode_state.dart'; import 'normallyOpenMode_state.dart';
class NormallyOpenModeLogic extends BaseGetXController{ class NormallyOpenModeLogic extends BaseGetXController {
NormallyOpenModeState state = NormallyOpenModeState(); NormallyOpenModeState state = NormallyOpenModeState();
// //
Future<void> configPassageMode() async{ Future<void> configPassageMode() async {
if(state.weekDays.value.isEmpty){ if (state.weekDays.value.isEmpty) {
showToast('请选择常开日期'.tr); showToast('请选择常开日期'.tr);
return; return;
} }
if(state.endTimeMinute.value < state.beginTimeMinute.value){ if (state.endTimeMinute.value < state.beginTimeMinute.value) {
showToast('结束时间不能小于开始时间哦'.tr); showToast('结束时间不能小于开始时间哦'.tr);
return; return;
} }
final List passageModeConfig = []; final List passageModeConfig = [];
final Map<String, Object> map = <String, Object>{ final Map<String, Object> map = <String, Object>{
'isAllDay':state.isAllDay.value, 'isAllDay': state.isAllDay.value,
'weekDays':state.weekDays.value, 'weekDays': state.weekDays.value,
'startDate':state.beginTimeMinute.value, 'startDate': state.beginTimeMinute.value,
'endDate':state.endTimeMinute.value, 'endDate': state.endTimeMinute.value,
}; };
passageModeConfig.add(map); passageModeConfig.add(map);
final LoginEntity entity = await ApiRepository.to.setNormallyModeData( final LoginEntity entity = await ApiRepository.to.setNormallyModeData(
lockId: state.lockSetInfoData.value.lockId!, lockId: state.lockSetInfoData.value.lockId!,
passageMode:state.isOpenNormallyOpenMode.value == true ? 1:0, passageMode: state.isOpenNormallyOpenMode.value == true ? 1 : 0,
passageModeConfig: passageModeConfig, passageModeConfig: passageModeConfig,
); );
if(entity.errorCode!.codeIsSuccessful){ if (entity.errorCode!.codeIsSuccessful) {
showToast('操作成功'.tr, something: (){ showToast('操作成功'.tr, something: () {
eventBus.fire(RefreshLockListInfoDataEvent()); eventBus.fire(RefreshLockListInfoDataEvent());
state.lockSetInfoData.value.lockSettingInfo!.passageMode = state.isOpenNormallyOpenMode.value == true ? 1:0; state.lockSetInfoData.value.lockSettingInfo!.passageMode =
eventBus.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value)); state.isOpenNormallyOpenMode.value == true ? 1 : 0;
eventBus.fire(LockSetChangeSetRefreshLockDetailWithType(2, state.lockSetInfoData.value.lockSettingInfo!.passageMode!.toString())); eventBus
.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
eventBus.fire(LockSetChangeSetRefreshLockDetailWithType(
2,
state.lockSetInfoData.value.lockSettingInfo!.passageMode!
.toString()));
Get.back();
}); });
} }
} }
// //
late StreamSubscription<Reply> _replySubscription; late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() { void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) { _replySubscription =
if(reply is SetSupportFunctionsWithParametersReply) { EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
if (reply is SetSupportFunctionsWithParametersReply) {
_replySetSupportFunctionsWithParameters(reply); _replySetSupportFunctionsWithParameters(reply);
} }
@ -93,7 +100,7 @@ class NormallyOpenModeLogic extends BaseGetXController{
// //
Future<void> _replySetSupportFunctionsWithParameters(Reply reply) async { Future<void> _replySetSupportFunctionsWithParameters(Reply reply) async {
final int status = reply.data[2]; final int status = reply.data[2];
switch(status){ switch (status) {
case 0x00: case 0x00:
// //
state.sureBtnState.value = 0; state.sureBtnState.value = 0;
@ -111,38 +118,44 @@ class NormallyOpenModeLogic extends BaseGetXController{
// () // ()
Future<void> sendAutoLock() async { Future<void> sendAutoLock() async {
if(state.sureBtnState.value == 1){ if (state.sureBtnState.value == 1) {
return; return;
} }
state.sureBtnState.value = 1; state.sureBtnState.value = 1;
showEasyLoading(); showEasyLoading();
showBlueConnetctToastTimer(action: (){ showBlueConnetctToastTimer(action: () {
dismissEasyLoading(); dismissEasyLoading();
state.sureBtnState.value = 0; state.sureBtnState.value = 0;
}); });
BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState connectionState) async { BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async {
if (connectionState == BluetoothConnectionState.connected) { if (connectionState == BluetoothConnectionState.connected) {
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey); final List<String>? privateKey =
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!); await Storage.getStringList(saveBluePrivateKey);
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!);
final List<String>? publicKey = await Storage.getStringList(saveBluePublicKey); final List<String>? publicKey =
final List<int> getPublicKeyList = changeStringListToIntList(publicKey!); await Storage.getStringList(saveBluePublicKey);
final List<int> getPublicKeyList =
changeStringListToIntList(publicKey!);
String weekStr = '00000000'; String weekStr = '00000000';
for (var day in state.weekDays.value) { for (var day in state.weekDays.value) {
final int index = day % 7; // 0 final int index = day % 7; // 0
weekStr = '${weekStr.substring(0, index)}1${weekStr.substring(index + 1)}'; weekStr =
'${weekStr.substring(0, index)}1${weekStr.substring(index + 1)}';
} }
// weekStr // weekStr
weekStr = weekStr.split('').reversed.join(''); weekStr = weekStr.split('').reversed.join('');
final int number = int.parse(weekStr, radix: 2); final int number = int.parse(weekStr, radix: 2);
final List<int> list = <int>[]; final List<int> list = <int>[];
list.add(state.isOpenNormallyOpenMode.value == true ? 1:0); list.add(state.isOpenNormallyOpenMode.value == true ? 1 : 0);
final int bieginTime = state.beginTimeMinute.value; final int bieginTime = state.beginTimeMinute.value;
final double bieginDouble = bieginTime / 256; final double bieginDouble = bieginTime / 256;
@ -159,7 +172,7 @@ class NormallyOpenModeLogic extends BaseGetXController{
list.add(end1); list.add(end1);
list.add(end2); list.add(end2);
list.add(state.isAllDay.value == 1 ? 1:0); list.add(state.isAllDay.value == 1 ? 1 : 0);
list.add(number); list.add(number);
list.add(0); list.add(0);
@ -177,7 +190,7 @@ class NormallyOpenModeLogic extends BaseGetXController{
dismissEasyLoading(); dismissEasyLoading();
cancelBlueConnetctToastTimer(); cancelBlueConnetctToastTimer();
state.sureBtnState.value = 0; state.sureBtnState.value = 0;
if(state.ifCurrentScreen.value == true){ if (state.ifCurrentScreen.value == true) {
showBlueConnetctToast(); showBlueConnetctToast();
} }
} }

View File

@ -90,6 +90,12 @@ class AddPalmLogic extends BaseGetXController {
isBeforeAddUser: false isBeforeAddUser: false
); );
break; break;
case 0xFE:
case 12:
//
showToast('管理员已满'.tr);
Get.close(1);
break;
default: default:
// //
state.ifAddState.value = false; state.ifAddState.value = false;
@ -111,6 +117,7 @@ class AddPalmLogic extends BaseGetXController {
Get.close(1); Get.close(1);
break; break;
case 0xFE: case 0xFE:
case 12:
// //
showToast('管理员已满'.tr); showToast('管理员已满'.tr);
Get.close(1); Get.close(1);

View File

@ -152,6 +152,13 @@ class PasswordKeyDetailLogic extends BaseGetXController {
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!);
int startTime = 0;
int endTime = 0;
if (state.itemData.value.keyboardPwdType != 2) {
startTime = state.itemData.value.startDate! ~/ 1000;
endTime = state.itemData.value.endDate! ~/ 1000;
}
IoSenderManage.senderCustomPasswordsCommand( IoSenderManage.senderCustomPasswordsCommand(
keyID: state.itemData.value.keyboardPwdId!.toString(), keyID: state.itemData.value.keyboardPwdId!.toString(),
userID: await Storage.getUid(), userID: await Storage.getUid(),
@ -162,8 +169,8 @@ class PasswordKeyDetailLogic extends BaseGetXController {
? (state.isDeletPasswordKey.value == true ? 2 : 1) ? (state.isDeletPasswordKey.value == true ? 2 : 1)
: 3, : 3,
isAdmin: state.isAdministrator.value == true ? 1 : 0, isAdmin: state.isAdministrator.value == true ? 1 : 0,
startTime: state.itemData.value.startDate! ~/ 1000, startTime: startTime,
endTime: state.itemData.value.endDate! ~/ 1000, endTime: endTime,
needAuthor: 1, needAuthor: 1,
isBeforeAddUser: false, isBeforeAddUser: false,
signKey: signKeyDataList, signKey: signKeyDataList,

View File

@ -90,6 +90,13 @@ class AddRemoteControlLogic extends BaseGetXController{
isBeforeAddUser: false isBeforeAddUser: false
); );
break; break;
case 0xFE:
case 12:
//
showToast('管理员已满'.tr);
state.ifAddState.value = false;
Get.close(1);
break;
default: default:
// //
state.ifAddState.value = false; state.ifAddState.value = false;
@ -110,6 +117,7 @@ class AddRemoteControlLogic extends BaseGetXController{
Get.close(1); Get.close(1);
break; break;
case 0xFE: case 0xFE:
case 0x12:
// //
showToast('管理员已满'.tr); showToast('管理员已满'.tr);
Get.close(1); Get.close(1);

View File

@ -93,7 +93,6 @@ class NearbyLockLogic extends BaseGetXController {
showToast('固件升级完成'.tr); showToast('固件升级完成'.tr);
closeOTADAta(); closeOTADAta();
} }
dismissEasyLoading();
}); });
} }
@ -160,6 +159,7 @@ class NearbyLockLogic extends BaseGetXController {
// //
Future<void> _replyGetStarLockStatusInfo(Reply reply) async { Future<void> _replyGetStarLockStatusInfo(Reply reply) async {
final int status = reply.data[2]; final int status = reply.data[2];
dismissEasyLoading();
switch (status) { switch (status) {
case 0x00: case 0x00:
// //
@ -449,50 +449,6 @@ class NearbyLockLogic extends BaseGetXController {
} }
} }
/// 128-bit UUID
bool isPaired128Bit(String serviceUuid) {
if (serviceUuid.length != 36) return false; // 128-bit UUID
try {
String status = serviceUuid.substring(30, 32); // 31 32
return status == '01'; // '01'
} catch (e) {
return false; // false
}
}
/// 128-bit UUID
bool isSleeping128Bit(String serviceUuid) {
if (serviceUuid.length != 36) return false; // 128-bit UUID
try {
String status = serviceUuid.substring(32, 34); // 33 34
return status == '00'; // '00'
} catch (e) {
return false; // false
}
}
/// 32-bit UUID
bool isPaired32Bit(String serviceUuid) {
if (serviceUuid.length != 8) return false; // 32-bit UUID
try {
String status = serviceUuid.substring(3, 5); // 4 5
return status == '01'; // '01'
} catch (e) {
return false; // false
}
}
/// 32-bit UUID
bool isSleeping32Bit(String serviceUuid) {
if (serviceUuid.length != 8) return false; // 32-bit UUID
try {
String status = serviceUuid.substring(5, 7); // 6 7
return status == '00'; // '00'
} catch (e) {
return false; // false
}
}
void stopScanBlueList() { void stopScanBlueList() {
BlueManage().disconnect(); BlueManage().disconnect();
BlueManage().stopScan(); BlueManage().stopScan();
@ -743,8 +699,8 @@ class NearbyLockLogic extends BaseGetXController {
@override @override
void onClose() { void onClose() {
super.onClose();
_replySubscription?.cancel(); _replySubscription?.cancel();
super.onClose();
} }
Future<void> getNearByLimits() async { Future<void> getNearByLimits() async {

View File

@ -456,10 +456,10 @@ class _MineSetPageState extends State<MineSetPage>
// showLoginOutAlertTipDialog(); // showLoginOutAlertTipDialog();
}), }),
Container( Container(
padding: EdgeInsets.only(right: 30.w, top: 30.h), padding: EdgeInsets.only(left: 30.w, top: 30.h),
// color: Colors.red, // color: Colors.red,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[ children: <Widget>[
TextButton( TextButton(
child: Text( child: Text(

View File

@ -1,7 +1,19 @@
import 'package:star_lock/talk/starChart/proto/talk_expect.pb.dart';
class TalkConstant { class TalkConstant {
// TalkPing (s) // TalkPing (s)
static const int talkePingOverTime = 10; static const int talkePingOverTime = 10;
static const int talkeDataOverTime = 10; static const int talkeDataOverTime = 10;
// TalkRequest (s) // TalkRequest (s)
static const int talkeRequestOverTime = 30; static const int talkeRequestOverTime = 30;
static TalkExpectReq ImageExpect = TalkExpectReq(
videoType: [VideoTypeE.IMAGE],
audioType: [AudioTypeE.G711],
);
static TalkExpectReq H264Expect = TalkExpectReq(
videoType: [VideoTypeE.H264],
audioType: [AudioTypeE.G711],
);
} }

View File

@ -4,6 +4,7 @@ import 'package:star_lock/talk/call/g711.dart';
import 'package:star_lock/talk/starChart/constant/message_type_constant.dart'; import 'package:star_lock/talk/starChart/constant/message_type_constant.dart';
import 'package:star_lock/talk/starChart/entity/scp_message.dart'; import 'package:star_lock/talk/starChart/entity/scp_message.dart';
import 'package:star_lock/talk/starChart/handle/other/h264_frame_handler.dart'; import 'package:star_lock/talk/starChart/handle/other/h264_frame_handler.dart';
import 'package:star_lock/talk/starChart/handle/other/packet_loss_statistics.dart';
import 'package:star_lock/talk/starChart/handle/scp_message_base_handle.dart'; import 'package:star_lock/talk/starChart/handle/scp_message_base_handle.dart';
import 'package:star_lock/talk/starChart/handle/scp_message_handle.dart'; import 'package:star_lock/talk/starChart/handle/scp_message_handle.dart';
import 'package:star_lock/talk/starChart/proto/talk_data.pb.dart'; import 'package:star_lock/talk/starChart/proto/talk_data.pb.dart';
@ -14,62 +15,6 @@ import 'package:star_lock/talk/starChart/proto/talk_data_h264_frame.pb.dart';
// implements ScpMessageHandler { // implements ScpMessageHandler {
class UdpTalkDataHandler extends ScpMessageBaseHandle class UdpTalkDataHandler extends ScpMessageBaseHandle
implements ScpMessageHandler { implements ScpMessageHandler {
factory UdpTalkDataHandler() {
return _instance;
}
UdpTalkDataHandler._internal();
static final UdpTalkDataHandler _instance = UdpTalkDataHandler._internal();
int _recentRecvDataRate = 0;
int _recentRecvPacketCount = 0;
int _recentSendDataRate = 0;
int _recentSendPacketCount = 0;
int _lastRecvDataRate = 0;
int _lastRecvPacketCount = 0;
int _lastSendDataRate = 0;
int _lastSendPacketCount = 0;
void updateRecvDataRate(int dataSize) {
_recentRecvDataRate += dataSize;
_recentRecvPacketCount++;
}
void updateSendDataRate(int dataSize) {
_recentSendDataRate += dataSize;
_recentSendPacketCount++;
}
void resetDataRates() {
_lastRecvDataRate = _recentRecvDataRate;
_lastRecvPacketCount = _recentRecvPacketCount;
_lastSendDataRate = _recentSendDataRate;
_lastSendPacketCount = _recentSendPacketCount;
_recentRecvDataRate = 0;
_recentRecvPacketCount = 0;
_recentSendDataRate = 0;
_recentSendPacketCount = 0;
}
int getLastRecvDataRate() {
return _lastRecvDataRate;
}
int getLastRecvPacketCount() {
return _lastRecvPacketCount;
}
int getLastSendDataRate() {
return _lastSendDataRate;
}
int getLastSendPacketCount() {
return _lastSendPacketCount;
}
@override @override
void handleReq(ScpMessage scpMessage) {} void handleReq(ScpMessage scpMessage) {}
@ -95,6 +40,17 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
return buffer.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(); return buffer.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
} }
//
void _asyncLog(String message) {
Future.microtask(() {
try {
AppLog.log(message);
} catch (e) {
//
}
});
}
@override @override
deserializePayload( deserializePayload(
{required int payloadType, {required int payloadType,
@ -105,10 +61,12 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
int? spTotal, int? spTotal,
int? spIndex, int? spIndex,
int? messageId}) { int? messageId}) {
// AppLog.log( //
// '没有组包之前的每一个包的数据:${byte.length} messageId:$messageId spTotal:$spTotal spIndex:$spIndex PayloadLength:$PayloadLength,byte:${bufferToHexString(byte)}'); final stats = PacketLossStatistics().getStatistics();
_asyncLog('丢包统计: $stats');
// _asyncLog(
// '分包数据:messageId:$messageId [$spIndex/$spTotal] PayloadLength:$PayloadLength');
if (messageType == MessageTypeConstant.RealTimeData) { if (messageType == MessageTypeConstant.RealTimeData) {
//
if (spTotal != null && if (spTotal != null &&
spTotal > 1 && spTotal > 1 &&
messageId != null && messageId != null &&
@ -161,8 +119,6 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
final TalkDataH264Frame talkDataH264Frame = TalkDataH264Frame(); final TalkDataH264Frame talkDataH264Frame = TalkDataH264Frame();
talkDataH264Frame.mergeFromBuffer(talkData.content); talkDataH264Frame.mergeFromBuffer(talkData.content);
frameHandler.handleFrame(talkDataH264Frame); frameHandler.handleFrame(talkDataH264Frame);
// AppLog.log(
// "帧:${talkDataH264Frame.frameType},帧序号:${talkDataH264Frame.frameSeq},对应I帧序号${talkDataH264Frame.frameSeqI}");
} }
/// ///

View File

@ -25,8 +25,24 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
RxString currentLanguage = RxString currentLanguage =
CurrentLocaleTool.getCurrentLocaleString().obs; // CurrentLocaleTool.getCurrentLocaleString().obs; //
//
int _lastRequestTime = 0;
@override @override
void handleReq(ScpMessage scpMessage) async { void handleReq(ScpMessage scpMessage) async {
final currentTime = DateTime.now().millisecondsSinceEpoch;
// 1
if (currentTime - _lastRequestTime < 1000) {
// 1
replyErrorMessage(scpMessage);
AppLog.log('对讲请求过于频繁,已拒绝');
return;
}
//
_lastRequestTime = currentTime;
// //
final loginData = await Storage.getLoginData(); final loginData = await Storage.getLoginData();
@ -47,6 +63,7 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
} else { } else {
// , // ,
replyErrorMessage(scpMessage); replyErrorMessage(scpMessage);
AppLog.log('正在接听,回复拒绝');
} }
} }

View File

@ -1,105 +1,17 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/app_settings/app_settings.dart';
import '../../proto/talk_data_h264_frame.pb.dart'; import '../../proto/talk_data_h264_frame.pb.dart';
class H264FrameHandler { class H264FrameHandler {
final LinkedHashMap<int, TalkDataH264Frame> _frameBuffer = LinkedHashMap();
final void Function(List<int> frameData) onCompleteFrame;
final LinkedHashMap<int, TalkDataH264Frame_FrameTypeE> _frameTypeIndex = LinkedHashMap(); final void Function(List<int> frameData) onCompleteFrame;
H264FrameHandler({required this.onCompleteFrame}); H264FrameHandler({required this.onCompleteFrame});
void handleFrame(TalkDataH264Frame frame) { void handleFrame(TalkDataH264Frame frame) {
// onCompleteFrame(frame.frameData);
_frameBuffer[frame.frameSeq] = frame;
_frameTypeIndex[frame.frameSeq] = frame.frameType;
// GOP (Group of Pictures)
_tryAssembleFrames(frame.frameSeq);
}
void _tryAssembleFrames(int currentSeq) {
final List<int> framesToProcess = [];
int? startFrameSeq;
// I P
for (int seq = currentSeq; seq >= 0; seq--) {
final frameType = _frameTypeIndex[seq];
if (frameType == null) continue;
if (frameType == TalkDataH264Frame_FrameTypeE.I) {
startFrameSeq = seq;
break;
} else if (frameType == TalkDataH264Frame_FrameTypeE.P) {
if (_frameBuffer.containsKey(_frameBuffer[seq]!.frameSeqI)) {
startFrameSeq = seq;
break;
} else {
_frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
}
}
}
if (startFrameSeq != null) {
for (int seq = startFrameSeq; _frameBuffer.containsKey(seq); seq++) {
framesToProcess.add(seq);
}
if (framesToProcess.isNotEmpty) {
_processFrames(framesToProcess);
}
} else {
_clearOldFrames(currentSeq);
}
}
void _processFrames(List<int> frameSeqs) {
//
// final List<int> assembledData = [];
//
// for (var seq in frameSeqs) {
// final frame = _frameBuffer[seq]!;
// assembledData.addAll(frame.frameData);
//
// //
// _frameBuffer.remove(seq);
// }
//
// //
// onCompleteFrame(assembledData);
// Calculate the total length of the assembled data
int totalLength = frameSeqs.fold(
0, (sum, seq) => sum + _frameBuffer[seq]!.frameData.length);
// Allocate a buffer for the assembled data
final assembledData = Uint8List(totalLength);
int offset = 0;
for (var seq in frameSeqs) {
final frame = _frameBuffer[seq]!;
assembledData.setRange(
offset, offset + frame.frameData.length, frame.frameData);
offset += frame.frameData.length;
// Remove the frame from the buffer after processing
_frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
}
// Callback with the complete frame data
onCompleteFrame(assembledData);
}
void clear() {
_frameBuffer.clear();
}
void _clearOldFrames(int currentSeq) {
//
_frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); //
_frameTypeIndex.removeWhere((seq, frameType) => seq < currentSeq - 200);
} }
} }

View File

@ -0,0 +1,94 @@
import 'dart:collection';
class PacketLossStatistics {
static final PacketLossStatistics _instance =
PacketLossStatistics._internal();
factory PacketLossStatistics() => _instance;
PacketLossStatistics._internal();
// messageId的分包信息
// key: messageId, value: {totalPackets, receivedPackets}
final Map<int, PacketInfo> _packetsMap = HashMap();
//
int _totalMessages = 0; //
int _lostMessages = 0; //
int _totalPackets = 0; //
int _lostPackets = 0; //
//
void recordPacket(int messageId, int currentIndex, int totalPackets) {
if (!_packetsMap.containsKey(messageId)) {
_packetsMap[messageId] = PacketInfo(totalPackets);
_totalMessages++;
_totalPackets += totalPackets;
}
_packetsMap[messageId]!.receivedPackets.add(currentIndex);
// messageId的最后一个包
if (currentIndex == totalPackets) {
_checkPacketLoss(messageId);
}
}
//
void _checkPacketLoss(int messageId) {
final info = _packetsMap[messageId]!;
//
int received = info.receivedPackets.length;
if (received < info.totalPackets) {
_lostMessages++;
_lostPackets += (info.totalPackets - received);
}
// messageId的记录
_packetsMap.remove(messageId);
}
//
PacketLossInfo getStatistics() {
if (_totalMessages == 0 || _totalPackets == 0) {
return PacketLossInfo(0.0, 0.0);
}
//
double messageLossRate = (_lostMessages / _totalMessages) * 100;
//
double packetLossRate = (_lostPackets / _totalPackets) * 100;
return PacketLossInfo(messageLossRate, packetLossRate);
}
//
void reset() {
_packetsMap.clear();
_totalMessages = 0;
_lostMessages = 0;
_totalPackets = 0;
_lostPackets = 0;
}
}
//
class PacketInfo {
final int totalPackets;
final Set<int> receivedPackets = HashSet<int>();
PacketInfo(this.totalPackets);
}
//
class PacketLossInfo {
final double messageLossRate; //
final double packetLossRate; //
PacketLossInfo(this.messageLossRate, this.packetLossRate);
@override
String toString() {
return 'Message Loss Rate: ${messageLossRate.toStringAsFixed(2)}%, Packet Loss Rate: ${packetLossRate.toStringAsFixed(2)}%';
}
}

View File

@ -2,7 +2,6 @@ import 'dart:async';
import 'package:star_lock/talk/starChart/proto/talk_data.pb.dart'; import 'package:star_lock/talk/starChart/proto/talk_data.pb.dart';
class TalkDataRepository { class TalkDataRepository {
//
TalkDataRepository._() { TalkDataRepository._() {
_talkDataStreamController = StreamController<TalkData>.broadcast( _talkDataStreamController = StreamController<TalkData>.broadcast(
onListen: () { onListen: () {
@ -11,47 +10,26 @@ class TalkDataRepository {
onCancel: () { onCancel: () {
_isListening = false; _isListening = false;
}, },
sync: false, // sync: false, //
); );
} }
// 使 _instance
static final TalkDataRepository _instance = TalkDataRepository._(); static final TalkDataRepository _instance = TalkDataRepository._();
//
static TalkDataRepository get instance => _instance; static TalkDataRepository get instance => _instance;
// StreamController
late final StreamController<TalkData> _talkDataStreamController; late final StreamController<TalkData> _talkDataStreamController;
bool _isListening = false; bool _isListening = false;
// //
final List<TalkData> _buffer = []; Stream<TalkData> get talkDataStream => _talkDataStreamController.stream;
// Stream
Stream<TalkData> get talkDataStream =>
_talkDataStreamController.stream.transform(
StreamTransformer<TalkData, TalkData>.fromHandlers(
handleData: (TalkData data, EventSink<TalkData> sink) {
// 100
if (_buffer.length >= 100) {
_buffer.removeAt(0); //
}
_buffer.add(data);
sink.add(data);
},
),
);
// TalkData Stream
void addTalkData(TalkData talkData) { void addTalkData(TalkData talkData) {
if (_isListening) { if (_isListening) {
_talkDataStreamController.add(talkData); _talkDataStreamController.add(talkData);
} }
} }
// StreamController
void dispose() { void dispose() {
_talkDataStreamController.close(); _talkDataStreamController.close();
} }

View File

@ -22,6 +22,7 @@ import 'package:star_lock/talk/starChart/constant/ip_constant.dart';
import 'package:star_lock/talk/starChart/constant/listen_addr_type_constant.dart'; import 'package:star_lock/talk/starChart/constant/listen_addr_type_constant.dart';
import 'package:star_lock/talk/starChart/constant/message_type_constant.dart'; import 'package:star_lock/talk/starChart/constant/message_type_constant.dart';
import 'package:star_lock/talk/starChart/constant/payload_type_constant.dart'; import 'package:star_lock/talk/starChart/constant/payload_type_constant.dart';
import 'package:star_lock/talk/starChart/constant/talk_constant.dart';
import 'package:star_lock/talk/starChart/constant/talk_status.dart'; import 'package:star_lock/talk/starChart/constant/talk_status.dart';
import 'package:star_lock/talk/starChart/entity/relay_info_entity.dart'; import 'package:star_lock/talk/starChart/entity/relay_info_entity.dart';
import 'package:star_lock/talk/starChart/entity/report_information_data.dart'; import 'package:star_lock/talk/starChart/entity/report_information_data.dart';
@ -31,6 +32,7 @@ import 'package:star_lock/talk/starChart/exception/start_chart_message_exception
import 'package:star_lock/talk/starChart/handle/impl/debug_Info_model.dart'; import 'package:star_lock/talk/starChart/handle/impl/debug_Info_model.dart';
import 'package:star_lock/talk/starChart/handle/impl/udp_talk_data_handler.dart'; import 'package:star_lock/talk/starChart/handle/impl/udp_talk_data_handler.dart';
import 'package:star_lock/talk/starChart/handle/other/do_sign.dart'; import 'package:star_lock/talk/starChart/handle/other/do_sign.dart';
import 'package:star_lock/talk/starChart/handle/other/packet_loss_statistics.dart';
import 'package:star_lock/talk/starChart/handle/other/talke_data_over_time_timer_manager.dart'; import 'package:star_lock/talk/starChart/handle/other/talke_data_over_time_timer_manager.dart';
import 'package:star_lock/talk/starChart/handle/other/talke_ping_over_time_timer_manager.dart'; import 'package:star_lock/talk/starChart/handle/other/talke_ping_over_time_timer_manager.dart';
import 'package:star_lock/talk/starChart/handle/other/talke_request_over_time_timer_manager.dart'; import 'package:star_lock/talk/starChart/handle/other/talke_request_over_time_timer_manager.dart';
@ -111,10 +113,7 @@ class StartChartManage {
final int _maxPayloadSize = 8 * 1024; // final int _maxPayloadSize = 8 * 1024; //
// //
TalkExpectReq _defaultTalkExpect = TalkExpectReq( TalkExpectReq _defaultTalkExpect = TalkConstant.ImageExpect;
videoType: [VideoTypeE.IMAGE],
audioType: [AudioTypeE.G711],
);
String relayPeerId = ''; // peerId String relayPeerId = ''; // peerId
@ -342,7 +341,7 @@ class StartChartManage {
} }
} }
// RbcuConfirm //
void _sendRbcuConfirmMessage() async { void _sendRbcuConfirmMessage() async {
RbcuConfirm( RbcuConfirm(
sessionId: _rbcuSessionId, sessionId: _rbcuSessionId,
@ -595,27 +594,39 @@ class StartChartManage {
// //
void startTalkRejectMessageTimer() async { void startTalkRejectMessageTimer() async {
talkRejectTimer ??= Timer.periodic( try {
Duration(seconds: _defaultIntervalTime), int count = 0;
(Timer timer) async { final int maxCount = 10; // 10
_sendTalkRejectMessage();
},
);
// talkRejectTimer ??= Timer.periodic(
StartChartTalkStatus.instance.setRejected(); Duration(seconds: _defaultIntervalTime),
// (Timer timer) async {
AudioPlayerManager().stopRingtone(); _sendTalkRejectMessage();
// count++;
stopTalkExpectMessageTimer(); if (count >= maxCount) {
stopTalkPingMessageTimer(); timer.cancel();
stopCallRequestMessageTimer(); talkRejectTimer = null;
stopSendingRbcuInfoMessages(); }
stopSendingRbcuProBeMessages(); },
// );
} catch (e) {
AppLog.log("startTalkRejectMessageTimer e:${e}");
} finally {
//
StartChartTalkStatus.instance.setRejected();
//
AudioPlayerManager().stopRingtone();
//
stopTalkExpectMessageTimer();
stopTalkPingMessageTimer();
stopCallRequestMessageTimer();
stopSendingRbcuInfoMessages();
stopSendingRbcuProBeMessages();
//
talkePingOverTimeTimerManager.cancel(); talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel(); talkDataOverTimeTimerManager.cancel();
}
} }
// //
@ -1031,6 +1042,14 @@ class StartChartManage {
final int payloadType = scpMessage.PayloadType ?? 0; final int payloadType = scpMessage.PayloadType ?? 0;
final int messageType = scpMessage.MessageType ?? 0; final int messageType = scpMessage.MessageType ?? 0;
try { try {
//
if (scpMessage.SpIndex != null &&
scpMessage.SpTotal != null &&
scpMessage.MessageId != null) {
PacketLossStatistics().recordPacket(
scpMessage.MessageId!, scpMessage.SpIndex!, scpMessage.SpTotal!);
}
final ScpMessageHandler handler = final ScpMessageHandler handler =
ScpMessageHandlerFactory.createHandler(payloadType); ScpMessageHandlerFactory.createHandler(payloadType);
if (messageType == MessageTypeConstant.Req) { if (messageType == MessageTypeConstant.Req) {
@ -1126,10 +1145,7 @@ class StartChartManage {
} }
void reSetDefaultTalkExpect() { void reSetDefaultTalkExpect() {
_defaultTalkExpect = TalkExpectReq( _defaultTalkExpect = TalkConstant.ImageExpect;
videoType: [VideoTypeE.IMAGE],
audioType: [AudioTypeE.G711],
);
} }
TalkExpectReq getDefaultTalkExpect() { TalkExpectReq getDefaultTalkExpect() {
@ -1148,10 +1164,7 @@ class StartChartManage {
/// ///
void sendImageVideoAndG711AudioTalkExpectData() { void sendImageVideoAndG711AudioTalkExpectData() {
final talkExpectReq = TalkExpectReq( final talkExpectReq = TalkConstant.ImageExpect;
videoType: [VideoTypeE.IMAGE],
audioType: [AudioTypeE.G711],
);
changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer( changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(
talkExpect: talkExpectReq); talkExpect: talkExpectReq);
} }
@ -1212,6 +1225,7 @@ class StartChartManage {
await Storage.removerStarChartRegisterNodeInfo(); await Storage.removerStarChartRegisterNodeInfo();
// udp服务 // udp服务
closeUdpSocket(); closeUdpSocket();
PacketLossStatistics().reset();
} }
/// ///

View File

@ -28,17 +28,16 @@ class AppLifecycleObserver extends WidgetsBindingObserver {
void onAppPaused() { void onAppPaused() {
// //
print('App has entered the background.');
if (StartChartManage().talkStatus.status == final status = StartChartManage().talkStatus.status;
TalkStatus.passiveCallWaitingAnswer ||
StartChartManage().talkStatus.status == if (status == TalkStatus.passiveCallWaitingAnswer ||
TalkStatus.proactivelyCallWaitingAnswer) { status == TalkStatus.proactivelyCallWaitingAnswer ||
StartChartManage().startTalkHangupMessageTimer(); status == TalkStatus.answeredSuccessfully ||
StartChartManage().startTalkRejectMessageTimer(); status == TalkStatus.uninitialized) {
// 退 StartChartManage().destruction();
Get.back(); Get.back();
} }
StartChartManage().destruction();
} }
void onAppResumed() async { void onAppResumed() async {

View File

@ -38,8 +38,8 @@ class TalkViewLogic extends BaseGetXController {
final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state; final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state;
final int minBufferSize = 2; // 2166ms final int minBufferSize = 2; // 2166ms
final int maxBufferSize = 8; // 8666ms final int maxBufferSize = 20; // 8666ms
int bufferSize = 3; // int bufferSize = 8; //
// //
final int minAudioBufferSize = 1; // 1 final int minAudioBufferSize = 1; // 1
final int maxAudioBufferSize = 3; // 3 final int maxAudioBufferSize = 3; // 3
@ -56,6 +56,9 @@ class TalkViewLogic extends BaseGetXController {
final Map<String, ui.Image> _imageCache = {}; final Map<String, ui.Image> _imageCache = {};
//
int _lastFrameTimestamp = 0; // 0
// //
int _frameCount = 0; int _frameCount = 0;
int _lastFpsUpdateTime = 0; int _lastFpsUpdateTime = 0;
@ -100,11 +103,11 @@ class TalkViewLogic extends BaseGetXController {
// //
switch (contentType) { switch (contentType) {
case TalkData_ContentTypeE.G711: case TalkData_ContentTypeE.G711:
// // //
if (_isFirstAudioFrame) { // if (_isFirstAudioFrame) {
_startAudioTime = currentTime; // _startAudioTime = currentTime;
_isFirstAudioFrame = false; // _isFirstAudioFrame = false;
} // }
// //
final expectedTime = _startAudioTime + talkData.durationMs; final expectedTime = _startAudioTime + talkData.durationMs;
@ -130,15 +133,16 @@ class TalkViewLogic extends BaseGetXController {
if (_isFirstFrame) { if (_isFirstFrame) {
_startTime = currentTime; _startTime = currentTime;
_isFirstFrame = false; _isFirstFrame = false;
// AppLog.log('记录第一帧的时间戳${currentTime},${talkData.durationMs}'); AppLog.log('第一帧帧的时间戳:${talkData.durationMs}');
} }
// AppLog.log('其他帧的时间戳:${talkData.durationMs}');
//
if (_lastFrameTimestamp != 0) {
final int frameInterval = talkData.durationMs - _lastFrameTimestamp;
_adjustBufferSize(frameInterval); //
}
_lastFrameTimestamp = talkData.durationMs; //
// -
final expectedTime = _startTime + talkData.durationMs;
final videoDelay = currentTime - expectedTime; //
//
_adjustBufferSize(videoDelay);
// //
if (state.videoBuffer.length >= bufferSize) { if (state.videoBuffer.length >= bufferSize) {
state.videoBuffer.removeAt(0); state.videoBuffer.removeAt(0);
@ -180,20 +184,18 @@ class TalkViewLogic extends BaseGetXController {
state.listData.value = Uint8List.fromList(oldestFrame.content); state.listData.value = Uint8List.fromList(oldestFrame.content);
state.videoBuffer.removeAt(oldestIndex); // state.videoBuffer.removeAt(oldestIndex); //
// // //
_frameCount++; // _frameCount++;
final currentTime = DateTime.now().millisecondsSinceEpoch; // final currentTime = DateTime.now().millisecondsSinceEpoch;
final elapsed = currentTime - _lastFpsUpdateTime; // final elapsed = currentTime - _lastFpsUpdateTime;
//
// if (elapsed >= 1000) {
// //
// state.fps.value = (_frameCount * 1000 / elapsed).round();
// _frameCount = 0;
// _lastFpsUpdateTime = currentTime;
// }
if (elapsed >= 1000) {
//
state.fps.value = (_frameCount * 1000 / elapsed).round();
_frameCount = 0;
_lastFpsUpdateTime = currentTime;
}
// AppLog.log('🎬 播放帧 - 缓冲区剩余: ${state.videoBuffer.length}/${bufferSize}, '
// '播放延迟: ${currentTime - oldestFrame.durationMs}ms, '
// '帧时间戳: ${oldestFrame.durationMs}');
} else { } else {
// AppLog.log('⚠️ 帧未找到缓存 - Key: $cacheKey'); // AppLog.log('⚠️ 帧未找到缓存 - Key: $cacheKey');
state.videoBuffer.removeAt(oldestIndex); // state.videoBuffer.removeAt(oldestIndex); //
@ -257,19 +259,21 @@ class TalkViewLogic extends BaseGetXController {
} }
// //
void _adjustBufferSize(int delay) { void _adjustBufferSize(int frameInterval) {
const int delayThresholdHigh = 250; // 3 const int frameDuration = 83; // 83ms12fps
const int delayThresholdLow = 166; // 2 const int delayThresholdHigh = frameDuration * 2; // 2
const int delayThresholdLow = frameDuration; // 1
const int adjustInterval = 1; // 1 const int adjustInterval = 1; // 1
if (delay > delayThresholdHigh && bufferSize < maxBufferSize) { if (frameInterval > delayThresholdHigh && bufferSize < maxBufferSize) {
// //
bufferSize = min(bufferSize + adjustInterval, maxBufferSize); bufferSize = min(bufferSize + adjustInterval, maxBufferSize);
// AppLog.log('📈 增加缓冲区 - 当前大小: $bufferSize, 延迟: ${delay}ms'); AppLog.log('📈 增加缓冲区 - 当前大小: $bufferSize, 帧间间隔: ${frameInterval}ms');
} else if (delay < delayThresholdLow && bufferSize > minBufferSize) { } else if (frameInterval < delayThresholdLow &&
// bufferSize > minBufferSize) {
//
bufferSize = max(bufferSize - adjustInterval, minBufferSize); bufferSize = max(bufferSize - adjustInterval, minBufferSize);
// AppLog.log('📉 减少缓冲区 - 当前大小: $bufferSize, 延迟: ${delay}ms'); AppLog.log('📉 减少缓冲区 - 当前大小: $bufferSize, 帧间间隔: ${frameInterval}ms');
} }
} }
@ -493,6 +497,7 @@ class TalkViewLogic extends BaseGetXController {
_initAudioRecorder(); _initAudioRecorder();
requestPermissions(); requestPermissions();
} }
@override @override

View File

@ -615,7 +615,7 @@ class _TalkViewPageState extends State<TalkViewPage>
state.videoBuffer.clear(); state.videoBuffer.clear();
state.listData.value = Uint8List(0); state.listData.value = Uint8List(0);
CallTalk().finishAVData(); CallTalk().finishAVData();
UdpTalkDataHandler().resetDataRates(); // UdpTalkDataHandler().resetDataRates();
super.dispose(); super.dispose();
} }
} }

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection';
import 'dart:io'; import 'dart:io';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'dart:math'; // Import the math package to use sqrt import 'dart:math'; // Import the math package to use sqrt
@ -23,11 +24,13 @@ import 'package:star_lock/main/lockMian/entity/lockListInfo_entity.dart';
import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/talk/call/g711.dart'; import 'package:star_lock/talk/call/g711.dart';
import 'package:star_lock/talk/starChart/constant/talk_status.dart'; import 'package:star_lock/talk/starChart/constant/talk_status.dart';
import 'package:star_lock/talk/starChart/handle/other/packet_loss_statistics.dart';
import 'package:star_lock/talk/starChart/proto/talk_data.pb.dart'; import 'package:star_lock/talk/starChart/proto/talk_data.pb.dart';
import 'package:star_lock/talk/starChart/proto/talk_expect.pb.dart'; import 'package:star_lock/talk/starChart/proto/talk_expect.pb.dart';
import 'package:star_lock/talk/starChart/star_chart_manage.dart'; import 'package:star_lock/talk/starChart/star_chart_manage.dart';
import 'package:star_lock/talk/starChart/views/talkView/talk_view_state.dart'; import 'package:star_lock/talk/starChart/views/talkView/talk_view_state.dart';
import 'package:star_lock/talk/starChart/webView/h264_web_view_state.dart'; import 'package:star_lock/talk/starChart/webView/h264_web_view_state.dart';
import 'package:star_lock/tools/G711Tool.dart';
import 'package:star_lock/tools/bugly/bugly_tool.dart'; import 'package:star_lock/tools/bugly/bugly_tool.dart';
import 'package:webview_flutter/webview_flutter.dart'; import 'package:webview_flutter/webview_flutter.dart';
@ -38,6 +41,14 @@ class H264WebViewLogic extends BaseGetXController {
final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state; final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state;
//
static const int CHUNK_SIZE = 4096;
Timer? _mockDataTimer;
//
final List<int> _bufferedAudioFrames = <int>[];
final Queue<List<int>> _frameBuffer = Queue<List<int>>();
static const int FRAME_BUFFER_SIZE = 25;
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@ -57,7 +68,7 @@ class H264WebViewLogic extends BaseGetXController {
_loadLocalHtml(); _loadLocalHtml();
// //
_createFramesStreamListen(); _createFramesStreamListen();
// playLocalTestVideo();
_startListenTalkStatus(); _startListenTalkStatus();
state.talkStatus.value = state.startChartTalkStatus.status; state.talkStatus.value = state.startChartTalkStatus.status;
// //
@ -86,11 +97,43 @@ class H264WebViewLogic extends BaseGetXController {
void _createFramesStreamListen() async { void _createFramesStreamListen() async {
state.talkDataRepository.talkDataStream.listen((TalkData event) async { state.talkDataRepository.talkDataStream.listen((TalkData event) async {
// js处理 //
_sendBufferedData(event.content); _frameBuffer.add(event.content);
// ,
while (_frameBuffer.length > FRAME_BUFFER_SIZE) {
if (_frameBuffer.isNotEmpty) {
final frame = _frameBuffer.removeFirst();
await _sendBufferedData(frame);
}
}
}); });
} }
///
// Future<void> playLocalTestVideo() async {
// try {
// ByteData data = await rootBundle.load('assets/html/demo.h264');
// List<int> bytes = data.buffer.asUint8List();
//
// int offset = 0;
// _mockDataTimer = Timer.periodic(Duration(milliseconds: 40), (timer) {
// if (offset >= bytes.length) {
// timer.cancel();
// return;
// }
//
// int end = min(offset + CHUNK_SIZE, bytes.length);
// List<int> chunk = bytes.sublist(offset, end);
// _sendBufferedData(chunk);
//
// offset += CHUNK_SIZE;
// });
// } catch (e) {
// AppLog.log('加载测试视频文件失败: $e');
// }
// }
/// html文件 /// html文件
Future<void> _loadLocalHtml() async { Future<void> _loadLocalHtml() async {
// HTML // HTML
@ -226,15 +269,17 @@ class H264WebViewLogic extends BaseGetXController {
// //
Future<void> startProcessingAudio() async { Future<void> startProcessingAudio() async {
//
state.voiceProcessor?.addFrameListener(_onFrame);
state.voiceProcessor?.addErrorListener(_onError);
try { try {
if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) { if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) {
await state.voiceProcessor?.start(state.frameLength, state.sampleRate); await state.voiceProcessor?.start(state.frameLength, state.sampleRate);
final bool? isRecording = await state.voiceProcessor?.isRecording(); final bool? isRecording = await state.voiceProcessor?.isRecording();
state.isRecordingAudio.value = isRecording!; state.isRecordingAudio.value = isRecording!;
state.startRecordingAudioTime.value = DateTime.now(); state.startRecordingAudioTime.value = DateTime.now();
//
state.voiceProcessor
?.addFrameListeners(<VoiceProcessorFrameListener>[_onFrame]);
state.voiceProcessor?.addErrorListener(_onError);
} else { } else {
// state.errorMessage.value = 'Recording permission not granted'; // state.errorMessage.value = 'Recording permission not granted';
} }
@ -254,8 +299,8 @@ class H264WebViewLogic extends BaseGetXController {
state.endRecordingAudioTime.value = DateTime.now(); state.endRecordingAudioTime.value = DateTime.now();
// //
final duration = state.endRecordingAudioTime.value! final Duration duration = state.endRecordingAudioTime.value
.difference(state.startRecordingAudioTime.value!); .difference(state.startRecordingAudioTime.value);
state.recordingAudioTime.value = duration.inSeconds; state.recordingAudioTime.value = duration.inSeconds;
} on PlatformException catch (ex) { } on PlatformException catch (ex) {
@ -267,25 +312,71 @@ class H264WebViewLogic extends BaseGetXController {
} }
} }
// //
Future<void> _onFrame(List<int> frame) async { Future<void> _onFrame(List<int> frame) async {
// 线 //
// final processedFrame = await compute(preprocessAudio, frame); if (_bufferedAudioFrames.length > state.frameLength * 3) {
// final list = listLinearToALaw(processedFrame); _bufferedAudioFrames.clear(); //
final List<int> processedFrame = preprocessAudio(frame); return;
final List<int> list = listLinearToALaw(processedFrame); }
final int ms = DateTime.now().millisecondsSinceEpoch - //
state.startRecordingAudioTime.value.millisecondsSinceEpoch; List<int> amplifiedFrame = _applyGain(frame, 1.6);
// G711数据
List<int> encodedData = G711Tool.encode(amplifiedFrame, 0); // 0A-law
_bufferedAudioFrames.addAll(encodedData);
// 使
final int ms = DateTime.now().millisecondsSinceEpoch % 1000000; // 使
int getFrameLength = state.frameLength;
if (Platform.isIOS) {
getFrameLength = state.frameLength * 2;
}
// UDP //
await StartChartManage().sendTalkDataMessage( if (_bufferedAudioFrames.length >= state.frameLength) {
talkData: TalkData( try {
content: list, await StartChartManage().sendTalkDataMessage(
contentType: TalkData_ContentTypeE.G711, talkData: TalkData(
durationMs: ms, content: _bufferedAudioFrames,
), contentType: TalkData_ContentTypeE.G711,
); durationMs: ms,
),
);
} finally {
_bufferedAudioFrames.clear(); //
}
} else {
_bufferedAudioFrames.addAll(encodedData);
}
}
//
void _onError(VoiceProcessorException error) {
AppLog.log(error.message!);
}
//
List<int> _applyGain(List<int> pcmData, double gainFactor) {
List<int> result = List<int>.filled(pcmData.length, 0);
for (int i = 0; i < pcmData.length; i++) {
// PCM数据通常是有符号的16位整数
int sample = pcmData[i];
//
double amplified = sample * gainFactor;
//
if (amplified > 32767) {
amplified = 32767;
} else if (amplified < -32768) {
amplified = -32768;
}
result[i] = amplified.toInt();
}
return result;
} }
/// ///
@ -297,6 +388,9 @@ class H264WebViewLogic extends BaseGetXController {
// //
StartChartManage().startTalkRejectMessageTimer(); StartChartManage().startTalkRejectMessageTimer();
} }
// _mockDataTimer?.cancel();
// _mockDataTimer = null;
PacketLossStatistics().reset();
Get.back(); Get.back();
} }
@ -315,7 +409,7 @@ class H264WebViewLogic extends BaseGetXController {
}); });
final LockSetInfoEntity lockSetInfoEntity = final LockSetInfoEntity lockSetInfoEntity =
await ApiRepository.to.getLockSettingInfoData( await ApiRepository.to.getLockSettingInfoData(
lockId: lockId.toString(), lockId: lockId.toString(),
); );
if (lockSetInfoEntity.errorCode!.codeIsSuccessful) { if (lockSetInfoEntity.errorCode!.codeIsSuccessful) {
@ -333,93 +427,11 @@ class H264WebViewLogic extends BaseGetXController {
} }
} }
List<int> preprocessAudio(List<int> pcmList) {
//
final List<int> processedList = [];
for (int pcmVal in pcmList) {
// 0
if (pcmVal.abs() < 200) {
pcmVal = 0;
}
processedList.add(pcmVal);
}
return processedList;
}
List<int> listLinearToALaw(List<int> pcmList) {
final List<int> aLawList = [];
for (int pcmVal in pcmList) {
final int aLawVal = linearToALaw(pcmVal);
aLawList.add(aLawVal);
}
return aLawList;
}
int linearToALaw(int pcmVal) {
const int ALAW_MAX = 0x7FFF; // 32767
const int ALAW_BIAS = 0x84; // 132
int mask;
int seg;
int aLawVal;
// Handle sign
if (pcmVal < 0) {
pcmVal = -pcmVal;
mask = 0x7F; // 127 (sign bit is 1)
} else {
mask = 0xFF; // 255 (sign bit is 0)
}
// Add bias and clamp to ALAW_MAX
pcmVal += ALAW_BIAS;
if (pcmVal > ALAW_MAX) {
pcmVal = ALAW_MAX;
}
// Determine segment
seg = search(pcmVal);
// Calculate A-law value
if (seg >= 8) {
aLawVal = 0x7F ^ mask; // Clamp to maximum value
} else {
int quantized = (pcmVal >> (seg + 3)) & 0xF;
aLawVal = (seg << 4) | quantized;
aLawVal ^= 0xD5; // XOR with 0xD5 to match standard A-law table
}
return aLawVal;
}
int search(int val) {
final List<int> table = [
0xFF, // Segment 0
0x1FF, // Segment 1
0x3FF, // Segment 2
0x7FF, // Segment 3
0xFFF, // Segment 4
0x1FFF, // Segment 5
0x3FFF, // Segment 6
0x7FFF // Segment 7
];
const int size = 8;
for (int i = 0; i < size; i++) {
if (val <= table[i]) {
return i;
}
}
return size;
}
//
void _onError(VoiceProcessorException error) {
AppLog.log(error.message!);
}
@override @override
void dispose() { void dispose() {
// TODO: implement dispose // _mockDataTimer?.cancel();
// _mockDataTimer = null;
super.dispose(); super.dispose();
StartChartManage().startTalkHangupMessageTimer(); StartChartManage().startTalkHangupMessageTimer();
state.animationController.dispose(); state.animationController.dispose();
@ -429,5 +441,6 @@ class H264WebViewLogic extends BaseGetXController {
state.oneMinuteTimeTimer = null; state.oneMinuteTimeTimer = null;
stopProcessingAudio(); stopProcessingAudio();
StartChartManage().reSetDefaultTalkExpect(); StartChartManage().reSetDefaultTalkExpect();
_frameBuffer.clear();
} }
} }

View File

@ -195,3 +195,12 @@ class RogerThatLockInfoDataEvent {
class GetGatewayListRefreshUI { class GetGatewayListRefreshUI {
GetGatewayListRefreshUI(); GetGatewayListRefreshUI();
} }
///
class AgreePrivacyAgreement {
AgreePrivacyAgreement();
}
///
class SuccessfulDistributionNetwork {
SuccessfulDistributionNetwork();
}