develop_sky #1

Merged
liyi merged 62 commits from develop_sky into develop_sky_liyi 2025-09-22 17:48:20 +08:00
49 changed files with 43393 additions and 43106 deletions
Showing only changes of commit c4c82ea8f8 - Show all commits

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1162,5 +1162,9 @@
"锁语音包设置": "鎖語音包設定",
"(中国台湾)": "(中国台湾)",
"男声": "男聲",
"女声": "女聲"
"女声": "女聲",
"您的图像和视频数据仅保留": "您的圖像和視頻數據僅保留",
"后图像和视频数据将会失效,开通": "后圖像和視頻數據將會失效,開通",
"云存会员": "雲存會員",
"服务,图像视频信息随心存!": "服務,圖像視頻資訊隨心存!"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1172,5 +1172,9 @@
"语音包设置": "语音包设置",
"(中国台湾)": "(中国台湾)",
"男声": "男声",
"女声": "女声"
"女声": "女声",
"您的图像和视频数据仅保留": "您的图像和视频数据仅保留",
"后图像和视频数据将会失效,开通": "后图像和视频数据将会失效,开通",
"云存会员": "云存会员",
"服务,图像视频信息随心存!": "服务,图像视频信息随心存!"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1166,5 +1166,9 @@
"语音包设置": "Configurações do pacote de voz",
"(中国台湾)": "(中国台湾)",
"男声": "Macho",
"女声": "Garota"
"女声": "Garota",
"您的图像和视频数据仅保留": "Seus dados de imagem e vídeo são retidos apenas",
"后图像和视频数据将会失效,开通": "Depois disso, os dados de imagem e vídeo serão inválidos e ativados",
"云存会员": "Associação de armazenamento em nuvem",
"服务,图像视频信息随心存!": "Informações de serviço, imagem e vídeo estão no seu coração!"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1161,5 +1161,9 @@
"锁语音包设置": "Закључајте подешавања говорног пакета",
"(中国台湾)": "(中国台湾)",
"男声": "мушки глас",
"女声": "женски глас"
"女声": "женски глас",
"您的图像和视频数据仅保留": "Ваши подаци о слици и видео записима се задржавају само",
"后图像和视频数据将会失效,开通": "Након тога, сликовни и видео подаци ће бити неважећи и активирани",
"云存会员": "Чланство у облаку за складиштење",
"服务,图像视频信息随心存!": "Сервис , слике и видео информације су у вашем срцу!"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1161,5 +1161,9 @@
"锁语音包设置": "鎖語音包設定",
"(中国台湾)": "(中国台湾)",
"男声": "男聲",
"女声": "女聲"
"女声": "女聲",
"您的图像和视频数据仅保留": "您的圖像和視頻數據僅保留",
"后图像和视频数据将会失效,开通": "后圖像和視頻數據將會失效,開通",
"云存会员": "雲存會員",
"服务,图像视频信息随心存!": "服務,圖像視頻資訊隨心存!"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,6 @@
"授权管理员拥有操作这把锁的重要权限,请确保只发给我你信任的人": "授权管理员拥有操作这把锁的重要权限,请确保只发给我你信任的人",
"功能开启后,你将可以通过网关远程开锁。此功能的开启和关闭只能在锁附近通过手机蓝牙进行。": "功能开启后,你将可以通过网关远程开锁。此功能的开启和关闭只能在锁附近通过手机蓝牙进行。",
"此功能的开启和关闭只能在锁附近通过手机蓝牙进行": "此功能的开启和关闭只能在锁附近通过手机蓝牙进行",
"功能开启后,你将可以通过网关远程开锁。": "功能开启后,你将可以通过网关远程开锁。",
"排列方式": "排列方式",
"早到榜": "早到榜",
@ -1102,7 +1101,7 @@
"支持的国家": "支持的国家",
"支持的国家值": "美国、加拿大、英国、澳大利亚、印度、德国、法国、意大利、西班牙、日本",
"操作流程": "操作流程",
"操作流程值":"1 用智能锁APP添加锁和网关\n\n2 在APP里开启锁的远程开锁功能这个功能默认是关闭的。如果没有这个选项则锁不支持Alexa \n\n3 在Alexa中添加Skill并用智能锁APP的账号和密码进行授权。授权成功后就可以发现账号下的设备\n\n4 在Alexa app里找到锁开启语音开锁的功能并设置语言密码\n\n5 可以通过Alexa操作锁了",
"操作流程值": "1 用智能锁APP添加锁和网关\n\n2 在APP里开启锁的远程开锁功能这个功能默认是关闭的。如果没有这个选项则锁不支持Alexa \n\n3 在Alexa中添加Skill并用智能锁APP的账号和密码进行授权。授权成功后就可以发现账号下的设备\n\n4 在Alexa app里找到锁开启语音开锁的功能并设置语言密码\n\n5 可以通过Alexa操作锁了",
"Google Home": "Google Home",
"Action name": "Action name",
"ScienerSmart": "ScienerSmart",
@ -1174,5 +1173,9 @@
"语音包设置": "语音包设置",
"(中国台湾)": "(中国台湾)",
"男声": "男声",
"女声": "女声"
}
"女声": "女声",
"您的图像和视频数据仅保留": "您的图像和视频数据仅保留",
"后图像和视频数据将会失效,开通": "后图像和视频数据将会失效,开通",
"云存会员": "云存会员",
"服务,图像视频信息随心存!": "服务,图像视频信息随心存!"
}

View File

@ -125,4 +125,9 @@ class DoorLockLogDataItem {
data['recordDetailStr'] = recordDetailStr;
return data;
}
@override
String toString() {
return 'DoorLockLogDataItem{recordId: $recordId, lockId: $lockId, lockAlias: $lockAlias, recordType: $recordType, recordTypeName: $recordTypeName, username: $username, operateDate: $operateDate, imagesUrl: $imagesUrl, videoUrl: $videoUrl, headUrl: $headUrl, userid: $userid, keyboardPwd: $keyboardPwd, recordStr: $recordStr, recordDetailStr: $recordDetailStr}';
}
}

View File

@ -3,12 +3,15 @@ import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:star_lock/apm/apm_helper.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/date_time_extensions.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_state.dart';
import 'package:star_lock/main/lockDetail/lockOperatingRecord/lockOperatingRecordGetLastRecordTime_entity.dart';
import 'package:star_lock/mine/valueAddedServices/advancedFeaturesWeb/advancedFeaturesWeb_entity.dart';
import 'package:star_lock/tools/commonDataManage.dart';
import 'package:star_lock/tools/dateTool.dart';
import 'package:star_lock/tools/eventBusEventManage.dart';
@ -402,7 +405,20 @@ class DoorLockLogLogic extends BaseGetXController {
void refreshWeek() {
_setWeekRange();
}
getWebPlayUrl() async {
final AdvancedFeaturesWebEntity entity =
await ApiRepository.to.getServicePackageBuyUrl();
if (entity.errorCode!.codeIsSuccessful) {
state.cloudStorageWebViewUrl.value = entity.data!.cloudStorage!;
final uploadReportBuyRequest = await ApiRepository.to
.uploadReportBuyRequest(lockId: state.keyInfos.value.lockId!);
if (uploadReportBuyRequest.errorCode!.codeIsSuccessful) {
Get.toNamed(Routers.advancedFeaturesWebPage, arguments: <String, int>{
'webBuyType': XSConstantMacro.webBuyTypeCloudStorage,
});
}
}
}
@override
Future<void> onClose() async {
super.onClose();

View File

@ -1,4 +1,5 @@
import 'package:flustars/flustars.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -284,6 +285,17 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
return formatter.format(dateTime);
}
bool _checkIsVideoOrImagesType(DoorLockLogDataItem item) {
final recordType = item.recordType;
switch (recordType) {
case 130:
case 220:
return true;
default:
return false;
}
}
String _buildIDByType(DoorLockLogDataItem item) {
final recordType = item.recordType;
switch (recordType) {
@ -407,6 +419,14 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
itemCount: state.lockLogItemList.length,
contentsBuilder: (BuildContext context, int index) {
final DoorLockLogDataItem timelineData = state.lockLogItemList[index];
// 👇 videoUrl build
int? firstVideoIndex = state.lockLogItemList
.indexWhere((item) => _checkIsVideoOrImagesType(item));
bool isInvalid = _checkIsVideoOrImagesType(timelineData) &&
((timelineData.imagesUrl == null &&
timelineData.videoUrl == null) ||
(timelineData.videoUrl == '' && timelineData.imagesUrl == ''));
AppLog.log('isInvalid:${isInvalid}');
return GestureDetector(
onTap: () {
Get.toNamed(
@ -428,17 +448,33 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
// 使 SingleChildScrollView
SingleChildScrollView(
scrollDirection: Axis.horizontal, //
child: Text(
_buildIDByType(timelineData),
child: RichText(
textAlign: TextAlign.left,
style: TextStyle(
color: _buildTextColorByType(timelineData),
fontSize: 24.sp,
fontWeight: FontWeight.w600,
text: TextSpan(
style: TextStyle(
color: _buildTextColorByType(timelineData),
fontSize: 24.sp,
fontWeight: FontWeight.w600,
),
children: [
TextSpan(
text: _buildIDByType(timelineData) +
(isInvalid ? '' + '已失效'.tr + '' : ''),
),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Visibility(
visible: isInvalid,
child: Icon(
Icons.error,
size: 24.sp,
color: Colors.red,
),
),
),
],
),
//
maxLines: 1,
//
overflow: TextOverflow.ellipsis,
),
),
@ -455,8 +491,71 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
),
),
SizedBox(
height: 20.h,
height: 12.h,
),
Visibility(
visible: _checkIsVideoOrImagesType(timelineData) &&
index == firstVideoIndex,
child: GestureDetector(
onTap: () async {
await logic.getWebPlayUrl();
},
child: Container(
padding: EdgeInsets.all(8.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.r)),
),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
//
TextSpan(
text:
'${'您的图像和视频数据仅保留'.tr} ${state.rollingStorageDays.value} ${''.tr} ,${state.rollingStorageDays.value} ${''.tr} ${'后图像和视频数据将会失效,开通'.tr}',
style: TextStyle(
color: Colors.grey,
fontSize: 16.sp,
fontWeight: FontWeight.w600,
height: 1.8,
),
),
// 🔥
TextSpan(
text: '云存会员'.tr,
style: TextStyle(
color: AppColors.mainColor,
fontSize: 22.sp,
fontWeight: FontWeight.w800,
//
decoration: TextDecoration.underline,
decorationThickness: 1.5,
height: 1.8,
),
recognizer: TapGestureRecognizer()
..onTap = () async {
// 👉
print('点击了“云存会员”');
await logic.getWebPlayUrl();
// Navigator.push(context, MaterialPageRoute(builder: ...));
},
),
//
TextSpan(
text: '服务,图像视频信息随心存!'.tr,
style: TextStyle(
color: Colors.grey,
fontSize: 16.sp,
fontWeight: FontWeight.w600,
height: 1.8,
),
),
],
),
),
),
),
)
],
),
),

View File

@ -1,4 +1,5 @@
import 'package:get/get.dart';
import 'package:get/get_rx/get_rx.dart';
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart';
import 'package:star_lock/tools/advancedCalendar/src/controller.dart';
@ -73,4 +74,6 @@ class DoorLockLogState {
int logCountPage = 10; //
Rx<DateTime> currentSelectDate = DateTime.now().obs;
bool isLockReceiveResponse = false; //
RxString cloudStorageWebViewUrl = ''.obs;
RxInt rollingStorageDays = 3.obs; //
}

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/blue/blue_manage.dart';
import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsWithParameters.dart';
import 'package:star_lock/blue/io_reply.dart';
@ -82,30 +83,31 @@ class CatEyeSetLogic extends BaseGetXController {
//
cancelBlueConnetctToastTimer();
dismissEasyLoading();
AppLog.log('state.settingOptions.value:${state.settingOptions.value}');
switch (state.settingOptions.value) {
case 1: //
{
updateAutoLightScreenConfig();
await updateAutoLightScreenConfig();
}
break;
case 2: //
{
updateStayWarnConfig();
await updateStayWarnConfig();
}
break;
case 3: //
{
updateAbnormalWarnConfig();
await updateAbnormalWarnConfig();
}
break;
case 4: //
{
updateLightScreenTimeConfig();
await updateLightScreenTimeConfig();
}
break;
case 5: //
{
updateCatEyeModeConfig();
await updateCatEyeModeConfig();
}
break;
default:
@ -288,6 +290,7 @@ class CatEyeSetLogic extends BaseGetXController {
.catEyeConfig![0]
.catEyeModeConfig
?.realTimeMode = state.catEyeConfig.value.realTimeMode;
eventBus
.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
}
@ -456,6 +459,10 @@ class CatEyeSetLogic extends BaseGetXController {
}
void sendBlueMessage() {
showEasyLoading();
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
});
final message = _buildCatEyeSetBlueMessage();
BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async {

View File

@ -104,10 +104,10 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
codecType: 'h264',
);
// textureId
AppLog.log('StartChartManage().videoWidth:${StartChartManage()
.videoWidth}');
AppLog.log('StartChartManage().videoHeight:${StartChartManage()
.videoHeight}');
AppLog.log(
'StartChartManage().videoWidth:${StartChartManage().videoWidth}');
AppLog.log(
'StartChartManage().videoHeight:${StartChartManage().videoHeight}');
final textureId = await VideoDecodePlugin.initDecoder(config);
if (textureId != null) {
Future.microtask(() => state.textureId.value = textureId);
@ -746,7 +746,6 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
//
Future<void> startProcessingAudio() async {
try {
if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) {
await state.voiceProcessor?.start(state.frameLength, state.sampleRate);
@ -793,27 +792,13 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
//
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;
return pcmData.map((sample) {
//
int amplified = (sample * gainFactor).round();
return amplified.clamp(-32768, 32767);
}).toList();
}
static const int chunkSize = 320; // 32010ms G.711
static const int intervalMs = 35; // 40ms发送一次4chunk
void _sendAudioChunk(Timer timer) async {
@ -849,10 +834,11 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
List<int> encodedData = G711Tool.encode(applyGain, 0); // 0A-law
_bufferedAudioFrames.addAll(encodedData);
//
if (_startProcessingAudioTimer == null && _bufferedAudioFrames.length > chunkSize) {
_startProcessingAudioTimer = Timer.periodic(Duration(milliseconds: intervalMs), _sendAudioChunk);
if (_startProcessingAudioTimer == null &&
_bufferedAudioFrames.length > chunkSize) {
_startProcessingAudioTimer =
Timer.periodic(Duration(milliseconds: intervalMs), _sendAudioChunk);
}
}