Merge branch 'develop_liyi' of code-internal.star-lock.cn:StarlockTeam/app-starlock into develop_liyi

This commit is contained in:
“DaisyWu” 2025-02-24 19:01:43 +08:00
commit 1c74b54cd4
24 changed files with 321 additions and 157 deletions

View File

@ -56,7 +56,7 @@
}, },
flushingTime: 0, // 禁用自动刷新 flushingTime: 0, // 禁用自动刷新
clearBuffer: false, // 保留解码缓存 clearBuffer: false, // 保留解码缓存
maxBufferLength: 2, fps:20,
onReady: () => { onReady: () => {
console.log('播放器初始化完成'); console.log('播放器初始化完成');
// 通知Flutter端准备就绪 // 通知Flutter端准备就绪

View File

@ -2,6 +2,7 @@ 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/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import '../../../blue/io_reply.dart'; import '../../../blue/io_reply.dart';
import '../../lockMian/entity/lockListInfo_entity.dart'; import '../../lockMian/entity/lockListInfo_entity.dart';
@ -9,7 +10,7 @@ import '../../lockMian/entity/lockListInfo_entity.dart';
class LockDetailState { class LockDetailState {
Rx<LockListInfoItemEntity> keyInfos = LockListInfoItemEntity().obs; Rx<LockListInfoItemEntity> keyInfos = LockListInfoItemEntity().obs;
final Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
late StreamSubscription<Reply> replySubscription; late StreamSubscription<Reply> replySubscription;
StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent; StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent;
StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription; StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription;

View File

@ -8,6 +8,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:network_info_plus/network_info_plus.dart'; import 'package:network_info_plus/network_info_plus.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.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/io_gateway/io_gateway_configuringWifi.dart'; import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart';
import 'package:star_lock/blue/io_gateway/io_gateway_getStatus.dart'; import 'package:star_lock/blue/io_gateway/io_gateway_getStatus.dart';
@ -68,7 +69,12 @@ class ConfiguringWifiLogic extends BaseGetXController {
secretKey: secretKey, secretKey: secretKey,
peerId: peerId, peerId: peerId,
); );
Get.close(2);
if (state.pageName.value == 'lockSet') {
Get.close(2);
} else {
Get.offAllNamed(Routers.starLockMain);
}
}); });
} }
} }

View File

@ -47,7 +47,8 @@ class _ConfiguringWifiPageState extends State<ConfiguringWifiPage>
SubmitBtn( SubmitBtn(
btnName: '确定'.tr, btnName: '确定'.tr,
onClick: () { onClick: () {
logic.senderConfiguringWifiAction(); FocusScope.of(context).requestFocus(FocusNode());
logic.senderConfiguringWifiAction();
}, },
), ),
], ],

View File

@ -9,6 +9,7 @@ class ConfiguringWifiState{
ConfiguringWifiState() { ConfiguringWifiState() {
var map = Get.arguments; var map = Get.arguments;
lockSetInfoData.value = map['lockSetInfoData']; lockSetInfoData.value = map['lockSetInfoData'];
pageName.value = map['pageName'];
lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!; lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!;
if (map['wifiName'] != null) { if (map['wifiName'] != null) {
wifiName.value = map['wifiName']; wifiName.value = map['wifiName'];
@ -20,6 +21,7 @@ class ConfiguringWifiState{
Rx<LockBasicInfo> lockBasicInfo = LockBasicInfo().obs; Rx<LockBasicInfo> lockBasicInfo = LockBasicInfo().obs;
RxString wifiName = ''.obs; RxString wifiName = ''.obs;
RxString pageName = ''.obs;
RxBool ifCurrentScreen = true.obs; // , RxBool ifCurrentScreen = true.obs; // ,
RxInt sureBtnState = 0.obs;// 0() 1() RxInt sureBtnState = 0.obs;// 0() 1()

View File

@ -24,11 +24,18 @@ class _WifiListPageState extends State<WifiListPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return WillPopScope(
backgroundColor: Colors.white, onWillPop: () async {
appBar: TitleAppBar( if (state.pageName.value == 'lockSet') {
return true;
}
return false;
},
child: Scaffold(
backgroundColor: Colors.white,
appBar: TitleAppBar(
barTitle: 'WIFI列表'.tr, barTitle: 'WIFI列表'.tr,
haveBack: true, haveBack: state.pageName.value == 'lockSet',
actionsList: <Widget>[ actionsList: <Widget>[
TextButton( TextButton(
child: Text( child: Text(
@ -38,45 +45,50 @@ class _WifiListPageState extends State<WifiListPage> {
onPressed: logic.senderGetWifiListWifiAction, onPressed: logic.senderGetWifiListWifiAction,
), ),
], ],
backgroundColor: AppColors.mainColor), backgroundColor: AppColors.mainColor,
body: Column( ),
children: <Widget>[ body: Column(
Expanded( children: <Widget>[
child: Obx(() => state.wifiNameDataList.value.isNotEmpty Expanded(
? ListView.builder( child: Obx(() => state.wifiNameDataList.value.isNotEmpty
itemCount: state.wifiNameDataList.value.length, ? ListView.builder(
itemBuilder: (BuildContext c, int index) { itemCount: state.wifiNameDataList.value.length,
Map wifiNameStr = state.wifiNameDataList.value[index]; itemBuilder: (BuildContext c, int index) {
return _messageListItem( Map wifiNameStr = state.wifiNameDataList.value[index];
wifiNameStr['wifiName'], wifiNameStr['rssi'], () { return _messageListItem(
Get.toNamed(Routers.configuringWifiPage, arguments: { wifiNameStr['wifiName'], wifiNameStr['rssi'], () {
'lockSetInfoData': state.lockSetInfoData.value, Get.toNamed(Routers.configuringWifiPage,
'wifiName': wifiNameStr['wifiName'], arguments: {
'lockSetInfoData':
state.lockSetInfoData.value,
'wifiName': wifiNameStr['wifiName'],
'pageName': state.pageName.value,
});
}); });
})
: NoData(
noDataHeight: 1.sh -
ScreenUtil().statusBarHeight -
ScreenUtil().bottomBarHeight -
64.h)),
),
SubmitBtn(
btnName: '手动配网'.tr,
fontSize: 28.sp,
borderRadius: 20.w,
padding: EdgeInsets.only(top: 25.w, bottom: 25.w),
onClick: () {
Get.toNamed(Routers.configuringWifiPage,
arguments: <String, LockSetInfoData>{
'lockSetInfoData': state.lockSetInfoData.value
}); });
}) }),
: NoData( SizedBox(
noDataHeight: 1.sh - height: 64.h,
ScreenUtil().statusBarHeight - )
ScreenUtil().bottomBarHeight - ],
64.h)), )),
), );
SubmitBtn(
btnName: '手动配网'.tr,
fontSize: 28.sp,
borderRadius: 20.w,
padding: EdgeInsets.only(top: 25.w, bottom: 25.w),
onClick: () {
Get.toNamed(Routers.configuringWifiPage,
arguments: <String, LockSetInfoData>{
'lockSetInfoData': state.lockSetInfoData.value
});
}),
SizedBox(
height: 64.h,
)
],
));
} }
Widget _messageListItem(String wifiName, String rssi, Function() action) { Widget _messageListItem(String wifiName, String rssi, Function() action) {

View File

@ -1,18 +1,22 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../lockSet/lockSetInfo_entity.dart'; import '../../lockSet/lockSetInfo_entity.dart';
class WifiListState{// 0() 1() class WifiListState {
// 0() 1()
WifiListState() { WifiListState() {
final map = Get.arguments; final map = Get.arguments;
lockSetInfoData.value = map['lockSetInfoData']; lockSetInfoData.value = map['lockSetInfoData'];
pageName.value = map['pageName'];
lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!; lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!;
} }
final RxList<Map<String, String>> wifiNameDataList = <Map<String, String>>[].obs;
final RxList<Map<String, String>> wifiNameDataList =
<Map<String, String>>[].obs;
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs; Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
Rx<LockBasicInfo> lockBasicInfo = LockBasicInfo().obs; Rx<LockBasicInfo> lockBasicInfo = LockBasicInfo().obs;
RxBool ifCurrentScreen = true.obs; // , RxBool ifCurrentScreen = true.obs; // ,
RxInt sureBtnState = 0.obs; RxInt sureBtnState = 0.obs;
} RxString pageName = ''.obs;
}

View File

@ -595,10 +595,10 @@ class _LockSetPageState extends State<LockSetPage>
isHaveLine: true, isHaveLine: true,
isHaveDirection: true, isHaveDirection: true,
action: () { action: () {
Get.toNamed(Routers.wifiListPage, Get.toNamed(Routers.wifiListPage, arguments: {
arguments: <String, LockSetInfoData>{ 'lockSetInfoData': state.lockSetInfoData.value,
'lockSetInfoData': state.lockSetInfoData.value 'pageName': 'lockSet'
}); });
// Get.toNamed(Routers.configuringWifiPage, arguments: { // Get.toNamed(Routers.configuringWifiPage, arguments: {
// 'lockSetInfoData': state.lockSetInfoData.value // 'lockSetInfoData': state.lockSetInfoData.value
// }); // });

View File

@ -170,7 +170,7 @@ class _VideoLogDetailPageState extends State<VideoLogDetailPage> {
_buildImageItem(RecordListData recordData) { _buildImageItem(RecordListData recordData) {
return RotatedBox( return RotatedBox(
quarterTurns: 1, quarterTurns: -1,
child: Image.network( child: Image.network(
recordData.imagesUrl!, recordData.imagesUrl!,
fit: BoxFit.cover, fit: BoxFit.cover,

View File

@ -345,6 +345,8 @@ class LockFeature {
this.isSupportCatEye, this.isSupportCatEye,
this.isSupportBackupBattery, this.isSupportBackupBattery,
this.isNoSupportedBlueBroadcast, this.isNoSupportedBlueBroadcast,
this.wifiLockType,
this.wifi,
}); });
LockFeature.fromJson(Map<String, dynamic> json) { LockFeature.fromJson(Map<String, dynamic> json) {
@ -360,6 +362,8 @@ class LockFeature {
isSupportCatEye = json['isSupportCatEye']; isSupportCatEye = json['isSupportCatEye'];
isSupportBackupBattery = json['isSupportBackupBattery']; isSupportBackupBattery = json['isSupportBackupBattery'];
isNoSupportedBlueBroadcast = json['isNoSupportedBlueBroadcast']; isNoSupportedBlueBroadcast = json['isNoSupportedBlueBroadcast'];
wifiLockType = json['wifiLockType'];
wifi = json['wifi'];
} }
int? password; int? password;
@ -374,6 +378,8 @@ class LockFeature {
int? isSupportCatEye; int? isSupportCatEye;
int? isSupportBackupBattery; int? isSupportBackupBattery;
int? isNoSupportedBlueBroadcast; int? isNoSupportedBlueBroadcast;
int? wifiLockType;
int? wifi;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
@ -389,6 +395,8 @@ class LockFeature {
data['isSupportCatEye'] = isSupportCatEye; data['isSupportCatEye'] = isSupportCatEye;
data['isSupportBackupBattery'] = isSupportBackupBattery; data['isSupportBackupBattery'] = isSupportBackupBattery;
data['isNoSupportedBlueBroadcast'] = isNoSupportedBlueBroadcast; data['isNoSupportedBlueBroadcast'] = isNoSupportedBlueBroadcast;
data['wifiLockType'] = wifiLockType;
data['wifi'] = wifi;
return data; return data;
} }
} }

View File

@ -1,11 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.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:star_lock/appRouters.dart';
import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_logic.dart'; import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_logic.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import 'package:star_lock/mine/addLock/saveLock/entity/SaveLockEntity.dart'; import 'package:star_lock/mine/addLock/saveLock/entity/SaveLockEntity.dart';
import '../../../app_settings/app_settings.dart'; import '../../../app_settings/app_settings.dart';
@ -408,10 +409,11 @@ class SaveLockLogic extends BaseGetXController {
final String getMobile = (await Storage.getMobile())!; final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('save_lock_result', { ApmHelper.instance.trackEvent('save_lock_result', {
'lock_name':BlueManage().connectDeviceName, 'lock_name': BlueManage().connectDeviceName,
'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, 'account':
'date':DateTool().getNowDateWithType(1), getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'save_lock_result':'成功', 'date': DateTool().getNowDateWithType(1),
'save_lock_result': '成功',
}); });
backAction(); backAction();
// await senderCustomPasswords(); // await senderCustomPasswords();
@ -424,10 +426,11 @@ class SaveLockLogic extends BaseGetXController {
final String getMobile = (await Storage.getMobile())!; final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('save_lock_result', { ApmHelper.instance.trackEvent('save_lock_result', {
'lock_name':BlueManage().connectDeviceName, 'lock_name': BlueManage().connectDeviceName,
'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, 'account':
'date':DateTool().getNowDateWithType(1), getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'save_lock_result':'${entity.errorCode}--${entity.errorMsg}', 'date': DateTool().getNowDateWithType(1),
'save_lock_result': '${entity.errorCode}--${entity.errorMsg}',
}); });
} }
} }
@ -482,20 +485,52 @@ class SaveLockLogic extends BaseGetXController {
// ); // );
// } // }
void backAction() { void backAction() async {
eventBus.fire(RefreshLockListInfoDataEvent(clearScanDevices: true)); eventBus.fire(RefreshLockListInfoDataEvent(clearScanDevices: true));
BlueManage().disconnect(); BlueManage().disconnect();
Future<void>.delayed(const Duration(seconds: 1), () {
Get.close(state.isFromMap == 1 ? (CommonDataManage().seletLockType == 0 ? 4 : 5) : (CommonDataManage().seletLockType == 0 ? 5 : 6)); //
}); final LockSetInfoEntity entity =
// 2 await ApiRepository.to.getLockSettingInfoDataIsNotLoadingIcon(
Future<void>.delayed(const Duration(milliseconds: 200), () { lockId: state.lockId.toString(),
if (Get.isRegistered<LockDetailLogic>()) { );
Get.find<LockDetailLogic>() if (entity.errorCode!.codeIsSuccessful) {
.functionBlocker state.lockSetInfoData.value = entity.data!;
.countdownProhibited(duration: const Duration(seconds: 2)); if (state.lockSetInfoData.value.lockFeature?.wifi == 1) {
// await Future<void>.delayed(const Duration(seconds: 1), () {c
// Get.close(state.isFromMap == 1
// ? (CommonDataManage().seletLockType == 0 ? 4 : 5)
// : (CommonDataManage().seletLockType == 0 ? 5 : 6));
// });
// // 2
// await Future<void>.delayed(const Duration(milliseconds: 200), () {
// if (Get.isRegistered<LockDetailLogic>()) {
// Get.find<LockDetailLogic>()
// .functionBlocker
// .countdownProhibited(duration: const Duration(seconds: 2));
// }
// });
// wifi锁WIFI
Get.toNamed(Routers.wifiListPage, arguments: {
'lockSetInfoData': state.lockSetInfoData.value,
'pageName': 'saveLock'
});
} else {
Future<void>.delayed(const Duration(seconds: 1), () {
Get.close(state.isFromMap == 1
? (CommonDataManage().seletLockType == 0 ? 4 : 5)
: (CommonDataManage().seletLockType == 0 ? 5 : 6));
});
// 2
Future<void>.delayed(const Duration(milliseconds: 200), () {
if (Get.isRegistered<LockDetailLogic>()) {
Get.find<LockDetailLogic>()
.functionBlocker
.countdownProhibited(duration: const Duration(seconds: 2));
}
});
} }
}); }
} }
@override @override

View File

@ -3,6 +3,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import '../../../blue/blue_manage.dart'; import '../../../blue/blue_manage.dart';
@ -25,7 +26,7 @@ class SaveLockState {
RxString aliName = ''.obs; RxString aliName = ''.obs;
RxInt pwdTimestamp = 0.obs; RxInt pwdTimestamp = 0.obs;
RxMap addressInfo = {}.obs; RxMap addressInfo = {}.obs;
final Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
TextEditingController aliNameController = TextEditingController(); TextEditingController aliNameController = TextEditingController();
FocusNode focusNode = FocusNode(); FocusNode focusNode = FocusNode();

View File

@ -24,7 +24,7 @@ class StarLockMineLogic extends BaseGetXController {
// //
Future<void> userLogoutRequest() async { Future<void> userLogoutRequest() async {
final LoginEntity entity = await ApiRepository.to.userLogout(deviceld: ''); final LoginEntity entity = await ApiRepository.to.userLogout(storageNonce: '');
if (entity.errorCode!.codeIsSuccessful) {} if (entity.errorCode!.codeIsSuccessful) {}
} }

View File

@ -130,7 +130,7 @@ class MineSetLogic extends BaseGetXController {
} }
}); });
final LoginEntity entity = final LoginEntity entity =
await ApiRepository.to.userLogout(deviceld: getPushDeviceID); await ApiRepository.to.userLogout(storageNonce: getPushDeviceID);
final String getMobile = (await Storage.getMobile())!; final String getMobile = (await Storage.getMobile())!;
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
ApmHelper.instance.logout(); ApmHelper.instance.logout();
@ -169,6 +169,8 @@ class MineSetLogic extends BaseGetXController {
///退 ///退
void logOut() async { void logOut() async {
final XSJPushProvider jpushProvider = XSJPushProvider();
await jpushProvider.resetJPushService();
Storage.clearAll(); Storage.clearAll();
} }

View File

@ -292,21 +292,20 @@ class _MineSetPageState extends State<MineSetPage>
SizedBox( SizedBox(
height: 10.h, height: 10.h,
), ),
Obx(() {
// AppLog.log('state.currentLanguageName: ${state.currentLanguageName} state.currentLanguage.value: ${state.currentLanguage.value}'); // AppLog.log('state.currentLanguageName: ${state.currentLanguageName} state.currentLanguage.value: ${state.currentLanguage.value}');
return CommonItem( CommonItem(
leftTitel: '多语言'.tr, leftTitel: '多语言'.tr,
rightTitle: state.currentLanguageName, rightTitle: state.currentLanguageName,
isHaveLine: true, isHaveLine: true,
isHaveDirection: true, isHaveDirection: true,
action: () async { action: () async {
// Get.toNamed(Routers.mineMultiLanguagePage); // Get.toNamed(Routers.mineMultiLanguagePage);
await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) { await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) {
state.currentLanguage.value = value['currentLanguage']; state.currentLanguage.value = value['currentLanguage'];
setState(() {}); setState(() {});
});
}); });
}), }),
/* 2024-01-12 by DaisyWu /* 2024-01-12 by DaisyWu
Obx(() => CommonItem( Obx(() => CommonItem(
leftTitel: TranslationLoader.lanKeys!.lockScreen!.tr, leftTitel: TranslationLoader.lanKeys!.lockScreen!.tr,

View File

@ -67,8 +67,7 @@ abstract class Api {
final String getWifiServiceIpURL = '/wifiLock/getWifiServiceIp'; // Wifi锁服务器 final String getWifiServiceIpURL = '/wifiLock/getWifiServiceIp'; // Wifi锁服务器
final String updateLockSettingUrl = final String updateLockSettingUrl =
'/v2/lockSetting/updateLockSetting'; // '/v2/lockSetting/updateLockSetting'; //
final String deviceNetworkConfiguration = final String deviceNetworkConfiguration = '/deviceNetwork/setting'; //
'/deviceNetwork/setting'; //
final String getDeviceNetworkConfiguration = final String getDeviceNetworkConfiguration =
'/deviceNetwork/getNetworkInfo'; // '/deviceNetwork/getNetworkInfo'; //
final String roomQueryDateUrl = '/room/queryDate'; // final String roomQueryDateUrl = '/room/queryDate'; //
@ -195,6 +194,7 @@ abstract class Api {
final String setAppUnlockMustOnlineURL = final String setAppUnlockMustOnlineURL =
'/room/setAppUnlockMustOnline'; //APP开锁时需手机联网的锁 '/room/setAppUnlockMustOnline'; //APP开锁时需手机联网的锁
final String userLogoutURL = '/v2/user/logout'; //退 final String userLogoutURL = '/v2/user/logout'; //退
final String userLogout3URL = '/v3/user/logout'; //退
final String deleteAccountURL = '/user/delete'; // final String deleteAccountURL = '/user/delete'; //
final String getUserInfoURL = '/user/getUserInfo'; // final String getUserInfoURL = '/user/getUserInfo'; //
final String sendValidationCodeAuthURL = final String sendValidationCodeAuthURL =
@ -214,6 +214,7 @@ abstract class Api {
final String unbindPhoneTokenURL = '/user/unbindPhoneToken'; //Token final String unbindPhoneTokenURL = '/user/unbindPhoneToken'; //Token
final String unbindEmailTokenURL = '/user/unbindEmailToken'; //Token final String unbindEmailTokenURL = '/user/unbindEmailToken'; //Token
final String pushBindAppIdURL = '/user/bindAppId'; //APP设备 final String pushBindAppIdURL = '/user/bindAppId'; //APP设备
final String bindPushTokenURL = '/user/bindPushToken'; //APP设备
final String messageListURL = '/notifications/list'; // final String messageListURL = '/notifications/list'; //
final String readMessageURL = '/notifications/markAsRead'; // final String readMessageURL = '/notifications/markAsRead'; //

View File

@ -423,6 +423,15 @@ class ApiProvider extends BaseProvider {
'lockId': lockId, 'lockId': lockId,
})); }));
//
Future<Response> getLockSettingInfoDataIsNotLoadingIcon(String lockId) =>
post(
getLockSettingURL.toUrl,
jsonEncode({
'lockId': lockId,
}),
isUnShowLoading: true);
// //
Future<Response> deletLockInfo(int lockId) => post( Future<Response> deletLockInfo(int lockId) => post(
deletLockURL.toUrl, deletLockURL.toUrl,
@ -1950,8 +1959,8 @@ class ApiProvider extends BaseProvider {
})); }));
//退 //退
Future<Response> userLogout(String deviceld) => Future<Response> userLogout(String storageNonce) =>
post(userLogoutURL.toUrl, jsonEncode({'deviceld': deviceld})); post(userLogout3URL.toUrl, jsonEncode({'storageNonce': storageNonce}));
// //
Future<Response> deleteAccount( Future<Response> deleteAccount(
@ -2115,6 +2124,12 @@ class ApiProvider extends BaseProvider {
pushBindAppIdURL.toUrl, pushBindAppIdURL.toUrl,
jsonEncode({'deviceId': deviceId, 'deviceType': deviceType})); jsonEncode({'deviceId': deviceId, 'deviceType': deviceType}));
//channel绑定
Future<Response> pushBindChannels(
String storageNonce, List<Map<String, dynamic>> channels) =>
post(bindPushTokenURL.toUrl,
jsonEncode({'storageNonce': storageNonce, 'channels': channels}));
// //
Future<Response> messageListLoadData(String pageNo, String pageSize) => post( Future<Response> messageListLoadData(String pageNo, String pageSize) => post(
messageListURL.toUrl, messageListURL.toUrl,

View File

@ -486,6 +486,12 @@ class ApiRepository {
final res = await apiProvider.getLockSettingInfoData(lockId); final res = await apiProvider.getLockSettingInfoData(lockId);
return LockSetInfoEntity.fromJson(res.body); return LockSetInfoEntity.fromJson(res.body);
} }
// ()
Future<LockSetInfoEntity> getLockSettingInfoDataIsNotLoadingIcon(
{required String lockId}) async {
final res = await apiProvider.getLockSettingInfoDataIsNotLoadingIcon(lockId);
return LockSetInfoEntity.fromJson(res.body);
}
// //
Future<LockListInfoEntity> deletOwnerLockData({required int lockId}) async { Future<LockListInfoEntity> deletOwnerLockData({required int lockId}) async {
@ -1871,8 +1877,8 @@ class ApiRepository {
} }
// 退 // 退
Future<LoginEntity> userLogout({required String deviceld}) async { Future<LoginEntity> userLogout({required String storageNonce}) async {
final res = await apiProvider.userLogout(deviceld); final res = await apiProvider.userLogout(storageNonce);
return LoginEntity.fromJson(res.body); return LoginEntity.fromJson(res.body);
} }
@ -2170,6 +2176,13 @@ class ApiRepository {
return MineUnbindPhoneOrEmailEntity.fromJson(res.body); return MineUnbindPhoneOrEmailEntity.fromJson(res.body);
} }
//channel绑定
Future<MineUnbindPhoneOrEmailEntity> pushBindChannels(
String storageNonce, List<Map<String, dynamic>> channels) async {
final res = await apiProvider.pushBindChannels(storageNonce, channels);
return MineUnbindPhoneOrEmailEntity.fromJson(res.body);
}
// //
Future<MessageListEntity> messageListLoadData( Future<MessageListEntity> messageListLoadData(
{required String pageNo, required String pageSize}) async { {required String pageNo, required String pageSize}) async {
@ -2731,7 +2744,4 @@ class ApiRepository {
); );
return DeviceNetwork.fromJson(res.body); return DeviceNetwork.fromJson(res.body);
} }
} }

View File

@ -160,6 +160,8 @@ 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

@ -1,52 +1,51 @@
import 'dart:collection';
import 'dart:typed_data';
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 Map<int, TalkDataH264Frame> _frameBuffer = {}; final LinkedHashMap<int, TalkDataH264Frame> _frameBuffer = LinkedHashMap();
final void Function(List<int> frameData) onCompleteFrame; final void Function(List<int> frameData) onCompleteFrame;
int _lastProcessedSeq = -1;
final LinkedHashMap<int, TalkDataH264Frame_FrameTypeE> _frameTypeIndex = LinkedHashMap();
H264FrameHandler({required this.onCompleteFrame}); H264FrameHandler({required this.onCompleteFrame});
void handleFrame(TalkDataH264Frame frame) { void handleFrame(TalkDataH264Frame frame) {
// //
_frameBuffer[frame.frameSeq] = frame; _frameBuffer[frame.frameSeq] = frame;
_frameTypeIndex[frame.frameSeq] = frame.frameType;
// GOP (Group of Pictures) // GOP (Group of Pictures)
_tryAssembleFrames(frame.frameSeq); _tryAssembleFrames(frame.frameSeq);
} }
void _tryAssembleFrames(int currentSeq) { void _tryAssembleFrames(int currentSeq) {
//
final List<int> sortedSeqs = _frameBuffer.keys.toList()..sort();
final List<int> framesToProcess = []; final List<int> framesToProcess = [];
int? startFrameSeq;
// I P // I P
int? startFrameSeq; for (int seq = currentSeq; seq >= 0; seq--) {
for (var seq in sortedSeqs.reversed) { final frameType = _frameTypeIndex[seq];
final frame = _frameBuffer[seq]; if (frameType == null) continue;
if (frame?.frameType == TalkDataH264Frame_FrameTypeE.I) { if (frameType == TalkDataH264Frame_FrameTypeE.I) {
startFrameSeq = seq; startFrameSeq = seq;
break; break;
} else if (frame?.frameType == TalkDataH264Frame_FrameTypeE.P) { } else if (frameType == TalkDataH264Frame_FrameTypeE.P) {
// P I if (_frameBuffer.containsKey(_frameBuffer[seq]!.frameSeqI)) {
if (_frameBuffer.containsKey(frame?.frameSeqI)) {
startFrameSeq = seq; startFrameSeq = seq;
break; break;
} else { } else {
// I P
_frameBuffer.remove(seq); _frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
} }
} }
} }
if (startFrameSeq != null) { if (startFrameSeq != null) {
// I P for (int seq = startFrameSeq; _frameBuffer.containsKey(seq); seq++) {
int expectedSeq = startFrameSeq;
for (var seq in sortedSeqs.where((s) => s >= startFrameSeq!)) {
if (seq != expectedSeq) break;
framesToProcess.add(seq); framesToProcess.add(seq);
expectedSeq++;
} }
if (framesToProcess.isNotEmpty) { if (framesToProcess.isNotEmpty) {
@ -57,28 +56,50 @@ class H264FrameHandler {
} }
} }
void _clearOldFrames(int currentSeq) {
//
_frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); //
}
void _processFrames(List<int> frameSeqs) { void _processFrames(List<int> frameSeqs) {
// //
final List<int> assembledData = []; // 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) { for (var seq in frameSeqs) {
final frame = _frameBuffer[seq]!; final frame = _frameBuffer[seq]!;
assembledData.addAll(frame.frameData); assembledData.setRange(
offset, offset + frame.frameData.length, frame.frameData);
offset += frame.frameData.length;
// // Remove the frame from the buffer after processing
_frameBuffer.remove(seq); _frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
} }
// // Callback with the complete frame data
onCompleteFrame(assembledData); onCompleteFrame(assembledData);
} }
void clear() { void clear() {
_frameBuffer.clear(); _frameBuffer.clear();
} }
void _clearOldFrames(int currentSeq) {
//
_frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); //
_frameTypeIndex.removeWhere((seq, frameType) => seq < currentSeq - 200);
}
} }

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -13,11 +15,37 @@ import 'package:star_lock/tools/storage.dart';
import '../../app_settings/app_settings.dart'; import '../../app_settings/app_settings.dart';
class XSJPushProvider { class XSJPushProvider {
static const Map<int, String> channelTypeMapping = <int, String>{
1: 'xiaomi',
2: 'huawei',
3: 'meizu',
4: 'oppo',
5: 'vivo',
6: 'honor',
7: 'apns',
8: 'fcm',
9: 'jiguang'
};
final JPush jpush = JPush(); final JPush jpush = JPush();
late Completer<Map<String, dynamic>> _jpushRegistrationIdCompleter;
late Completer<Map<String, dynamic>> _vendorTokenCompleter;
Future<void> resetJPushService() async {
debugPrint("resetJPushService start");
jpush.setup(
appKey: '',
channel: 'flutter_channel',
production: F.isProductionEnv,
debug: !F.isProductionEnv,
);
}
// appKey: 251fc8074820d122b6de58d2--AppKey // appKey: 251fc8074820d122b6de58d2--AppKey
// appKey: 7ff37d174c1a568a89e98dad--sky // appKey: 7ff37d174c1a568a89e98dad--sky
Future<void> initJPushService() async { Future<void> initJPushService() async {
debugPrint("initJPushService start");
_jpushRegistrationIdCompleter = Completer<Map<String, dynamic>>();
_vendorTokenCompleter = Completer<Map<String, dynamic>>();
final String? data = await Storage.getString(saveUserLoginData); final String? data = await Storage.getString(saveUserLoginData);
if (data == null || data.isEmpty) { if (data == null || data.isEmpty) {
AppLog.log('No user data found.'); AppLog.log('No user data found.');
@ -34,25 +62,49 @@ class XSJPushProvider {
production: F.isProductionEnv, production: F.isProductionEnv,
debug: !F.isProductionEnv, debug: !F.isProductionEnv,
); );
jpush.applyPushAuthority( jpush.applyPushAuthority(
const NotificationSettingsIOS(sound: true, alert: true, badge: false), const NotificationSettingsIOS(sound: true, alert: true, badge: false),
); );
addJPushEventHandler(); addJPushEventHandler();
AppLog.log('JPush initialized.'); AppLog.log('JPush initialized.');
debugPrint("initJPushService end");
final String rid = await jpush.getRegistrationID();
AppLog.log('flutter get registration id : $rid');
pushBindDeviceID(rid);
} }
static const int CMD_GET_REGISTRATION_ID = 2005; //getRegistrationID
static const int CMD_GET_TOKEN = 10000; // token
// //
void addJPushEventHandler() { void addJPushEventHandler() {
jpush.addEventHandler( jpush.addEventHandler(
onCommandResult: (Map<String, dynamic> message) async { onCommandResult: (Map<String, dynamic> data) async {
AppLog.log('onCommandResult: $message'); AppLog.log('onCommandResult: $data');
debugPrint("addJPushEventHandler onCommandResult:$message"); debugPrint("addJPushEventHandler onCommandResult:$data");
final int cmdCode = data['cmd'];
switch (cmdCode) {
case CMD_GET_REGISTRATION_ID:
await Storage.setString(pushDeviceID, data['message']);
AppLog.log('flutter get registration id : ${data['message']}');
_jpushRegistrationIdCompleter.complete(<String, dynamic>{
'channel': 'jiguang',
'channelToken': data['message']
});
// final String? channel2TokenStr =
// await Storage.getString(vendorPushChannelInfo);
// if (Platform.isAndroid && channel2TokenStr != null) {
// _vendorTokenCompleter.complete(jsonDecode(channel2TokenStr));
// }
break;
case CMD_GET_TOKEN:
final Map<String, dynamic> channel2Token = <String, dynamic>{
'channel': channelTypeMapping[data['platform']],
'channelToken': data['token']
};
await Storage.setString(
vendorPushChannelInfo, jsonEncode(channel2Token));
_vendorTokenCompleter.complete(channel2Token);
break;
}
}, },
onReceiveNotification: (Map<String, dynamic> message) async { onReceiveNotification: (Map<String, dynamic> message) async {
AppLog.log('onReceiveNotification: $message'); AppLog.log('onReceiveNotification: $message');
@ -79,32 +131,22 @@ class XSJPushProvider {
debugPrint("addJPushEventHandler onInAppMessageShow:$message"); debugPrint("addJPushEventHandler onInAppMessageShow:$message");
}, },
onConnected: (Map<String, dynamic> message) async { onConnected: (Map<String, dynamic> message) async {
//id
final String rid = await jpush.getRegistrationID();
AppLog.log('onConnected registration id : $rid');
debugPrint("addJPushEventHandler onConnected:$message");
await Storage.setString(pushDeviceID, rid);
await pushBindDeviceID(rid);
return Future.value(); return Future.value();
}, },
); );
bindPushChannels();
// Remove the incorrect addEventHandler call
} }
Future<void> pushBindDeviceID(String deviceID) async { // jpush
Future<void> bindPushChannels() async {
try { try {
if (deviceID.isEmpty) { debugPrint("await PushChannels start");
AppLog.log('Device ID is empty.'); var channels = await Future.wait(
//id [_jpushRegistrationIdCompleter.future, _vendorTokenCompleter.future]);
final String rid = await jpush.getRegistrationID(); final String? registrationId = await Storage.getString(pushDeviceID);
AppLog.log('onConnected registration id : $rid'); debugPrint("await PushChannels end");
deviceID = rid; final MineUnbindPhoneOrEmailEntity entity =
} await ApiRepository.to.pushBindChannels(registrationId!, channels);
await Storage.setString(pushDeviceID, deviceID);
final MineUnbindPhoneOrEmailEntity entity = await ApiRepository.to
.pushBindAppId(deviceID, Platform.isAndroid ? 10 : 20);
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
AppLog.log('绑定成功'); AppLog.log('绑定成功');
} else { } else {

View File

@ -25,6 +25,7 @@ const String isAgreeCamera = 'isAgreeCamera'; //是否同意获取相机/相册
const String isShowUpdateVersion = 'isShowUpdateVersion'; // const String isShowUpdateVersion = 'isShowUpdateVersion'; //
const String saveLockAlias = 'saveLockAlias'; // const String saveLockAlias = 'saveLockAlias'; //
const String pushDeviceID = 'pushDeviceID'; //ID const String pushDeviceID = 'pushDeviceID'; //ID
const String vendorPushChannelInfo = 'pushChannelInfo'; //ID
const String saveIsVip = 'saveIsVip'; //VIP const String saveIsVip = 'saveIsVip'; //VIP
const String saveUserLoginData = 'userLoginData'; const String saveUserLoginData = 'userLoginData';
@ -37,6 +38,7 @@ const String relayInfo = 'relayInfo'; //星图中继服务器信息
const String lockNetWorkInfo = 'lockNetWorkInfo'; // const String lockNetWorkInfo = 'lockNetWorkInfo'; //
const String appVersionHistoryUrl = 'appVersionHistoryUrl'; // const String appVersionHistoryUrl = 'appVersionHistoryUrl'; //
class Storage { class Storage {
factory Storage() => _instance; factory Storage() => _instance;

View File

@ -992,8 +992,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: "807ddb8e396c2dce16919df84efe795072404dde" ref: ed2bd31147ccc929d9b9cf47205c2b8142a6d3f2
resolved-ref: "807ddb8e396c2dce16919df84efe795072404dde" resolved-ref: ed2bd31147ccc929d9b9cf47205c2b8142a6d3f2
url: "git@code-internal.star-lock.cn:StarlockTeam/jpush_flutter.git" url: "git@code-internal.star-lock.cn:StarlockTeam/jpush_flutter.git"
source: git source: git
version: "2.5.8" version: "2.5.8"

View File

@ -214,7 +214,7 @@ dependencies:
jpush_flutter: jpush_flutter:
git: git:
url: git@code-internal.star-lock.cn:StarlockTeam/jpush_flutter.git url: git@code-internal.star-lock.cn:StarlockTeam/jpush_flutter.git
ref: 807ddb8e396c2dce16919df84efe795072404dde ref: ed2bd31147ccc929d9b9cf47205c2b8142a6d3f2
#视频播放器 #视频播放器
video_player: ^2.9.2 video_player: ^2.9.2