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

# Conflicts:
#	pubspec.yaml
This commit is contained in:
“DaisyWu” 2025-01-21 15:14:22 +08:00
commit 2ee6782714
78 changed files with 1193 additions and 452 deletions

View File

@ -20,6 +20,7 @@ variables:
- if: $CI_COMMIT_BRANCH == "release" - if: $CI_COMMIT_BRANCH == "release"
- if: $CI_COMMIT_BRANCH =~ /feat_[a-zA-Z]+/ - if: $CI_COMMIT_BRANCH =~ /feat_[a-zA-Z]+/
- if: $CI_COMMIT_BRANCH == "canary_release" - if: $CI_COMMIT_BRANCH == "canary_release"
- if: $CI_COMMIT_BRANCH == "develop_liyi"
- if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z]+\.[0-9]+)?$/ - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z]+\.[0-9]+)?$/
.notify_rule: .notify_rule:

View File

@ -78,6 +78,13 @@ android {
keyAlias = 'upload' keyAlias = 'upload'
keyPassword 'xhj8872' keyPassword 'xhj8872'
} }
xhj_bundle {
storeFile file("xhj_bundle.jks")
storePassword 'xhj8872'
keyAlias = 'xhj'
keyPassword 'xhj8872'
}
} }
// ----- BEGIN flavorDimensions (autogenerated by flutter_flavorizr) ----- // ----- BEGIN flavorDimensions (autogenerated by flutter_flavorizr) -----
@ -135,6 +142,16 @@ android {
manifestPlaceholders.JPUSH_PKGNAME = "com.xhjcn.lock" manifestPlaceholders.JPUSH_PKGNAME = "com.xhjcn.lock"
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules-xhj.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules-xhj.pro'
} }
xhj_bundle {
dimension "flavor-type"
applicationId "ltd.xhjcn.lock"
signingConfig signingConfigs.xhj_bundle
resValue "string", "app_name", "Star Lock"
manifestPlaceholders.JPUSH_PKGNAME = "ltd.xhjcn.lock"
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules-xhj.pro'
}
xhj_pre { xhj_pre {
dimension "flavor-type" dimension "flavor-type"
applicationId "com.xhjcn.lock.pre" applicationId "com.xhjcn.lock.pre"

View File

@ -0,0 +1,48 @@
{
"project_info": {
"project_number": "281500445726",
"project_id": "skychip2023-ecdff",
"storage_bucket": "skychip2023-ecdff.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:ddf52ac7b7f83cf5c4d20f",
"android_client_info": {
"package_name": "com.skychip.lock.dev"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4DanQ0sq9g"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:468195b9cc68dd6cc4d20f",
"android_client_info": {
"package_name": "com.starlock.lock.local"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4DanQ0sq9g"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View File

@ -0,0 +1,48 @@
{
"project_info": {
"project_number": "281500445726",
"project_id": "skychip2023-ecdff",
"storage_bucket": "skychip2023-ecdff.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:ddf52ac7b7f83cf5c4d",
"android_client_info": {
"package_name": "com.skychip.lock.pre"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4DanQ"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:468195b9cc68dd6cc",
"android_client_info": {
"package_name": "com.starlock.lock.local"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4DanQ0sq9g"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View File

@ -0,0 +1,48 @@
{
"project_info": {
"project_number": "28150044todo",
"project_id": "skychip2023-etodo",
"storage_bucket": "skychip2023-etodo.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:ddf52ac7b7f83cf5c4todo",
"android_client_info": {
"package_name": "com.xhjcn.lock"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4DanQ0todo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:468195b9cc68dd6cc4todo",
"android_client_info": {
"package_name": "com.xhjcn.lock.local"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4Dank9todo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View File

@ -0,0 +1,48 @@
{
"project_info": {
"project_number": "28150044todo",
"project_id": "skychip2023-etodo",
"storage_bucket": "skychip2023-etodo.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:ddf52ac7b7f83cf5c4todo",
"android_client_info": {
"package_name": "com.xhjcn.lock"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4DanQ0todo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:281500445726:android:468195b9cc68dd6cc4todo",
"android_client_info": {
"package_name": "com.xhjcn.lock.local"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyC-3-ABWuy9LrYyAw_KxDRto4Dank9todo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

BIN
android/app/xhj_bundle.jks Normal file

Binary file not shown.

View File

@ -18,7 +18,7 @@ elif [[ $ENV_BUILD_TAG =~ $regex ]]; then
echo "===build release===$ENV_BUILD_TAG" echo "===build release===$ENV_BUILD_TAG"
bundle exec fastlane release_apk flavor:xhj --verbose bundle exec fastlane release_apk flavor:xhj --verbose
bundle exec fastlane release_apk flavor:sky --verbose bundle exec fastlane release_apk flavor:sky --verbose
bundle exec fastlane release_bundle flavor:xhj --verbose bundle exec fastlane release_bundle flavor:xhj_bundle --verbose
bundle exec fastlane release_bundle flavor:sky --verbose bundle exec fastlane release_bundle flavor:sky --verbose
elif [[ "${ENV_BUILD_BRANCH}" == "develop" ]]; then elif [[ "${ENV_BUILD_BRANCH}" == "develop" ]]; then
echo "===build dev===${NEXT_VERSION}" echo "===build dev===${NEXT_VERSION}"

View File

@ -2,4 +2,5 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip #distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-7.4-all.zip

View File

@ -23,7 +23,7 @@ elif [[ "${ENV_BUILD_BRANCH}" == "develop" ]]; then
echo "===build dev===${NEXT_VERSION}" echo "===build dev===${NEXT_VERSION}"
bundle exec fastlane beta flavor:xhj env:Dev --verbose bundle exec fastlane beta flavor:xhj env:Dev --verbose
bundle exec fastlane beta flavor:sky env:Dev --verbose bundle exec fastlane beta flavor:sky env:Dev --verbose
elif [[ "${ENV_BUILD_BRANCH}" == "release" ]] || [[ "${ENV_BUILD_BRANCH}" == "feat_devops" ]] ; then elif [[ "${ENV_BUILD_BRANCH}" == "release" ]] || [[ "${ENV_BUILD_BRANCH}" == "feat_devops" ]] || [[ "${ENV_BUILD_BRANCH}" == "develop_liyi" ]] ; then
echo "===build pre===${NEXT_VERSION}" echo "===build pre===${NEXT_VERSION}"
bundle exec fastlane beta flavor:xhj env:Pre --verbose bundle exec fastlane beta flavor:xhj env:Pre --verbose
bundle exec fastlane beta flavor:sky env:Pre --verbose bundle exec fastlane beta flavor:sky env:Pre --verbose

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "اتبع النظام", "跟随系统": "اتبع النظام",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "بعد إعادة الضبط ، سيتم حذف بصمات القفل. هل أنت متأكد أنك تريد إعادة ضبطه ؟", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "بعد إعادة الضبط ، سيتم حذف بصمات القفل. هل أنت متأكد أنك تريد إعادة ضبطه ؟",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "بعد إعادة الضبط ، سيتم حذف جهاز التحكم عن بعد للقفل. هل تريد إعادة ضبطه ؟" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "بعد إعادة الضبط ، سيتم حذف جهاز التحكم عن بعد للقفل. هل تريد إعادة ضبطه ؟",
"版本说明": "تعليمات الإصدار"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Следете система", "跟随系统": "Следете система",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "След нулиране, пръстовите отпечатъци на заключването ще бъдат изтрити. Сигурен ли сте, че искате да го нулирате?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "След нулиране, пръстовите отпечатъци на заключването ще бъдат изтрити. Сигурен ли сте, че искате да го нулирате?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "След нулиране, дистанционното управление на ключалката ще бъде изтрито. Искате ли да го нулирате?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "След нулиране, дистанционното управление на ключалката ще бъде изтрито. Искате ли да го нулирате?",
"版本说明": "Обяснение на версията"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "এক্ফক্লোসিস্টেম", "跟随系统": "এক্ফক্লোসিস্টেম",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "ব্যান্ডোটারট্রাসেট, thelock'sferprinতা?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "ব্যান্ডোটারট্রাসেট, thelock'sferprinতা?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "ব্যান্ডোটারপ্রাসেট, নিয়ন্ত্রণের নিয়ন্ত্রণ। ডোডো ডাইভান্টটুরে?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "ব্যান্ডোটারপ্রাসেট, নিয়ন্ত্রণের নিয়ন্ত্রণ। ডোডো ডাইভান্টটুরে?",
"版本说明": "ভার্সনপরিচিতি",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Sledovat systém", "跟随系统": "Sledovat systém",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po resetování budou otisky prstů zámku odstraněny. Opravdu ho chcete obnovit?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po resetování budou otisky prstů zámku odstraněny. Opravdu ho chcete obnovit?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po resetu bude dálkové ovládání zámku odstraněno. Chcete ho obnovit?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po resetu bude dálkové ovládání zámku odstraněno. Chcete ho obnovit?",
"版本说明": "Verze"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Følg systemet", "跟随系统": "Følg systemet",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Efter nulstilling vil låsens fingeraftryk blive slettet. Er du sikker på at du vil nulstille den?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Efter nulstilling vil låsens fingeraftryk blive slettet. Er du sikker på at du vil nulstille den?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Efter nulstilling, fjernbetjeningen af låsen vil blive slettet. Vil du nulstille den?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Efter nulstilling, fjernbetjeningen af låsen vil blive slettet. Vil du nulstille den?",
"版本说明": "Versionsbeskrivelse",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "System folgen", "跟随系统": "System folgen",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Nach dem Zurücksetzen werden die Finger abdrücke des Schlosses gelöscht. Sind Sie sicher, dass Sie es zurücksetzen wollen?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Nach dem Zurücksetzen werden die Finger abdrücke des Schlosses gelöscht. Sind Sie sicher, dass Sie es zurücksetzen wollen?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Nach dem Zurücksetzen wird die Fernbedienung des Schlosses gelöscht. Willst du es zurücksetzen?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Nach dem Zurücksetzen wird die Fernbedienung des Schlosses gelöscht. Willst du es zurücksetzen?",
"版本说明": "Versionsbeschreibung"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Ακολουθήστε το σύστημα", "跟随系统": "Ακολουθήστε το σύστημα",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Μετά την επαναφορά, τα αποτυπώματα της κλειδαριάς θα διαγραφούν. Είστε σίγουροι ότι θέλετε να το επαναφέρετε;", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Μετά την επαναφορά, τα αποτυπώματα της κλειδαριάς θα διαγραφούν. Είστε σίγουροι ότι θέλετε να το επαναφέρετε;",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Μετά την επαναφορά, το τηλεχειριστήριο της κλειδαριάς θα διαγραφεί. Θέλεις να το επαναφέρεις;" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Μετά την επαναφορά, το τηλεχειριστήριο της κλειδαριάς θα διαγραφεί. Θέλεις να το επαναφέρεις;",
"版本说明": "Περιγραφή έκδοσης",
} }

View File

@ -1121,5 +1121,12 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Follow system", "跟随系统": "Follow system",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "After reset, the lock's fingerprints will be deleted. Are you sure you want to reset it?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "After reset, the lock's fingerprints will be deleted. Are you sure you want to reset it?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "After reset, the remote control of the lock will be deleted. Do you want to reset it?" "通话未接通,已挂断": "Call not connected, hung up",
"通话异常中断": "Abnormal call interruption",
"通话连接失败": "Call connection failed",
"已挂断": "Hanging up",
"正在说话...": "Talking now...",
"下载完成,请到相册查看": "Download completed, please go to the album to view",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "After reset, the remote control of the lock will be deleted. Do you want to reset it?",
"版本说明": "Version description"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Seguir sistema", "跟随系统": "Seguir sistema",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Después de restablecer, se eliminarán las huellas dactilares del bloqueo. ¿Está seguro de que desea restablecerlo?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Después de restablecer, se eliminarán las huellas dactilares del bloqueo. ¿Está seguro de que desea restablecerlo?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Después del reinicio, se eliminará el control remoto de la cerradura. ¿Quieres resetearlo?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Después del reinicio, se eliminará el control remoto de la cerradura. ¿Quieres resetearlo?",
"版本说明": "Instrucciones de versión"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Süsteemi jälgimine", "跟随系统": "Süsteemi jälgimine",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Pärast lähtestamist kustutatakse luku sõrmejäljed. Kas tõesti soovid see lähtestada?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Pärast lähtestamist kustutatakse luku sõrmejäljed. Kas tõesti soovid see lähtestada?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Pärast lähtestamist kustutatakse luku kaugjuhtimine. Kas sa tahad seda lähtestada?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Pärast lähtestamist kustutatakse luku kaugjuhtimine. Kas sa tahad seda lähtestada?",
"版本说明": "Versiooniteave",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Seuraa järjestelmää", "跟随系统": "Seuraa järjestelmää",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Lukon sormenjäljet poistetaan. Haluatko varmasti nollataa sen?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Lukon sormenjäljet poistetaan. Haluatko varmasti nollataa sen?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Nollauksen jälkeen lukon kaukosäädin poistetaan. Haluatko palauttaa sen?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Nollauksen jälkeen lukon kaukosäädin poistetaan. Haluatko palauttaa sen?",
"版本说明": "Versio",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Suivre le système", "跟随系统": "Suivre le système",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Après réinitialisation, les empreintes digitales de la serrure seront supprimées. Êtes-vous sûr de vouloir le réinitialiser?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Après réinitialisation, les empreintes digitales de la serrure seront supprimées. Êtes-vous sûr de vouloir le réinitialiser?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Après réinitialisation, la télécommande du verrou sera supprimée. Voulez-vous le réinitialiser?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Après réinitialisation, la télécommande du verrou sera supprimée. Voulez-vous le réinitialiser?",
"版本说明": "Explication de la version",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "מערכת מעקב", "跟随系统": "מערכת מעקב",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "לאחר איפוס, טביעות האצבעות של המנעול יימחקו. אתה בטוח שברצונך לאפס את זה?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "לאחר איפוס, טביעות האצבעות של המנעול יימחקו. אתה בטוח שברצונך לאפס את זה?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "לאחר איפוס, השליטה מרחוק של המנעול יימחק. אתה רוצה לאפס את זה?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "לאחר איפוס, השליטה מרחוק של המנעול יימחק. אתה רוצה לאפס את זה?",
"版本说明": "המידע על גרסה",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "跟隨系統", "跟随系统": "跟隨系統",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置之後,鎖嘅指紋將被刪除。 你確定要重置它啊?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置之後,鎖嘅指紋將被刪除。 你確定要重置它啊?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置之後,鎖嘅遙控器將被刪除。 是否要重置它?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置之後,鎖嘅遙控器將被刪除。 是否要重置它?",
"版本说明": "版本說明"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Prati sistem:", "跟随系统": "Prati sistem:",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Nakon resetovanja, otisci brave će biti izbrisani. Jeste li sigurni da ga želite resetirati?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Nakon resetovanja, otisci brave će biti izbrisani. Jeste li sigurni da ga želite resetirati?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Nakon resetovanja, daljinski upravljač brave će biti izbrisan. Hoæeš da ga resetuješ?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Nakon resetovanja, daljinski upravljač brave će biti izbrisan. Hoæeš da ga resetuješ?",
"版本说明": "Informacije o verziji",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Follow system", "跟随系统": "Follow system",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "A reset után a zár ujjlenyomatai törlődnek. Biztos vagy benne, hogy vissza szeretné állítani?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "A reset után a zár ujjlenyomatai törlődnek. Biztos vagy benne, hogy vissza szeretné állítani?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "A reset után a zár távirányítója törlődik. Szeretné visszaállítani?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "A reset után a zár távirányítója törlődik. Szeretné visszaállítani?",
"版本说明": "Versió leírás",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Sistem mengikuti", "跟随系统": "Sistem mengikuti",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Setelah mengulang, sidik jari kunci akan dihapus. Yakin ingin meresetnya?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Setelah mengulang, sidik jari kunci akan dihapus. Yakin ingin meresetnya?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Setelah reset, remote control kunci akan dihapus. Ingin mengatur ulang?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Setelah reset, remote control kunci akan dihapus. Ingin mengatur ulang?",
"版本说明": "Catatan versi",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Seguire il sistema", "跟随系统": "Seguire il sistema",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Dopo il reset, le impronte digitali del lucchetto verranno cancellate. Sei sicuro di volerlo resettare?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Dopo il reset, le impronte digitali del lucchetto verranno cancellate. Sei sicuro di volerlo resettare?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Dopo il reset, il telecomando del lucchetto verrà eliminato. Vuoi resettarlo?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Dopo il reset, il telecomando del lucchetto verrà eliminato. Vuoi resettarlo?",
"版本说明": "Versione"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "システムに従う", "跟随系统": "システムに従う",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "リセット後、ロックの指紋は削除されます。リセットしてもよろしいですか。", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "リセット後、ロックの指紋は削除されます。リセットしてもよろしいですか。",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "リセット後、ロックのリモコンが削除されます。リセットしますか?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "リセット後、ロックのリモコンが削除されます。リセットしますか?",
"版本说明": "バージョン説明",
} }

View File

@ -1121,5 +1121,12 @@
"分简称": "分简称", "分简称": "分简称",
"跟随系统": "跟随系统", "跟随系统": "跟随系统",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置后,该锁的指纹都将被删除哦,确认要重置吗?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置后,该锁的指纹都将被删除哦,确认要重置吗?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置后,该锁的遥控都将被删除哦,确认要重置吗?" "通话未接通,已挂断": "通话未接通,已挂断",
"通话异常中断": "通话异常中断",
"通话连接失败": "通话连接失败",
"已挂断": "已挂断",
"正在说话...": "正在说话...",
"下载完成,请到相册查看": "下载完成,请到相册查看",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置后,该锁的遥控都将被删除哦,确认要重置吗?",
"版本说明": "版本说明"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Жүйені қолдану", "跟随系统": "Жүйені қолдану",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Қайта ысырып тастау Шынымен ысырып тастауды қалайсыз ба?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Қайта ысырып тастау Шынымен ысырып тастауды қалайсыз ба?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Қайта ысырып ысырып тасымалдауын өшіріледі. Оны ысырып тастауды қалайсыз ба?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Қайта ысырып ысырып тасымалдауын өшіріледі. Оны ысырып тастауды қалайсыз ба?",
"版本说明": "Версиятын көрсету",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "시스템을 따르십시오", "跟随系统": "시스템을 따르십시오",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "재설정 후 잠금 장치의 지문이 삭제됩니다. 당신은 그것을 재설정 하시겠습니까?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "재설정 후 잠금 장치의 지문이 삭제됩니다. 당신은 그것을 재설정 하시겠습니까?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "재설정 후 잠금 장치의 리모컨이 삭제됩니다. 당신은 그것을 재설정 하시겠습니까?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "재설정 후 잠금 장치의 리모컨이 삭제됩니다. 당신은 그것을 재설정 하시겠습니까?",
"版本说明": "버전 설명",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Sekti sistema", "跟随系统": "Sekti sistema",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po reset užrakto pirštų atspaudai bus ištrinti. Ar tikrai norite jį atkurti?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po reset užrakto pirštų atspaudai bus ištrinti. Ar tikrai norite jį atkurti?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po reset, nuotolinis valdymo pultas užraktas bus ištrintas. Ar norite jį atkurti?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po reset, nuotolinis valdymo pultas užraktas bus ištrintas. Ar norite jį atkurti?",
"版本说明": "Versijos aprašymas",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Ikut system", "跟随系统": "Ikut system",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Selepas menetapkan semula, cap jari kunci akan dipadamkan. Adakah anda pasti anda mahu menetapkan semula?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Selepas menetapkan semula, cap jari kunci akan dipadamkan. Adakah anda pasti anda mahu menetapkan semula?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Selepas menetapkan semula, kawalan jauh kunci akan dipadamkan. Adakah anda mahu menetapkan semula?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Selepas menetapkan semula, kawalan jauh kunci akan dipadamkan. Adakah anda mahu menetapkan semula?",
"版本说明": "Penerangan versi",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Systeem volgen", "跟随系统": "Systeem volgen",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Na het resetten worden de vingerafdrukken van het slot verwijderd. Weet je zeker dat je het wilt resetten?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Na het resetten worden de vingerafdrukken van het slot verwijderd. Weet je zeker dat je het wilt resetten?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Na het resetten wordt de afstandsbediening van het slot verwijderd. Wilt u het resetten?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Na het resetten wordt de afstandsbediening van het slot verwijderd. Wilt u het resetten?",
"版本说明": "Versieomschrijving",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Śledź system", "跟随系统": "Śledź system",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po zresetowaniu odciski palców zamka zostaną usunięte. Czy na pewno chcesz go zresetować?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po zresetowaniu odciski palców zamka zostaną usunięte. Czy na pewno chcesz go zresetować?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po zresetowaniu zdalne sterowanie zamkiem zostanie usunięte. Czy chcesz go zresetować?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po zresetowaniu zdalne sterowanie zamkiem zostanie usunięte. Czy chcesz go zresetować?",
"版本说明": "Wersja",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Siga o sistema", "跟随系统": "Siga o sistema",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Após a redefinição, as impressões digitais do bloqueio serão apagadas. Tens a certeza que queres redefini-lo?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Após a redefinição, as impressões digitais do bloqueio serão apagadas. Tens a certeza que queres redefini-lo?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Após a reinicialização, o controle remoto do bloqueio será excluído. Você quer redefini-lo?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Após a reinicialização, o controle remoto do bloqueio será excluído. Você quer redefini-lo?",
"版本说明": "Descrição da versão",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Urmează sistemul:", "跟随系统": "Urmează sistemul:",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "După resetare, amprentele încuietorii vor fi şterse. Sigur doriți să-l resetați?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "După resetare, amprentele încuietorii vor fi şterse. Sigur doriți să-l resetați?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "După resetare, telecomanda de blocare va fi ştersă. Vrei să-l resetezi?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "După resetare, telecomanda de blocare va fi ştersă. Vrei să-l resetezi?",
"版本说明": "Descrierea versiunii",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Следуйте системе", "跟随系统": "Следуйте системе",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "После сброса отпечатки пальцев замка будут удалены. Вы уверены, что хотите его перезагрузить?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "После сброса отпечатки пальцев замка будут удалены. Вы уверены, что хотите его перезагрузить?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "После сброса пульт дистанционного управления замком будет удален. А вы хотите его сбросить?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "После сброса пульт дистанционного управления замком будет удален. А вы хотите его сбросить?",
"版本说明": "Объяснение версии",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Sledovať systém", "跟随系统": "Sledovať systém",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po resetovaní budú prstové odtlačky zámku vymazané. Ste si istí, že chcete obnoviť?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Po resetovaní budú prstové odtlačky zámku vymazané. Ste si istí, že chcete obnoviť?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po resetovaní bude diaľkové ovládanie zámku vymazané. Chcete ho obnoviť?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Po resetovaní bude diaľkové ovládanie zámku vymazané. Chcete ho obnoviť?",
"版本说明": "Popis verzie"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Пратите систем", "跟随系统": "Пратите систем",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Након ресетовања, отисци прстију браве ће бити избрисани. Да ли сте сигурни да желите да га ресетујете?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Након ресетовања, отисци прстију браве ће бити избрисани. Да ли сте сигурни да желите да га ресетујете?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Након ресетовања, даљински управљач браве ће бити избрисан. Да ли желите да га ресетујете?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Након ресетовања, даљински управљач браве ће бити избрисан. Да ли желите да га ресетујете?",
"版本说明": "Опис верзије"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Följ system", "跟随系统": "Följ system",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Efter återställd, kommer låsets fingeravtryck tas bort. Är du säker på att du vill återställa den?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Efter återställd, kommer låsets fingeravtryck tas bort. Är du säker på att du vill återställa den?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Efter återställd, fjärrkontrollen på låset tas bort. Vill du återställa den?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Efter återställd, fjärrkontrollen på låset tas bort. Vill du återställa den?",
"版本说明": "Versionsbeskrivning"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "ระบบติดตามผล", "跟随系统": "ระบบติดตามผล",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "หลังจากรีเซ็ตแล้วลายนิ้วมือของล็อคจะถูกลบออกคุณแน่ใจว่าอยากจะรีเซ็ต?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "หลังจากรีเซ็ตแล้วลายนิ้วมือของล็อคจะถูกลบออกคุณแน่ใจว่าอยากจะรีเซ็ต?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "หลังจากรีเซ็ตแล้วรีโมทคอนโทรลของล็อคจะถูกลบออกคุณต้องการรีเซ็ตไหม" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "หลังจากรีเซ็ตแล้วรีโมทคอนโทรลของล็อคจะถูกลบออกคุณต้องการรีเซ็ตไหม",
"版本说明": "คำอธิบายรุ่น"
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Sistemi takip et", "跟随系统": "Sistemi takip et",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Sıfırlamadan sonra, kilidin parmak izleri silinecektir. Sıfırlamak istediğine emin misin?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Sıfırlamadan sonra, kilidin parmak izleri silinecektir. Sıfırlamak istediğine emin misin?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Sıfırladıktan sonra, kilidin uzaktan kumandası silinecektir. Sıfırlamak ister misin?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Sıfırladıktan sonra, kilidin uzaktan kumandası silinecektir. Sıfırlamak ister misin?",
"版本说明": "Sürüm açıklaması",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "跟蹤系統", "跟随系统": "跟蹤系統",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置後,鎖的指紋將被刪除。 是否確實要重置它?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置後,鎖的指紋將被刪除。 是否確實要重置它?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置後,鎖的遙控器將被刪除。 是否要重置它?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置後,鎖的遙控器將被刪除。 是否要重置它?",
"版本说明": "版本說明",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Система стеження за", "跟随系统": "Система стеження за",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Після скидання відбитки пальців замка будуть видалені. Ви впевнені, що хочете скинути налаштування?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Після скидання відбитки пальців замка будуть видалені. Ви впевнені, що хочете скинути налаштування?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Після скидання пульт дистанційного керування замком буде видалено. Хочете його скинути?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Після скидання пульт дистанційного керування замком буде видалено. Хочете його скинути?",
"版本说明": "Опис версії",
} }

View File

@ -1120,5 +1120,6 @@
"分简称": "M", "分简称": "M",
"跟随系统": "Hệ thống theo dõi", "跟随系统": "Hệ thống theo dõi",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Sau khi đặt lại, dấu vân tay của khóa sẽ bị xóa. Bạn có chắc chắn muốn thiết lập lại nó?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "Sau khi đặt lại, dấu vân tay của khóa sẽ bị xóa. Bạn có chắc chắn muốn thiết lập lại nó?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Sau khi đặt lại, điều khiển từ xa của khóa sẽ bị xóa. Bạn có muốn đặt lại không?" "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "Sau khi đặt lại, điều khiển từ xa của khóa sẽ bị xóa. Bạn có muốn đặt lại không?",
"版本说明": "Thông tin phiên bản"
} }

View File

@ -1121,5 +1121,12 @@
"分简称": "分", "分简称": "分",
"跟随系统": "跟随系统", "跟随系统": "跟随系统",
"重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置后,该锁的指纹都将被删除哦,确认要重置吗?", "重置后,该锁的指纹都将被删除哦,确认要重置吗?": "重置后,该锁的指纹都将被删除哦,确认要重置吗?",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置后,该锁的遥控都将被删除哦,确认要重置吗?" "通话未接通,已挂断": "通话未接通,已挂断",
"通话异常中断": "通话异常中断",
"通话连接失败": "通话连接失败",
"已挂断": "已挂断",
"正在说话...": "正在说话...",
"下载完成,请到相册查看": "下载完成,请到相册查看",
"重置后,该锁的遥控都将被删除哦,确认要重置吗?": "重置后,该锁的遥控都将被删除哦,确认要重置吗?",
"版本说明": "版本说明"
} }

View File

@ -199,28 +199,28 @@ class F {
switch (appFlavor) { switch (appFlavor) {
case Flavor.local: case Flavor.local:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'local-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'local-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
case Flavor.dev: case Flavor.dev:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'dev-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'dev-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
case Flavor.pre: case Flavor.pre:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'pre-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'pre-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
case Flavor.sky_dev: case Flavor.sky_dev:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'sky_dev-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'sky_dev-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
case Flavor.sky_pre: case Flavor.sky_pre:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'sky_pre-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'sky_pre-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
case Flavor.sky: case Flavor.sky:
return const UmengKey( return const UmengKey(
@ -229,13 +229,13 @@ class F {
channel: 'Product'); channel: 'Product');
case Flavor.xhj_dev: case Flavor.xhj_dev:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'xhj_dev-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'xhj_dev-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
case Flavor.xhj_pre: case Flavor.xhj_pre:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'xhj_pre-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'xhj_pre-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
case Flavor.xhj: case Flavor.xhj:
return const UmengKey( return const UmengKey(
@ -244,8 +244,8 @@ class F {
channel: 'Product'); channel: 'Product');
default: default:
return const UmengKey( return const UmengKey(
androidKey: '671244cf80464b33f6df9648', androidKey: 'default-671244cf80464b33f6df9648',
iosKey: '671244ae80464b33f6df9646', iosKey: 'default-671244ae80464b33f6df9646',
channel: 'Product'); channel: 'Product');
} }
} }

View File

@ -29,10 +29,12 @@ class Data {
Data.fromJson(Map<String, dynamic> json) { Data.fromJson(Map<String, dynamic> json) {
wechatServiceUrl = json['wechat_service_url']; wechatServiceUrl = json['wechat_service_url'];
appSiteUrl = json['app_site_url']; appSiteUrl = json['app_site_url'];
appVersionHistoryUrl = json['appVersionHistoryUrl'];
} }
String? wechatServiceUrl; String? wechatServiceUrl;
String? appSiteUrl; String? appSiteUrl;
String? appVersionHistoryUrl;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};

View File

@ -9,7 +9,7 @@ import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_state.dart';
import 'package:star_lock/main/lockDetail/doorLockLog/exportRecordDialog/exportRecordDialog_page.dart'; import 'package:star_lock/main/lockDetail/doorLockLog/exportRecordDialog/exportRecordDialog_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail_image.dart';
import 'package:star_lock/tools/EasyRefreshTool.dart'; import 'package:star_lock/tools/EasyRefreshTool.dart';
import 'package:star_lock/tools/advancedCalendar/src/widget.dart'; import 'package:star_lock/tools/advancedCalendar/src/widget.dart';
import 'package:star_lock/tools/commonDataManage.dart'; import 'package:star_lock/tools/commonDataManage.dart';
@ -399,13 +399,27 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
} }
_buildVideoItem(RecordListData recordData) { _buildVideoItem(RecordListData recordData) {
return VideoThumbnail(videoUrl: recordData.videoUrl!); return VideoThumbnailImage(videoUrl: recordData.videoUrl!);
} }
_buildImageItem(RecordListData recordData) { _buildImageItem(RecordListData recordData) {
return Image.network( return RotatedBox(
quarterTurns: -1,
child: Image.network(
recordData.imagesUrl!, recordData.imagesUrl!,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
//
return RotatedBox(
quarterTurns: -1,
child: Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
),
);
},
),
); );
} }

View File

@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart';
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';
@ -151,11 +152,6 @@ class ConfiguringWifiLogic extends BaseGetXController {
} }
state.sureBtnState.value = 1; state.sureBtnState.value = 1;
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
state.sureBtnState.value = 0;
});
final GetGatewayConfigurationEntity entity = final GetGatewayConfigurationEntity entity =
await ApiRepository.to.getGatewayConfiguration(timeout: 60); await ApiRepository.to.getGatewayConfiguration(timeout: 60);
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
@ -191,6 +187,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
// //
state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}"; state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
} }
BlueManage().blueSendData(BlueManage().connectDeviceName, BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async { (BluetoothConnectionState connectionState) async {
if (connectionState == BluetoothConnectionState.connected) { if (connectionState == BluetoothConnectionState.connected) {
@ -199,11 +196,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
password: state.wifiPWDController.text, password: state.wifiPWDController.text,
gatewayConfigurationStr: state.getGatewayConfigurationStr, gatewayConfigurationStr: state.getGatewayConfigurationStr,
); );
} else if (connectionState == BluetoothConnectionState.disconnected) { EasyLoading.show();
state.sureBtnState.value = 0;
if (state.ifCurrentScreen.value == true) {
showBlueConnetctToast();
}
} }
}, isAddEquipment: true); }, isAddEquipment: true);
} }

View File

@ -1,4 +1,10 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
@ -9,18 +15,20 @@ class EditVideoLogLogic extends BaseGetXController {
EditVideoLogState state = EditVideoLogState(); EditVideoLogState state = EditVideoLogState();
Future<void> deleteLockCloudStorageList() async { Future<void> deleteLockCloudStorageList() async {
final VersionUndateEntity entity = await ApiRepository.to.deleteLockCloudStorageList( final VersionUndateEntity entity =
await ApiRepository.to.deleteLockCloudStorageList(
recordIds: state.selectVideoLogList.value.map((e) => e.recordId).toList(), recordIds: state.selectVideoLogList.value.map((e) => e.recordId).toList(),
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
state.selectVideoLogList.value.clear();
showToast('删除成功'.tr); showToast('删除成功'.tr);
getLockCloudStorageList(); await getLockCloudStorageList();
state.selectVideoLogList.clear();
} }
} }
Future<void> getLockCloudStorageList() async { Future<void> getLockCloudStorageList() async {
final VideoLogEntity entity = await ApiRepository.to.getLockCloudStorageList( final VideoLogEntity entity =
await ApiRepository.to.getLockCloudStorageList(
lockId: state.getLockId.value, lockId: state.getLockId.value,
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
@ -28,4 +36,59 @@ class EditVideoLogLogic extends BaseGetXController {
state.videoLogList.refresh(); state.videoLogList.refresh();
} }
} }
Future<void> downloadAndSaveToGallery(String url, String fileName) async {
try {
//
if (await _requestPermission()) {
final dio = Dio();
final directory = await getTemporaryDirectory();
final filePath = '${directory.path}/$fileName';
//
await dio.download(
url,
filePath,
onReceiveProgress: (received, total) {
if (total != -1) {
final progress = (received / total) * 100;
print('下载进度: $progress%');
}
},
);
//
if (fileName.endsWith('.jpg') || fileName.endsWith('.png')) {
//
final result = await ImageGallerySaver.saveFile(filePath);
if (result['isSuccess']) {
print('图片已保存到图库');
} else {
print('图片保存失败');
}
} else if (fileName.endsWith('.mp4')) {
//
final result = await ImageGallerySaver.saveFile(filePath);
if (result['isSuccess']) {
print('视频已保存到图库');
} else {
print('视频保存失败');
}
}
//
await File(filePath).delete();
} else {
print('存储权限被拒绝');
}
} catch (e) {
print('下载或保存文件失败: $e');
}
}
//
Future<bool> _requestPermission() async {
final status = await Permission.storage.request();
return status.isGranted;
}
} }

View File

@ -1,10 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/appRouters.dart'; import 'package:star_lock/appRouters.dart';
import 'package:star_lock/main/lockDetail/videoLog/editVideoLog/editVideoLog_state.dart'; import 'package:star_lock/main/lockDetail/videoLog/editVideoLog/editVideoLog_state.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail_image.dart';
import 'package:star_lock/tools/dateTool.dart'; import 'package:star_lock/tools/dateTool.dart';
import '../../../../app_settings/app_colors.dart'; import '../../../../app_settings/app_colors.dart';
@ -97,6 +99,7 @@ class _EditVideoLogPageState extends State<EditVideoLogPage> {
double itemW = (1.sw - 15.w * 4) / 3; double itemW = (1.sw - 15.w * 4) / 3;
double itemH = (1.sw - 15.w * 4) / 3 + 40.h; double itemH = (1.sw - 15.w * 4) / 3 + 40.h;
Widget mainListView(int index, CloudStorageData itemData) { Widget mainListView(int index, CloudStorageData itemData) {
return GridView.builder( return GridView.builder(
padding: EdgeInsets.only(left: 15.w, right: 15.w), padding: EdgeInsets.only(left: 15.w, right: 15.w),
@ -114,99 +117,143 @@ class _EditVideoLogPageState extends State<EditVideoLogPage> {
childAspectRatio: itemW / itemH), childAspectRatio: itemW / itemH),
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
final RecordListData recordData = itemData.recordList![index]; final RecordListData recordData = itemData.recordList![index];
return videoItem(recordData, index); return videoItem(recordData);
}, },
); );
} }
Widget videoItem(RecordListData recordData, int index) { // Widget videoItem(RecordListData recordData, int index) {
return Container( // return Container(
width: itemW, // width: itemW,
height: itemH, // height: itemH,
color: Colors.white, // color: Colors.white,
child: GestureDetector( // child: GestureDetector(
onTap: () { // onTap: () {
recordData.isSelect = !recordData.isSelect!; // recordData.isSelect = !recordData.isSelect!;
if (recordData.isSelect! == true) { // if (recordData.isSelect! == true) {
state.selectVideoLogList.add(recordData); // state.selectVideoLogList.add(recordData);
} else { // } else {
state.selectVideoLogList.remove(recordData); // state.selectVideoLogList.remove(recordData);
} // }
setState(() {}); // setState(() {});
}, // },
child: Stack( // child: Stack(
children: <Widget>[ // children: <Widget>[
Column( // Column(
children: <Widget>[ // children: <Widget>[
Container( // Container(
width: itemW, // width: itemW,
height: itemW, // height: itemW,
margin: const EdgeInsets.all(0), // margin: const EdgeInsets.all(0),
color: Colors.white, // color: Colors.white,
child: ClipRRect( // child: ClipRRect(
borderRadius: BorderRadius.circular(10.w), // borderRadius: BorderRadius.circular(10.w),
child: Image( // child: Image(
fit: BoxFit.cover, // fit: BoxFit.cover,
image: Image.network(recordData.imagesUrl ?? // image: Image.network(recordData.imagesUrl ??
'images/icon_video_placeholder.jpg') // 'images/icon_video_placeholder.jpg')
.image), // .image),
), // ),
), // ),
SizedBox(height: 5.h), // SizedBox(height: 5.h),
Text( // Text(
DateTool() // DateTool()
.dateToYMDHNString(recordData.operateDate.toString()), // .dateToYMDHNString(recordData.operateDate.toString()),
textAlign: TextAlign.center, // textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.sp)) // style: TextStyle(fontSize: 18.sp))
], // ],
), // ),
Positioned( // Positioned(
top: 0.w, // top: 0.w,
right: 0.w, // right: 0.w,
child: Image( // child: Image(
width: 36.w, // width: 36.w,
height: 36.w, // height: 36.w,
image: state.selectVideoLogList.value.contains(recordData) // image: state.selectVideoLogList.value.contains(recordData)
? const AssetImage('images/icon_round_select.png') // ? const AssetImage('images/icon_round_select.png')
: const AssetImage('images/icon_round_unSelect.png'))) // : const AssetImage('images/icon_round_unSelect.png')))
], // ],
)), // )),
); // );
} // }
Widget bottomBottomBtnWidget() { Widget bottomBottomBtnWidget() {
return SizedBox( return SizedBox(
width: 1.sw, width: 1.sw,
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ child:
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
bottomBtnItemWidget( bottomBtnItemWidget(
'images/main/icon_lockDetail_monitoringDownloadVideo.png', 'images/main/icon_lockDetail_monitoringDownloadVideo.png',
'下载'.tr, '下载'.tr,
Colors.white, () { Colors.white,
if (state.selectVideoLogList.value.isNotEmpty) { _onDownLoadClick,
Get.toNamed(Routers.videoLogDownLoadPage, arguments: <String, List<RecordListData>>{ ),
'downloadVideoLogList': state.selectVideoLogList.value
});
} else {
logic.showToast('请选择要下载的视频');
}
}),
SizedBox(width: 100.w), SizedBox(width: 100.w),
bottomBtnItemWidget( bottomBtnItemWidget(
'images/main/icon_lockDetail_monitoringDeletVideo.png', 'images/main/icon_lockDetail_monitoringDeletVideo.png',
'删除'.tr, '删除'.tr,
AppColors.mainColor, () { AppColors.mainColor,
if (state.selectVideoLogList.value.isNotEmpty) { _onDelClick,
logic.deleteLockCloudStorageList(); )
} else {
logic.showToast('请选择要删除的视频'.tr);
}
})
]), ]),
); );
} }
Future<void> _onDownLoadClick() async {
if (state.selectVideoLogList.value.isNotEmpty) {
double _progress = 0.0;
//
//
EasyLoading.showProgress(_progress, status: '加载数据中'.tr);
//
for (int i = 0; i <= state.selectVideoLogList.length - 1; i++) {
final item = state.selectVideoLogList.value[i];
// imagesUrl
if (item.imagesUrl != null && item.imagesUrl!.isNotEmpty) {
await logic.downloadAndSaveToGallery(item.imagesUrl!, 'image_$i.jpg');
}
// videoUrl
if (item.videoUrl != null && item.videoUrl!.isNotEmpty) {
await logic.downloadAndSaveToGallery(item.videoUrl!, 'video_$i.mp4');
}
//
_progress = (i + 1) / state.selectVideoLogList.length;
EasyLoading.showProgress(_progress, status: '加载数据中'.tr);
}
//
EasyLoading.dismiss();
EasyLoading.showSuccess('下载完成,请到相册查看'.tr);
state.selectVideoLogList.clear();
setState(() {});
// Get.toNamed(Routers.videoLogDownLoadPage,
// arguments: <String, List<RecordListData>>{
// 'downloadVideoLogList': state.selectVideoLogList.value
// });
} else {
logic.showToast('请选择要下载的视频');
}
}
Future<void> _onDelClick() async {
if (state.selectVideoLogList.value.isNotEmpty) {
await logic.deleteLockCloudStorageList();
setState(() {});
} else {
logic.showToast('请选择要删除的视频'.tr);
}
}
Widget bottomBtnItemWidget( Widget bottomBtnItemWidget(
String iconUrl, String name, Color backgroundColor, Function() onClick) { String iconUrl,
String name,
Color backgroundColor,
Future<void> Function() onClick,
) {
final double wh = 40.w; final double wh = 40.w;
return GestureDetector( return GestureDetector(
onTap: onClick, onTap: onClick,
@ -221,9 +268,118 @@ class _EditVideoLogPageState extends State<EditVideoLogPage> {
Expanded( Expanded(
child: Text(name, child: Text(name,
style: TextStyle(fontSize: 22.sp), style: TextStyle(fontSize: 22.sp),
textAlign: TextAlign.center)) textAlign: TextAlign.center),
)
], ],
)), ),
),
);
}
Widget videoItem(RecordListData recordData) {
return GestureDetector(
onTap: () {
if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) {
Get.toNamed(Routers.videoLogDetailPage, arguments: <String, Object>{
'recordData': recordData,
'videoDataList': state.videoLogList.value
});
} else if (recordData.imagesUrl != null &&
recordData.imagesUrl!.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FullScreenImagePage(
imageUrl: recordData.imagesUrl!,
),
),
);
}
},
child: Stack(
children: [
SizedBox(
width: itemW,
height: itemH,
child: Column(
children: <Widget>[
Container(
width: itemW,
height: itemW,
margin: const EdgeInsets.all(0),
color: Colors.white,
child: ClipRRect(
borderRadius: BorderRadius.circular(10.w),
child: _buildImageOrVideoItem(recordData),
),
),
SizedBox(height: 5.h),
Text(
DateTool()
.dateToYMDHNString(recordData.operateDate.toString()),
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.sp),
)
],
),
),
Positioned(
top: 0.w,
right: 0.w,
child: GestureDetector(
onTap: () {
recordData.isSelect = !recordData.isSelect!;
if (recordData.isSelect! == true) {
state.selectVideoLogList.add(recordData);
} else {
state.selectVideoLogList.remove(recordData);
}
setState(() {});
},
child: Image(
width: 36.w,
height: 36.w,
image: state.selectVideoLogList.value.contains(recordData)
? const AssetImage('images/icon_round_select.png')
: const AssetImage('images/icon_round_unSelect.png'),
),
),
)
],
),
);
}
_buildImageOrVideoItem(RecordListData recordData) {
if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) {
return _buildVideoItem(recordData);
} else {
return _buildImageItem(recordData);
}
}
_buildVideoItem(RecordListData recordData) {
return VideoThumbnailImage(videoUrl: recordData.videoUrl!);
}
_buildImageItem(RecordListData recordData) {
return RotatedBox(
quarterTurns: -1,
child: Image.network(
recordData.imagesUrl!,
fit: BoxFit.cover,
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
//
return RotatedBox(
quarterTurns: -1,
child: Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
),
);
},
),
); );
} }
} }

View File

@ -1,3 +1,6 @@
import 'dart:convert';
import 'dart:typed_data';
class VideoLogEntity { class VideoLogEntity {
int? errorCode; int? errorCode;
String? description; String? description;
@ -61,21 +64,28 @@ class RecordListData {
int? operateDate; int? operateDate;
String? imagesUrl; String? imagesUrl;
String? videoUrl; String? videoUrl;
Uint8List? thumbnailData; // Uint8List
int? recordType; int? recordType;
bool? isSelect = false; bool? isSelect = false;
RecordListData( RecordListData({
{this.recordId, this.recordId,
this.operateDate, this.operateDate,
this.imagesUrl, this.imagesUrl,
this.videoUrl, this.videoUrl,
this.recordType}); this.thumbnailData, //
this.recordType,
});
RecordListData.fromJson(Map<String, dynamic> json) { RecordListData.fromJson(Map<String, dynamic> json) {
recordId = json['recordId']; recordId = json['recordId'];
operateDate = json['operateDate']; operateDate = json['operateDate'];
imagesUrl = json['imagesUrl']; imagesUrl = json['imagesUrl'];
videoUrl = json['videoUrl']; videoUrl = json['videoUrl'];
// JSON base64 Uint8List
if (json['thumbnailData'] != null) {
thumbnailData = base64Decode(json['thumbnailData']);
}
recordType = json['recordType']; recordType = json['recordType'];
} }
@ -85,6 +95,10 @@ class RecordListData {
data['operateDate'] = operateDate; data['operateDate'] = operateDate;
data['imagesUrl'] = imagesUrl; data['imagesUrl'] = imagesUrl;
data['videoUrl'] = videoUrl; data['videoUrl'] = videoUrl;
// Uint8List base64
if (thumbnailData != null) {
data['thumbnailData'] = base64Encode(thumbnailData!);
}
data['recordType'] = recordType; data['recordType'] = recordType;
return data; return data;
} }

View File

@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
@ -14,6 +15,15 @@ class VideoLogLogic extends BaseGetXController {
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
state.videoLogList.value = entity.data!; state.videoLogList.value = entity.data!;
state.videoLogList.value.forEach((element) {
// imagesUrl videoUrl null
element.recordList = element.recordList!
.where((record) =>
(record.imagesUrl != null && record.imagesUrl!.isNotEmpty) ||
(record.videoUrl != null && record.videoUrl!.isNotEmpty))
.toList();
});
state.videoLogList.refresh(); state.videoLogList.refresh();
} }
} }

View File

@ -6,7 +6,7 @@ import 'package:star_lock/flavors.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_state.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_state.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail_image.dart';
import 'package:star_lock/tools/dateTool.dart'; import 'package:star_lock/tools/dateTool.dart';
import 'package:star_lock/tools/noData.dart'; import 'package:star_lock/tools/noData.dart';
import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
@ -228,15 +228,18 @@ class _VideoLogPageState extends State<VideoLogPage> {
child: Row( child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween, // mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Text(state.isNavLocal.value == true ? '已下载'.tr : '全部视频'.tr, Text(
style: TextStyle(fontSize: 26.sp, fontWeight: FontWeight.w500)), state.isNavLocal.value == true ? '已下载'.tr : '全部视频'.tr,
style: TextStyle(fontSize: 26.sp, fontWeight: FontWeight.w500),
),
Expanded(child: SizedBox(width: 10.w)), Expanded(child: SizedBox(width: 10.w)),
IconButton( IconButton(
icon: Image( icon: Image(
width: 40.w, width: 40.w,
height: 40.w, height: 40.w,
image: const AssetImage( image: const AssetImage(
'images/main/icon_lockDetail_monitoringEditVoice.png')), 'images/main/icon_lockDetail_monitoringEditVoice.png'),
),
iconSize: 30, iconSize: 30,
color: Colors.black54, color: Colors.black54,
onPressed: () { onPressed: () {
@ -338,13 +341,27 @@ class _VideoLogPageState extends State<VideoLogPage> {
} }
_buildVideoItem(RecordListData recordData) { _buildVideoItem(RecordListData recordData) {
return VideoThumbnail(videoUrl: recordData.videoUrl!); return VideoThumbnailImage(videoUrl: recordData.videoUrl!);
} }
_buildImageItem(RecordListData recordData) { _buildImageItem(RecordListData recordData) {
return Image.network( return RotatedBox(
quarterTurns: -1,
child: Image.network(
recordData.imagesUrl!, recordData.imagesUrl!,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
//
return RotatedBox(
quarterTurns: -1,
child: Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
),
);
},
),
); );
} }
} }

View File

@ -150,7 +150,8 @@ class _ControlsOverlayState extends State<ControlsOverlay> {
Text( Text(
DateTool().dateToYMDHNString( DateTool().dateToYMDHNString(
widget.recordData.operateDate.toString()), widget.recordData.operateDate.toString()),
style: TextStyle(color: Colors.white, fontSize: 20.sp)), style: TextStyle(color: Colors.white, fontSize: 20.sp),
),
// Expanded(child: SizedBox(width: 10.w)), // Expanded(child: SizedBox(width: 10.w)),
// Container( // Container(
// width: 50.w, // width: 50.w,

View File

@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -7,7 +8,7 @@ import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart
import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/controlsOverlay_page.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/controlsOverlay_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_state.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_state.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail_image.dart';
import 'package:star_lock/tools/dateTool.dart'; import 'package:star_lock/tools/dateTool.dart';
import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
@ -72,20 +73,19 @@ class _VideoLogDetailPageState extends State<VideoLogDetailPage> {
? Column( ? Column(
children: <Widget>[ children: <Widget>[
Container( Container(
color: Colors.black,
height: 500.h, height: 500.h,
decoration: BoxDecoration(color: Colors.black), width: 1.sw,
child: AspectRatio(
aspectRatio: 16 / 9,
child: Stack( child: Stack(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
children: <Widget>[ children: <Widget>[
FittedBox( RotatedBox(
child: SizedBox( quarterTurns: -1,
width: state.videoController.value.size.width, child: AspectRatio(
height: state.videoController.value.size.height, aspectRatio: state.videoController.value.size.width /
state.videoController.value.size.height,
child: VideoPlayer(state.videoController), child: VideoPlayer(state.videoController),
), ),
fit: BoxFit.cover,
), ),
ControlsOverlay( ControlsOverlay(
controller: state.videoController, controller: state.videoController,
@ -104,7 +104,6 @@ class _VideoLogDetailPageState extends State<VideoLogDetailPage> {
], ],
), ),
), ),
),
_buildOther(), _buildOther(),
], ],
) )
@ -166,13 +165,27 @@ class _VideoLogDetailPageState extends State<VideoLogDetailPage> {
} }
_buildVideoItem(RecordListData recordData) { _buildVideoItem(RecordListData recordData) {
return VideoThumbnail(videoUrl: recordData.videoUrl!); return VideoThumbnailImage(videoUrl: recordData.videoUrl!);
} }
_buildImageItem(RecordListData recordData) { _buildImageItem(RecordListData recordData) {
return Image.network( return RotatedBox(
quarterTurns: 1,
child: Image.network(
recordData.imagesUrl!, recordData.imagesUrl!,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
//
return RotatedBox(
quarterTurns: -1,
child: Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
),
);
},
),
); );
} }

View File

@ -10,11 +10,19 @@ class FullScreenImagePage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: Container( body: GestureDetector(
onTap: (){
Navigator.pop(context); //
},
child: Container(
child: RotatedBox(
quarterTurns: -1,
child: PhotoView( child: PhotoView(
imageProvider: NetworkImage(imageUrl), imageProvider: NetworkImage(imageUrl),
), ),
), ),
),
),
); );
} }
} }

View File

@ -1,73 +0,0 @@
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoThumbnail extends StatefulWidget {
final String videoUrl;
VideoThumbnail({required this.videoUrl});
@override
_VideoThumbnailState createState() => _VideoThumbnailState();
}
class _VideoThumbnailState extends State<VideoThumbnail> {
late VideoPlayerController _controller;
late Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
super.initState();
// VideoPlayerController
_controller = VideoPlayerController.network(widget.videoUrl)
..initialize().then((_) {
// UI以便显示第一帧
setState(() {});
});
}
@override
void dispose() {
//
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
// onTap: () {
// setState(() {
// if (_controller.value.isPlaying) {
// _controller.pause();
// } else {
// _controller.play();
// }
// });
// },
child: Stack(
alignment: Alignment.center,
children: <Widget>[
//
_controller.value.isInitialized
? AspectRatio(
aspectRatio: 1 / 1, //
child: FittedBox(
fit: BoxFit.cover, //
child: SizedBox(
width: _controller.value.size.width,
height: _controller.value.size.height,
child: VideoPlayer(_controller),
),
),
)
: Center(
child: CircularProgressIndicator(), //
),
if (!_controller.value.isPlaying && _controller.value.isInitialized)
Icon(Icons.play_arrow_rounded,
size: 80, color: Colors.white.withOpacity(0.8)),
],
),
);
}
}

View File

@ -0,0 +1,97 @@
import 'dart:io'; // dart:io 使 File
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart'; // path_provider
import 'package:video_thumbnail/video_thumbnail.dart'; // video_thumbnail
class VideoThumbnailImage extends StatefulWidget {
final String videoUrl;
VideoThumbnailImage({required this.videoUrl});
@override
_VideoThumbnailState createState() => _VideoThumbnailState();
}
class _VideoThumbnailState extends State<VideoThumbnailImage> {
final Map<String, String> _thumbnailCache = {}; //
late Future<String?> _thumbnailFuture; // Future
@override
void initState() {
super.initState();
_thumbnailFuture = _generateThumbnail(); // initState Future
}
//
Future<String?> _generateThumbnail() async {
try {
//
if (_thumbnailCache.containsKey(widget.videoUrl)) {
return _thumbnailCache[widget.videoUrl];
}
//
final tempDir = await getTemporaryDirectory();
final thumbnailPath = await VideoThumbnail.thumbnailFile(
video: widget.videoUrl,
// URL
thumbnailPath: tempDir.path,
//
imageFormat: ImageFormat.JPEG,
//
maxHeight: 200,
//
quality: 100, // (0-100)
);
//
_thumbnailCache[widget.videoUrl] = thumbnailPath!;
return thumbnailPath;
} catch (e) {
print('Failed to generate thumbnail: $e');
return null;
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<String?>(
future: _thumbnailFuture, // Future
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
//
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError || !snapshot.hasData) {
//
return Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
);
} else {
//
final thumbnailPath = snapshot.data!;
return Stack(
alignment: Alignment.center,
children: <Widget>[
RotatedBox(
quarterTurns: -1,
child: Image.file(
File(thumbnailPath), //
width: 200,
height: 200,
fit: BoxFit.cover,
),
),
Icon(
Icons.play_arrow_rounded,
size: 80,
color: Colors.white.withOpacity(0.8),
),
],
);
}
},
);
}
}

View File

@ -1,3 +1,6 @@
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -9,7 +12,9 @@ import 'package:star_lock/mine/about/about_console.dart';
import '../../app_settings/app_colors.dart'; import '../../app_settings/app_colors.dart';
import '../../flavors.dart'; import '../../flavors.dart';
import '../../tools/commonItem.dart'; import '../../tools/commonItem.dart';
import '../../tools/storage.dart';
import '../../tools/titleAppBar.dart'; import '../../tools/titleAppBar.dart';
import '../../tools/wechat/wechatManageTool.dart';
class AboutPage extends StatefulWidget { class AboutPage extends StatefulWidget {
const AboutPage({Key? key}) : super(key: key); const AboutPage({Key? key}) : super(key: key);
@ -80,6 +85,44 @@ class _AboutPageState extends State<AboutPage> {
Widget listView() { Widget listView() {
Widget view = Column( Widget view = Column(
children: [ children: [
CommonItem(
leftTitel: '版本说明'.tr,
rightTitle: '',
isHaveLine: false,
isHaveDirection: true,
action: () async {
WechatManageTool.getAppInfo(() async {
final String? appVersionHistoryBaseUrl =
await Storage.getString(appVersionHistoryUrl);
if (appVersionHistoryBaseUrl == null) {
return;
}
String brandName = '';
if (Platform.isAndroid) {
final AndroidDeviceInfo androidDeviceInfo =
await DeviceInfoPlugin().androidInfo;
brandName = androidDeviceInfo.manufacturer;
} else {
final IosDeviceInfo iosDeviceInfo =
await DeviceInfoPlugin().iosInfo;
brandName = iosDeviceInfo.systemName ?? 'ios';
}
final PackageInfo packageInfo =
await PackageInfo.fromPlatform();
Navigator.pushNamed(context, Routers.webviewShowPage,
arguments: {
'url': appVersionHistoryBaseUrl +
'?version=${packageInfo.version}&brandName=${brandName}',
'title': '版本说明'.tr
});
});
}),
Divider(
height: 1,
color: AppColors.greyLineColor,
indent: 20.w,
endIndent: 20.w,
),
CommonItem( CommonItem(
leftTitel: '介绍'.tr, leftTitel: '介绍'.tr,
rightTitle: '', rightTitle: '',

View File

@ -11,7 +11,7 @@ class StartChartApi extends BaseProvider {
// url // url
final String _startChartHost = 'http://sls1-scd.star-lock.cn:8080'; final String _startChartHost = 'http://sls1-scd.star-lock.cn:8080';
static StartChartApi get to => Get.find<StartChartApi>(); static StartChartApi get to => Get.put(StartChartApi());
// -- // --
Future<StarChartRegisterNodeEntity> starChartRegisterNode({ Future<StarChartRegisterNodeEntity> starChartRegisterNode({
@ -68,6 +68,4 @@ class StartChartApi extends BaseProvider {
); );
return response; return response;
} }
} }

View File

@ -149,122 +149,200 @@ class ScpMessage {
static ScpMessage deserialize(Uint8List bytes) { static ScpMessage deserialize(Uint8List bytes) {
final message = ScpMessage(); final message = ScpMessage();
final length = bytes.length;
int offset = 0; int offset = 0;
// String hexString = //
// bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(); if (length < 4 + 1 + 2 + 1 + 1 + 44 + 44 + 2 + 2 + 4) {
// // _log(text: 'result bytes hex: ${hexString}'); throw FormatException("Invalid message length");
// _log( }
// text:
// '\n result bytes hex: ${hexString} \n payload hex: ${hexString.substring(210)}'); // 使 ByteData
final byteData = ByteData.sublistView(bytes);
// ProtocolFlag (4 bytes) // ProtocolFlag (4 bytes)
if (bytes.length - offset >= 4) {
message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4)); message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4));
offset += 4; offset += 4;
} else {
throw FormatException("Invalid ProtocolFlag length");
}
// MessageType (1 byte) // MessageType (1 byte)
if (bytes.length - offset >= 1) {
message.MessageType = bytes[offset]; message.MessageType = bytes[offset];
offset += 1; offset += 1;
} else {
throw FormatException("Invalid MessageType length");
}
// MessageId (2 bytes, little-endian) // MessageId (2 bytes, little-endian)
if (bytes.length - offset >= 2) { message.MessageId = byteData.getUint16(offset, Endian.little);
message.MessageId = (bytes[offset + 1] << 8) | bytes[offset];
offset += 2; offset += 2;
} else {
throw FormatException("Invalid MessageId length");
}
// SpTotal (1 byte) // SpTotal (1 byte)
if (bytes.length - offset >= 1) {
message.SpTotal = bytes[offset]; message.SpTotal = bytes[offset];
offset += 1; offset += 1;
} else {
throw FormatException("Invalid SpTotal length");
}
// SpIndex (1 byte) // SpIndex (1 byte)
if (bytes.length - offset >= 1) {
message.SpIndex = bytes[offset]; message.SpIndex = bytes[offset];
offset += 1; offset += 1;
} else {
throw FormatException("Invalid SpIndex length");
}
// FromPeerId (44) // FromPeerId (44 bytes)
if (bytes.length - offset >= 44) {
message.FromPeerId = message.FromPeerId =
utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); utf8.decode(bytes.sublist(offset, offset + 44)).trimRight();
offset += 44; offset += 44;
} else {
throw FormatException("Invalid FromPeerId length");
}
// ToPeerId (44) // ToPeerId (44 bytes)
if (bytes.length - offset >= 44) {
message.ToPeerId = message.ToPeerId =
utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); utf8.decode(bytes.sublist(offset, offset + 44)).trimRight();
offset += 44; offset += 44;
} else {
throw FormatException("Invalid ToPeerId length");
}
// PayloadType (2 bytes, little-endian) // PayloadType (2 bytes, little-endian)
if (bytes.length - offset >= 2) { message.PayloadType = byteData.getUint16(offset, Endian.little);
message.PayloadType = (bytes[offset + 1] << 8) | bytes[offset];
offset += 2; offset += 2;
} else {
throw FormatException("Invalid PayloadType length");
}
// PayloadCRC (2 bytes, little-endian) // PayloadCRC (2 bytes, little-endian)
if (bytes.length - offset >= 2) { message.PayloadCRC = byteData.getUint16(offset, Endian.little);
message.PayloadCRC = (bytes[offset + 1] << 8) | bytes[offset];
offset += 2; offset += 2;
} else {
throw FormatException("Invalid PayloadCRC length");
}
// PayloadLength (4 bytes, little-endian) // PayloadLength (4 bytes, little-endian)
if (bytes.length - offset >= 4) { message.PayloadLength = byteData.getUint32(offset, Endian.little);
message.PayloadLength = (bytes[offset] |
(bytes[offset + 1] << 8) |
(bytes[offset + 2] << 16) |
(bytes[offset + 3] << 24)); // little-endian
offset += 4; offset += 4;
} else {
throw FormatException("Invalid PayloadLength length"); // Payload
if (message.PayloadLength == null ||
length - offset < message.PayloadLength!) {
throw FormatException("Invalid Payload or PayloadLength");
} }
// Payload // Payload
if (message.PayloadLength != null && final payloadBytes = bytes.sublist(offset, offset + message.PayloadLength!);
bytes.length - offset >= message.PayloadLength!) {
final sublist = bytes.sublist(offset, offset + message.PayloadLength!);
offset += message.PayloadLength!; offset += message.PayloadLength!;
message.Payload = _handlePayLoad( message.Payload = _handlePayLoad(
payloadType: message.PayloadType ?? 0, payloadType: message.PayloadType ?? 0,
messageType: message.MessageType ?? 0, messageType: message.MessageType ?? 0,
byte: sublist, byte: payloadBytes,
offset: offset, offset: offset,
PayloadLength: message.PayloadLength, PayloadLength: message.PayloadLength,
spIndex: message.SpIndex, spIndex: message.SpIndex,
spTotal: message.SpTotal, spTotal: message.SpTotal,
messageId: message.MessageId, messageId: message.MessageId,
); );
} else {
throw FormatException("Invalid Payload or PayloadLength");
}
return message; return message;
} }
// static ScpMessage deserialize(Uint8List bytes) {
// final message = ScpMessage();
// int offset = 0;
//
// // String hexString =
// // bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
// // // _log(text: 'result bytes hex: ${hexString}');
// // _log(
// // text:
// // '\n result bytes hex: ${hexString} \n payload hex: ${hexString.substring(210)}');
//
// // ProtocolFlag (4 bytes)
// if (bytes.length - offset >= 4) {
// message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4));
// offset += 4;
// } else {
// throw FormatException("Invalid ProtocolFlag length");
// }
//
// // MessageType (1 byte)
// if (bytes.length - offset >= 1) {
// message.MessageType = bytes[offset];
// offset += 1;
// } else {
// throw FormatException("Invalid MessageType length");
// }
//
// // MessageId (2 bytes, little-endian)
// if (bytes.length - offset >= 2) {
// message.MessageId = (bytes[offset + 1] << 8) | bytes[offset];
// offset += 2;
// } else {
// throw FormatException("Invalid MessageId length");
// }
//
// // SpTotal (1 byte)
// if (bytes.length - offset >= 1) {
// message.SpTotal = bytes[offset];
// offset += 1;
// } else {
// throw FormatException("Invalid SpTotal length");
// }
//
// // SpIndex (1 byte)
// if (bytes.length - offset >= 1) {
// message.SpIndex = bytes[offset];
// offset += 1;
// } else {
// throw FormatException("Invalid SpIndex length");
// }
//
// // FromPeerId (44)
// if (bytes.length - offset >= 44) {
// message.FromPeerId =
// utf8.decode(bytes.sublist(offset, offset + 44)).trimRight();
// offset += 44;
// } else {
// throw FormatException("Invalid FromPeerId length");
// }
//
// // ToPeerId (44)
// if (bytes.length - offset >= 44) {
// message.ToPeerId =
// utf8.decode(bytes.sublist(offset, offset + 44)).trimRight();
// offset += 44;
// } else {
// throw FormatException("Invalid ToPeerId length");
// }
//
// // PayloadType (2 bytes, little-endian)
// if (bytes.length - offset >= 2) {
// message.PayloadType = (bytes[offset + 1] << 8) | bytes[offset];
// offset += 2;
// } else {
// throw FormatException("Invalid PayloadType length");
// }
//
// // PayloadCRC (2 bytes, little-endian)
// if (bytes.length - offset >= 2) {
// message.PayloadCRC = (bytes[offset + 1] << 8) | bytes[offset];
// offset += 2;
// } else {
// throw FormatException("Invalid PayloadCRC length");
// }
//
// // PayloadLength (4 bytes, little-endian)
// if (bytes.length - offset >= 4) {
// message.PayloadLength = (bytes[offset] |
// (bytes[offset + 1] << 8) |
// (bytes[offset + 2] << 16) |
// (bytes[offset + 3] << 24)); // little-endian
// offset += 4;
// } else {
// throw FormatException("Invalid PayloadLength length");
// }
//
// // Payload
// if (message.PayloadLength != null &&
// bytes.length - offset >= message.PayloadLength!) {
// final sublist = bytes.sublist(offset, offset + message.PayloadLength!);
// offset += message.PayloadLength!;
// message.Payload = _handlePayLoad(
// payloadType: message.PayloadType ?? 0,
// messageType: message.MessageType ?? 0,
// byte: sublist,
// offset: offset,
// PayloadLength: message.PayloadLength,
// spIndex: message.SpIndex,
// spTotal: message.SpTotal,
// messageId: message.MessageId,
// );
// } else {
// throw FormatException("Invalid Payload or PayloadLength");
// }
//
// return message;
// }
// payloadType序列化对应的payload结构体 // payloadType序列化对应的payload结构体
static dynamic _handlePayLoad({ static dynamic _handlePayLoad({
required int payloadType, required int payloadType,

View File

@ -29,7 +29,6 @@ class UdpTalkAcceptHandler extends ScpMessageBaseHandle
// //
final GenericResp genericResp = scpMessage.Payload; final GenericResp genericResp = scpMessage.Payload;
if (checkGenericRespSuccess(genericResp)) { if (checkGenericRespSuccess(genericResp)) {
print('收到同意接听的回复');
// //
startChartManage.stopTalkAcceptTimer(); startChartManage.stopTalkAcceptTimer();
// //

View File

@ -156,7 +156,7 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
void _handleVideoH264(TalkData talkData) { void _handleVideoH264(TalkData talkData) {
final TalkDataH264Frame talkDataH264Frame = TalkDataH264Frame(); final TalkDataH264Frame talkDataH264Frame = TalkDataH264Frame();
talkDataH264Frame.mergeFromBuffer(talkData.content); talkDataH264Frame.mergeFromBuffer(talkData.content);
AppLog.log('H264 TalkData :$talkDataH264Frame'); // AppLog.log('H264 TalkData :$talkDataH264Frame');
talkDataRepository.addTalkData(talkData); talkDataRepository.addTalkData(talkData);
} }

View File

@ -21,7 +21,7 @@ class UdpTalkHangUpHandler extends ScpMessageBaseHandle
// // // //
// return; // return;
// } // }
print('收到通话中挂断请求');
// //
replySuccessMessage(scpMessage); replySuccessMessage(scpMessage);
talkStatus.setHangingUpDuring(); talkStatus.setHangingUpDuring();
@ -34,7 +34,7 @@ class UdpTalkHangUpHandler extends ScpMessageBaseHandle
talkePingOverTimeTimerManager.cancel(); talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel(); talkDataOverTimeTimerManager.cancel();
EasyLoading.showToast('已挂断'); EasyLoading.showToast('已挂断'.tr);
Get.back(); Get.back();
} }

View File

@ -28,7 +28,7 @@ class TalkDataOverTimeTimerManager {
// //
static void _handleTalkeDataOverTime() { static void _handleTalkeDataOverTime() {
EasyLoading.showToast('通话连接失败', duration: 2000.milliseconds); EasyLoading.showToast('通话连接失败'.tr, duration: 2000.milliseconds);
// //
StartChartManage().sendTalkHangupMessage(); StartChartManage().sendTalkHangupMessage();
StartChartManage().stopTalkPingMessageTimer(); StartChartManage().stopTalkPingMessageTimer();

View File

@ -28,7 +28,7 @@ class TalkePingOverTimeTimerManager {
// //
static void _handleTalkePingOverTime() { static void _handleTalkePingOverTime() {
if (talkStatus.status == TalkStatus.answeredSuccessfully) { if (talkStatus.status == TalkStatus.answeredSuccessfully) {
EasyLoading.showToast('通话异常中断', duration: 2000.milliseconds); EasyLoading.showToast('通话异常中断'.tr, duration: 2000.milliseconds);
// //
StartChartManage().stopTalkPingMessageTimer(); StartChartManage().stopTalkPingMessageTimer();
StartChartManage().stopTalkExpectMessageTimer(); StartChartManage().stopTalkExpectMessageTimer();

View File

@ -29,7 +29,7 @@ class TalkeRequestOverTimeTimerManager {
static void _handleTalkeRequestOverTime() { static void _handleTalkeRequestOverTime() {
if (talkStatus.status == TalkStatus.passiveCallWaitingAnswer || if (talkStatus.status == TalkStatus.passiveCallWaitingAnswer ||
talkStatus.status == TalkStatus.proactivelyCallWaitingAnswer) { talkStatus.status == TalkStatus.proactivelyCallWaitingAnswer) {
EasyLoading.showToast('通话未接通,以挂断', duration: 2000.milliseconds); EasyLoading.showToast('通话未接通,已挂断'.tr, duration: 2000.milliseconds);
// //
StartChartManage().sendTalkRejectMessage(); StartChartManage().sendTalkRejectMessage();
talkStatus.setInitializationCompleted(); talkStatus.setInitializationCompleted();

View File

@ -50,7 +50,6 @@ class TalkViewLogic extends BaseGetXController {
int audioFrameIntervalMs = 20; // 4522FPS int audioFrameIntervalMs = 20; // 4522FPS
int minFrameIntervalMs = 30; // 33 FPS int minFrameIntervalMs = 30; // 33 FPS
int maxFrameIntervalMs = 100; // 1 FPS int maxFrameIntervalMs = 100; // 1 FPS
// int maxFrameIntervalMs = 100; // 10 FPS
/// ///
void _initFlutterPcmSound() { void _initFlutterPcmSound() {
@ -118,6 +117,17 @@ class TalkViewLogic extends BaseGetXController {
case TalkStatus.end: case TalkStatus.end:
_handleInvalidTalkStatus(); _handleInvalidTalkStatus();
break; break;
case TalkStatus.answeredSuccessfully:
state.oneMinuteTimeTimer?.cancel(); //
state.oneMinuteTimeTimer ??=
Timer.periodic(const Duration(seconds: 1), (Timer t) {
state.oneMinuteTime.value++;
if (state.oneMinuteTime.value >= 60) {
t.cancel(); //
state.oneMinuteTime.value = 0;
}
});
break;
default: default:
// //
break; break;
@ -160,12 +170,6 @@ class TalkViewLogic extends BaseGetXController {
/// ///
void _adjustFrameInterval() { void _adjustFrameInterval() {
int newFrameIntervalMs = frameIntervalMs; int newFrameIntervalMs = frameIntervalMs;
if (state.networkStatus.value == NetworkStatus.lagging) {
bufferSize = 60; //
} else {
bufferSize = 40; //
}
if (state.videoBuffer.length < 10 && frameIntervalMs < maxFrameIntervalMs) { if (state.videoBuffer.length < 10 && frameIntervalMs < maxFrameIntervalMs) {
// //
frameIntervalMs += 5; frameIntervalMs += 5;
@ -303,7 +307,7 @@ class TalkViewLogic extends BaseGetXController {
bluetoothDeviceName: BlueManage().connectDeviceName, bluetoothDeviceName: BlueManage().connectDeviceName,
openLockCommand: messageDetail, openLockCommand: messageDetail,
); );
showToast('已发送开门通知'); showToast('正在开锁中...'.tr);
} }
int _getUTCNetTime() { int _getUTCNetTime() {
@ -442,7 +446,8 @@ class TalkViewLogic extends BaseGetXController {
_syncTimer = null; // _syncTimer = null; //
_audioTimer?.cancel(); _audioTimer?.cancel();
_audioTimer = null; // _audioTimer = null; //
state.oneMinuteTimeTimer?.cancel();
state.oneMinuteTimeTimer = null;
stopProcessingAudio(); stopProcessingAudio();
super.onClose(); super.onClose();
} }

View File

@ -110,13 +110,13 @@ class _TalkViewPageState extends State<TalkViewPage>
canPop: false, canPop: false,
child: RepaintBoundary( child: RepaintBoundary(
key: state.globalKey, key: state.globalKey,
child: Transform.rotate( child: SizedBox.expand(
angle: child: RotatedBox(
state.rotateAngle.value * (pi / 180), // 90 quarterTurns: -1,
child: Transform.scale(
scale: scale, //
child: Image.memory( child: Image.memory(
state.listData.value, state.listData.value,
width: ScreenUtil().scaleWidth,
height: ScreenUtil().scaleHeight,
gaplessPlayback: true, gaplessPlayback: true,
fit: BoxFit.cover, fit: BoxFit.cover,
filterQuality: FilterQuality.high, filterQuality: FilterQuality.high,
@ -142,6 +142,34 @@ class _TalkViewPageState extends State<TalkViewPage>
style: TextStyle(color: Colors.black, fontSize: 26.sp), style: TextStyle(color: Colors.black, fontSize: 26.sp),
)) ))
: Container()), : Container()),
Obx(
() => state.listData.value.isNotEmpty
? Positioned(
top: ScreenUtil().statusBarHeight + 75.h,
width: 1.sw,
child: Obx(
() {
final String sec = (state.oneMinuteTime.value % 60)
.toString()
.padLeft(2, '0');
final String min = (state.oneMinuteTime.value ~/ 60)
.toString()
.padLeft(2, '0');
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$min:$sec',
style: TextStyle(
fontSize: 26.sp, color: Colors.white),
),
],
);
},
),
)
: Container(),
),
Positioned( Positioned(
bottom: 10.w, bottom: 10.w,
child: Container( child: Container(
@ -197,7 +225,7 @@ class _TalkViewPageState extends State<TalkViewPage>
Icon(Icons.mic, color: Colors.white, size: 24.w), Icon(Icons.mic, color: Colors.white, size: 24.w),
SizedBox(width: 10.w), SizedBox(width: 10.w),
Text( Text(
'正在说话...', '正在说话...'.tr,
style: TextStyle( style: TextStyle(
fontSize: 20.sp, color: Colors.white), fontSize: 20.sp, color: Colors.white),
), ),
@ -342,13 +370,13 @@ class _TalkViewPageState extends State<TalkViewPage>
Colors.white, Colors.white,
longPress: () async { longPress: () async {
if (state.talkStatus.value == TalkStatus.answeredSuccessfully) { if (state.talkStatus.value == TalkStatus.answeredSuccessfully) {
print('开始录音'); //
logic.startProcessingAudio(); logic.startProcessingAudio();
state.isLongPressing.value = true; state.isLongPressing.value = true;
} }
}, },
longPressUp: () async { longPressUp: () async {
print('停止录音'); //
logic.stopProcessingAudio(); logic.stopProcessingAudio();
state.isLongPressing.value = false; state.isLongPressing.value = false;
}, },
@ -369,7 +397,7 @@ class _TalkViewPageState extends State<TalkViewPage>
}), }),
bottomBtnItemWidget( bottomBtnItemWidget(
'images/main/icon_lockDetail_monitoringUnlock.png', 'images/main/icon_lockDetail_monitoringUnlock.png',
'开锁', '开锁'.tr,
AppColors.mainColor, AppColors.mainColor,
onClick: () { onClick: () {
// if (UDPManage().remoteUnlock == 1) { // if (UDPManage().remoteUnlock == 1) {

View File

@ -37,8 +37,7 @@ class TalkViewState {
RxList<int> listAudioData = <int>[].obs; // RxList<int> listAudioData = <int>[].obs; //
GlobalKey globalKey = GlobalKey(); GlobalKey globalKey = GlobalKey();
late Timer oneMinuteTimeTimer = Timer? oneMinuteTimeTimer; // 60
Timer(const Duration(seconds: 1), () {}); // 60
RxInt oneMinuteTime = 0.obs; // RxInt oneMinuteTime = 0.obs; //
// 10 // 10

View File

@ -36,6 +36,7 @@ const String starChartRegisterNodeInfo = 'starChartRegisterNodeInfo'; //星图
const String relayInfo = 'relayInfo'; // const String relayInfo = 'relayInfo'; //
const String lockNetWorkInfo = 'lockNetWorkInfo'; // const String lockNetWorkInfo = 'lockNetWorkInfo'; //
const String appVersionHistoryUrl = 'appVersionHistoryUrl'; //
class Storage { class Storage {
factory Storage() => _instance; factory Storage() => _instance;

View File

@ -1,7 +1,6 @@
import '../../login/login/app_get_version.dart'; import '../../login/login/app_get_version.dart';
import '../../network/api_repository.dart'; import '../../network/api_repository.dart';
import '../storage.dart';
import 'customer_tool.dart'; import 'customer_tool.dart';
import 'pay/wx_pay_tool.dart'; import 'pay/wx_pay_tool.dart';
@ -14,11 +13,11 @@ class WechatManageTool {
// AppLog.log('AppFirstEnterHandle调用了获取App信息接口'); // AppLog.log('AppFirstEnterHandle调用了获取App信息接口');
final GetAppInfo entity = await ApiRepository.to.getAppInfo(); final GetAppInfo entity = await ApiRepository.to.getAppInfo();
if (entity.errorCode == 0) { if (entity.errorCode == 0) {
Storage.setString(
appVersionHistoryUrl, entity.data?.appVersionHistoryUrl ?? '');
CustomerTool.init(entity.data?.wechatServiceUrl ?? ''); CustomerTool.init(entity.data?.wechatServiceUrl ?? '');
WxPayTool.setAssociationUrl(entity.data!.appSiteUrl!); WxPayTool.setAssociationUrl(entity.data!.appSiteUrl!);
action(); action();
} }
} }
} }

View File

@ -401,7 +401,7 @@ packages:
source: hosted source: hosted
version: "7.0.2" version: "7.0.2"
dio: dio:
dependency: transitive dependency: "direct main"
description: description:
name: dio name: dio
sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8" sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8"
@ -1785,6 +1785,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.2"
video_thumbnail:
dependency: "direct main"
description:
name: video_thumbnail
sha256: "3455c189d3f0bb4e3fc2236475aa84fe598b9b2d0e08f43b9761f5bc44210016"
url: "https://pub.dev"
source: hosted
version: "0.5.3"
visibility_detector: visibility_detector:
dependency: transitive dependency: transitive
description: description:

View File

@ -269,7 +269,8 @@ dependencies:
# 图片预览 # 图片预览
photo_view: ^0.15.0 photo_view: ^0.15.0
provider: ^6.1.2 provider: ^6.1.2
dio: ^4.0.6 # 网络请求库
video_thumbnail: ^0.5.3