diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 868db348..eeb98d56 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -151,8 +151,8 @@ create-release: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/StarLock/${StarLock_VERSION}/StarLock-${StarLock_VERSION}-*" - 'curl -i --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/app/outputs/flutter-apk/starlock-xhj-release-${CI_COMMIT_TAG}.apk "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/StarLock/${StarLock_VERSION}/starlock-xhj-release-${CI_COMMIT_TAG}.apk"' - - 'curl -i --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/app/outputs/flutter-apk/starlock-xhj-release-${CI_COMMIT_TAG}.aab - "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/StarLock/${StarLock_VERSION}/starlock-xhj-release-${CI_COMMIT_TAG}.aab"' + - 'curl -i --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/app/outputs/flutter-apk/starlock-xhj_bundle-release-${CI_COMMIT_TAG}.aab + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/StarLock/${StarLock_VERSION}/starlock-xhj_bundle-release-${CI_COMMIT_TAG}.aab"' - 'curl -i --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/app/outputs/flutter-apk/starlock-sky-release-${CI_COMMIT_TAG}.apk "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/StarLock/${StarLock_VERSION}/starlock-sky-release-${CI_COMMIT_TAG}.apk"' - 'curl -i --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/app/outputs/flutter-apk/starlock-sky-release-${CI_COMMIT_TAG}.aab diff --git a/android/app/src/main/res/raw/ring.mp3 b/android/app/src/main/res/raw/ring.mp3 new file mode 100755 index 00000000..eee971ac Binary files /dev/null and b/android/app/src/main/res/raw/ring.mp3 differ diff --git a/assets/test.jpg b/assets/test.jpg deleted file mode 100644 index f74d412c..00000000 Binary files a/assets/test.jpg and /dev/null differ diff --git a/lan/lan_ar.json b/lan/lan_ar.json index 938e2aa1..63371d82 100644 --- a/lan/lan_ar.json +++ b/lan/lan_ar.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "بعد إعادة الضبط ، سيتم حذف الأوردة المشطية للقفل. هل أنت متأكد أنك تريد إعادة الضبط ؟", "在线": "الإنترنت", "离线": "غير متصل", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "وظيفة الفتح عن بعد لهذا القفل غير ممكنة", "下载完成,请到相册查看": "اكتملت عملية التحميل، الرجاء الذهاب إلى الألبوم لمشاهدته", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "عند ضبط عين على وضع توفير الطاقة لا يمكن إجراء المراقبة يرجى الانتقال إلى الأوضاع الأخرى في إعدادات", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "لا يمكن فتح القفل عن بعد عند ضبط عين على وضع توفير الطاقة يرجى الانتقال إلى وضع آخر في إعدادات عين القطة" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "لا يمكن فتح القفل عن بعد عند ضبط عين على وضع توفير الطاقة يرجى الانتقال إلى وضع آخر في إعدادات عين القطة", + "呼叫目标": "الاتصال الهدف", + "管理员APP": "برنامج التطبيقات الخاص بالمسؤول", + "可视门铃码": "رمز جرس الباب البصري", + "电子反锁": "جهاز إلكتروني لمنع القفل", + "双重认证": "المصادقة من عاملين", + "双锁联动": "وصلة القفل المزدوج", + "1.用智能锁APP添加锁和网关": "1. أضف أقفال وبوابات باستخدام تطبيق القفل الذكي", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. تمكين وظيفة الفتح عن بعد للقفل في APP (يتم إيقاف هذه الوظيفة بشكل افتراضي). إذا كان هذا الخيار غير متاح، لن يدعم القفل جوجل هوم", + "3.安装Google Home APP,点击左上角的加号按钮": "3. قم بتثبيت تطبيق Google Home وانقر فوق الزر زائد في الزاوية العلوية اليسرى", + "暂无最新记录": "لا توجد حاليا أحدث السجلات المتاحة", + "请将手机切换至2.4G WiFi进行手动连接": "الرجاء تحويل هاتفك إلى \"واي فاي 2.4\" للاتصال اليدوي" } \ No newline at end of file diff --git a/lan/lan_bg.json b/lan/lan_bg.json index 033c9ef5..56750a26 100644 --- a/lan/lan_bg.json +++ b/lan/lan_bg.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "След нулиране, метакарпалните вени на ключалката ще бъдат изтрити. Сигурен ли сте, че искате да се възстанови?", "在线": "Онлайн", "离线": "Офлайн", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Функцията за дистанционно отключване на тази ключалка не е активирана", "下载完成,请到相册查看": "Изтеглянето е завършено, моля, отидете на албума, за да го видите", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Когато Cat Eye е настроен на режим на пестене на енергия, наблюдението не може да се извършва. Моля, превключете към други режими в настройките на Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Дистанционното отключване не е възможно, когато Cat Eye е настроен в режим на пестене на енергия. Моля, превключете на друг режим в настройките на Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Дистанционното отключване не е възможно, когато Cat Eye е настроен в режим на пестене на енергия. Моля, превключете на друг режим в настройките на Cat Eye", + "呼叫目标": "Цел на обаждане", + "管理员APP": "Приложение за администратор", + "可视门铃码": "Визуален код на звънеца", + "电子反锁": "Електронна анти блокировка", + "双重认证": "Двуфакторно удостоверяване", + "双锁联动": "Връзка с двойно заключване", + "1.用智能锁APP添加锁和网关": "1. Добавете брави и шлюзове с помощта на приложението Smart Lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Активирайте функцията за дистанционно отключване на ключалката в приложението (тази функция е изключена по подразбиране). Ако тази опция не е налице, заключването няма да поддържа Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Инсталирайте приложението Google Home и щракнете върху бутона плюс в горния ляв ъгъл", + "暂无最新记录": "В момента няма най-новите налични записи", + "请将手机切换至2.4G WiFi进行手动连接": "Моля, превключете телефона си на 2.4G WiFi за ръчно свързване" } \ No newline at end of file diff --git a/lan/lan_bn.json b/lan/lan_bn.json index 3a4df8b0..8a7d28df 100644 --- a/lan/lan_bn.json +++ b/lan/lan_bn.json @@ -177,7 +177,7 @@ "开启": "টেকওন", "确定要开启重置键?": "গানট্টটন?", "确定要关闭重置键?": "গানট্টটন?", - "隐藏无效开锁权限": "Hide ali▁alidaccessGenericName", + "隐藏无效开锁权限": "অবৈধ অনুমতি আড়াল করো", "APP开锁时需手机连网的锁": "ব্লকস্ক্রিয়ামিংফোনলাইন", "增值服务": "ওয়ার্ডেরিসিস", "关于": "কুবআউট", @@ -217,7 +217,7 @@ "重新通电": "পরীক্ষা", "指示灯": "কেয়ানারেটরলাইট", "选择网关": "সিওসিকারওয়ে", - "不支持5G WiFi网络,请选择2.4G WiFi网络进行配置": "5 gisnoteigpped,.", + "不支持5G WiFi网络,请选择2.4G WiFi网络进行配置": "5G ওয়াইফাই নেটওয়ার্ক সমর্থন করে না, কনফিগার করার জন্য 2.4G ওয়াইফাই নেটওয়ার্ক নির্বাচন করুন", "WiFi密码": "উইফিক", "请输入WiFi密码": "দ্বিতীয় ওয়ার্ড", "网关名称": "সমুদ্রনাম", @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "ব্যান্ডোটারআইসেট, হাসিপাল রিরিইনস্ফথেলকবইল্ডজেডড।?", "在线": "কনলাইন", "离线": "দেউন্টলাইনCity in Ontario Canada", @@ -1087,13 +1089,13 @@ "修改名字": "নেম", "时": "Hour", "分": "নিউট", - "Amazon Alexa": "Ammogonalexa", + "Amazon Alexa": "Amazon Alexa", "您可以使用Alexa进行开锁、闭锁和查看锁状态": "/অনুপন্থির", "支持的国家": "আদিবাস্য", "支持的国家值": "ইউসা, চা, uk, ঊর্ধ্ব, ডাইডিয়া, germany, ডিফায়েন্স, লি, ইম্পোসি, ইজেড", "操作流程": "ক্যামেশনprocesscess", "操作流程值": "1 বিরোধীদ্যালক্যান্ডgatkorethrouthhescartchlockParp\n\n2 দশমিক... ...সম্পোকলকিং... লকটিংয়ের (সংখ্যা ইংলিপিস অফবি-রফ-এফল্ট)। ফিফডোনট্যানস্ট্রিওপশন, থেলক ক্যান্টোনট\n\n3 বিদ্রোহী স্কুই ls টু-এক্সাআন্ড ঊর্ধ্বতন পোস্টার্থে\n\n৪লক্যাটথলকের দিন ইক্সাপপ্প, টেসিতে ইসোলাকক fun\n\n5thelockcanbe equavaedunderroughalexaxa", - "Google Home": "শ্রোগল", + "Google Home": "Google Home", "Action name": "কর্মসূচী", "ScienerSmart": "ইসিসিভার্ট", "支持的语言": "আদিবাস্য", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "এই লকের রিমোট আনলকিং ফাংশন সক্ষম নেই", "下载完成,请到相册查看": "ডাউনলোড সম্পন্ন হয়েছে, দেখতে অনুগ্রহ করে অ্যালবামে যান", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "যখন ক্যাট আই পাওয়ার-সেভিং মোডে সেট করা থাকে, তখন পর্যবেক্ষণ করা যায় না। দয়া করে ক্যাট আই সেটিংসে অন্যান্য মোডে স্যুইচ করুন", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "ক্যাট আই পাওয়ার-সাশ্রয় মোডে সেট করা থাকলে রিমোট আনলক করা সম্ভব নয়। দয়া করে ক্যাট আই সেটিংসে অন্য মোডে স্যুইচ করুন" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "ক্যাট আই পাওয়ার-সাশ্রয় মোডে সেট করা থাকলে রিমোট আনলক করা সম্ভব নয়। দয়া করে ক্যাট আই সেটিংসে অন্য মোডে স্যুইচ করুন", + "呼叫目标": "কল টার্গেট", + "管理员APP": "প্রশাসক অ্যাপ", + "可视门铃码": "ভিজ্যুয়াল ডোরবেল কোড", + "电子反锁": "বৈদ্যুতিন বিরোধী লক", + "双重认证": "টু-ফ্যাক্টর অথেনটিকেশন", + "双锁联动": "ডাবল লক লিঙ্কেজ", + "1.用智能锁APP添加锁和网关": "1. স্মার্ট লক অ্যাপ ব্যবহার করে লক ও গেটওয়ে যোগ করুন", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. অ্যাপে লকের রিমোট আনলকিং ফাংশন সক্ষম করুন (এই ফাংশনটি ডিফল্টরূপে বন্ধ রয়েছে)। যদি এই বিকল্পটি উপলভ্য না হয় তবে লকটি গুগল হোম সমর্থন করবে না", + "3.安装Google Home APP,点击左上角的加号按钮": "গুগল হোম অ্যাপ্লিকেশনটি ইনস্টল করুন এবং উপরের বাম কোণে প্লাস বোতামটি ক্লিক করুন", + "暂无最新记录": "বর্তমানে কোনও সাম্প্রতিকতম রেকর্ড সুলভ নেই", + "请将手机切换至2.4G WiFi进行手动连接": "ম্যানুয়াল সংযোগের জন্য দয়া করে আপনার ফোনটি 2.4 জি ওয়াইফাইতে স্যুইচ করুন" } \ No newline at end of file diff --git a/lan/lan_cs.json b/lan/lan_cs.json index ceff8a23..08925658 100644 --- a/lan/lan_cs.json +++ b/lan/lan_cs.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Po resetování budou metakarpální žíly zámku odstraněny. Jste si jistý, že chcete resetovat?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Funkce dálkového odemykání tohoto zámku není povolena", "下载完成,请到相册查看": "Stahování dokončeno, přejděte prosím na album k zobrazení", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Když je Cat Eye nastaven do úsporného režimu, monitorování nelze provádět. Přepněte prosím do jiných režimů v nastavení Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Dálkové odemykání není možné, pokud je Cat Eye nastaven do úsporného režimu. Přepněte prosím do jiného režimu v nastavení Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Dálkové odemykání není možné, pokud je Cat Eye nastaven do úsporného režimu. Přepněte prosím do jiného režimu v nastavení Cat Eye", + "呼叫目标": "Cíl hovoru", + "管理员APP": "Aplikace správce", + "可视门铃码": "Vizuální kód zvonku", + "电子反锁": "Elektronické blokování", + "双重认证": "Dvoufaktorová autentizace", + "双锁联动": "Dvojitý zámek", + "1.用智能锁APP添加锁和网关": "1. Přidejte zámky a brány pomocí aplikace chytrého zámku", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Povolte funkci dálkového odemykání zámku v APP (tato funkce je ve výchozím nastavení vypnutá). Pokud tato možnost není k dispozici, zámek nebude podporovat Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Nainstalujte aplikaci Google Home a klikněte na tlačítko plus v levém horním rohu", + "暂无最新记录": "Momentálně nejsou k dispozici žádné nejnovější záznamy", + "请将手机切换至2.4G WiFi进行手动连接": "Přepněte prosím svůj telefon na 2.4G WiFi pro ruční připojení" } \ No newline at end of file diff --git a/lan/lan_da.json b/lan/lan_da.json index 09b0b141..d3db1465 100644 --- a/lan/lan_da.json +++ b/lan/lan_da.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Efter nulstilling, de metacarpal vener i låsen vil blive slettet. Er du sikker på at du vil nulstille?", "在线": "OnlineComment", "离线": "OfflineComment", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Fjernoplåsningsfunktionen for denne lås er ikke aktiveret", "下载完成,请到相册查看": "Download fuldført, gå til albummet for at se", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Når Cat Eye er indstillet til strømbesparende tilstand, kan overvågning ikke udføres. Skift venligst til andre tilstande i Cat Eye-indstillingerne", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Fjernoplåsning er ikke mulig, når Cat Eye er indstillet til strømbesparende tilstand. Skift venligst til en anden tilstand i Cat Eye-indstillinger" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Fjernoplåsning er ikke mulig, når Cat Eye er indstillet til strømbesparende tilstand. Skift venligst til en anden tilstand i Cat Eye-indstillinger", + "呼叫目标": "Mål for opkald", + "管理员APP": "Administrator APP", + "可视门铃码": "Visuel dørklokkekode", + "电子反锁": "Elektronisk anti-lås", + "双重认证": "To-faktor-godkendelse", + "双锁联动": "Dobbelt låseforbindelse", + "1.用智能锁APP添加锁和网关": "1. Tilføj låse og gateways ved hjælp af smart lock-appen", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Aktiver fjernoplåsningsfunktionen for låsen i APP'en (denne funktion er slået fra som standard). Hvis denne mulighed ikke er tilgængelig, understøtter låsen ikke Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Installer Google Home-appen, og klik på plusknappen i øverste venstre hjørne", + "暂无最新记录": "Der er i øjeblikket ingen nyeste optegnelser tilgængelige", + "请将手机切换至2.4G WiFi进行手动连接": "Skift venligst din telefon til 2.4G WiFi for manuel forbindelse" } \ No newline at end of file diff --git a/lan/lan_de.json b/lan/lan_de.json index e4b18d4d..79e2516d 100644 --- a/lan/lan_de.json +++ b/lan/lan_de.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Nach dem Zurücksetzen werden die Mittelhand adern des Schlosses gelöscht. Sind Sie sicher, dass Sie zurücksetzen wollen?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Die fernsteuerung des schlüssels nicht geöffnet", "下载完成,请到相册查看": "Die herunterladen ist abgeschlossen. Gehen sie ins fotoalbum", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Die überwachung kann nicht durchgeführt werden, wenn die katze auf schaltungsmodus eingestellt ist. Wechseln sie in die einstellungen für die katze auf einen anderen modus", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Die katze kann nicht aus der ferne entsperren, wenn sie so eingestellt ist, dass strom gespart wird Wechseln sie in die einstellungen für die katze auf einen anderen modus" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Die katze kann nicht aus der ferne entsperren, wenn sie so eingestellt ist, dass strom gespart wird Wechseln sie in die einstellungen für die katze auf einen anderen modus", + "呼叫目标": "Aktiviere ziel.", + "管理员APP": "Administrator tor wenden.", + "可视门铃码": "Achter türcode", + "电子反锁": "Die elektronische abwehrvorrichtung", + "双重认证": "Duale identität", + "双锁联动": "Ein doppelschloss verbindet sich", + "1.用智能锁APP添加锁和网关": "1. Schlösser und gateway mit der anwendung intelligente schlösser hinzufügen", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Entsichern in einer APP, die ein schloss öffnet (standard abschalten) Wenn diese option nicht verfügbar ist, wird das schloss google nicht unterstützen", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Installiert die google-app und klicken auf den knopf hinzufügen in der oberen linken ecke", + "暂无最新记录": "Wir haben keine neuen daten", + "请将手机切换至2.4G WiFi进行手动连接": "Wenn manuelle verbindung hergestellt wird, schalten sie das handy auf 2,4 G WiFi" } \ No newline at end of file diff --git a/lan/lan_el.json b/lan/lan_el.json index 91697172..8eac3390 100644 --- a/lan/lan_el.json +++ b/lan/lan_el.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Μετά την επαναφορά, οι μετακάρπιες φλέβες της κλειδαριάς θα διαγραφούν. Είστε σίγουροι ότι θέλετε να επαναφέρετε;", "在线": "Σε απευθείας σύνδεση", "离线": "Εκτός σύνδεσης:", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Η λειτουργία απομακρυσμένου ξεκλειδώματος αυτής της κλειδαριάς δεν είναι ενεργοποιημένη", "下载完成,请到相册查看": "Η λήψη ολοκληρώθηκε, μεταβείτε στο άλμπουμ για προβολή", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Όταν το Cat Eye έχει ρυθμιστεί σε λειτουργία εξοικονόμησης ενέργειας, δεν είναι δυνατή η εκτέλεση παρακολούθησης. Μεταβείτε σε άλλες λειτουργίες στις ρυθμίσεις του Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Το απομακρυσμένο ξεκλείδωμα δεν είναι δυνατό όταν το Cat Eye έχει ρυθμιστεί σε λειτουργία εξοικονόμησης ενέργειας. Μεταβείτε σε άλλη λειτουργία στις ρυθμίσεις του Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Το απομακρυσμένο ξεκλείδωμα δεν είναι δυνατό όταν το Cat Eye έχει ρυθμιστεί σε λειτουργία εξοικονόμησης ενέργειας. Μεταβείτε σε άλλη λειτουργία στις ρυθμίσεις του Cat Eye", + "呼叫目标": "Στόχος κλήσης", + "管理员APP": "Εφαρμογή διαχειριστή", + "可视门铃码": "Οπτικός κωδικός κουδουνιού πόρτας", + "电子反锁": "Ηλεκτρονικό αντικλείδωμα", + "双重认证": "Έλεγχος ταυτότητας δύο παραγόντων", + "双锁联动": "Σύνδεσμος διπλού κλειδώματος", + "1.用智能锁APP添加锁和网关": "1. Προσθέστε κλειδαριές και πύλες χρησιμοποιώντας την εφαρμογή Smart Lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Ενεργοποιήστε τη λειτουργία απομακρυσμένου ξεκλειδώματος της κλειδαριάς στην εφαρμογή (αυτή η λειτουργία είναι απενεργοποιημένη από προεπιλογή). Εάν αυτή η επιλογή δεν είναι διαθέσιμη, το κλείδωμα δεν θα υποστηρίζει το Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Εγκαταστήστε την εφαρμογή Google Home και κάντε κλικ στο κουμπί συν στην επάνω αριστερή γωνία", + "暂无最新记录": "Προς το παρόν δεν υπάρχουν διαθέσιμες τελευταίες εγγραφές", + "请将手机切换至2.4G WiFi进行手动连接": "Αλλάξτε το τηλέφωνό σας σε 2.4G WiFi για χειροκίνητη σύνδεση" } \ No newline at end of file diff --git a/lan/lan_en.json b/lan/lan_en.json index 1f5ac308..99767e88 100644 --- a/lan/lan_en.json +++ b/lan/lan_en.json @@ -1080,6 +1080,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "After reset, the metacarpal veins of the lock will be deleted. Are you sure you want to reset?", "在线": "Online", "离线": "Offline", @@ -1137,6 +1139,21 @@ "版本说明": "Version description", "呼叫目标": "Call target", "管理员APP": "Administrator APP", + "可视门铃码": "Visual doorbell code", + "电子反锁": "Electronic anti lock", + "双重认证": "Two-factor authentication", + "双锁联动": "Double lock linkage", + "1.用智能锁APP添加锁和网关": "1. Add locks and gateways using the smart lock app", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Enable the remote unlocking function of the lock in the APP (this function is turned off by default). If this option is not available, the lock will not support Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Install the Google Home app and click the plus button in the upper left corner", "网关通电后,长按重置按钮5秒,蓝色指示灯闪烁时点击下一步": "After the gateway is powered on, press and hold the reset button for 5 seconds. Click Next when the blue indicator light flashes", + "暂无最新记录": "There are currently no latest records available", + "请将手机切换至2.4G WiFi进行手动连接": "Please switch your phone to 2.4G WiFi for manual connection", + "请确保网络是2.4GHz Wi-Fi": "Please ensure that the network is 2.4GHz Wi Fi", + "是否要远程开锁": "Do you want to unlock remotely", + "国家地区的选择将影响数据安全,你当前选择的是": "The choice of country or region will affect data security. What is your current choice", + "请确认后再继续": "Please confirm before continuing", + "需要相机权限": "Camera permission required", + "此功能的开启和关闭只能在锁附近通过手机蓝牙进行": "The activation and deactivation of this feature can only be done through Bluetooth on the phone near the lock", "网关添加成功": "Gateway added successfully" } diff --git a/lan/lan_es.json b/lan/lan_es.json index e1f203ba..4dabcf0d 100644 --- a/lan/lan_es.json +++ b/lan/lan_es.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Después del reinicio, se eliminarán las venas metacarpiales de la cerradura. ¿Está seguro de que desea restablecer?", "在线": "En línea", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "La función de desbloqueo remoto de este bloqueo no está habilitada", "下载完成,请到相册查看": "Descargar completado, por favor vaya al álbum para ver", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Cuando Cat Eye está configurado en modo de ahorro de energía, no se puede realizar la monitorización. Cambie a otros modos en la configuración de ojo gato", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "El desbloqueo remoto no es posible cuando Cat Eye está en modo de ahorro de energía. Cambie a otro modo en la configuración de ojos de gato" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "El desbloqueo remoto no es posible cuando Cat Eye está en modo de ahorro de energía. Cambie a otro modo en la configuración de ojos de gato", + "呼叫目标": "Objetivo de la llamada", + "管理员APP": "Aplicación de administrador", + "可视门铃码": "Código de timbre Visual de la puerta", + "电子反锁": "Antibloqueo electrónico", + "双重认证": "Autenticación de dos factores", + "双锁联动": "Doble cierre", + "1.用智能锁APP添加锁和网关": "1. Agregue bloqueos y puertas de enlace con la aplicación smart lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Habilitar la función de desbloqueo remoto del bloqueo en la aplicación (esta función se desactiva por defecto). Si esta opción no está disponible, el bloqueo no será compatible con Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Instale la aplicación de Google Home y haga clic en el botón más en la esquina superior izquierda", + "暂无最新记录": "Actualmente no hay registros más recientes disponibles", + "请将手机切换至2.4G WiFi进行手动连接": "Por favor cambia tu teléfono a 2.4G WiFi para la conexión manual" } \ No newline at end of file diff --git a/lan/lan_et.json b/lan/lan_et.json index c0a777f0..48888bd6 100644 --- a/lan/lan_et.json +++ b/lan/lan_et.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Pärast lähtestamist kustutatakse luku metakarpaalveenid. Kas tõesti soovid lähtestada?", "在线": "Võrgus", "离线": "Mitte ühendust", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Selle luku kaugavamise funktsioon pole lubatud", "下载完成,请到相册查看": "Allalaadimine on lõpetatud, vaatamiseks minge albumisse", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Kui Cat Eye on seatud energiasäästurežiimile, ei saa jälgimist teostada. Palun lülituge Cat Eye seadetes muudele režiimidele", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Kaugavamine ei ole võimalik, kui Cat Eye on seatud energiasäästurežiimile. Palun lülituge Cat Eye seadetes teisele režiimile" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Kaugavamine ei ole võimalik, kui Cat Eye on seatud energiasäästurežiimile. Palun lülituge Cat Eye seadetes teisele režiimile", + "呼叫目标": "Kõne sihtmärk", + "管理员APP": "Administraatori rakendus", + "可视门铃码": "Visuaalne uksekella kood", + "电子反锁": "Elektrooniline mitteblokeeruv", + "双重认证": "Kahefaktoriline autentimine", + "双锁联动": "Kahekordne lukustusühendus", + "1.用智能锁APP添加锁和网关": "1. Lisage lukke ja lüüse nutiluku rakenduse abil", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Lubage rakenduses APP luku kaugavamise funktsioon (see funktsioon on vaikimisi välja lülitatud). Kui see valik pole saadaval, ei toeta lukk Google Home'i", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Installige rakendus Google Home ja klõpsake vasakus ülanurgas plussnuppu", + "暂无最新记录": "Praegu pole uusimaid andmeid saadaval", + "请将手机切换至2.4G WiFi进行手动连接": "Käsitsi ühendamiseks lülitage telefon 2.4G WiFi-le" } \ No newline at end of file diff --git a/lan/lan_fi.json b/lan/lan_fi.json index 079be028..a6cd4aba 100644 --- a/lan/lan_fi.json +++ b/lan/lan_fi.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Kun lukko on nollattu, metakarppinen suoneet poistetaan. Haluatko varmasti palauttaa?", "在线": "Verkossa", "离线": "Offline-verkosto", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Tämän lukon etälukituksen avaustoiminto ei ole käytössä", "下载完成,请到相册查看": "Lataus valmis, siirry albumiin nähdäksesi", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Kun Cat Eye on asetettu virransäästötilaan, valvontaa ei voi suorittaa. Vaihda muihin tiloihin Cat Eye -asetuksissa", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Lukituksen avaaminen ei ole mahdollista, kun Cat Eye on asetettu virransäästötilaan. Vaihda toiseen tilaan Cat Eye -asetuksissa" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Lukituksen avaaminen ei ole mahdollista, kun Cat Eye on asetettu virransäästötilaan. Vaihda toiseen tilaan Cat Eye -asetuksissa", + "呼叫目标": "Puhelun kohde", + "管理员APP": "Järjestelmänvalvojan APP", + "可视门铃码": "Visuaalinen ovikellon koodi", + "电子反锁": "Elektroninen lukkiutumaton", + "双重认证": "Kaksivaiheinen todennus", + "双锁联动": "Kaksinkertainen lukitus", + "1.用智能锁APP添加锁和网关": "1. Lisää lukkoja ja yhdyskäytäviä älylukkosovelluksella", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Ota lukon etälukituksen avaustoiminto käyttöön APP:ssa (tämä toiminto on oletuksena pois päältä). Jos tämä vaihtoehto ei ole käytettävissä, lukko ei tue Google Homea", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Asenna Google Home -sovellus ja napsauta vasemmassa yläkulmassa olevaa pluspainiketta", + "暂无最新记录": "Viimeisimpiä tietoja ei ole tällä hetkellä saatavilla", + "请将手机切换至2.4G WiFi进行手动连接": "Vaihda puhelimesi 2.4G WiFi-verkkoon manuaalista yhteyttä varten" } \ No newline at end of file diff --git a/lan/lan_fr.json b/lan/lan_fr.json index 0df73d91..ffcf5c00 100644 --- a/lan/lan_fr.json +++ b/lan/lan_fr.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Après réinitialisation, les veines métacarpiennes de la serrure seront supprimées. Êtes-vous sûr de vouloir réinitialiser?", "在线": "En ligne", "离线": "Hors ligne", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "La fonction de déverrouillage à distance de ce verrou n’est pas activée", "下载完成,请到相册查看": "Téléchargement terminé, s’il vous plaît aller à l’album pour voir", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Lorsque l’oeil de chat est réglé en mode économie d’énergie, la surveillance ne peut pas être effectuée. S’il vous plaît passer à d’autres modes dans les paramètres de l’oeil de chat", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Le déverrouillage à distance n’est pas possible lorsque l’oeil de chat est réglé sur le mode d’économie d’énergie. Veuillez passer à un autre mode dans les paramètres des yeux de chat" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Le déverrouillage à distance n’est pas possible lorsque l’oeil de chat est réglé sur le mode d’économie d’énergie. Veuillez passer à un autre mode dans les paramètres des yeux de chat", + "呼叫目标": "Cible d’appel", + "管理员APP": "Application administrateur", + "可视门铃码": "Code visuel de sonnette", + "电子反锁": "Anti serrure électronique", + "双重认证": "Authentification à deux facteurs", + "双锁联动": "Double liaison de serrure", + "1.用智能锁APP添加锁和网关": "1. Ajoutez des serrures et des passerelles à l’aide de l’application smart lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Activez la fonction de déverrouillage à distance de la serrure dans l’application (cette fonction est désactivée par défaut). Si cette option n’est pas disponible, le verrou ne prendra pas en charge Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Installez l’application Google Home et cliquez sur le bouton plus dans le coin supérieur gauche", + "暂无最新记录": "Il n’y a actuellement aucun dernier enregistrement disponible", + "请将手机切换至2.4G WiFi进行手动连接": "Veuillez passer votre téléphone à 2.4G WiFi pour une connexion manuelle" } \ No newline at end of file diff --git a/lan/lan_he.json b/lan/lan_he.json index 96df165b..acc3c4f2 100644 --- a/lan/lan_he.json +++ b/lan/lan_he.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "לאחר איפוס, הורידים של המנעול יימחקו. אתה בטוח שברצונך לאפס?", "在线": "באינטרנט", "离线": "מנותק", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "פונקציית ביטול הנעילה מרחוק של מנעול זה אינה מופעלת", "下载完成,请到相册查看": "ההורדה הושלמה, אנא עבור לאלבום לצפייה", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "כאשר Cat Eye מוגדר למצב חיסכון בחשמל, לא ניתן לבצע ניטור. עבור למצבים אחרים בהגדרות Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "ביטול נעילה מרחוק אינו אפשרי כאשר Cat Eye מוגדר למצב חיסכון בחשמל. עבור למצב אחר בהגדרות Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "ביטול נעילה מרחוק אינו אפשרי כאשר Cat Eye מוגדר למצב חיסכון בחשמל. עבור למצב אחר בהגדרות Cat Eye", + "呼叫目标": "יעד שיחה", + "管理员APP": "יישום מנהל מערכת", + "可视门铃码": "קוד פעמון דלת חזותי", + "电子反锁": "אנטי לוק אלקטרוני", + "双重认证": "אימות דו-שלבי", + "双锁联动": "הצמדת נעילה כפולה", + "1.用智能锁APP添加锁和网关": "1. הוסיפו מנעולים ושערים באמצעות אפליקציית Smart Lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. הפעל את פונקציית ביטול הנעילה מרחוק של המנעול באפליקציה (פונקציה זו כבויה כברירת מחדל). אם אפשרות זו אינה זמינה, המנעול לא יתמוך ב-Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. התקן את אפליקציית Google Home ולחץ על כפתור הפלוס בפינה השמאלית העליונה", + "暂无最新记录": "אין כרגע רשומות עדכניות זמינות", + "请将手机切换至2.4G WiFi进行手动连接": "אנא העבר את הטלפון שלך ל- WiFi 2.4G לחיבור ידני" } \ No newline at end of file diff --git a/lan/lan_hi.json b/lan/lan_hi.json index d32b69fc..1e608b4f 100644 --- a/lan/lan_hi.json +++ b/lan/lan_hi.json @@ -1080,6 +1080,8 @@ "印度尼西亚语": "बाहसा इंडोनेशिया", "芬兰语": "सूमी", "丹麦语": "मूर्ख व्यक्ति", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "रीसेट के बाद, लॉक के मेटाकार्पल नसों को हटा दिया जाएगा। क्या आप निश्चित रूप से रीसेट करना चाहते हैं?", "在线": "ऑनलाइन", "离线": "ऑफ़लाइन", @@ -1136,5 +1138,16 @@ "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "रीसेट के बाद, लॉक का रिमोट कंट्रोल हटा दिया जाएगा। क्या आप इसे रीसेट करना चाहते हैं?", "版本说明": "संस्करण वर्णन", "网关通电后,长按重置按钮5秒,蓝色指示灯闪烁时点击下一步": "गेटवे चालू होने के बाद, रीसेट बटन को 5 सेकंड के लिए दबाकर रखें। जब नीला संकेतक हल्का फ्लैश हो, तो अगला क्लिक करें।", - "网关添加成功": "गेटवे सफलतापूर्वक जोड़ा गया" + "网关添加成功": "गेटवे सफलतापूर्वक जोड़ा गया", + "呼叫目标": "कॉल लक्ष्य", + "管理员APP": "व्यवस्थापक एप", + "可视门铃码": "Name", + "电子反锁": "इलेक्ट्रॉनिक विरोधी लॉक", + "双重认证": "द्वि-कारक प्रमाणीकरण", + "双锁联动": "द्वि पाश सहलग्नता", + "1.用智能锁APP添加锁和网关": "1. स्मार्ट लॉक ऐप का उपयोग करके लॉक्स और गेटवे जोड़ें", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. एप्लिकेशन में लॉक का रिमोट अनलॉकिंग फ़ंक्शन सक्षम करें (यह फ़ंक्शन डिफ़ॉल्ट रूप से बंद है). यदि यह विकल्प उपलब्ध नहीं है, तो लॉक आपके गूगल होम को सपोर्ट नहीं करेगा।", + "3.安装Google Home APP,点击左上角的加号按钮": "3. गूगल होम ऐप को इंस्टॉल करें और ऊपरी बाएं कोने में प्लस बटन पर क्लिक करें।", + "暂无最新记录": "वर्तमान में कोई नवीनतम रिकॉर्ड उपलब्ध नहीं हैं", + "请将手机切换至2.4G WiFi进行手动连接": "मैन्युअल कनेक्शन के लिए कृपया अपना फोन 2.4 जी वाईफ़ाई पर स्विच करें।" } \ No newline at end of file diff --git a/lan/lan_hk.json b/lan/lan_hk.json index 5c3b4bb1..bf486ffa 100644 --- a/lan/lan_hk.json +++ b/lan/lan_hk.json @@ -1,10 +1,10 @@ { - "星锁": "星空鎖", - "锁通通": "鎖定直通", - "点击开锁,长按闭锁": "掂解鎖,按住鎖定", + "星锁": "星鎖", + "锁通通": "鎖通通", + "点击开锁,长按闭锁": "點擊開鎖,長按閉鎖", "考勤": "出席", "考勤设置": "考勤設置", - "电子钥匙": "eKey", + "电子钥匙": "電子鑰匙", "添加卡": "添加卡", "卡号": "卡號", "添加指纹": "添加指紋", @@ -152,7 +152,7 @@ "升级": "更新", "空闲": "空置", "已入住": "佔領", - "多语言": "語言", + "多语言": "多語言", "添加锁": "添加鎖", "锁地址": "鎖定地址", "选择锁类型": "選擇鎖類型", @@ -185,7 +185,7 @@ "退出": "註銷", "删除账号": "刪除帳戶", "个人信息": "賬戶信息", - "头像": "化身", + "头像": "頭像", "昵称": "暱稱", "请输入昵称": "請輸入您的暱稱", "修改昵称": "重命名", @@ -373,7 +373,7 @@ "未打卡": "暫無記錄", "钥匙将在": "此ekey將在", "天后失效": "天", - "电量更新时间:": "電池更新時間:", + "电量更新时间:": "電量更新時間:", "新增配件": "加", "钥匙不可用": "密鑰不可用", "正在开锁中...": "解鎖。。。", @@ -505,7 +505,7 @@ "您的钥匙已过期": "您的密鑰已過期", "常开模式开启": "鎖處於Passage Mode", "超级管理员": "超級管理員", - "授权管理员": "設為admin", + "授权管理员": "授權管理員", "普通用户": "普通用戶", "余": "平衡", "天": "日", @@ -718,7 +718,7 @@ "钥匙无效": "密鑰無效", "操作失败,请确认锁是否在附近,或重启手机蓝牙后再试。": "無法連接到鎖。請重新啟動手機嘅Blutooth並重試。", "如果是全自动锁,请使屏幕变亮": "如果係全自動鎖,請讓屏幕更光", - "正在尝试闭锁……": "嘗試鎖定。 請稍候。。。", + "正在尝试闭锁……": "正在嘗試閉鎖……", "清空记录": "清除記錄", "是否要删除操作记录?": "繼續刪除記錄?", "被删除的记录不能恢复": "刪除後無法恢復記錄。", @@ -815,7 +815,7 @@ "配置网络": "配置網絡", "你好": "你好", "成功": "成功的", - "类型选择": "鍵入select", + "类型选择": "類型選擇", "请选择要使用哪种类型": "請選擇要使用的類型", "系统邮件(推荐)": "系統電子郵件(推薦)", "系统短信(推荐)": "系統短信(推薦)", @@ -1042,42 +1042,44 @@ "导出锁数据": "導出鎖定數據", "一键开锁": "一鍵解鎖", "已开通": "打開", - "英文": "英文", - "简体中文": "簡體中文", + "英文": "English", + "简体中文": "简体中文", "繁体中文": "繁體中文", - "法语": "法文", + "法语": "Français", "俄语": "Русский", - "德语": "德文", + "德语": "Deutsch", "日语": "日本語", "韩语": "한국어", "意大利语": "Italiano", "乌克兰语": "Українська", "葡萄牙语": "Português", - "西班牙语": "西班牙人", + "西班牙语": "Español", "阿拉伯语": "العربية", "越南语": "Tiếng Việt", - "马来语": "馬來文", - "荷兰语": "荷蘭", - "罗马尼亚语": "羅曼", + "马来语": "Bahasa Melayu", + "荷兰语": "Nederlands", + "罗马尼亚语": "Română", "立陶宛语": "Lietuvių", - "瑞典语": "斯文斯卡", - "爱沙尼亚语": "埃斯蒂", - "波兰语": "波蘭", - "斯洛伐克语": "斯洛文尼亞", + "瑞典语": "Svenska", + "爱沙尼亚语": "Eesti", + "波兰语": "Polski", + "斯洛伐克语": "Slovenčina", "捷克语": "Čeština", "希腊语": "Ελληνικά", "希伯来语": "עברית", "塞尔维亚语": "Српски", "土耳其语": "Türkçe", - "匈牙利语": "匈牙利嘅", + "匈牙利语": "Magyar", "保加利亚语": "Български", "哈萨克斯坦语": "Қазақ", "孟加拉语": "বাংলা", - "克罗地亚语": "赫尔瓦茨基", + "克罗地亚语": "Hrvatski", "泰语": "ไทย", "印度尼西亚语": "Bahasa Indonesia", - "芬兰语": "索米", - "丹麦语": "丹斯克", + "芬兰语": "Suomi", + "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "重置後,鎖的掌靜脈將被刪除。 你確定要重置啊?", "在线": "在線", "离线": "離線", @@ -1100,8 +1102,8 @@ "英语": "英文", "Google Home操作流程的值": "1.使用智能鎖APP添加鎖和網關\n\n2.喺APP中開啟鎖嘅遠程解鎖功能(此功能默認關閉)。 如果冇此選項,鎖唔撐Google Home\n\n3.安裝Google Home APP,點擊左上角嘅“+”按鈕\n\n4.在“設置”頁面上,選擇“與Google合作”\n\n5.搜索“ScienerSmart”,使用智能鎖APP賬號和密碼進行授權", "密码需至少包含数字/字母/字符中的2种组合": "密碼必須至少包含以下2個:數字、字母同特殊字符", - "已开锁": "解鎖", - "已闭锁": "鎖", + "已开锁": "已開鎖", + "已闭锁": "已閉鎖", "两次密码不一致哦": "密碼不一緻", "中功率": "中等功率", "常规使用": "經常使用", @@ -1136,5 +1138,18 @@ "该锁的远程开锁功能未启用": "此鎖嘅遠程解鎖功能未啟用", "下载完成,请到相册查看": "下載完成,請至相冊查看", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "当Cat Eye設置為省電模式時,無法執行監控。 請喺Cat Eye設置中切換到其他模式", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "当Cat Eye設置為省電模式時,無法遠程解鎖。 請喺Cat Eye設置中切換到其他模式" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "当Cat Eye設置為省電模式時,無法遠程解鎖。 請喺Cat Eye設置中切換到其他模式", + "呼叫目标": "呼叫目標", + "管理员APP": "管理員APP", + "可视门铃码": "可視門鈴密碼", + "电子反锁": "電子防抱死", + "双重认证": "雙重認證", + "双锁联动": "雙鎖聯動", + "1.用智能锁APP添加锁和网关": "1.使用智能鎖應用程序添加鎖和網關", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2.喺APP中開啟鎖嘅遠程解鎖功能(此功能默認關閉)。 如果此選項不可用,則鎖將唔撐Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3.安裝Google Home應用,點擊左上角嘅加號掣", + "暂无最新记录": "目前冇可用嘅最新記錄", + "繁体中文(中国台湾)": "繁體中文(中國臺灣)", + "繁体中文(中国香港)": "繁體中文(中國香港)", + "请将手机切换至2.4G WiFi进行手动连接": "請把手機切換到2.4G WiFi進行手動連接" } \ No newline at end of file diff --git a/lan/lan_hr.json b/lan/lan_hr.json index 772bf665..ece14b96 100644 --- a/lan/lan_hr.json +++ b/lan/lan_hr.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Nakon resetiranja, metakarpalne vene brave će biti izbrisane. Jeste li sigurni da želite resetiranje?", "在线": "Na internetu", "离线": "Odspojeno", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Funkcija daljinskog otključavanja ove brave nije omogućena", "下载完成,请到相册查看": "Preuzimanje je završeno, idite na album za pregled", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Kada je Cat Eye postavljen na način rada za uštedu energije, nadzor se ne može izvršiti. Prebacite se na druge načine rada u postavkama Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Daljinsko otključavanje nije moguće kada je Cat Eye postavljen na način rada za uštedu energije. Prebacite se na drugi način rada u postavkama Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Daljinsko otključavanje nije moguće kada je Cat Eye postavljen na način rada za uštedu energije. Prebacite se na drugi način rada u postavkama Cat Eye", + "呼叫目标": "Cilj poziva", + "管理员APP": "Administratorska aplikacija", + "可视门铃码": "Vizualni kod zvona na vratima", + "电子反锁": "Elektronička zaštita od blokiranja", + "双重认证": "Dvofaktorska autentifikacija", + "双锁联动": "Dvostruka brava", + "1.用智能锁APP添加锁和网关": "1. Dodajte brave i pristupnike pomoću aplikacije pametne brave", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Omogućite funkciju daljinskog otključavanja brave u APP-u (ova je funkcija prema zadanim postavkama isključena). Ako ova opcija nije dostupna, zaključavanje neće podržavati Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Instalirajte aplikaciju Google Home i kliknite gumb plus u gornjem lijevom kutu", + "暂无最新记录": "Trenutno nema dostupnih najnovijih podataka", + "请将手机切换至2.4G WiFi进行手动连接": "Prebacite telefon na 2.4G WiFi za ručno povezivanje" } \ No newline at end of file diff --git a/lan/lan_hu.json b/lan/lan_hu.json index d93cdbfa..894a44e3 100644 --- a/lan/lan_hu.json +++ b/lan/lan_hu.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "A reset után a zár metakarpális erei törlődnek. Biztos vagy benne, hogy vissza akarsz állítani?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Ennek a zárnak a távoli feloldási funkciója nincs engedélyezve", "下载完成,请到相册查看": "A letöltés befejeződött, kérjük, menjen az albumra a megtekintéshez", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Ha a Cat Eye energiatakarékos üzemmódba van állítva, a felügyelet nem végezhető el. Kérjük, váltson más módokra a Cat Eye beállításaiban", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "A távoli feloldás nem lehetséges, ha a Cat Eye energiatakarékos üzemmódba van állítva. Kérjük, váltson másik módra a Cat Eye beállításaiban" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "A távoli feloldás nem lehetséges, ha a Cat Eye energiatakarékos üzemmódba van állítva. Kérjük, váltson másik módra a Cat Eye beállításaiban", + "呼叫目标": "Hívás cél", + "管理员APP": "Rendszergazdai alkalmazás", + "可视门铃码": "Vizuális csengő kód", + "电子反锁": "Elektronikus blokkolásgátló", + "双重认证": "Kétfaktoros hitelesítés", + "双锁联动": "Dupla reteszelő rudazat", + "1.用智能锁APP添加锁和网关": "1. Adjon hozzá zárakat és átjárókat az intelligens zár alkalmazással", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Engedélyezze a zár távoli feloldási funkcióját az APP-ban (ez a funkció alapértelmezés szerint ki van kapcsolva). Ha ez az opció nem érhető el, a zár nem támogatja a Google Home szolgáltatást", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Telepítse a Google Home alkalmazást, és kattintson a plusz gombra a bal felső sarokban", + "暂无最新记录": "Jelenleg nem állnak rendelkezésre legfrissebb rekordok", + "请将手机切换至2.4G WiFi进行手动连接": "Kérjük, kapcsolja át telefonját 2.4G WiFi-re a kézi csatlakozáshoz" } \ No newline at end of file diff --git a/lan/lan_id.json b/lan/lan_id.json index 21934da7..a0dd8c94 100644 --- a/lan/lan_id.json +++ b/lan/lan_id.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Setelah mengulang, pembuluh darah metakarpal dari kunci akan dihapus. Yakin ingin mengatur ulang?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Fungsi unlocking jarak jauh dari kunci ini tidak diaktifkan", "下载完成,请到相册查看": "Download selesai, silakan pergi ke album untuk melihat", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Jika mata kucing disetel ke mode penyimpanan daya, pemantauan tidak dapat dilakukan. Silakan beralih ke mode lain di pengaturan mata kucing", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Membuka kunci jarak jauh tidak mungkin jika mata kucing diatur untuk mode menghemat daya. Silakan beralih ke mode lain di pengaturan mata kucing" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Membuka kunci jarak jauh tidak mungkin jika mata kucing diatur untuk mode menghemat daya. Silakan beralih ke mode lain di pengaturan mata kucing", + "呼叫目标": "Hubungi target.", + "管理员APP": "Aplikasi Administrator", + "可视门铃码": "Kode bel Visual", + "电子反锁": "Anti elektronik", + "双重认证": "Dua faktor otentikasi", + "双锁联动": "Kunci ganda hubungan", + "1.用智能锁APP添加锁和网关": "1. Tambahkan kunci dan gerbang menggunakan aplikasi smart lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Aktifkan fungsi kunci pengunci jarak jauh di aplikasi (fungsi ini dimatikan secara standar). Jika opsi ini tidak tersedia, kunci tidak akan mendukung Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Instal aplikasi Google Home dan klik tombol plus di sudut kiri atas", + "暂无最新记录": "Saat ini tidak ada catatan terbaru yang tersedia", + "请将手机切换至2.4G WiFi进行手动连接": "Silahkan beralih ke 2.4G WiFi untuk koneksi manual" } \ No newline at end of file diff --git a/lan/lan_it.json b/lan/lan_it.json index a87d0a27..00fa3d12 100644 --- a/lan/lan_it.json +++ b/lan/lan_it.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Dopo il reset, le vene metacarpali della serratura verranno cancellate. Sei sicuro di voler reimpostare?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "La funzione di sblocco remoto di questa serratura non è abilitata", "下载完成,请到相册查看": "Scaricamento completato, vai all’ album da visualizzare", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Quando l’occhio gatto è impostato alla modalità risparmio energetico, il monitoraggio non può essere effettuato. Passa ad altre modalità nelle impostazioni degli occhi di gatto", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Lo sblocco a distanza non è possibile quando l’occhio gatto è impostato alla modalità risparmio energetico. Passa a un’altra modalità nelle impostazioni degli occhi di gatto" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Lo sblocco a distanza non è possibile quando l’occhio gatto è impostato alla modalità risparmio energetico. Passa a un’altra modalità nelle impostazioni degli occhi di gatto", + "呼叫目标": "Obiettivo chiamata", + "管理员APP": "Applicazione amministratore", + "可视门铃码": "Codice campanella visiva", + "电子反锁": "Antibloccaggio elettronico", + "双重认证": "Autenticazione a due fattori", + "双锁联动": "Collegamento a doppio bloccaggio", + "1.用智能锁APP添加锁和网关": "1. Aggiunge serrature e gateway usando l’applicazione smart lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Abilita la funzione di sblocco remoto del lock nella APP (questa funzione è disattivata in modo predefinito). Se questa opzione non è disponibile, il lock non supporta Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Installa l’applicazione Home di Google e fai clic sul pulsante più nell’angolo in alto a sinistra", + "暂无最新记录": "Attualmente non sono disponibili dati più recenti", + "请将手机切换至2.4G WiFi进行手动连接": "Passa il telefono a 2,4g WiFi per la connessione manuale" } \ No newline at end of file diff --git a/lan/lan_ja.json b/lan/lan_ja.json index 6df21bfe..f58e6062 100644 --- a/lan/lan_ja.json +++ b/lan/lan_ja.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "リセット後、ロックの中手骨静脈が削除されます。リセットしてもよろしいですか。", "在线": "オンライン", "离线": "オフライン", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "このロックのリモートロック解除機能は有効になっていません", "下载完成,请到相册查看": "ダウンロードが完了しましたので、アルバムでご覧ください", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "cat eyeが省電力モードに設定されている場合、監視はできません。cat eye設定で他のモードに切り替えてください", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "cat eyeが省電力モードに設定されている場合、リモートロック解除はできません。cat eye設定で別のモードに切り替えてください" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "cat eyeが省電力モードに設定されている場合、リモートロック解除はできません。cat eye設定で別のモードに切り替えてください", + "呼叫目标": "通話ターゲットの", + "管理员APP": "管理者アプリ", + "可视门铃码": "視覚チャイムコード", + "电子反锁": "電子反ロック", + "双重认证": "2ファクタ認証", + "双锁联动": "二重ロック連動", + "1.用智能锁APP添加锁和网关": "1. スマートロックappを使用してロックとゲートウェイを追加します", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. アプリでロックのリモートロック解除機能を有効にします(この機能はデフォルトでオフになっています)。このオプションが利用できない場合、ロックはgoogle homeをサポートしません", + "3.安装Google Home APP,点击左上角的加号按钮": "3. google homeアプリをインストールし、左上隅のプラスボタンをクリックします", + "暂无最新记录": "最新の記録は残っていない", + "请将手机切换至2.4G WiFi进行手动连接": "手動接続のため、携帯電話を2.4 g wifiに切り替えてください" } \ No newline at end of file diff --git a/lan/lan_keys.json b/lan/lan_keys.json index 62c5b3f0..b9e8172d 100755 --- a/lan/lan_keys.json +++ b/lan/lan_keys.json @@ -1081,6 +1081,8 @@ "印度尼西亚语": "印度尼西亚语", "芬兰语": "芬兰语", "丹麦语": "丹麦语", + "印地语": "印地语", + "乌尔都语": "乌尔都语", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?", "在线": "在线", "离线": "离线", @@ -1138,5 +1140,27 @@ "版本说明": "版本说明", "呼叫目标": "呼叫目标", "管理员APP": "管理员APP", + "可视门铃码": "可视门铃码", + "电子反锁": "电子反锁", + "双重认证": "双重认证", + "双锁联动": "双锁联动", + "1.用智能锁APP添加锁和网关": "1.用智能锁APP添加锁和网关", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3.安装Google Home APP,点击左上角的加号按钮", + "4.在设置页面,选择与Google协同工作": "4.在设置页面,选择与Google协同工作", + "5.搜索": "5.搜索", + ",并用智能锁APP的账号和密码进行授权": ",并用智能锁APP的账号和密码进行授权", + "暂无最新记录": "暂无最新记录", + "请将手机切换至2.4G WiFi进行手动连接": "请将手机切换至2.4G WiFi进行手动连接", + "请扫描可视门铃码二维码": "请扫描可视门铃码二维码", + "请确保网络是2.4GHz Wi-Fi": "请确保网络是2.4GHz Wi-Fi", + "已选": "已选", + "是否要远程开锁": "是否要远程开锁", + "繁体中文(中国台湾)": "繁体中文(中国台湾)", + "繁体中文(中国香港)": "繁体中文(中国香港)", + "国家地区的选择将影响数据安全,你当前选择的是": "国家地区的选择将影响数据安全,你当前选择的是", + "请确认后再继续": "请确认后再继续", + "需要相机权限": "需要相机权限", + "此功能的开启和关闭只能在锁附近通过手机蓝牙进行": "此功能的开启和关闭只能在锁附近通过手机蓝牙进行", "网关添加成功": "网关添加成功" } diff --git a/lan/lan_kk.json b/lan/lan_kk.json index 8f1ed1da..cf4ec926 100644 --- a/lan/lan_kk.json +++ b/lan/lan_kk.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Қайта ысырып тастағаннан соң бұғаттағы метакарпалар өшіріледі. Шынымен ысырып тастауды қалайсыз ба?", "在线": "Онлайн", "离线": "Желіде емес", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Бұғаттаудың қашықтан құлыптан босату функциясы қосылмаған", "下载完成,请到相册查看": "Жүктеу аяқталды, көру үшін альбомға өтуіңізді сұраймыз", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Cat Eye қуат үнемдейтін режимге орнатылғанда, мониторингті орындау мүмкін емес. Cat Eye параметрлеріндегі басқа режимдерге ауысуыңызды сұраймын", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Cat Eye қуат үнемдейтін режимге орнатылғанда қашықтан құлыптан босату мүмкін емес. Cat Eye параметрлерінде басқа режимге ауысуыңызды сұраймыз" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Cat Eye қуат үнемдейтін режимге орнатылғанда қашықтан құлыптан босату мүмкін емес. Cat Eye параметрлерінде басқа режимге ауысуыңызды сұраймыз", + "呼叫目标": "Қоңырау шалу мақсаты", + "管理员APP": "APP әкімшісі", + "可视门铃码": "Көзбен шолып есігінің коды", + "电子反锁": "Электрондық бұғаттауға қарсы", + "双重认证": "Екі факторлы аутентификация", + "双锁联动": "Қос бұғаттау сілтемесі", + "1.用智能锁APP添加锁和网关": "1. Смарт-құлыптау бағдарламасын пайдалана отырып құлыптар мен шлюздерді қосу", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. APP бағдарламасында құлыпты қашықтан ашу функциясын қосу (бұл функция әдепкі бойынша өшіріледі). Егер бұл параметр қол жетімді болмаса, бұғаттау Google Home-ды қолдамайды", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Google Home бағдарламасын орнатып, жоғарғы сол жақ бұрыштағы қосу түймешігін басыңыз", + "暂无最新记录": "Қазіргі уақытта қол жетімді соңғы жазбалар жоқ", + "请将手机切换至2.4G WiFi进行手动连接": "Телефонды қолмен қосу үшін 2.4G WiFi бағдарламасына ауыстыруыңызды сұраймыз" } \ No newline at end of file diff --git a/lan/lan_ko.json b/lan/lan_ko.json index f6b736e3..5d8c6ef0 100644 --- a/lan/lan_ko.json +++ b/lan/lan_ko.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "재설정 후 잠금 장치의 중수골 정맥이 삭제됩니다. 당신은 당신이 재설정 하시겠습니까?", "在线": "온라인", "离线": "오프라인", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "이 잠금의 원격 잠금 해제 기능을 사용할 수 없습니다", "下载完成,请到相册查看": "다운로드가 완료되었습니다. 보려면 앨범으로 이동하십시오", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Cat Eye 가 절전 모드로 설정되면 모니터링을 수행할 수 없습니다.캣아이 설정에서 다른 모드로 전환해 주세요", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Cat Eye 가 절전 모드로 설정된 경우에는 원격 잠금 해제가 불가능합니다.Cat Eye 설정에서 다른 모드로 전환해 주세요" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Cat Eye 가 절전 모드로 설정된 경우에는 원격 잠금 해제가 불가능합니다.Cat Eye 설정에서 다른 모드로 전환해 주세요", + "呼叫目标": "전화 대상", + "管理员APP": "관리자 앱", + "可视门铃码": "시각 초인종 부호", + "电子反锁": "전자식 anti lock", + "双重认证": "이중 인증", + "双锁联动": "2 중 잠금 연결", + "1.用智能锁APP添加锁和网关": "1. 스마트 잠금 앱을 사용하여 잠금 및 게이트웨이를 추가합니다", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. 앱에서 잠금의 원격 잠금 해제 기능을 활성화합니다 (이 기능은 기본적으로 꺼져 있습니다).이 옵션을 사용할 수 없는 경우 잠금은 Google Home을 지원하지 않습니다", + "3.安装Google Home APP,点击左上角的加号按钮": "3. 구글 홈 앱을 설치하고 왼쪽 상단 모서리에 있는 더하기 버튼을 클릭합니다", + "暂无最新记录": "현재 사용 가능한 최신 레코드가 없습니다", + "请将手机切换至2.4G WiFi进行手动连接": "수동 연결을 위해 핸드폰을 2.4G WiFi로 바꿔주세요" } \ No newline at end of file diff --git a/lan/lan_lt.json b/lan/lan_lt.json index 73a83706..ebb9df23 100644 --- a/lan/lan_lt.json +++ b/lan/lan_lt.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Po reset užrakto metakarpinės venos bus ištrintos. Ar tikrai norite atstatyti?", "在线": "Online", "离线": "Neprisijungęs", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Šio užrakto nuotolinio atrakinimo funkcija neįjungta", "下载完成,请到相册查看": "Atsisiuntimas baigtas, eikite į albumą, kad peržiūrėtumėte", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Kai \"Cat Eye\" nustatytas energijos taupymo režimas, stebėjimo atlikti negalima. \"Cat Eye\" nustatymuose perjunkite į kitus režimus", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Nuotolinis atrakinimas neįmanomas, kai \"Cat Eye\" nustatytas energijos taupymo režimas. \"Cat Eye\" nustatymuose perjunkite į kitą režimą" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Nuotolinis atrakinimas neįmanomas, kai \"Cat Eye\" nustatytas energijos taupymo režimas. \"Cat Eye\" nustatymuose perjunkite į kitą režimą", + "呼叫目标": "Skambučio tikslas", + "管理员APP": "Administratoriaus programa", + "可视门铃码": "Vaizdinis durų skambučio kodas", + "电子反锁": "Elektroninis antiblokavimas", + "双重认证": "Dviejų veiksnių autentifikavimas", + "双锁联动": "Dvigubo užrakto jungtis", + "1.用智能锁APP添加锁和网关": "1. Pridėkite spynas ir šliuzus naudodami \"smart lock\" programą", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Įjunkite užrakto nuotolinio atrakinimo funkciją APP (ši funkcija yra išjungta pagal numatytuosius nustatymus). Jei ši parinktis nepasiekiama, užraktas nepalaikys \"Google Home\"", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Įdiekite \"Google Home\" programą ir spustelėkite pliuso mygtuką viršutiniame kairiajame kampe", + "暂无最新记录": "Šiuo metu nėra naujausių įrašų", + "请将手机切换至2.4G WiFi进行手动连接": "Perjunkite telefoną į 2.4G WiFi, kad galėtumėte prisijungti rankiniu būdu" } \ No newline at end of file diff --git a/lan/lan_ms.json b/lan/lan_ms.json index 75e8bbc9..d003ba80 100644 --- a/lan/lan_ms.json +++ b/lan/lan_ms.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Selepas menetapkan semula, urat metacarpal kunci akan dipadamkan. Adakah anda pasti anda mahu menetapkan semula?", "在线": "Dalam talian", "离线": "Luar talian", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Fungsi buka kunci jauh kunci ini tidak didayakan", "下载完成,请到相册查看": "Muat turun selesai, sila pergi ke album untuk melihat", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Apabila Cat Eye ditetapkan kepada mod penjimatan kuasa, pemantauan tidak boleh dilakukan. Sila tukar kepada mod lain dalam tetapan Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Buka kunci jauh tidak boleh dilakukan apabila Cat Eye ditetapkan kepada mod penjimatan kuasa. Sila tukar kepada mod lain dalam tetapan Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Buka kunci jauh tidak boleh dilakukan apabila Cat Eye ditetapkan kepada mod penjimatan kuasa. Sila tukar kepada mod lain dalam tetapan Cat Eye", + "呼叫目标": "Sasaran panggilan", + "管理员APP": "APP Pentadbir", + "可视门铃码": "Kod loceng pintu visual", + "电子反锁": "Anti kunci elektronik", + "双重认证": "Pengesahan dua faktor", + "双锁联动": "Pautan kunci berganda", + "1.用智能锁APP添加锁和网关": "1. Tambah kunci dan pintu masuk menggunakan apl kunci pintar", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Dayakan fungsi buka kunci jauh kunci dalam APP (fungsi ini dimatikan secara lalai). Jika pilihan ini tidak tersedia, kunci tidak akan menyokong Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Pasang apl Google Home dan klik butang tambah di penjuru kiri sebelah atas", + "暂无最新记录": "Pada masa ini tiada rekod terkini tersedia", + "请将手机切换至2.4G WiFi进行手动连接": "Sila tukar telefon anda kepada WiFi 2.4G untuk sambungan manual" } \ No newline at end of file diff --git a/lan/lan_nl.json b/lan/lan_nl.json index 56be2060..afdd971d 100644 --- a/lan/lan_nl.json +++ b/lan/lan_nl.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Na reset worden de middenhandsbeenaders van het slot verwijderd. Weet je zeker dat je wilt resetten?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "De remote unlock functie van het slot is niet ingeschakeld", "下载完成,请到相册查看": "De download is voltooid, ga naar het album om het te bekijken", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Wanneer 'kattenoog' is ingesteld op de energiebesparende modus, is monitoring niet mogelijk. Ga naar een andere modus in de kattenoog instellingen", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Wanneer cat eye is ingesteld op de energiebesparende modus, kan deze niet op afstand worden ontgrendeld. Ga naar een andere modus in de kattenoog instellingen" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Wanneer cat eye is ingesteld op de energiebesparende modus, kan deze niet op afstand worden ontgrendeld. Ga naar een andere modus in de kattenoog instellingen", + "呼叫目标": "Doel van de oproep", + "管理员APP": "Toepassing door de beheerder", + "可视门铃码": "Visuele deurbel code", + "电子反锁": "Elektronische abs", + "双重认证": "Twee-factor authenticatie", + "双锁联动": "Dubbele vergrendeling voor koppeling", + "1.用智能锁APP添加锁和网关": "1. Voeg sloten en gateways toe met de smart lock app", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Open het slot op afstand in de APP (standaard uitgeschakeld). Als deze optie niet beschikbaar is, wordt google Home niet ondersteund", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Installeer de google home-app en klik op de plus-knop in de linkerbovenhoek", + "暂无最新记录": "Er zijn momenteel geen recente gegevens beschikbaar", + "请将手机切换至2.4G WiFi进行手动连接": "Stel uw telefoon in op 2. 4g WiFi bij handmatige verbinding" } \ No newline at end of file diff --git a/lan/lan_pl.json b/lan/lan_pl.json index 8c958c55..120281a1 100644 --- a/lan/lan_pl.json +++ b/lan/lan_pl.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Po zresetowaniu żyły śródręcza zamka zostaną usunięte. Czy na pewno chcesz zresetować?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Funkcja zdalnego odblokowania tego zamka nie jest włączona", "下载完成,请到相册查看": "Pobieranie zakończone, przejdź do albumu, aby wyświetlić", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Gdy Cat Eye jest ustawiony w trybie oszczędzania energii, nie można przeprowadzić monitorowania. Przełącz się na inne tryby w ustawieniach Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Zdalne odblokowanie nie jest możliwe, gdy Cat Eye jest ustawiony w trybie oszczędzania energii. Przełącz się na inny tryb w ustawieniach Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Zdalne odblokowanie nie jest możliwe, gdy Cat Eye jest ustawiony w trybie oszczędzania energii. Przełącz się na inny tryb w ustawieniach Cat Eye", + "呼叫目标": "Cel połączenia", + "管理员APP": "Aplikacja administratora", + "可视门铃码": "Wizualny kod dzwonka do drzwi", + "电子反锁": "Elektroniczny układ przeciwblokujący", + "双重认证": "Uwierzytelnianie dwuskładnikowe", + "双锁联动": "Podwójny zamek zawieszenia", + "1.用智能锁APP添加锁和网关": "1. Dodaj zamki i bramy za pomocą aplikacji inteligentnego zamka", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Włącz funkcję zdalnego odblokowywania zamka w aplikacji (ta funkcja jest domyślnie wyłączona). Jeśli ta opcja nie jest dostępna, zamek nie będzie obsługiwał Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Zainstaluj aplikację Google Home i kliknij przycisk plusa w lewym górnym rogu", + "暂无最新记录": "Obecnie nie ma dostępnych najnowszych rekordów", + "请将手机切换至2.4G WiFi进行手动连接": "Przełącz telefon na 2.4G Wi-Fi, aby uzyskać ręczne połączenie" } \ No newline at end of file diff --git a/lan/lan_pt.json b/lan/lan_pt.json index 9d0d2657..4d3a3436 100644 --- a/lan/lan_pt.json +++ b/lan/lan_pt.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Após a reinicialização, as veias do metacarpo do bloqueio serão excluídas. Tens a certeza que queres reiniciar?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "A função de desbloqueio remoto desta fechadura não está habilitada", "下载完成,请到相册查看": "Download concluído, por favor, vá para o álbum para ver", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Quando o Cat Eye está definido para o modo de economia de energia, o monitoramento não pode ser executado. Por favor, mude para outros modos nas configurações do Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "O desbloqueio remoto não é possível quando o Cat Eye está definido para o modo de economia de energia. Por favor, mude para outro modo nas configurações do Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "O desbloqueio remoto não é possível quando o Cat Eye está definido para o modo de economia de energia. Por favor, mude para outro modo nas configurações do Cat Eye", + "呼叫目标": "Destino da chamada", + "管理员APP": "Aplicativo Administrador", + "可视门铃码": "Código visual da campainha", + "电子反锁": "Anti bloqueio eletrônico", + "双重认证": "Autenticação de dois fatores", + "双锁联动": "Articulação de trava dupla", + "1.用智能锁APP添加锁和网关": "1. Adicione fechaduras e gateways usando o aplicativo Smart Lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Ative a função de desbloqueio remoto da fechadura no APP (esta função está desativada por padrão). Se esta opção não estiver disponível, o bloqueio não será compatível com o Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Instale o aplicativo Google Home e clique no botão de adição no canto superior esquerdo", + "暂无最新记录": "Atualmente não há registros mais recentes disponíveis", + "请将手机切换至2.4G WiFi进行手动连接": "Mude seu telefone para WiFi 2.4G para conexão manual" } \ No newline at end of file diff --git a/lan/lan_ro.json b/lan/lan_ro.json index 584e33af..a439b5fa 100644 --- a/lan/lan_ro.json +++ b/lan/lan_ro.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "După resetare, venele metacarpale ale încuietorii vor fi şterse. Sigur doriți să resetați?", "在线": "Online", "离线": "Deconectat", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Funcția de deblocare de la distanță a acestei încuietori nu este activată", "下载完成,请到相册查看": "Descărcare finalizată, vă rugăm să accesați albumul pentru a vizualiza", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Când Cat Eye este setat în modul de economisire a energiei, monitorizarea nu poate fi efectuată. Vă rugăm să comutați la alte moduri în setările Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Deblocarea de la distanță nu este posibilă atunci când Cat Eye este setat în modul de economisire a energiei. Vă rugăm să comutați la un alt mod în setările Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Deblocarea de la distanță nu este posibilă atunci când Cat Eye este setat în modul de economisire a energiei. Vă rugăm să comutați la un alt mod în setările Cat Eye", + "呼叫目标": "Țintă de apel", + "管理员APP": "Aplicație de administrator", + "可视门铃码": "Codul vizual al soneriei", + "电子反锁": "Antiblocare electronică", + "双重认证": "Autentificare cu doi factori", + "双锁联动": "Legătură dublă de blocare", + "1.用智能锁APP添加锁和网关": "1. Adăugați încuietori și gateway-uri folosind aplicația smart lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Activați funcția de deblocare de la distanță a încuietorului în aplicație (această funcție este dezactivată în mod implicit). Dacă această opțiune nu este disponibilă, blocarea nu va accepta Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Instalați aplicația Google Home și faceți clic pe butonul plus din colțul din stânga sus", + "暂无最新记录": "În prezent nu există cele mai recente înregistrări disponibile", + "请将手机切换至2.4G WiFi进行手动连接": "Vă rugăm să comutați telefonul la WiFi 2.4G pentru conectarea manuală" } \ No newline at end of file diff --git a/lan/lan_ru.json b/lan/lan_ru.json index 393a68f7..07772f3b 100644 --- a/lan/lan_ru.json +++ b/lan/lan_ru.json @@ -504,7 +504,7 @@ "您的钥匙已过期": "Срок действия вашего ключа истек", "常开模式开启": "Замок находится в режиме прохода", "超级管理员": "Супер админ", - "授权管理员": "Авторизованный администратор", + "授权管理员": "Автор. администратор", "普通用户": "Обычный пользователь", "余": "Баланс", "天": "День", @@ -630,12 +630,12 @@ "关锁": "Закрыть замок", "功能": "Функция", "配件": "Детали", - "云存": "Облачное хранилище", + "云存": "Cloud", "本地": "Эта местность", "3天滚动储存": "3 дня прокатного хранения", "去升级": "Обновить сейчас", "下载列表": "Скачать список", - "已下载": "Загружено", + "已下载": "Downloaded", "全部视频": "Все видео", "已为本设备免费提供3大滚动视频储存服务": "Для этого устройства бесплатно предоставлены три услуги по хранению видео с прокруткой.", "视频播放": "Воспроизведение видео", @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "После сброса пястные вены замка будут удалены. Вы уверены, что хотите сбросить?", "在线": "Онлайн", "离线": "Оффлайн", @@ -1136,5 +1138,20 @@ "该锁的远程开锁功能未启用": "Функция дистанционного разблокирования этого замка не включена", "下载完成,请到相册查看": "Загрузка завершена, пожалуйста, перейдите на альбом, чтобы посмотреть", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Когда кошачий глаз установлен в режим энергосбережения, мониторинг не может быть выполнен. Переключитесь на другие режимы в настройках кошачьего глаза", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Удаленная разблокировка невозможна, если кошачий глаз установлен в режим энергосбережения. Пожалуйста, переключитесь в другой режим в настройках кошачьего глаза" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Удаленная разблокировка невозможна, если кошачий глаз установлен в режим энергосбережения. Пожалуйста, переключитесь в другой режим в настройках кошачьего глаза", + "呼叫目标": "Звони в цель.", + "管理员APP": "Приложение для администратора", + "可视门铃码": "Визуальный код дверного звонка", + "电子反锁": "Электронный анти-блокировка", + "双重认证": "Двухфакторная аутентификация", + "双锁联动": "2.1.3 двойная блокировка", + "1.用智能锁APP添加锁和网关": "1. Добавить замки и шлюзы с помощью приложения smart lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Включите функцию удаленного разблокирования замка в приложении (эта функция выключается по умолчанию). Если эта опция не доступна, блокировка не будет поддерживать Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Установите приложение Google Home и нажмите кнопку plus в левом верхнем углу", + "暂无最新记录": "В настоящее время последние данные отсутствуют", + "请扫描可视门铃码二维码": "Сканируйте код вызова", + "请确保网络是2.4GHz Wi-Fi": "Убедитесь, что сеть имеет 2,4 ГГц Wi - Fi", + "已选": "Выбранные", + "是否要远程开锁": "Нужно ли удалённо открывать замок", + "请将手机切换至2.4G WiFi进行手动连接": "Пожалуйста, переключите телефон на 2.4G WiFi для ручного подключения" } \ No newline at end of file diff --git a/lan/lan_sk.json b/lan/lan_sk.json index 176aab1b..18c30d61 100644 --- a/lan/lan_sk.json +++ b/lan/lan_sk.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Po resetovaní budú metakarpálne žily zámku vymazané. Ste si istí, že chcete obnoviť?", "在线": "Online", "离线": "Offline", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Funkcia diaľkového odomykania tohto zámku nie je povolená", "下载完成,请到相册查看": "Sťahovanie dokončené, prejdite na album view", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Keď je Cat Eye nastavený na režim úspory energie, monitorovanie nie je možné vykonať. Prepnite na iné režimy v nastaveniach Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Diaľkové odomknutie nie je možné, keď je Cat Eye nastavený do režimu úspory energie. Prepnite do iného režimu v nastaveniach Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Diaľkové odomknutie nie je možné, keď je Cat Eye nastavený do režimu úspory energie. Prepnite do iného režimu v nastaveniach Cat Eye", + "呼叫目标": "Cieľ hovoru", + "管理员APP": "Aplikácia správcu", + "可视门铃码": "Vizuálny kód zvončeka", + "电子反锁": "Elektronický protiblokovací systém", + "双重认证": "Dvojfaktorová autentifikácia", + "双锁联动": "Dvojitý zámok", + "1.用智能锁APP添加锁和网关": "1. Pridajte zámky a brány pomocou aplikácie inteligentného zámku", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Povoľte funkciu diaľkového odomykania zámku v aplikácii APP (táto funkcia je predvolene vypnutá). Ak táto možnosť nie je k dispozícii, zámok nebude podporovať Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Nainštalujte si aplikáciu Google Home a kliknite na tlačidlo plus v ľavom hornom rohu", + "暂无最新记录": "Momentálne nie sú k dispozícii žiadne najnovšie záznamy", + "请将手机切换至2.4G WiFi进行手动连接": "Pre manuálne pripojenie prepnite telefón na 2.4G WiFi" } \ No newline at end of file diff --git a/lan/lan_sr_cyrl.json b/lan/lan_sr_cyrl.json index 6ddf1a89..67bc4ada 100644 --- a/lan/lan_sr_cyrl.json +++ b/lan/lan_sr_cyrl.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Након ресетовања, метакарпалне вене браве ће бити избрисане. Да ли сте сигурни да желите да ресетујете?", "在线": "Онлине", "离线": "Ванмрежне", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Функција даљинског откључавања ове браве није омогућена", "下载完成,请到相册查看": "Преузимање завршено, идите на албум да видите", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Када је Цат Еие подешен на режим за уштеду енергије, праћење се не може извршити. Молимо Вас да пређете на друге режиме у подешавањима Цат Еие", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Даљинско откључавање није могуће када је Цат Еие подешен на режим за уштеду енергије. Молимо Вас да пређете на други режим у подешавањима Цат Еие" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Даљинско откључавање није могуће када је Цат Еие подешен на режим за уштеду енергије. Молимо Вас да пређете на други режим у подешавањима Цат Еие", + "呼叫目标": "Циљ позива", + "管理员APP": "Администратор АПП", + "可视门铃码": "Визуелни код звона", + "电子反锁": "Електронски против блокирања", + "双重认证": "Двофакторска аутентификација", + "双锁联动": "Двострука брава веза", + "1.用智能锁APP添加锁和网关": "1 . Додајте браве и гатеваи помоћу апликације Смарт Лоцк", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2 . Омогућите функцију даљинског откључавања браве у АПП-у (ова функција је подразумевано искључена). Ако ова опција није доступна, брава неће подржати Гоогле Хоме", + "3.安装Google Home APP,点击左上角的加号按钮": "3 . Инсталирајте апликацију Гоогле Хоме и кликните на дугме плус у горњем левом углу", + "暂无最新记录": "Тренутно нема доступних најновијих података", + "请将手机切换至2.4G WiFi进行手动连接": "Пребаците телефон на КСНУМКСГ ВиФи за ручно повезивање" } \ No newline at end of file diff --git a/lan/lan_sv.json b/lan/lan_sv.json index 27a46c37..22dcfa65 100644 --- a/lan/lan_sv.json +++ b/lan/lan_sv.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Efter återställd, de metakarpal venerna i låset tas bort. Är du säker på att du vill återställa?", "在线": "Online:", "离线": "Frånkoppling", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Fjärrupplåsningsfunktionen för detta lås är inte aktiverad", "下载完成,请到相册查看": "Nedladdningen är klar, gå till albumet för att se", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "När Cat Eye är inställt på energisparläge kan övervakning inte utföras. Växla till andra lägen i Cat Eye-inställningarna", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Fjärrupplåsning är inte möjlig när Cat Eye är inställt på energisparläge. Byt till ett annat läge i Cat Eye-inställningarna" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Fjärrupplåsning är inte möjlig när Cat Eye är inställt på energisparläge. Byt till ett annat läge i Cat Eye-inställningarna", + "呼叫目标": "Anropa mål", + "管理员APP": "APP för administratör", + "可视门铃码": "Visuell dörrklockakod", + "电子反锁": "Elektroniskt låsningsfritt läge", + "双重认证": "Tvåfaktorsautentisering", + "双锁联动": "Dubbel låslänkage", + "1.用智能锁APP添加锁和网关": "1. Lägg till lås och gateways med hjälp av den smarta låsappen", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Aktivera fjärrupplåsningsfunktionen för låset i APP (den här funktionen är avstängd som standard). Om det här alternativet inte är tillgängligt kommer låset inte att stödja Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Installera Google Home-appen och klicka på plusknappen i det övre vänstra hörnet", + "暂无最新记录": "Det finns för närvarande inga senaste poster tillgängliga", + "请将手机切换至2.4G WiFi进行手动连接": "Byt din telefon till 2.4G WiFi för manuell anslutning" } \ No newline at end of file diff --git a/lan/lan_th.json b/lan/lan_th.json index 77c4451a..fb568c47 100644 --- a/lan/lan_th.json +++ b/lan/lan_th.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "หลังจากรีเซ็ตแล้วหลอดเลือดดำ metacarpal ของล็อคจะถูกลบออกคุณแน่ใจว่าอยากจะรีเซ็ต?", "在线": "ออนไลน์ผ่าน", "离线": "ออฟไลน์", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "ไม่เปิดใช้ฟังก์ชันการปลดล็อคระยะไกลของการล็อคนี้", "下载完成,请到相册查看": "การดาวน์โหลดเสร็จสมบูรณ์แล้วโปรดไป ที่อัลบั้มเพื่อดู", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "เมื่อตั้งค่าตาแมวให้เป็นโหมดประหยัดพลังงานการตรวจสอบจะไม่สามารถทำงานได้ โปรดเปลี่ยนไปใช้โหมดอื่น ๆ ในการตั้งค่าตาแมว", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "ไม่สามารถปลดล็อคระยะไกลได้เมื่อตั้งค่าดวงตาแมวให้เป็นโหมดประหยัดพลังงาน โปรดเปลี่ยนเป็นโหมดอื่นในการตั้งค่าตาแมว" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "ไม่สามารถปลดล็อคระยะไกลได้เมื่อตั้งค่าดวงตาแมวให้เป็นโหมดประหยัดพลังงาน โปรดเปลี่ยนเป็นโหมดอื่นในการตั้งค่าตาแมว", + "呼叫目标": "เรียกเป้าหมาย", + "管理员APP": "แอพผู้ดูแลระบบ", + "可视门铃码": "รหัสประตูหน้า", + "电子反锁": "ล็อคป้องกันอิเล็กทรอนิกส์", + "双重认证": "การตรวจสอบสิทธิ์สองระดับ", + "双锁联动": "ดับเบิ้ลล็อคการเชื่อมต่อ", + "1.用智能锁APP添加锁和网关": "1. เพิ่มล็อค และเกตเวย์โดยใช้แอพสมาร์ทล็อค", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. เปิดใช้งานฟังก์ชันการปลดล็อคระยะไกลของการล็อคในแอพ (ฟังก์ชันนี้ จะถูกปิดโดยค่าเริ่มต้น) หากไม่มีตัวเลือกนี้ การล็อคจะไม่สนับสนุนกูเกิ้ลโฮม", + "3.安装Google Home APP,点击左上角的加号按钮": "3. ติดตั้ง googlehome แอพ และคลิกปุ่มบวก ที่มุมบนซ้าย", + "暂无最新记录": "ปัจจุบันยังไม่มีบันทึกล่าสุด ที่มีอยู่", + "请将手机切换至2.4G WiFi进行手动连接": "กรุณาเปลี่ยนโทรศัพท์เป็น 2.4 GWiFi สำหรับการเชื่อมต่อด้วยตนเอง" } \ No newline at end of file diff --git a/lan/lan_tr.json b/lan/lan_tr.json index 58d3e84e..34f6a7e9 100644 --- a/lan/lan_tr.json +++ b/lan/lan_tr.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Sıfırlamadan sonra, kilidin metacarpal damarları silinecektir. Sıfırlamak istediğine emin misin?", "在线": "Çevrimiçi", "离线": "Çevrimdışı", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Bu kilidin uzaktan kilit açma işlevi etkin değil", "下载完成,请到相册查看": "İndirme tamamlandı, görüntülemek için lütfen albüme gidin", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Cat Eye güç tasarrufu moduna ayarlandığında izleme yapılamaz. Lütfen Cat Eye ayarlarında diğer modlara geçin", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Cat Eye güç tasarrufu moduna ayarlandığında uzaktan kilit açma mümkün değildir. Lütfen Cat Eye ayarlarında başka bir moda geçin" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Cat Eye güç tasarrufu moduna ayarlandığında uzaktan kilit açma mümkün değildir. Lütfen Cat Eye ayarlarında başka bir moda geçin", + "呼叫目标": "Çağrı hedefi", + "管理员APP": "Yönetici APP", + "可视门铃码": "Görsel kapı zili kodu", + "电子反锁": "Elektronik kilitlenme önleyici", + "双重认证": "İki faktörlü kimlik doğrulama", + "双锁联动": "Çift kilit bağlantısı", + "1.用智能锁APP添加锁和网关": "1. Akıllı kilit uygulamasını kullanarak kilitler ve ağ geçitleri ekleyin", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. APP'de kilidin uzaktan kilit açma işlevini etkinleştirin (bu işlev varsayılan olarak kapalıdır). Bu seçenek mevcut değilse, kilit Google Home'u desteklemeyecektir", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Google Home uygulamasını yükleyin ve sol üst köşedeki artı düğmesini tıklayın", + "暂无最新记录": "Şu anda en son kayıt mevcut değil", + "请将手机切换至2.4G WiFi进行手动连接": "Manuel bağlantı için lütfen telefonunuzu 2.4G WiFi'ye getirin" } \ No newline at end of file diff --git a/lan/lan_tw.json b/lan/lan_tw.json index eb5482df..8f32a68e 100644 --- a/lan/lan_tw.json +++ b/lan/lan_tw.json @@ -1,6 +1,6 @@ { - "星锁": "星形鎖", - "锁通通": "鎖定通過", + "星锁": "星鎖", + "锁通通": "鎖通通", "点击开锁,长按闭锁": "觸摸以解鎖,按住以鎖定", "考勤": "出席情況", "考勤设置": "考勤設置", @@ -151,7 +151,7 @@ "升级": "更新", "空闲": "空缺", "已入住": "已占用", - "多语言": "語言", + "多语言": "多語言", "添加锁": "添加鎖定", "锁地址": "鎖地址", "选择锁类型": "選擇鎖定類型", @@ -267,9 +267,9 @@ "您可通过邮件将密码、电子钥匙信息发给接收人。": "電子郵件可用於向收件人發送密碼和ekey信息。", "购买实名认证提示": "啟用該功能後,您需要使用指紋,臉部或帳戶密碼才能打開該應用程序。 3分鐘不用再驗證", "请选择你希望的实名认证频次": "請選擇您想要的實名認證頻率", - "仅首次": "第一次", + "仅首次": "僅首次", "每日一次": "每天一次", - "每周一次": "每周一次", + "每周一次": "每週一次", "每月一次": "每月一次", "当前状态": "當前狀態", "试用中": "在審判中", @@ -1078,11 +1078,13 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "重置後,鎖的掌靜脈將被刪除。 是否確實要重置?", "在线": "在線", "离线": "離線", - "购买记录": "採購記錄", - "使用记录": "用戶記錄", + "购买记录": "購買記錄", + "使用记录": "使用記錄", "失效时间要大于当前时间": "過期時間必須長於當前時間", "修改名字": "編輯名稱", "时": "小時", @@ -1125,16 +1127,29 @@ "网关添加成功": "已成功添加網關", "功能开启后,你将可以通过网关远程开锁。": "啓用該功能後,您可以通過網關遠程解鎖。", "录屏已保存到相册": "屏幕錄製文件保存到相冊", - "通话未接通,已挂断": "電話未接通,掛了", + "通话未接通,已挂断": "電話未接通,已掛斷", "通话异常中断": "異常呼叫中斷", "通话连接失败": "呼叫連接失敗", - "已挂断": "掛", - "正在说话...": "說現在…", + "已挂断": "已掛斷", + "正在说话...": "正在說話…", "设备不在线": "設備未在線", "设备未配网": "設備未連接到網絡", "已静音": "聲音已被關掉了", "该锁的远程开锁功能未启用": "未開啓該鎖的遠程解鎖功能", "下载完成,请到相册查看": "下載完成,請到相冊查看", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "當“貓眼”設置爲省電模式時,無法進行監控。請在貓眼設置中切換到其他模式", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "當貓眼設置爲省電模式時,無法遠程解鎖。請在貓眼設置中切換到其他模式" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "當貓眼設置爲省電模式時,無法遠程解鎖。請在貓眼設置中切換到其他模式", + "呼叫目标": "調用目標", + "管理员APP": "管理員應用", + "可视门铃码": "可視門鈴碼", + "电子反锁": "電子反鎖", + "双重认证": "雙重認證", + "双锁联动": "雙鎖聯動", + "1.用智能锁APP添加锁和网关": "1. 使用智能鎖應用程序添加鎖和網關", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. 在APP中開啓鎖的遠程開鎖功能(默認關閉)。如果這個選項不可用,鎖將不支持谷歌Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. 安裝谷歌Home應用程序並單擊左上角的加號按鈕", + "暂无最新记录": "目前沒有最新的記錄", + "繁体中文(中国台湾)": "繁體中文(中國臺灣)", + "繁体中文(中国香港)": "繁體中文(中國香港)", + "请将手机切换至2.4G WiFi进行手动连接": "手動連接時請將手機調至2.4G WiFi" } \ No newline at end of file diff --git a/lan/lan_uk.json b/lan/lan_uk.json index 46af9456..a0451246 100644 --- a/lan/lan_uk.json +++ b/lan/lan_uk.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Після скидання п'ясткові вени замку будуть видалені. Ви впевнені, що хочете скинути налаштування?", "在线": "Онлайн", "离线": "Автономних", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Функція дистанційного розблокування цього замка не ввімкнена", "下载完成,请到相册查看": "Завантаження завершено, будь ласка, перейдіть до альбому для перегляду", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Коли функцію «Котяче око» переведено в режим енергозбереження, моніторинг неможливий. Будь ласка, перейдіть на інші режими в налаштуваннях Cat Eye", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Віддалене розблокування неможливе, коли Cat Eye переведено в режим енергозбереження. Будь ласка, перейдіть в інший режим у налаштуваннях Cat Eye" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Віддалене розблокування неможливе, коли Cat Eye переведено в режим енергозбереження. Будь ласка, перейдіть в інший режим у налаштуваннях Cat Eye", + "呼叫目标": "Ціль дзвінка", + "管理员APP": "Додаток адміністратора", + "可视门铃码": "Візуальний код дверного дзвінка", + "电子反锁": "Електронний антиблокувальний засіб", + "双重认证": "Двофакторна аутентифікація", + "双锁联动": "Важіль з подвійним замком", + "1.用智能锁APP添加锁和网关": "1. Додайте замки та шлюзи за допомогою програми Smart Lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Увімкніть функцію дистанційного розблокування замка в APP (ця функція вимкнена за замовчуванням). Якщо ця опція недоступна, замок не підтримуватиме Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Встановіть програму Google Home і натисніть кнопку плюс у верхньому лівому кутку", + "暂无最新记录": "Наразі немає останніх доступних записів", + "请将手机切换至2.4G WiFi进行手动连接": "Будь ласка, перемкніть свій телефон на 2.4G WiFi для ручного підключення" } \ No newline at end of file diff --git a/lan/lan_ur.json b/lan/lan_ur.json index c07e27d9..90574a85 100644 --- a/lan/lan_ur.json +++ b/lan/lan_ur.json @@ -1080,6 +1080,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "ری سیٹ کرنے کے بعد ، لاک کی میٹاکارپل رگیں حذف کردی جائیں گی۔ کیا آپ واقعی دوبارہ ترتیب دینا چاہتے ہیں؟", "在线": "آن لائن", "离线": "آف لائن", @@ -1136,5 +1138,16 @@ "重置后,该锁的遥控都将被删除哦,确认要重置吗?": "ری سیٹ کرنے کے بعد ، لاک کا ریموٹ کنٹرول حذف کردیا جائے گا۔ کیا آپ اسے دوبارہ ترتیب دینا چاہتے ہیں؟", "版本说明": "ورژن کی تفصیل", "网关通电后,长按重置按钮5秒,蓝色指示灯闪烁时点击下一步": "گیٹ وے کے چلنے کے بعد ، ری سیٹ بٹن کو 5 سیکنڈ تک دبائیں اور پکڑیں۔ جب نیلے اشارے کی روشنی چمکتی ہے تو اگلا پر کلک کریں", - "网关添加成功": "گیٹ وے نے کامیابی کے ساتھ اضافہ کیا" + "网关添加成功": "گیٹ وے نے کامیابی کے ساتھ اضافہ کیا", + "呼叫目标": "کال ہدف", + "管理员APP": "Administrator APP", + "可视门铃码": "Visual doorbell code", + "电子反锁": "الیکٹرانک اینٹی لاک", + "双重认证": "دو عوامل کی تصدیق", + "双锁联动": "ڈبل لاک لنک", + "1.用智能锁APP添加锁和网关": "1. سمارٹ لاک ایپ کا استعمال کرتے ہوئے لاک اور گیٹ وے شامل کریں", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. اے پی پی میں لاک کے ریموٹ ان لاکنگ فنکشن کو فعال کریں (یہ فنکشن ڈیفالٹ طور پر بند ہے)۔ اگر یہ آپشن دستیاب نہیں ہے تو ، لاک گوگل ہوم کو سپورٹ نہیں کرے گا۔", + "3.安装Google Home APP,点击左上角的加号按钮": "3. گوگل ہوم ایپ انسٹال کریں اور اوپری بائیں کونے میں پلس بٹن پر کلک کریں۔", + "暂无最新记录": "فی الحال کوئی تازہ ترین ریکارڈ دستیاب نہیں ہے", + "请将手机切换至2.4G WiFi进行手动连接": "براہ کرم دستی کنکشن کے لئے اپنے فون کو 2.4 جی وائی فائی پر سوئچ کریں" } \ No newline at end of file diff --git a/lan/lan_vi.json b/lan/lan_vi.json index 8a6c76d3..4086e02f 100644 --- a/lan/lan_vi.json +++ b/lan/lan_vi.json @@ -1078,6 +1078,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "Sau khi đặt lại, các tĩnh mạch metacarpal của khóa sẽ bị xóa. Bạn có chắc muốn thiết lập lại không?", "在线": "Trực tuyến", "离线": "Ngoại tuyến", @@ -1136,5 +1138,16 @@ "该锁的远程开锁功能未启用": "Chức năng mở khóa từ xa của khóa này không được kích hoạt", "下载完成,请到相册查看": "Hoàn tất tải về, xin hãy đến album để xem", "猫眼设置为省电模式时无法进行监控,请在猫眼设置中切换为其他模式": "Khi mắt mèo được thiết lập để tiết kiệm điện, giám sát không thể được thực hiện. Hãy chuyển sang chế độ khác trong mắt mèo", - "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Mở khóa từ xa là không thể khi mắt mèo được thiết lập ở chế độ tiết kiệm điện. Hãy chuyển sang chế độ khác trong thiết lập mắt mèo" + "猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式": "Mở khóa từ xa là không thể khi mắt mèo được thiết lập ở chế độ tiết kiệm điện. Hãy chuyển sang chế độ khác trong thiết lập mắt mèo", + "呼叫目标": "Đặt mục tiêu", + "管理员APP": "Ứng dụng quản trị viên", + "可视门铃码": "Hình ảnh chuông cửa", + "电子反锁": "Khóa chống điện tử", + "双重认证": "Chứng thực hai yếu tố", + "双锁联动": "Liên kết hai khóa", + "1.用智能锁APP添加锁和网关": "1. Thêm khoá và cổng bằng ứng dụng Smart Lock", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2. Kích hoạt chức năng mở khóa từ xa trong ứng dụng (chức năng này bị tắt theo mặc định). Nếu tùy chọn này không có sẵn, khóa sẽ không hỗ trợ Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3. Cài đặt ứng dụng Google Home và nhấn nút Plus ở góc trên bên trái", + "暂无最新记录": "Hiện tại không có hồ sơ mới nhất", + "请将手机切换至2.4G WiFi进行手动连接": "Vui lòng chuyển điện thoại sang 2.4G WiFi để kết nối bằng tay" } \ No newline at end of file diff --git a/lan/lan_zh.json b/lan/lan_zh.json index 2204763f..bde3239c 100755 --- a/lan/lan_zh.json +++ b/lan/lan_zh.json @@ -62,6 +62,8 @@ "批量授权锁": "批量授权锁", "授权管理员拥有操作这把锁的重要权限,请确保只发给我你信任的人": "授权管理员拥有操作这把锁的重要权限,请确保只发给我你信任的人", "功能开启后,你将可以通过网关远程开锁。此功能的开启和关闭只能在锁附近通过手机蓝牙进行。": "功能开启后,你将可以通过网关远程开锁。此功能的开启和关闭只能在锁附近通过手机蓝牙进行。", + "此功能的开启和关闭只能在锁附近通过手机蓝牙进行": "此功能的开启和关闭只能在锁附近通过手机蓝牙进行", + "功能开启后,你将可以通过网关远程开锁。": "功能开启后,你将可以通过网关远程开锁。", "排列方式": "排列方式", "早到榜": "早到榜", @@ -1081,6 +1083,8 @@ "印度尼西亚语": "Bahasa Indonesia", "芬兰语": "Suomi", "丹麦语": "Dansk", + "印地语": "हिंदीName", + "乌尔都语": "اوردو", "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "重置后,该锁的掌静脉都将被删除哦,确认要重置吗?", "在线": "在线", "离线": "离线", @@ -1138,5 +1142,26 @@ "版本说明": "版本说明", "呼叫目标": "呼叫目标", "管理员APP": "管理员APP", + "可视门铃码": "可视门铃码", + "电子反锁": "电子反锁", + "双重认证": "双重认证", + "双锁联动": "双锁联动", + "1.用智能锁APP添加锁和网关": "1.用智能锁APP添加锁和网关", + "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home": "2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home", + "3.安装Google Home APP,点击左上角的加号按钮": "3.安装Google Home APP,点击左上角的加号按钮", + "4.在设置页面,选择与Google协同工作": "4.在设置页面,选择与Google协同工作", + "5.搜索": "5.搜索", + ",并用智能锁APP的账号和密码进行授权": ",并用智能锁APP的账号和密码进行授权", + "暂无最新记录": "暂无最新记录", + "请将手机切换至2.4G WiFi进行手动连接": "请将手机切换至2.4G WiFi进行手动连接", + "请扫描可视门铃码二维码": "请扫描可视门铃码二维码", + "请确保网络是2.4GHz Wi-Fi": "请确保网络是2.4GHz Wi-Fi", + "已选": "已选", + "是否要远程开锁": "是否要远程开锁", + "繁体中文(中国台湾)": "繁体中文(中国台湾)", + "繁体中文(中国香港)": "繁体中文(中国香港)", + "国家地区的选择将影响数据安全,你当前选择的是": "国家地区的选择将影响数据安全,你当前选择的是", + "请确认后再继续": "请确认后再继续", + "需要相机权限": "需要相机权限", "网关添加成功": "网关添加成功" } diff --git a/lib/blue/io_reply.dart b/lib/blue/io_reply.dart index be395c47..856eb0d9 100755 --- a/lib/blue/io_reply.dart +++ b/lib/blue/io_reply.dart @@ -1,11 +1,10 @@ - import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; import '../app_settings/app_settings.dart'; import 'io_type.dart'; -abstract class Reply{ +abstract class Reply { Reply.parseData(this.commandType, List dataDetail); CommandType? commandType; @@ -13,10 +12,10 @@ abstract class Reply{ //command key flag int status = 0; List data = []; - static String logTag= '锁 -> App,指令订阅类型 :'; + static String logTag = '锁 -> App,指令订阅类型 :'; - void errorWithStstus(int status){ - switch(status){ + void errorWithStstus(int status) { + switch (status) { case 0x00: // 成功 AppLog.log('$logTag ${commandType?.typeName} 0x00 成功'); @@ -39,7 +38,7 @@ abstract class Reply{ case 0x04: // 用户未登记 AppLog.log('$logTag ${commandType!.typeName} 0x04 用户未登记'); - // showErrorMessage('用户未登记'); + showErrorMessage('用户未登记'.tr); break; case 0x05: // 参数错误 @@ -133,7 +132,7 @@ abstract class Reply{ } } - void showErrorMessage(String message){ + void showErrorMessage(String message) { EasyLoading.showToast(message, duration: 2000.milliseconds); } diff --git a/lib/blue/reciver_data.dart b/lib/blue/reciver_data.dart index 8f1db2af..2fc7fe54 100755 --- a/lib/blue/reciver_data.dart +++ b/lib/blue/reciver_data.dart @@ -57,7 +57,20 @@ class CommandReciverManager { if (data.isEmpty) { return; } + final int dataSize = data.length; + + // 验证CRC校验 + if (dataSize >= 2) { + final int calculatedCrc = + _calculateCRC16(data.sublist(0, dataSize - 2), dataSize - 2); + final int receivedCrc = (data[dataSize - 2] << 8) | data[dataSize - 1]; + + if (calculatedCrc != receivedCrc) { + AppLog.log('CRC校验失败'); + return; + } + } // 当小于包头加起来13个字节 if (dataSize < 13) { return; @@ -123,6 +136,16 @@ class CommandReciverManager { } } +// CRC16 校验计算 + static int _calculateCRC16(List bytes, int len) { + int value = 0x0000; + for (int i = 0; i < len; i++) { + int tmp = _reverse8(bytes[i]); + value = ((value << 8) ^ _crcTable[(value >> 8) ^ tmp & 0xFF]) & 0xFFFF; + } + return _reverse16(value); + } + static Future parseData(List data) async { if (data.isNotEmpty) { final int cmd = data[0] * 256 + data[1]; @@ -472,4 +495,282 @@ class CommandReciverManager { } return null; } + + // CRC16 查找表 + static const List _crcTable = [ + 0x0000, + 0x1021, + 0x2042, + 0x3063, + 0x4084, + 0x50a5, + 0x60c6, + 0x70e7, + 0x8108, + 0x9129, + 0xa14a, + 0xb16b, + 0xc18c, + 0xd1ad, + 0xe1ce, + 0xf1ef, + 0x1231, + 0x0210, + 0x3273, + 0x2252, + 0x52b5, + 0x4294, + 0x72f7, + 0x62d6, + 0x9339, + 0x8318, + 0xb37b, + 0xa35a, + 0xd3bd, + 0xc39c, + 0xf3ff, + 0xe3de, + 0x2462, + 0x3443, + 0x0420, + 0x1401, + 0x64e6, + 0x74c7, + 0x44a4, + 0x5485, + 0xa56a, + 0xb54b, + 0x8528, + 0x9509, + 0xe5ee, + 0xf5cf, + 0xc5ac, + 0xd58d, + 0x3653, + 0x2672, + 0x1611, + 0x0630, + 0x76d7, + 0x66f6, + 0x5695, + 0x46b4, + 0xb75b, + 0xa77a, + 0x9719, + 0x8738, + 0xf7df, + 0xe7fe, + 0xd79d, + 0xc7bc, + 0x48c4, + 0x58e5, + 0x6886, + 0x78a7, + 0x0840, + 0x1861, + 0x2802, + 0x3823, + 0xc9cc, + 0xd9ed, + 0xe98e, + 0xf9af, + 0x8948, + 0x9969, + 0xa90a, + 0xb92b, + 0x5af5, + 0x4ad4, + 0x7ab7, + 0x6a96, + 0x1a71, + 0x0a50, + 0x3a33, + 0x2a12, + 0xdbfd, + 0xcbdc, + 0xfbbf, + 0xeb9e, + 0x9b79, + 0x8b58, + 0xbb3b, + 0xab1a, + 0x6ca6, + 0x7c87, + 0x4ce4, + 0x5cc5, + 0x2c22, + 0x3c03, + 0x0c60, + 0x1c41, + 0xedae, + 0xfd8f, + 0xcdec, + 0xddcd, + 0xad2a, + 0xbd0b, + 0x8d68, + 0x9d49, + 0x7e97, + 0x6eb6, + 0x5ed5, + 0x4ef4, + 0x3e13, + 0x2e32, + 0x1e51, + 0x0e70, + 0xff9f, + 0xefbe, + 0xdfdd, + 0xcffc, + 0xbf1b, + 0xaf3a, + 0x9f59, + 0x8f78, + 0x9188, + 0x81a9, + 0xb1ca, + 0xa1eb, + 0xd10c, + 0xc12d, + 0xf14e, + 0xe16f, + 0x1080, + 0x00a1, + 0x30c2, + 0x20e3, + 0x5004, + 0x4025, + 0x7046, + 0x6067, + 0x83b9, + 0x9398, + 0xa3fb, + 0xb3da, + 0xc33d, + 0xd31c, + 0xe37f, + 0xf35e, + 0x02b1, + 0x1290, + 0x22f3, + 0x32d2, + 0x4235, + 0x5214, + 0x6277, + 0x7256, + 0xb5ea, + 0xa5cb, + 0x95a8, + 0x8589, + 0xf56e, + 0xe54f, + 0xd52c, + 0xc50d, + 0x34e2, + 0x24c3, + 0x14a0, + 0x0481, + 0x7466, + 0x6447, + 0x5424, + 0x4405, + 0xa7db, + 0xb7fa, + 0x8799, + 0x97b8, + 0xe75f, + 0xf77e, + 0xc71d, + 0xd73c, + 0x26d3, + 0x36f2, + 0x0691, + 0x16b0, + 0x6657, + 0x7676, + 0x4615, + 0x5634, + 0xd94c, + 0xc96d, + 0xf90e, + 0xe92f, + 0x99c8, + 0x89e9, + 0xb98a, + 0xa9ab, + 0x5844, + 0x4865, + 0x7806, + 0x6827, + 0x18c0, + 0x08e1, + 0x3882, + 0x28a3, + 0xcb7d, + 0xdb5c, + 0xeb3f, + 0xfb1e, + 0x8bf9, + 0x9bd8, + 0xabbb, + 0xbb9a, + 0x4a75, + 0x5a54, + 0x6a37, + 0x7a16, + 0x0af1, + 0x1ad0, + 0x2ab3, + 0x3a92, + 0xfd2e, + 0xed0f, + 0xdd6c, + 0xcd4d, + 0xbdaa, + 0xad8b, + 0x9de8, + 0x8dc9, + 0x7c26, + 0x6c07, + 0x5c64, + 0x4c45, + 0x3ca2, + 0x2c83, + 0x1ce0, + 0x0cc1, + 0xef1f, + 0xff3e, + 0xcf5d, + 0xdf7c, + 0xaf9b, + 0xbfba, + 0x8fd9, + 0x9ff8, + 0x6e17, + 0x7e36, + 0x4e55, + 0x5e74, + 0x2e93, + 0x3eb2, + 0x0ed1, + 0x1ef0 + ]; + + // 8位字节反转 + static int _reverse8(int data) { + int temp = 0; + for (int i = 0; i < 8; i++) { + temp |= ((data >> i) & 0x01) << (7 - i); + } + return temp; + } + + // 16位字反转 + static int _reverse16(int data) { + int temp = 0; + for (int i = 0; i < 16; i++) { + temp |= ((data >> i) & 0x0001) << (15 - i); + } + return temp; + } } diff --git a/lib/blue/sm4Encipher/sm4.dart b/lib/blue/sm4Encipher/sm4.dart index 38df45db..382cd5fa 100755 --- a/lib/blue/sm4Encipher/sm4.dart +++ b/lib/blue/sm4Encipher/sm4.dart @@ -263,7 +263,12 @@ class SM4 { 0x48 ]; - static const List FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC]; + static const List FK = [ + 0xA3B1BAC6, + 0x56AA3350, + 0x677D9197, + 0xB27022DC + ]; static const List CK = [ 0x00070e15, @@ -411,11 +416,27 @@ class SM4 { } return paddedList; } else { + // 解密时去除PKCS7填充 + final int lastByte = input.last; + if (lastByte > 0 && lastByte <= blockSize) { + // 验证填充是否合法 + bool isValidPadding = true; + for (int i = input.length - lastByte; i < input.length; i++) { + if (input[i] != lastByte) { + isValidPadding = false; + break; + } + } + if (isValidPadding) { + return input.sublist(0, input.length - lastByte); + } + } + return input; // final lastByte = input.last; // final cutLen = input.length - lastByte; - // AppLog.log("object input.length:${input.length} lastByte:$lastByte input:$input cutLen:$cutLen"); + // // AppLog.log("object input.length:${input.length} lastByte:$lastByte input:$input cutLen:$cutLen"); // return input.sublist(0, cutLen); - return input; + // return input; } } @@ -480,7 +501,8 @@ class SM4 { final List supplementList = List.filled(16, 0x00); /// complete list - final List completeList = [...list, ...supplementList].sublist(0, 16); + final List completeList = + [...list, ...supplementList].sublist(0, 16); return completeList; } diff --git a/lib/login/forgetPassword/starLock_forgetPassword_logic.dart b/lib/login/forgetPassword/starLock_forgetPassword_logic.dart index 7036c80c..8015cc6b 100755 --- a/lib/login/forgetPassword/starLock_forgetPassword_logic.dart +++ b/lib/login/forgetPassword/starLock_forgetPassword_logic.dart @@ -19,6 +19,7 @@ class StarLockForgetPasswordLogic extends BaseGetXController { final StarLockForgetPasswordState state = StarLockForgetPasswordState(); late Timer _timer; + void _startTimer() { _timer = Timer.periodic(1.seconds, (Timer timer) { if (state.currentSecond > 1) { @@ -37,12 +38,12 @@ class StarLockForgetPasswordLogic extends BaseGetXController { } Future resetPassword() async { - if(state.pwd.value != state.surePwd.value){ + if (state.pwd.value != state.surePwd.value) { showToast('两次密码不一致哦'.tr); return; } - if(!RegularExpression().validateString(state.pwd.value)){ + if (!RegularExpression().validateString(state.pwd.value)) { showToast('密码需至少包含数字/字母/字符中的2种组合'.tr); return; } @@ -56,42 +57,44 @@ class StarLockForgetPasswordLogic extends BaseGetXController { state.verificationCode.value); if (entity.errorCode!.codeIsSuccessful) { ApmHelper.instance.trackEvent('resetPassword_result', { - 'account':state.phoneStr.value, - 'date':DateTool().getNowDateWithType(1), - 'resetPassword_res':'成功', + 'account': state.phoneStr.value, + 'date': DateTool().getNowDateWithType(1), + 'resetPassword_res': '成功', }); showToast('重置成功'.tr); Get.back(); - }else{ + } else { ApmHelper.instance.trackEvent('resetPassword_result', { - 'account':state.phoneStr.value, - 'date':DateTool().getNowDateWithType(1), - 'resetPassword_res':'${entity.errorCode}--${entity.errorMsg}', + 'account': state.phoneStr.value, + 'date': DateTool().getNowDateWithType(1), + 'resetPassword_res': '${entity.errorCode}--${entity.errorMsg}', }); } } Future sendValidationCode() async { - final SendValidationCodeEntity entity = await ApiRepository.to.sendValidationCodeUnLogin( - // state.countryCode.value, - countryCode:state.countryCode.value, - account:state.phoneStr.value, - channel:state.codeType.value, - codeType:'2', - xWidth:state.xWidth.value.toString()); + final SendValidationCodeEntity entity = + await ApiRepository.to.sendValidationCodeUnLogin( + // state.countryCode.value, + countryCode: state.countryCode.value, + account: state.phoneStr.value, + channel: state.codeType.value, + codeType: '2', + xWidth: state.xWidth.value.toString()); if (entity.errorCode!.codeIsSuccessful) { _startTimer(); } } Future checkIpAction() async { - final CheckIPEntity entity = await ApiRepository.to.checkIpAction( - ip: '' - ); + final CheckIPEntity entity = await ApiRepository.to.checkIpAction(ip: ''); if (entity.errorCode!.codeIsSuccessful) { - if(state.countryName.value == entity.data!.name){ - ShowTipView().showSureAlertDialog('国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续'.tr, tipTitle: '确认国家或地区'.tr, sureStr: '我知道了'.tr); + if (state.countryName.value != entity.data!.name) { + ShowTipView().showSureAlertDialog( + '国家地区的选择将影响数据安全,你当前选择的是' + state.countryName.value + '请确认后再继续'.tr, + tipTitle: '确认国家或地区'.tr, + sureStr: '我知道了'.tr); } } } @@ -103,9 +106,9 @@ class StarLockForgetPasswordLogic extends BaseGetXController { void changeInput(TextEditingController controller) { if (controller == state.phoneController) { state.phoneStr.value = controller.text; - if(state.phoneStr.value.contains('@')){ + if (state.phoneStr.value.contains('@')) { state.codeType.value = '2'; - }else{ + } else { state.codeType.value = '1'; } } @@ -120,11 +123,13 @@ class StarLockForgetPasswordLogic extends BaseGetXController { } _resetCanSendCode(); _resetCanSub(); - AppLog.log('state.canSub.value:${state.canSub.value} state.pwdIsOK:${state.pwdIsOK} state.codeIsOK:${state.codeIsOK} state.phoneStr.value:${state.phoneStr.value}'); + AppLog.log( + 'state.canSub.value:${state.canSub.value} state.pwdIsOK:${state.pwdIsOK} state.codeIsOK:${state.codeIsOK} state.phoneStr.value:${state.phoneStr.value}'); } void _resetCanSub() { - state.canSub.value = state.pwdIsOK && state.codeIsOK && state.phoneStr.value.isNotEmpty; + state.canSub.value = + state.pwdIsOK && state.codeIsOK && state.phoneStr.value.isNotEmpty; } void _resetCanSendCode() { diff --git a/lib/login/forgetPassword/starLock_forgetPassword_page.dart b/lib/login/forgetPassword/starLock_forgetPassword_page.dart index 9e20dc8f..7cc992e6 100755 --- a/lib/login/forgetPassword/starLock_forgetPassword_page.dart +++ b/lib/login/forgetPassword/starLock_forgetPassword_page.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -58,8 +57,7 @@ class _StarLockForgetPasswordPageState children: [ SizedBox(width: 5.w), Expanded( - child: Text( - '国家/地区'.tr, + child: Text('国家/地区'.tr, style: TextStyle( fontSize: 26.sp, color: AppColors.blackColor))), SizedBox(width: 20.w), diff --git a/lib/login/login/starLock_login_logic.dart b/lib/login/login/starLock_login_logic.dart index 570fa80c..4dfa2b5d 100755 --- a/lib/login/login/starLock_login_logic.dart +++ b/lib/login/login/starLock_login_logic.dart @@ -141,9 +141,9 @@ class StarLockLoginLogic extends BaseGetXController { Future checkIpAction() async { final CheckIPEntity entity = await ApiRepository.to.checkIpAction(ip: ''); if (entity.errorCode!.codeIsSuccessful) { - if (state.countryName == entity.data!.name) { + if (state.countryName != entity.data!.name) { ShowTipView().showSureAlertDialog( - '国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续'.tr, + '国家地区的选择将影响数据安全,你当前选择的是'+state.countryName+'请确认后再继续'.tr, tipTitle: '确认国家或地区'.tr, sureStr: '我知道了'.tr); } diff --git a/lib/login/login/starLock_login_page.dart b/lib/login/login/starLock_login_page.dart index 0c39c91a..1875d334 100755 --- a/lib/login/login/starLock_login_page.dart +++ b/lib/login/login/starLock_login_page.dart @@ -108,7 +108,7 @@ class _StarLockLoginPageState extends State { if (result != null) { result as Map; state.countryCode.value = result['code']; - state.countryKey = result['countryName']; + state.countryKey.value = result['countryName']; logic.checkIpAction(); } }, @@ -133,6 +133,7 @@ class _StarLockLoginPageState extends State { inputFormatters: [ // FilteringTextInputFormatter.allow(RegExp('[0-9]')), LengthLimitingTextInputFormatter(30), + FilteringTextInputFormatter.singleLineFormatter ]), SizedBox(height: 10.h), LoginInput( diff --git a/lib/login/register/starLock_register_logic.dart b/lib/login/register/starLock_register_logic.dart index 93890b8e..5796d422 100755 --- a/lib/login/register/starLock_register_logic.dart +++ b/lib/login/register/starLock_register_logic.dart @@ -100,9 +100,11 @@ class StarLockRegisterLogic extends BaseGetXController { Future checkIpAction() async { final CheckIPEntity entity = await ApiRepository.to.checkIpAction(ip: ''); if (entity.errorCode!.codeIsSuccessful) { - if (state.countryName.value == entity.data!.name) { + if (state.countryName.value != entity.data!.name) { ShowTipView().showSureAlertDialog( - '国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续'.tr, + '国家地区的选择将影响数据安全,你当前选择的是'.tr + + '${state.countryName.value},' + + '请确认后再继续'.tr, tipTitle: '确认国家或地区'.tr, sureStr: '我知道了'.tr); } diff --git a/lib/login/register/starLock_register_page.dart b/lib/login/register/starLock_register_page.dart index 2e8174df..e9d599e9 100755 --- a/lib/login/register/starLock_register_page.dart +++ b/lib/login/register/starLock_register_page.dart @@ -1,4 +1,4 @@ - +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -87,7 +87,8 @@ class _StarLockRegisterPageState extends State { onTap: () { state.isIphoneType.value = true; }, - child: Obx(() => Container( + child: Obx( + () => Container( width: 170.w, height: 60.h, decoration: state.isIphoneType.value @@ -99,39 +100,52 @@ class _StarLockRegisterPageState extends State { width: 1.0, color: AppColors.greyLineColor)) : null, child: Center( - child: Text( - '手机'.tr, - style: TextStyle( - color: state.isIphoneType.value - ? Colors.white - : Colors.black), - )))), + child: Text( + '手机'.tr, + style: TextStyle( + color: state.isIphoneType.value + ? Colors.white + : Colors.black), + ), + ), + ), + ), ), Expanded( child: GestureDetector( onTap: () { state.isIphoneType.value = false; }, - child: Obx(() => Container( + child: Obx( + () => Container( height: 60.h, // color: Colors.red, decoration: state.isIphoneType.value ? null : BoxDecoration( color: AppColors.mainColor, - borderRadius: - BorderRadius.all(Radius.circular(30.h)), + borderRadius: BorderRadius.all( + Radius.circular( + 30.h, + ), + ), border: Border.all( - width: 1.0, - color: AppColors.greyLineColor)), + width: 1.0, + color: AppColors.greyLineColor, + ), + ), child: Center( - child: Text( - '邮箱'.tr, - style: TextStyle( + child: Text( + '邮箱'.tr, + style: TextStyle( color: state.isIphoneType.value ? Colors.black - : Colors.white), - )))), + : Colors.white, + ), + ), + ), + ), + ), ), ), ], @@ -157,8 +171,7 @@ class _StarLockRegisterPageState extends State { children: [ SizedBox(width: 5.w), Expanded( - child: Text( - '你所在的国家/地区'.tr, + child: Text('你所在的国家/地区'.tr, style: TextStyle( fontSize: 26.sp, color: AppColors.blackColor))), SizedBox(width: 20.w), @@ -213,8 +226,7 @@ class _StarLockRegisterPageState extends State { height: 30.w, ), ), - hintText: - state.isIphoneType.value ? '请输入手机号'.tr : '请输入邮箱'.tr, + hintText: state.isIphoneType.value ? '请输入手机号'.tr : '请输入邮箱'.tr, keyboardType: TextInputType.number, inputFormatters: [ // FilteringTextInputFormatter.allow(RegExp('[0-9]')), @@ -236,7 +248,7 @@ class _StarLockRegisterPageState extends State { height: 30.w, ), ), - hintText:'请输入密码'.tr, + hintText: '请输入密码'.tr, inputFormatters: [ LengthLimitingTextInputFormatter(20), ]), @@ -282,8 +294,7 @@ class _StarLockRegisterPageState extends State { height: 30.w, ), ), - hintText: - '请输入验证码'.tr, + hintText: '请输入验证码'.tr, inputFormatters: [ LengthLimitingTextInputFormatter(20), ]), @@ -292,29 +303,29 @@ class _StarLockRegisterPageState extends State { width: 20.w, ), Obx(() => GestureDetector( - onTap: - (state.canSendCode.value && state.canResend.value) - ? () async { - // Navigator.pushNamed(context, Routers.safetyVerificationPage, arguments: {"countryCode":"+86", "account":state.phoneOrEmailStr.value}); - final Object? result = await Navigator.pushNamed( - context, Routers.safetyVerificationPage, - arguments: { - 'countryCode': state.countryCode, - 'account': state.phoneOrEmailStr.value - }); - state.xWidth.value = - (result! as Map)['xWidth']; - logic.sendValidationCode(); - } - : null, + onTap: (state.canSendCode.value && state.canResend.value) + ? () async { + // Navigator.pushNamed(context, Routers.safetyVerificationPage, arguments: {"countryCode":"+86", "account":state.phoneOrEmailStr.value}); + final Object? result = await Navigator.pushNamed( + context, Routers.safetyVerificationPage, + arguments: { + 'countryCode': state.countryCode, + 'account': state.phoneOrEmailStr.value + }); + state.xWidth.value = + (result! as Map)['xWidth']; + logic.sendValidationCode(); + } + : null, child: Container( width: 180.w, // height: 60.h, padding: EdgeInsets.all(10.h), decoration: BoxDecoration( - color: (state.canSendCode.value && state.canResend.value) - ? AppColors.mainColor - : Colors.grey, + color: + (state.canSendCode.value && state.canResend.value) + ? AppColors.mainColor + : Colors.grey, borderRadius: BorderRadius.circular(5)), child: Center( child: Text(state.btnText.value, @@ -361,29 +372,29 @@ class _StarLockRegisterPageState extends State { WidgetSpan( alignment: PlaceholderAlignment.middle, child: GestureDetector( - child: Text( - '《${'用户协议'.tr}》', + child: Text('《${'用户协议'.tr}》', style: TextStyle( color: AppColors.mainColor, fontSize: 20.sp)), onTap: () { - Get.toNamed(Routers.webviewShowPage, arguments: { - 'url': XSConstantMacro.userAgreementURL, - 'title': '用户协议'.tr - }); + Get.toNamed(Routers.webviewShowPage, + arguments: { + 'url': XSConstantMacro.userAgreementURL, + 'title': '用户协议'.tr + }); }, )), WidgetSpan( alignment: PlaceholderAlignment.middle, child: GestureDetector( - child: Text( - '《${'隐私政策'.tr}》', + child: Text('《${'隐私政策'.tr}》', style: TextStyle( color: AppColors.mainColor, fontSize: 20.sp)), onTap: () { - Get.toNamed(Routers.webviewShowPage, arguments: { - 'url': XSConstantMacro.privacyPolicyURL, - 'title': '隐私政策'.tr - }); + Get.toNamed(Routers.webviewShowPage, + arguments: { + 'url': XSConstantMacro.privacyPolicyURL, + 'title': '隐私政策'.tr + }); }, )), ], diff --git a/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart b/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart index f8bc3360..4999b8ed 100755 --- a/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart +++ b/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:get/get.dart'; import 'package:star_lock/apm/apm_helper.dart'; +import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart'; import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_state.dart'; @@ -53,9 +54,11 @@ class DoorLockLogLogic extends BaseGetXController { switch (status) { case 0x00: + dismissEasyLoading(); + cancelBlueConnetctToastTimer(); //成功 final int dataLength = (reply.data[5] << 8) + reply.data[6]; - // AppLog.log("dataLength:$dataLength"); + AppLog.log("dataLength:$dataLength"); // var dataLength = reply.data[5]; if (dataLength > 0) { reply.data.removeRange(0, 7); @@ -68,34 +71,38 @@ class DoorLockLogLogic extends BaseGetXController { final List uploadList = []; for (int i = 0; i < getList.length; i++) { final List indexList = getList[i]; - // AppLog.log("indexList:$indexList"); - final Map indexMap = {}; - indexMap['type'] = indexList[0].toString(); + try { + // AppLog.log("indexList:$indexList"); + final Map indexMap = {}; + indexMap['type'] = indexList[0].toString(); - final int userNo = (indexList[1] * 256) + indexList[2]; - indexMap['user'] = userNo.toString(); - // AppLog.log('userNouserNouserNouserNo:$userNo'); + final int userNo = (indexList[1] * 256) + indexList[2]; + indexMap['user'] = userNo.toString(); + // AppLog.log('userNouserNouserNouserNo:$userNo'); - final List passwordData = indexList.sublist(7, 17); - final String password = utf8String(passwordData); - indexMap['password'] = password.toString(); - // AppLog.log('passwordpasswordpassword:$password'); + final List passwordData = indexList.sublist(7, 17); + final String password = utf8String(passwordData); + indexMap['password'] = password.toString(); + // AppLog.log('passwordpasswordpassword:$password'); - indexMap['success'] = '1'; + indexMap['success'] = '1'; - final int time = (0xff & indexList[3]) << 24 | - (0xff & indexList[4]) << 16 | - (0xff & indexList[5]) << 8 | - (0xFF & indexList[6]); - final int operateDate = time * 1000; - final int serverTime = state.currentDate; - if (DateTime.fromMillisecondsSinceEpoch(operateDate).isAfter( - DateTime.fromMillisecondsSinceEpoch(serverTime * 1000))) { - // AppLog.log('operateDate:$operateDate state.currentDate:${state.currentDate}'); - continue; + final int time = (0xff & indexList[3]) << 24 | + (0xff & indexList[4]) << 16 | + (0xff & indexList[5]) << 8 | + (0xFF & indexList[6]); + final int operateDate = time * 1000; + final int serverTime = state.currentDate; + if (DateTime.fromMillisecondsSinceEpoch(operateDate).isAfter( + DateTime.fromMillisecondsSinceEpoch(serverTime * 1000))) { + // AppLog.log('operateDate:$operateDate state.currentDate:${state.currentDate}'); + continue; + } + indexMap['date'] = '$operateDate'; + uploadList.add(indexMap); + } catch (e) { + AppLog.log('操作记录:$indexList,解析失败,跳过该跳记录,进行下一条记录解析。'); } - indexMap['date'] = '$operateDate'; - uploadList.add(indexMap); } if (dataLength == state.logCountPage) { state.ifHaveNext = true; @@ -103,6 +110,8 @@ class DoorLockLogLogic extends BaseGetXController { state.ifHaveNext = false; } lockRecordUploadData(uploadList); + } else { + showToast('暂无最新记录'.tr); } break; case 0x06: @@ -112,6 +121,7 @@ class DoorLockLogLogic extends BaseGetXController { default: //失败 dismissEasyLoading(); + cancelBlueConnetctToastTimer(); break; } } @@ -143,30 +153,23 @@ class DoorLockLogLogic extends BaseGetXController { ).toString(); showEasyLoading(); - showBlueConnetctToastTimer( - isShowBlueConnetctToast: true, - action: () async { - cancelBlueConnetctToastTimer(); + showBlueConnetctToastTimer(action: () async { + dismissEasyLoading(); + final String getMobile = (await Storage.getMobile())!; + ApmHelper.instance.trackEvent('check_doorLockLog', { + 'lockName': state.keyInfos.value.lockName!, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'open_lock_result': '超时', + }); - final String getMobile = (await Storage.getMobile())!; - ApmHelper.instance.trackEvent('check_doorLockLog', { - 'lockName': state.keyInfos.value.lockName!, - 'account': - getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date': DateTool().getNowDateWithType(1), - 'open_lock_result': '超时', - }); - - BuglyTool.uploadException( - message: '查询锁记录超时-查询锁记录失败', - detail: - '添加密码超时,查询锁记录失败--senderReferEventRecordTimeCommand:$command', - eventStr: '查询锁记录事件超时', - upload: true); - if (state.isLockReceiveResponse == false) { - dismissEasyLoading(); - } - }); + BuglyTool.uploadException( + message: '查询锁记录超时-查询锁记录失败', + detail: '添加密码超时,查询锁记录失败--senderReferEventRecordTimeCommand:$command', + eventStr: '查询锁记录事件超时', + upload: true); + }); BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState connectionStateState) async { if (connectionStateState == BluetoothConnectionState.connected) { @@ -298,20 +301,22 @@ class DoorLockLogLogic extends BaseGetXController { lockId: state.keyInfos.value.lockId.toString(), records: list); final String getMobile = (await Storage.getMobile())!; if (entity.errorCode!.codeIsSuccessful) { - if (state.ifHaveNext == true) { - showEasyLoading(); - getLockRecordLastUploadDataTime(); - } else { - ApmHelper.instance.trackEvent('check_doorLockLog', { - 'lockName': state.keyInfos.value.lockName!, - 'account': - getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date': DateTool().getNowDateWithType(1), - 'open_lock_result': '成功', - }); - mockNetworkDataRequest(isRefresh: true); - } - dismissEasyLoading(); + showToast('操作成功'.tr, something: () async { + dismissEasyLoading(); + if (state.ifHaveNext == true) { + showEasyLoading(); + getLockRecordLastUploadDataTime(); + } else { + ApmHelper.instance.trackEvent('check_doorLockLog', { + 'lockName': state.keyInfos.value.lockName!, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'open_lock_result': '成功', + }); + mockNetworkDataRequest(isRefresh: true); + } + }); } else { ApmHelper.instance.trackEvent('check_doorLockLog', { 'lockName': state.keyInfos.value.lockName!, diff --git a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart index 8fee41fd..da455907 100755 --- a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart +++ b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart @@ -531,7 +531,8 @@ class _SendElectronicKeyViewState extends State SizedBox( height: 10.h, ), - if (logic.emailOrPhone != null) + if (logic.emailOrPhone != null && + logic.state.currentLanguage.value == 'zh_CN') OutLineBtn( btnName: '微信通知'.tr, onClick: () { diff --git a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart index 353d884a..7ada2123 100755 --- a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart +++ b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart'; import 'package:get/get.dart'; import 'package:star_lock/tools/dateTool.dart'; +import 'package:star_lock/translations/current_locale_tool.dart'; class SendElectronicKeyViewState { //循环 @@ -42,4 +43,7 @@ class SendElectronicKeyViewState { final String permanentTips = '接收者可以使用此App开关锁'.tr; //永久 final String onceLimitTips = '单次钥匙有效期为1小时,只能使用一次'.tr; //单次 final String cycleLimitTips = '接收者可以在有效期内的固定时间段里,不限次数使用'.tr; + + RxString currentLanguage = + CurrentLocaleTool.getCurrentLocaleString().obs; // 当前选择语言 } diff --git a/lib/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_page.dart b/lib/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_page.dart index 90e4c33e..06efc928 100755 --- a/lib/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_page.dart +++ b/lib/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_page.dart @@ -95,6 +95,9 @@ class _SendEmailNotificationPageState extends State { maxLength: 1000, textAlign: TextAlign.start, controller: state.templateContentController, + keyboardType: TextInputType.multiline, // 多行文本键盘类型 + textInputAction: TextInputAction.done, // 键盘完成按钮 + onEditingComplete: () => FocusScope.of(context).unfocus(), // 点击完成 style: TextStyle( color: Colors.black, fontSize: 22.sp, diff --git a/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart b/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart index bab8f1f0..c8507a3f 100755 --- a/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart +++ b/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart @@ -1,4 +1,3 @@ - import 'dart:async'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; @@ -26,20 +25,23 @@ class AddFingerprintLogic extends BaseGetXController { // 监听设备返回的数据 late StreamSubscription _replySubscription; + void _initReplySubscription() { - _replySubscription = EventBusManager().eventBus!.on().listen((Reply reply) async { + _replySubscription = + EventBusManager().eventBus!.on().listen((Reply reply) async { // 添加指纹开始 - if((reply is SenderAddFingerprintWithTimeCycleCoercionReply) && (state.ifCurrentScreen.value == true)) { + if ((reply is SenderAddFingerprintWithTimeCycleCoercionReply) && + (state.ifCurrentScreen.value == true)) { _replyAddFingerprintBegin(reply); } // 添加指纹过程 - if(reply is SenderAddFingerprintProcessReply) { + if (reply is SenderAddFingerprintProcessReply) { _replyAddFingerprintProcess(reply); } // 添加指纹确认 - if(reply is SenderAddFingerprintConfirmationReply) { + if (reply is SenderAddFingerprintConfirmationReply) { _replyAddFingerprintConfirmation(reply); } }); @@ -49,11 +51,10 @@ class AddFingerprintLogic extends BaseGetXController { BuglyTool.uploadException( message: '添加指纹开始,解析数据', detail: '添加指纹开始,解析数据 _replyAddFingerprintBegin:${reply.data}', - upload: false - ); + upload: false); final int status = reply.data[2]; - switch(status){ + switch (status) { case 0x00: //成功 state.ifConnectScuess.value = true; @@ -67,10 +68,13 @@ class AddFingerprintLogic extends BaseGetXController { break; case 0x06: //无权限 - final List? privateKey = await Storage.getStringList(saveBluePrivateKey); - final List getPrivateKeyList = changeStringListToIntList(privateKey!); + final List? privateKey = + await Storage.getStringList(saveBluePrivateKey); + final List getPrivateKeyList = + changeStringListToIntList(privateKey!); - final List? signKey = await Storage.getStringList(saveBlueSignKey); + final List? signKey = + await Storage.getStringList(saveBlueSignKey); final List signKeyDataList = changeStringListToIntList(signKey!); final List token = reply.data.sublist(5, 9); @@ -78,30 +82,33 @@ class AddFingerprintLogic extends BaseGetXController { Storage.setStringList(saveBlueToken, saveStrList); IoSenderManage.senderAddFingerprintWithTimeCycleCoercionCommand( - keyID:'1', - userID:await Storage.getUid(), - fingerNo:0, - useCountLimit:0xffff, - isForce:state.isCoerced.value == '1' ? 1 : 0, // 是否是胁迫 - isAdmin: state.isAdministrator.value == '2' ? 1 : 0, - operate: 0, - isRound:state.selectType.value == '2' ? 1: 0, // 是否是循环 - weekRound:DateTool().accordingTheCycleIntoTheCorrespondingNumber(state.weekDay.value), // 周循环 - startDate: int.parse(state.startDate.value)~/1000, - endDate: int.parse(state.endDate.value)~/1000, - startTime:DateTool().dateToHNString(state.effectiveDateTime.value), - endTime:DateTool().dateToHNString(state.failureDateTime.value), - needAuthor:1, - signKey:signKeyDataList, - privateKey:getPrivateKeyList, - token: token, - isBeforeAddUser: false - ); + keyID: '1', + userID: await Storage.getUid(), + fingerNo: 0, + useCountLimit: 0xffff, + isForce: state.isCoerced.value == '1' ? 1 : 0, + // 是否是胁迫 + isAdmin: state.isAdministrator.value == '2' ? 1 : 0, + operate: 0, + isRound: state.selectType.value == '2' ? 1 : 0, + // 是否是循环 + weekRound: DateTool().accordingTheCycleIntoTheCorrespondingNumber( + state.weekDay.value), + // 周循环 + startDate: int.parse(state.startDate.value) ~/ 1000, + endDate: int.parse(state.endDate.value) ~/ 1000, + startTime: DateTool().dateToHNString(state.effectiveDateTime.value), + endTime: DateTool().dateToHNString(state.failureDateTime.value), + needAuthor: 1, + signKey: signKeyDataList, + privateKey: getPrivateKeyList, + token: token, + isBeforeAddUser: false); break; default: //失败 state.ifAddState.value = false; - showToast('添加指纹失败'.tr, something: (){ + showToast('添加指纹失败'.tr, something: () { Get.back(); }); break; @@ -112,13 +119,12 @@ class AddFingerprintLogic extends BaseGetXController { BuglyTool.uploadException( message: '添加指纹过程,解析数据', detail: '添加指纹过程,解析数据 _replyAddFingerprintProcess:${reply.data}', - upload: false - ); + upload: false); final int status = reply.data[2]; - switch(status){ + switch (status) { case 0x00: //成功 - switch(reply.data[5]){ + switch (reply.data[5]) { case 0xff: // 注册指纹失败 showToast('退出添加'.tr); @@ -166,35 +172,37 @@ class AddFingerprintLogic extends BaseGetXController { Future _replyAddFingerprintConfirmation(Reply reply) async { final int status = reply.data[2]; final String getMobile = (await Storage.getMobile())!; - switch(status){ + switch (status) { case 0x00: //成功 - // var fingerprintNum = listChangInt(reply.data.sublist(9, 11)).toString(); + // var fingerprintNum = listChangInt(reply.data.sublist(9, 11)).toString(); ApmHelper.instance.trackEvent('add_fingerprint', { - 'lock_name':BlueManage().connectDeviceName, - 'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date':DateTool().getNowDateWithType(1), - 'add_fingerprint_result':'成功', + 'lock_name': BlueManage().connectDeviceName, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'add_fingerprint_result': '成功', }); BuglyTool.uploadException( message: '添加指纹确认结果,解析数据', - detail: '添加指纹确认结果,解析数据 _replyAddFingerprintConfirmation:${reply.data}', - upload: false - ); + detail: + '添加指纹确认结果,解析数据 _replyAddFingerprintConfirmation:${reply.data}', + upload: false); - final List fingerprintList = reply.data.sublist(reply.data.length - 2); + final List fingerprintList = + reply.data.sublist(reply.data.length - 2); final String fingerprintNum = listChangInt(fingerprintList).toString(); state.regIndex.value++; - if(state.fingerprintNumber.value == fingerprintNum){ + if (state.fingerprintNumber.value == fingerprintNum) { return; - }else{ + } else { state.fingerprintNumber.value = fingerprintNum; } // if(state.isCoerced.value == "1"){ - // 调用添加指纹接口 + // 调用添加指纹接口 state.ifAddState.value = false; - addFingerprintsData(); + await addFingerprintsData(); // }else{ // // 如果是胁迫指纹在 添加完之后以后再调用添加胁迫指纹的 // senderAddStressFingerprint(); @@ -203,18 +211,19 @@ class AddFingerprintLogic extends BaseGetXController { default: //失败 ApmHelper.instance.trackEvent('add_fingerprint', { - 'lock_name':BlueManage().connectDeviceName, - 'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date':DateTool().getNowDateWithType(1), - 'add_fingerprint_result':'失败-${reply.data}', + 'lock_name': BlueManage().connectDeviceName, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'add_fingerprint_result': '失败-${reply.data}', }); BuglyTool.uploadException( message: '添加指纹确认结果,解析数据', - detail: '添加指纹确认结果蓝牙返回失败结果,解析数据 _replyAddFingerprintConfirmation:${reply.data}', + detail: + '添加指纹确认结果蓝牙返回失败结果,解析数据 _replyAddFingerprintConfirmation:${reply.data}', eventStr: '添加指纹事件蓝牙返回失败结果', - upload: true - ); + upload: true); state.ifAddState.value = false; break; } @@ -222,7 +231,8 @@ class AddFingerprintLogic extends BaseGetXController { // 添加指纹开始 Future senderAddFingerprint() async { - final List? privateKey = await Storage.getStringList(saveBluePrivateKey); + final List? privateKey = + await Storage.getStringList(saveBluePrivateKey); final List getPrivateKeyList = changeStringListToIntList(privateKey!); final List? signKey = await Storage.getStringList(saveBlueSignKey); @@ -232,90 +242,104 @@ class AddFingerprintLogic extends BaseGetXController { final List getTokenList = changeStringListToIntList(token!); final String command = SenderAddFingerprintWithTimeCycleCoercionCommand( - keyID:'1', - userID:await Storage.getUid(), - fingerNo:0, - useCountLimit:0xffff, - isForce:state.isCoerced.value == '1' ? 1 : 0, // 是否是胁迫 + keyID: '1', + userID: await Storage.getUid(), + fingerNo: 0, + useCountLimit: 0xffff, + isForce: state.isCoerced.value == '1' ? 1 : 0, + // 是否是胁迫 isAdmin: state.isAdministrator.value == '2' ? 1 : 0, operate: 0, - isRound:state.selectType.value == '2' ? 1: 0, // 是否是循环 - weekRound:DateTool().accordingTheCycleIntoTheCorrespondingNumber(state.weekDay.value), // 周循环 - startDate: int.parse(state.startDate.value)~/1000, - endDate: int.parse(state.endDate.value)~/1000, - startTime:DateTool().dateToHNString(state.effectiveDateTime.value), - endTime:DateTool().dateToHNString(state.failureDateTime.value), - needAuthor:1, - signKey:signKeyDataList, - privateKey:getPrivateKeyList, + isRound: state.selectType.value == '2' ? 1 : 0, + // 是否是循环 + weekRound: DateTool() + .accordingTheCycleIntoTheCorrespondingNumber(state.weekDay.value), + // 周循环 + startDate: int.parse(state.startDate.value) ~/ 1000, + endDate: int.parse(state.endDate.value) ~/ 1000, + startTime: DateTool().dateToHNString(state.effectiveDateTime.value), + endTime: DateTool().dateToHNString(state.failureDateTime.value), + needAuthor: 1, + signKey: signKeyDataList, + privateKey: getPrivateKeyList, token: getTokenList, ).toString(); showBlueConnetctToastTimer(action: () async { final String getMobile = (await Storage.getMobile())!; ApmHelper.instance.trackEvent('add_fingerprint', { - 'lock_name':BlueManage().connectDeviceName, - 'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date':DateTool().getNowDateWithType(1), - 'add_fingerprint_result':'超时', + 'lock_name': BlueManage().connectDeviceName, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'add_fingerprint_result': '超时', }); BuglyTool.uploadException( message: '添加指纹超时处理-添加指纹失败', - detail: '添加指纹超时处理,断开连接,添加指纹失败--SenderAddFingerprintWithTimeCycleCoercionCommand:$command', + detail: + '添加指纹超时处理,断开连接,添加指纹失败--SenderAddFingerprintWithTimeCycleCoercionCommand:$command', eventStr: '添加指纹事件超时', - upload: true - ); + upload: true); Get.close(1); }); - BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { - if (deviceConnectionState == BluetoothConnectionState.connected){ - final List? privateKey = await Storage.getStringList(saveBluePrivateKey); - final List getPrivateKeyList = changeStringListToIntList(privateKey!); + BlueManage().blueSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected) { + final List? privateKey = + await Storage.getStringList(saveBluePrivateKey); + final List getPrivateKeyList = + changeStringListToIntList(privateKey!); - final List? signKey = await Storage.getStringList(saveBlueSignKey); + final List? signKey = + await Storage.getStringList(saveBlueSignKey); final List signKeyDataList = changeStringListToIntList(signKey!); final List? token = await Storage.getStringList(saveBlueToken); final List getTokenList = changeStringListToIntList(token!); IoSenderManage.senderAddFingerprintWithTimeCycleCoercionCommand( - keyID:'1', - userID:await Storage.getUid(), - fingerNo:0, - useCountLimit:0xffff, - isForce:state.isCoerced.value == '1' ? 1 : 0, // 是否是胁迫 - isAdmin: state.isAdministrator.value == '2' ? 1 : 0, - operate: 0, - isRound:state.selectType.value == '2' ? 1: 0, // 是否是循环 - weekRound:DateTool().accordingTheCycleIntoTheCorrespondingNumber(state.weekDay.value), // 周循环 - startDate: int.parse(state.startDate.value)~/1000, - endDate: int.parse(state.endDate.value)~/1000, - startTime:DateTool().dateToHNString(state.effectiveDateTime.value), - endTime:DateTool().dateToHNString(state.failureDateTime.value), - needAuthor:1, - signKey:signKeyDataList, - privateKey:getPrivateKeyList, - token: getTokenList, - isBeforeAddUser: false - ); - }else if (deviceConnectionState == BluetoothConnectionState.disconnected){ + keyID: '1', + userID: await Storage.getUid(), + fingerNo: 0, + useCountLimit: 0xffff, + isForce: state.isCoerced.value == '1' ? 1 : 0, + // 是否是胁迫 + isAdmin: state.isAdministrator.value == '2' ? 1 : 0, + operate: 0, + isRound: state.selectType.value == '2' ? 1 : 0, + // 是否是循环 + weekRound: DateTool().accordingTheCycleIntoTheCorrespondingNumber( + state.weekDay.value), + // 周循环 + startDate: int.parse(state.startDate.value) ~/ 1000, + endDate: int.parse(state.endDate.value) ~/ 1000, + startTime: DateTool().dateToHNString(state.effectiveDateTime.value), + endTime: DateTool().dateToHNString(state.failureDateTime.value), + needAuthor: 1, + signKey: signKeyDataList, + privateKey: getPrivateKeyList, + token: getTokenList, + isBeforeAddUser: false); + } else if (deviceConnectionState == + BluetoothConnectionState.disconnected) { final String getMobile = (await Storage.getMobile())!; ApmHelper.instance.trackEvent('add_fingerprint', { - 'lock_name':BlueManage().connectDeviceName, - 'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date':DateTool().getNowDateWithType(1), - 'add_fingerprint_result':'断开', + 'lock_name': BlueManage().connectDeviceName, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'add_fingerprint_result': '断开', }); BuglyTool.uploadException( message: '添加指纹断开连接-添加指纹失败', - detail: '添加指纹断开连接-添加指纹失败--SenderAddFingerprintWithTimeCycleCoercionCommand:$command', + detail: + '添加指纹断开连接-添加指纹失败--SenderAddFingerprintWithTimeCycleCoercionCommand:$command', eventStr: '添加指纹事件断开连接', - upload: true - ); + upload: true); - if(state.ifCurrentScreen.value == true){ + if (state.ifCurrentScreen.value == true) { showBlueConnetctToast(); } cancelBlueConnetctToastTimer(); @@ -326,27 +350,32 @@ class AddFingerprintLogic extends BaseGetXController { // 取消添加指纹 Future senderCancelAddFingerprintCommand() async { - BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { - if (deviceConnectionState == BluetoothConnectionState.connected){ - final List? privateKey = await Storage.getStringList(saveBluePrivateKey); - final List getPrivateKeyList = changeStringListToIntList(privateKey!); + BlueManage().blueSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected) { + final List? privateKey = + await Storage.getStringList(saveBluePrivateKey); + final List getPrivateKeyList = + changeStringListToIntList(privateKey!); - final List? signKey = await Storage.getStringList(saveBlueSignKey); + final List? signKey = + await Storage.getStringList(saveBlueSignKey); final List signKeyDataList = changeStringListToIntList(signKey!); final List? token = await Storage.getStringList(saveBlueToken); final List getTokenList = changeStringListToIntList(token!); IoSenderManage.senderCancelAddFingerprintCommand( - keyID:'1', - userID:await Storage.getUid(), - needAuthor:1, - signKey:signKeyDataList, - privateKey:getPrivateKeyList, + keyID: '1', + userID: await Storage.getUid(), + needAuthor: 1, + signKey: signKeyDataList, + privateKey: getPrivateKeyList, token: getTokenList, ); - }else if (deviceConnectionState == BluetoothConnectionState.disconnected){ - if(state.ifCurrentScreen.value == true){ + } else if (deviceConnectionState == + BluetoothConnectionState.disconnected) { + if (state.ifCurrentScreen.value == true) { showBlueConnetctToast(); } cancelBlueConnetctToastTimer(); @@ -356,53 +385,54 @@ class AddFingerprintLogic extends BaseGetXController { } // 添加指纹 - Future addFingerprintsData() async{ - final AddFingerprintEntity entity = await ApiRepository.to.addFingerprintsData( + Future addFingerprintsData() async { + final AddFingerprintEntity entity = + await ApiRepository.to.addFingerprintsData( lockId: state.lockId.value.toString(), endDate: state.endDate.value, - addType:state.addType.value, + addType: state.addType.value, fingerprintName: state.fingerprintName.value, fingerprintNumber: state.fingerprintNumber.value, fingerprintType: state.fingerprintType.value, isCoerced: state.isCoerced.value, startDate: state.startDate.value, weekDay: state.weekDay.value, - fingerRight:state.isAdministrator.value == '2' ? 1 : 0, + fingerRight: state.isAdministrator.value == '2' ? 1 : 0, startTime: int.parse(state.effectiveDateTime.value), endTime: int.parse(state.failureDateTime.value), ); - if(entity.errorCode!.codeIsSuccessful){ + if (entity.errorCode!.codeIsSuccessful) { updateFingerprintUserNoLoadData(entity.data!.fingerprintId.toString()); BuglyTool.uploadException( message: '添加指纹调用接口成功', detail: '添加指纹调用接口成功', eventStr: '添加指纹事件用接口成功', - upload: true - ); - }else{ + upload: true); + } else { updateFingerprintUserNoLoadData(entity.data!.fingerprintId.toString()); BuglyTool.uploadException( message: '添加指纹调用接口失败', detail: '添加指纹调用接口添加指纹调用接口失败 - ${entity.errorMsg}', eventStr: '添加指纹事件接口失败', - upload: true - ); + upload: true); } } // 更新指纹用户账号 - Future updateFingerprintUserNoLoadData(String fingerprintId) async{ - final LoginEntity entity = await ApiRepository.to.updateFingerprintUserNoLoadData( - fingerprintId: fingerprintId, - lockId: state.lockId.value.toString(), - fingerprintUserNo: state.fingerprintNumber.value, + Future updateFingerprintUserNoLoadData(String fingerprintId) async { + final LoginEntity entity = + await ApiRepository.to.updateFingerprintUserNoLoadData( + fingerprintId: fingerprintId, + lockId: state.lockId.value.toString(), + fingerprintUserNo: state.fingerprintNumber.value, ); - if(entity.errorCode!.codeIsSuccessful){ - showToast('添加成功'.tr, something: (){ - if(state.fromType.value == 2){ + if (entity.errorCode!.codeIsSuccessful) { + showToast('添加成功'.tr, something: () { + if (state.fromType.value == 2) { // 回调指纹号 - eventBus.fire(ChickInAddStaffCardAndFingerprintBlockNumberEvent(state.fingerprintNumber.value)); - }else if(state.fromType.value == 1){ + eventBus.fire(ChickInAddStaffCardAndFingerprintBlockNumberEvent( + state.fingerprintNumber.value)); + } else if (state.fromType.value == 1) { eventBus.fire(OtherTypeRefreshListEvent()); } Get.close(2); @@ -430,5 +460,4 @@ class AddFingerprintLogic extends BaseGetXController { _replySubscription.cancel(); } - -} \ No newline at end of file +} diff --git a/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_logic.dart b/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_logic.dart index 37d56740..09523db0 100755 --- a/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_logic.dart +++ b/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_logic.dart @@ -23,6 +23,7 @@ class FingerprintListLogic extends BaseGetXController { // 获取解析后的数据 late StreamSubscription _replySubscription; + void _initReplySubscription() { _replySubscription = EventBusManager().eventBus!.on().listen((Reply reply) { @@ -74,11 +75,15 @@ class FingerprintListLogic extends BaseGetXController { userID: (await Storage.getUid())!, fingerNo: state.deletFingerNo, useCountLimit: 0xffff, - operate: state.isDeletAll == true ? 3 : 2, // 0:注册 1:修改 2:删除 3:删除全部 + operate: state.isDeletAll == true ? 3 : 2, + // 0:注册 1:修改 2:删除 3:删除全部 isAdmin: 0, - isForce: 0, // 是否是胁迫 - isRound: 0, // 是否是循环 - weekRound: 0, // 周循环 + isForce: 0, + // 是否是胁迫 + isRound: 0, + // 是否是循环 + weekRound: 0, + // 周循环 startDate: 0x11223344, endDate: 0x11223344, startTime: '0', @@ -275,11 +280,15 @@ class FingerprintListLogic extends BaseGetXController { userID: (await Storage.getUid())!, fingerNo: state.deletFingerNo, useCountLimit: 0xffff, - operate: state.isDeletAll == true ? 3 : 2, // 0:注册 1:修改 2:删除 3:删除全部 + operate: state.isDeletAll == true ? 3 : 2, + // 0:注册 1:修改 2:删除 3:删除全部 isAdmin: 0, - isForce: 0, // 是否是胁迫 - isRound: 0, // 是否是循环 - weekRound: 0, // 周循环 + isForce: 0, + // 是否是胁迫 + isRound: 0, + // 是否是循环 + weekRound: 0, + // 周循环 startDate: 0x11223344, endDate: 0x11223344, startTime: '0', @@ -299,30 +308,31 @@ class FingerprintListLogic extends BaseGetXController { } }); } + /** * //请求密码钥匙列表 - Future mockNetworkDataRequest( + Future mockNetworkDataRequest( {required bool isRefresh}) async { - // 如果是下拉刷新,清空已有数据 - if (isRefresh) { + // 如果是下拉刷新,清空已有数据 + if (isRefresh) { state.itemDataList.clear(); pageNo = 1; - } + } - final PasswordKeyListEntity entity = await ApiRepository.to.passwordKeyList( - state.keyInfo.value.keyStatus.toString(), - state.keyInfo.value.lockId.toString(), - pageNo.toString(), - pageSize.toString(), - state.searchController.text); - if (entity.errorCode!.codeIsSuccessful) { + final PasswordKeyListEntity entity = await ApiRepository.to.passwordKeyList( + state.keyInfo.value.keyStatus.toString(), + state.keyInfo.value.lockId.toString(), + pageNo.toString(), + pageSize.toString(), + state.searchController.text); + if (entity.errorCode!.codeIsSuccessful) { // 更新数据列表 state.itemDataList.addAll(entity.data!.itemList!); // 更新页码 pageNo++; - } - return entity; - } + } + return entity; + } */ @@ -390,6 +400,7 @@ class FingerprintListLogic extends BaseGetXController { // 监听修改完详情之后刷新列表 late StreamSubscription _teamEvent; + void _initRefreshAction() { _teamEvent = eventBus .on() @@ -450,6 +461,7 @@ class FingerprintListLogic extends BaseGetXController { _initReplySubscription(); _initRefreshAction(); + getFingerprintsListData(isRefresh: true); } } diff --git a/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart b/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart index acfb8e9a..15c16dbd 100755 --- a/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart +++ b/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart @@ -31,24 +31,9 @@ class _FingerprintListPageState extends State final FingerprintListLogic logic = Get.put(FingerprintListLogic()); final FingerprintListState state = Get.find().state; - Future getHttpData({required bool isRefresh}) async { - final bool? isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); - if (isDemoMode == false) { - logic - .getFingerprintsListData(isRefresh: isRefresh) - .then((FingerprintListDataEntity value) { - if (mounted) { - setState(() {}); - } - }); - } - } - @override void initState() { super.initState(); - - getHttpData(isRefresh: true); } @override @@ -91,17 +76,17 @@ class _FingerprintListPageState extends State ), body: EasyRefreshTool( onRefresh: () { - getHttpData(isRefresh: true); + logic.getFingerprintsListData(isRefresh: true); }, onLoad: () { - getHttpData(isRefresh: false); + logic.getFingerprintsListData(isRefresh: false); }, child: Column( children: [ KeySearchWidget( editingController: state.searchController, - onSubmittedAction: () { - getHttpData(isRefresh: true); + onSubmittedAction: () async { + await logic.getFingerprintsListData(isRefresh: true); }, ), SizedBox( @@ -116,7 +101,8 @@ class _FingerprintListPageState extends State 'lockId': state.lockId.value, 'fromType': 1 // 1从添加钥匙列表进入 2从考勤添加员工入口进入 })! - .then((value) => getHttpData(isRefresh: true)); + .then((value) => + logic.getFingerprintsListData(isRefresh: true)); // if (data != null) { // getHttpData(isRefresh: true); // } @@ -179,7 +165,7 @@ class _FingerprintListPageState extends State 'fingerprintItemData': fingerprintItemData, })! .then((value) { - getHttpData(isRefresh: true); + logic.getFingerprintsListData(isRefresh: true); }); // if (data == 'deletScuess') { // // state.fingerprintItemListData.removeWhere((FingerprintItemData item) => item.fingerprintId == fingerprintItemData.fingerprintId!); diff --git a/lib/main/lockDetail/lockDetail/lockDetail_logic.dart b/lib/main/lockDetail/lockDetail/lockDetail_logic.dart index 13a1a87e..9ee17ec3 100755 --- a/lib/main/lockDetail/lockDetail/lockDetail_logic.dart +++ b/lib/main/lockDetail/lockDetail/lockDetail_logic.dart @@ -344,38 +344,43 @@ class LockDetailLogic extends BaseGetXController { final List uploadList = []; for (int i = 0; i < getList.length; i++) { final List indexList = getList[i]; - AppLog.log('indexList:$indexList'); - final Map indexMap = {}; - indexMap['type'] = indexList[0].toString(); + try { + AppLog.log('indexList:$indexList'); + final Map indexMap = {}; + indexMap['type'] = indexList[0].toString(); - final int userNo = (indexList[1] * 256) + indexList[2]; - indexMap['user'] = userNo.toString(); - // AppLog.log('userNouserNouserNouserNo:$userNo'); + final int userNo = (indexList[1] * 256) + indexList[2]; + indexMap['user'] = userNo.toString(); + // AppLog.log('userNouserNouserNouserNo:$userNo'); - final List passwordData = indexList.sublist(7, 17); - final String password = utf8String(passwordData); - indexMap['password'] = password.toString(); - // AppLog.log('passwordpasswordpassword:$password'); + final List passwordData = indexList.sublist(7, 17); + final String password = utf8String(passwordData); + indexMap['password'] = password.toString(); + // AppLog.log('passwordpasswordpassword:$password'); - indexMap['success'] = '1'; + indexMap['success'] = '1'; - final int time = (0xff & indexList[3]) << 24 | - (0xff & indexList[4]) << 16 | - (0xff & indexList[5]) << 8 | - (0xFF & indexList[6]); - int operateDate = time * 1000; - if (DateTime.fromMillisecondsSinceEpoch(operateDate).isAfter( - DateTime.fromMillisecondsSinceEpoch(getUTCNetTime() * 1000))) { - continue; - } + final int time = (0xff & indexList[3]) << 24 | + (0xff & indexList[4]) << 16 | + (0xff & indexList[5]) << 8 | + (0xFF & indexList[6]); + int operateDate = time * 1000; + if (DateTime.fromMillisecondsSinceEpoch(operateDate).isAfter( + DateTime.fromMillisecondsSinceEpoch( + getUTCNetTime() * 1000))) { + continue; + } - indexMap['date'] = '$operateDate'; - uploadList.add(indexMap); + indexMap['date'] = '$operateDate'; + uploadList.add(indexMap); - if (i == getList.length - 1) { - //设置最后的时间戳 + if (i == getList.length - 1) { + //设置最后的时间戳 - state.operateDate = operateDate; + state.operateDate = operateDate; + } + } catch (e) { + AppLog.log('操作记录:$indexList,解析失败,跳过该跳记录,进行下一条记录解析。'); } } lockRecordUploadData(uploadList); diff --git a/lib/main/lockDetail/lockDetail/lockDetail_page.dart b/lib/main/lockDetail/lockDetail/lockDetail_page.dart index d6740553..3d0e818a 100755 --- a/lib/main/lockDetail/lockDetail/lockDetail_page.dart +++ b/lib/main/lockDetail/lockDetail/lockDetail_page.dart @@ -55,7 +55,19 @@ class _LockDetailPageState extends State void initState() { super.initState(); - listeningAnimations(); + state.animationController = + AnimationController(duration: const Duration(seconds: 1), vsync: this); + state.animationController!.repeat(); + //动画开始、结束、向前移动或向后移动时会调用StatusListener + state.animationController!.addStatusListener((AnimationStatus status) { + if (status == AnimationStatus.completed) { + state.animationController!.reset(); + state.animationController!.forward(); + } else if (status == AnimationStatus.dismissed) { + state.animationController!.reset(); + state.animationController!.forward(); + } + }); state.pageController.addListener(() { state.currentPage.value = state.pageController.page!.round(); @@ -1250,16 +1262,13 @@ class _LockDetailPageState extends State SizedBox( width: 42.w, height: 42.h, - child: FlavorsImg( - black: true, - child: Image.asset(iconUrl, - width: 42.w, - height: 42.w, - color: bottomBtnisEable - ? AppColors.mainColor - : AppColors.lockDetailBottomBtnUneable, - fit: BoxFit.fitWidth), - ), + child: Image.asset(iconUrl, + width: 42.w, + height: 42.w, + color: bottomBtnisEable + ? AppColors.mainColor + : AppColors.lockDetailBottomBtnUneable, + fit: BoxFit.fitWidth), ), SizedBox(height: 5.h), Expanded( @@ -1283,16 +1292,13 @@ class _LockDetailPageState extends State SizedBox( width: 42.w, height: 42.w, - child: FlavorsImg( - black: true, - child: Image.asset(iconUrl, - width: 42.w, - height: 42.w, - color: bottomBtnisEable - ? AppColors.mainColor - : AppColors.lockDetailBottomBtnUneable, - fit: BoxFit.fitWidth), - ), + child: Image.asset(iconUrl, + width: 42.w, + height: 42.w, + color: bottomBtnisEable + ? AppColors.mainColor + : AppColors.lockDetailBottomBtnUneable, + fit: BoxFit.fitWidth), ), SizedBox(height: 15.h), Text( @@ -1321,24 +1327,6 @@ class _LockDetailPageState extends State ); } - Future listeningAnimations() async { - await Future.delayed(Duration.zero, () { - state.animationController = AnimationController( - duration: const Duration(seconds: 1), vsync: this); - state.animationController!.repeat(); - //动画开始、结束、向前移动或向后移动时会调用StatusListener - state.animationController!.addStatusListener((AnimationStatus status) { - if (status == AnimationStatus.completed) { - state.animationController!.reset(); - state.animationController!.forward(); - } else if (status == AnimationStatus.dismissed) { - state.animationController!.reset(); - state.animationController!.forward(); - } - }); - }); - } - String showElectricIcon(int electricnumber) { if (electricnumber >= 100) { return 'images/main/icon_lockElectricLevel_5.png'; diff --git a/lib/main/lockDetail/lockSet/catEyeSet/catEyeCustomMode/catEyeCustomMode_page.dart b/lib/main/lockDetail/lockSet/catEyeSet/catEyeCustomMode/catEyeCustomMode_page.dart index 45fed154..6e472015 100755 --- a/lib/main/lockDetail/lockSet/catEyeSet/catEyeCustomMode/catEyeCustomMode_page.dart +++ b/lib/main/lockDetail/lockSet/catEyeSet/catEyeCustomMode/catEyeCustomMode_page.dart @@ -48,9 +48,18 @@ class _CatEyeCustomModePageState extends State { isHaveLine: false, isHaveDirection: true, isHaveRightWidget: true, - rightWidget: Text(state.selectVideoSlot.value, + rightWidget: Container( + constraints: BoxConstraints(maxWidth: 150.w), // 限制最大宽度 + child: Text( + state.selectVideoSlot.value, style: TextStyle( - fontSize: 22.sp, color: AppColors.darkGrayTextColor)), + fontSize: 22.sp, color: AppColors.darkGrayTextColor), + textAlign: TextAlign.right, // 右对齐 + softWrap: true, // 允许换行 + maxLines: 2, + overflow: TextOverflow.ellipsis, // 文本溢出时显示 + ), + ), action: () { Navigator.pushNamed(context, Routers.videoSlotPage, arguments: { diff --git a/lib/main/lockDetail/lockSet/catEyeSet/catEyeWorkMode/catEyeWorkMode_page.dart b/lib/main/lockDetail/lockSet/catEyeSet/catEyeWorkMode/catEyeWorkMode_page.dart index 61052c00..66d15f9a 100755 --- a/lib/main/lockDetail/lockSet/catEyeSet/catEyeWorkMode/catEyeWorkMode_page.dart +++ b/lib/main/lockDetail/lockSet/catEyeSet/catEyeWorkMode/catEyeWorkMode_page.dart @@ -37,48 +37,50 @@ class _CatEyeWorkModePageState extends State { Navigator.pop(context, true); }, backgroundColor: AppColors.mainColor), - body: Obx( - () => Column( - children: [ - SizedBox( - height: 30.h, - ), - _buildTipsView( - '省电模式'.tr + ':\n', - '适合门口较为安全的环境。'.tr + - '\n' + - '仅发生特定事件才录像,并可查看实时画面。'.tr + - '\n' + - '一般情况下,满电可使用7-8个月'.tr, - 0), - SizedBox( - height: 30.h, - ), - _buildTipsView( - '逗留抓拍模式'.tr + ':\n', - '有人逗留或发生特定事件才录像,可随时查看'.tr + - '\n' + - '实时画面。'.tr + - '\n' + - '一般情况下,满电可使用5~6个月。'.tr, - 1), - SizedBox( - height: 30.h, - ), - _buildTipsView( - '实时监控模式'.tr + ':\n', - '适合门口人员复杂、较不安全的环境。'.tr + - '\n' + - '有人出现就录像,可随时查看实时画面。'.tr + - '\n' + - '一般情况下,满电可使用2~4个月。'.tr, - 2), - SizedBox( - height: 30.h, - ), - _buildTipsView('自定义模式'.tr + ':\n', - '根据您家门口实际情况设置录像和实时画面功能。'.tr + '\n' + '可使用时长由具体设置决定。'.tr, 3) - ], + body: SingleChildScrollView( + child: Obx( + () => Column( + children: [ + SizedBox( + height: 30.h, + ), + _buildTipsView( + '省电模式'.tr + ':\n', + '适合门口较为安全的环境。'.tr + + '\n' + + '仅发生特定事件才录像,并可查看实时画面。'.tr + + '\n' + + '一般情况下,满电可使用7-8个月'.tr, + 0), + SizedBox( + height: 30.h, + ), + _buildTipsView( + '逗留抓拍模式'.tr + ':\n', + '有人逗留或发生特定事件才录像,可随时查看'.tr + + '\n' + + '实时画面。'.tr + + '\n' + + '一般情况下,满电可使用5~6个月。'.tr, + 1), + SizedBox( + height: 30.h, + ), + _buildTipsView( + '实时监控模式'.tr + ':\n', + '适合门口人员复杂、较不安全的环境。'.tr + + '\n' + + '有人出现就录像,可随时查看实时画面。'.tr + + '\n' + + '一般情况下,满电可使用2~4个月。'.tr, + 2), + SizedBox( + height: 30.h, + ), + _buildTipsView('自定义模式'.tr + ':\n', + '根据您家门口实际情况设置录像和实时画面功能。'.tr + '\n' + '可使用时长由具体设置决定。'.tr, 3) + ], + ), ), ), ); @@ -121,13 +123,14 @@ class _CatEyeWorkModePageState extends State { ), GestureDetector( child: Container( - width: 90.w, - height: 40.h, + padding: EdgeInsets.all(8.w), decoration: BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.circular(15.0), border: Border.all( - color: AppColors.placeholderTextColor, width: 1.w), + color: AppColors.placeholderTextColor, + width: 1.w, + ), ), child: Center( child: Text( diff --git a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart index 1ed6f736..4373a087 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart @@ -12,6 +12,7 @@ import 'package:star_lock/appRouters.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart'; import 'package:star_lock/blue/io_gateway/io_gateway_getStatus.dart'; +import 'package:star_lock/blue/io_protocol/io_updataLockSet.dart'; import 'package:star_lock/login/login/entity/LoginEntity.dart'; import 'package:star_lock/main/lockDetail/lockDetail/device_network_info.dart'; import 'package:star_lock/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifiEntity.dart'; @@ -20,6 +21,7 @@ import 'package:star_lock/mine/gateway/addGateway/selectGateway/getGatewayInfo_m import 'package:star_lock/talk/starChart/entity/star_chart_register_node_entity.dart'; import 'package:star_lock/talk/starChart/star_chart_manage.dart'; import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/commonDataManage.dart'; import '../../../../../blue/blue_manage.dart'; import '../../../../../blue/io_protocol/io_configuringWifi.dart'; @@ -59,7 +61,8 @@ class ConfiguringWifiLogic extends BaseGetXController { peerId: peerId, ); if (entity.errorCode!.codeIsSuccessful) { - showToast('配网成功'.tr, something: () { + await _getUploadLockSet(); + showToast('配网成功'.tr, something: () async { eventBus .fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value)); // 设置锁的peerID @@ -69,17 +72,6 @@ class ConfiguringWifiLogic extends BaseGetXController { secretKey: secretKey, peerId: peerId, ); - - if (state.pageName.value == 'lockSet') { - Get.close(2); - } else { - Get.offAllNamed(Routers.starLockMain); - } - dismissEasyLoading(); - if (state.loadingTimer != null) { - state.loadingTimer!.cancel(); - state.loadingTimer = null; - } }); } } @@ -101,6 +93,10 @@ class ConfiguringWifiLogic extends BaseGetXController { if (reply is GatewayGetStatusReply) { _replyStatusInfo(reply); } + // 上传数据获取锁设置 + if (reply is UpdataLockSetReply) { + _replyUpdataLockSetReply(reply); + } AppLog.log('蓝牙回调处理完毕${EasyLoading.isShow}'); }); } @@ -389,6 +385,100 @@ class ConfiguringWifiLogic extends BaseGetXController { void _replyStatusInfo(reply) {} + // 上传数据获取设置 + Future _getUploadLockSet() async { + showEasyLoading(); + showBlueConnetctToastTimer(action: () { + dismissEasyLoading(); + }); + BlueManage().blueSendData(BlueManage().connectDeviceName, + (BluetoothConnectionState connectionState) async { + if (connectionState == BluetoothConnectionState.connected) { + final List? token = await Storage.getStringList(saveBlueToken); + final List getTokenList = changeStringListToIntList(token!); + + _uploadLockSet(getTokenList); + } else if (connectionState == BluetoothConnectionState.disconnected) { + cancelBlueConnetctToastTimer(); + if (state.ifCurrentScreen.value == true) { + showBlueConnetctToast(); + } + } + }); + } + + // 公共的上传锁设置 + Future _uploadLockSet(List token) async { + final List? privateKey = + await Storage.getStringList(saveBluePrivateKey); + final List getPrivateKeyList = changeStringListToIntList(privateKey!); + + final List? signKey = await Storage.getStringList(saveBlueSignKey); + final List signKeyDataList = changeStringListToIntList(signKey!); + + IoSenderManage.updataLockSetCommand( + lockID: BlueManage().connectDeviceName, + userID: await Storage.getUid(), + token: token, + needAuthor: 1, + signKey: signKeyDataList, + privateKey: getPrivateKeyList); + } + + // 上传数据获取锁设置解析 + Future _replyUpdataLockSetReply(Reply reply) async { + final int status = reply.data[2]; + switch (status) { + case 0x00: + //成功 + dismissEasyLoading(); + cancelBlueConnetctToastTimer(); + _lockDataUpload( + uploadType: 1, + recordType: 0, + records: reply.data.sublist(7, reply.data.length)); + break; + case 0x06: + //无权限 + final List token = reply.data.sublist(3, 7); + final List saveStrList = changeIntListToStringList(token); + Storage.setStringList(saveBlueToken, saveStrList); + + _uploadLockSet(token); + break; + default: + dismissEasyLoading(); + cancelBlueConnetctToastTimer(); + break; + } + } + + // 锁数据上传服务器 + Future _lockDataUpload( + {required int uploadType, + required int recordType, + required List records}) async { + final LoginEntity entity = await ApiRepository.to.lockDataUpload( + lockId: state.lockBasicInfo.value.lockId ?? -1, + uploadType: uploadType, + recordType: recordType, + records: records, + isUnShowLoading: true); + if (entity.errorCode!.codeIsSuccessful) { + await Future.delayed((Duration(seconds: 1))); + if (state.pageName.value == 'lockSet') { + Get.close(2); + } else { + Get.offAllNamed(Routers.starLockMain); + } + dismissEasyLoading(); + if (state.loadingTimer != null) { + state.loadingTimer!.cancel(); + state.loadingTimer = null; + } + } + } + @override void dispose() { // TODO: implement dispose diff --git a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart index 89ea1ee1..ed653308 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart @@ -44,12 +44,28 @@ class _ConfiguringWifiPageState extends State SizedBox( height: 50.h, ), - SubmitBtn( - btnName: '确定'.tr, - onClick: () { - FocusScope.of(context).requestFocus(FocusNode()); - logic.senderConfiguringWifiAction(); - }, + Obx( + () => SubmitBtn( + btnName: '确定'.tr, + isDisabled: state.isLoading.isFalse, + onClick: state.isLoading.isTrue + ? null + : () { + FocusScope.of(context).requestFocus(FocusNode()); + logic.senderConfiguringWifiAction(); + }, + ), + ), + SizedBox( + height: 20.h, + ), + Text( + '请确保网络是2.4GHz Wi-Fi'.tr, + style: TextStyle( + color: AppColors.blackColor, + fontSize: 20.sp, + fontWeight: FontWeight.w500, + ), ), ], )); diff --git a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart index 1a090780..513fede2 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart @@ -1,13 +1,13 @@ - import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:network_info_plus/network_info_plus.dart'; import '../../lockSet/lockSetInfo_entity.dart'; import 'configuringWifiEntity.dart'; -class ConfiguringWifiState{ +class ConfiguringWifiState { ConfiguringWifiState() { var map = Get.arguments; lockSetInfoData.value = map['lockSetInfoData']; @@ -18,6 +18,7 @@ class ConfiguringWifiState{ wifiNameController.text = wifiName.value; } } + Rx configuringWifiEntity = ConfiguringWifiEntity().obs; Rx lockSetInfoData = LockSetInfoData().obs; Rx lockBasicInfo = LockBasicInfo().obs; @@ -25,12 +26,12 @@ class ConfiguringWifiState{ RxString wifiName = ''.obs; RxString pageName = ''.obs; RxBool ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 - RxInt sureBtnState = 0.obs;// 0普通状态(可用) 1连接中(不可用) + RxInt sureBtnState = 0.obs; // 0普通状态(可用) 1连接中(不可用) TextEditingController wifiNameController = TextEditingController(); TextEditingController wifiPWDController = TextEditingController(); String getGatewayConfigurationStr = ''; - RxBool isLoading=false.obs; + RxBool isLoading = false.obs; Timer? loadingTimer; -} \ No newline at end of file +} diff --git a/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart b/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart index d00e360d..2508cc27 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:network_info_plus/network_info_plus.dart'; import 'package:star_lock/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_state.dart'; import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart'; @@ -91,11 +92,23 @@ class _WifiListPageState extends State { fontSize: 28.sp, borderRadius: 20.w, padding: EdgeInsets.only(top: 25.w, bottom: 25.w), - onClick: () { - Get.toNamed(Routers.configuringWifiPage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value, - 'pageName': state.pageName.value, - }); + onClick: () async { + // 如果没有传wifi昵称,则使用当前系统连接的wifi + final info = NetworkInfo(); + + final wifiName = + (await info.getWifiName())?.replaceAll('"', '') ?? ''; + + // 判断是否为5G WiFi + if (wifiName.toLowerCase().contains('5g')) { + logic.showToast('请将手机切换至2.4G WiFi进行手动连接'.tr); + } else { + Get.toNamed(Routers.configuringWifiPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value, + 'pageName': state.pageName.value, + 'wifiName': wifiName, + }); + } }, ), SizedBox( diff --git a/lib/main/lockDetail/lockSet/liveVideo/liveVideo_page.dart b/lib/main/lockDetail/lockSet/liveVideo/liveVideo_page.dart index d07a8e5c..2f10c0a2 100755 --- a/lib/main/lockDetail/lockSet/liveVideo/liveVideo_page.dart +++ b/lib/main/lockDetail/lockSet/liveVideo/liveVideo_page.dart @@ -28,7 +28,7 @@ class _LiveVideoPageState extends State { return Scaffold( backgroundColor: AppColors.mainBackgroundColor, appBar: TitleAppBar( - barTitle: '实时画面', + barTitle: '实时画面'.tr, haveBack: true, backAction: () { Navigator.pop(context, true); diff --git a/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart b/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart index a0011308..4d8fac0e 100755 --- a/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart +++ b/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart @@ -362,7 +362,8 @@ class _LockSetPageState extends State //todo: 双重认证、双锁联动国际化、API接口 //双重认证 Obx(() => Visibility( - visible: true, + //state.lockFeature.value.doubleAuthentication == 1, + visible: false, child: CommonItem( leftTitel: '双重认证'.tr, rightTitle: '', diff --git a/lib/main/lockDetail/lockSet/lockTime/lockTime_logic.dart b/lib/main/lockDetail/lockSet/lockTime/lockTime_logic.dart index 6396bee5..bb2e9962 100755 --- a/lib/main/lockDetail/lockSet/lockTime/lockTime_logic.dart +++ b/lib/main/lockDetail/lockSet/lockTime/lockTime_logic.dart @@ -50,10 +50,25 @@ class LockTimeLogic extends BaseGetXController { // 有效时间 final List indate = reply.data.sublist(150, 154); - final int indateValue = (0xff & indate[0]) << 24 | + int indateValue = (0xff & indate[0]) << 24 | (0xff & indate[1]) << 16 | (0xff & indate[2]) << 8 | (0xFF & indate[3]); + // 检查时间戳是否无效或超出范围 + if (indateValue == 0xffffffff || indateValue <= 0) { + // 使用当前系统时间戳(秒) + indateValue = DateTime.now().millisecondsSinceEpoch ~/ 1000; + AppLog.log('检测到无效时间戳,使用系统时间:$indateValue'); + } + + // 验证时间戳是否在合理范围内(例如:2000年到2100年之间) + final DateTime dateTime = + DateTime.fromMillisecondsSinceEpoch(indateValue * 1000); + if (dateTime.year < 2000 || dateTime.year > 2100) { + AppLog.log('时间戳超出合理范围: $indateValue'); + indateValue = DateTime.now().millisecondsSinceEpoch ~/ 1000; + } + AppLog.log( '====================indate:$indate indateValue:$indateValue'); state.dateTime.value = DateTool().dateToYMDHNString('$indateValue'); @@ -86,11 +101,9 @@ class LockTimeLogic extends BaseGetXController { switch (status) { case 0x00: //成功 - // final String dataEime = - // DateTool().dateToYMDHNString('${state.serverTime}'); + final String dataEime = + DateTool().dateToYMDHNString('${state.serverTime}'); - final String dataEime = DateTool().dateToYMDHNString( - '${DateTime.now().millisecondsSinceEpoch ~/ 1000}'); state.dateTime.value = dataEime; state.sureBtnState.value = 0; diff --git a/lib/main/lockDetail/lockSet/motorPower/motorPower_logic.dart b/lib/main/lockDetail/lockSet/motorPower/motorPower_logic.dart index 44b72e64..79f860ea 100755 --- a/lib/main/lockDetail/lockSet/motorPower/motorPower_logic.dart +++ b/lib/main/lockDetail/lockSet/motorPower/motorPower_logic.dart @@ -30,9 +30,10 @@ class MotorPowerLogic extends BaseGetXController { state.lockSetInfoData.value.lockSettingInfo!.openDirectionValue = state.motorTorsion.value; - eventBus - .fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value)); - showToast('操作成功'.tr); + showToast('操作成功'.tr, something: () { + eventBus + .fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value)); + }); } } @@ -80,6 +81,7 @@ class MotorPowerLogic extends BaseGetXController { switch (status) { case 0x00: //成功 + cancelBlueConnetctToastTimer(); _setLockSetGeneralSetting(); break; case 0x06: @@ -123,6 +125,10 @@ class MotorPowerLogic extends BaseGetXController { // 设置支持功能(带参数) Future sendOpenDoorDirection() async { + showEasyLoading(); + showBlueConnetctToastTimer(action: () { + dismissEasyLoading(); + }); BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState connectionState) async { if (connectionState == BluetoothConnectionState.connected) { @@ -149,6 +155,10 @@ class MotorPowerLogic extends BaseGetXController { needAuthor: 1, publicKey: getPublicKeyList, privateKey: getPrivateKeyList); + } else if (connectionState == BluetoothConnectionState.disconnected) { + dismissEasyLoading(); + cancelBlueConnetctToastTimer(); + showBlueConnetctToast(); } }); } diff --git a/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_page.dart b/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_page.dart index 3489df75..b18d0286 100755 --- a/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_page.dart +++ b/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_page.dart @@ -1,4 +1,4 @@ - +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -19,7 +19,8 @@ class RemoteUnlockingPage extends StatefulWidget { State createState() => _RemoteUnlockingPageState(); } -class _RemoteUnlockingPageState extends State with RouteAware { +class _RemoteUnlockingPageState extends State + with RouteAware { final RemoteUnlockingLogic logic = Get.put(RemoteUnlockingLogic()); final RemoteUnlockingState state = Get.find().state; @@ -34,13 +35,14 @@ class _RemoteUnlockingPageState extends State with RouteAwa body: Container( padding: EdgeInsets.all(30.w), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( child: Text( - '功能开启后,你将可以通过网关远程开锁。'.tr, + '功能开启后,你将可以通过网关远程开锁。'.tr + '此功能的开启和关闭只能在锁附近通过手机蓝牙进行'.tr, style: TextStyle( fontSize: 20.sp, color: AppColors.darkGrayTextColor), )), @@ -62,16 +64,20 @@ class _RemoteUnlockingPageState extends State with RouteAwa ], ); }), + // Padding( + // padding: EdgeInsets.only(top: 20.h), + // child: Text('此功能的开启和关闭只能在锁附近通过手机蓝牙进行'.tr, + // style: TextStyle(fontSize: 20.sp)), + // ), SizedBox( height: 40.h, ), Obx(() => SubmitBtn( - btnName: state.remoteEnable.value == 1 - ? '关闭'.tr - : '开启'.tr, + btnName: state.remoteEnable.value == 1 ? '关闭'.tr : '开启'.tr, onClick: () { //全自动锁只判断是否开启远程开锁 - bool isContains = BlueManage().connectDeviceName.contains('T9A'); + bool isContains = + BlueManage().connectDeviceName.contains('T9A'); if (isContains) { logic.remoteUnlockingOpenOrClose(); } else { diff --git a/lib/main/lockDetail/messageWarn/msgNotification/msgNotification/msgNotification_page.dart b/lib/main/lockDetail/messageWarn/msgNotification/msgNotification/msgNotification_page.dart index 2fa56dd0..5e786d6f 100755 --- a/lib/main/lockDetail/messageWarn/msgNotification/msgNotification/msgNotification_page.dart +++ b/lib/main/lockDetail/messageWarn/msgNotification/msgNotification/msgNotification_page.dart @@ -155,10 +155,16 @@ class _MsgNotificationPageState extends State { SizedBox( height: 60.h, ), - Text( - '此模块功能需要锁联网后设置方可生效'.tr, - style: TextStyle(fontSize: 20.sp), - ) + Padding( + padding: EdgeInsets.symmetric(horizontal: 30.w), + child: Text( + '此模块功能需要锁联网后设置方可生效'.tr, + style: TextStyle(fontSize: 20.sp), + textAlign: TextAlign.center, // 文本居中对齐 + softWrap: true, // 允许文本换行 + overflow: TextOverflow.visible, // 文本溢出时显示 + ), + ), ], ); } diff --git a/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart b/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart index 9ed38957..04059392 100755 --- a/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart +++ b/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_logic.dart @@ -202,7 +202,7 @@ class PasswordKeyDetailLogic extends BaseGetXController { break; case 2: //永久 2 从开始时间开始永久有效,必需在开始时间24小时内使用一次,否则将失效 - useDateStr = '永久'; + useDateStr = '永久'.tr; state.isCirculation.value = false; break; case 3: diff --git a/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart b/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart index 65be1a07..cc02af47 100755 --- a/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart +++ b/lib/main/lockDetail/passwordKey/passwordKeyDetail/passwordKeyDetail_page.dart @@ -205,7 +205,7 @@ class _PasswordKeyDetailPageState extends State children: [ Expanded( child: Text( - '密码生成后,请在当日23:59前使用一次进行激活,否则过0点后未激活则失效。'.tr, + '密码生成后,请在当日23:59前使用一次进行激活,否则过0点后未激活则失效。密码激活后,有效期内不限次数使用。'.tr, textAlign: TextAlign.start, style: TextStyle(fontSize: 20.sp), )), diff --git a/lib/main/lockDetail/videoLog/videoLog/videoLog_page.dart b/lib/main/lockDetail/videoLog/videoLog/videoLog_page.dart index 97bd6ab6..5e83bee2 100755 --- a/lib/main/lockDetail/videoLog/videoLog/videoLog_page.dart +++ b/lib/main/lockDetail/videoLog/videoLog/videoLog_page.dart @@ -143,8 +143,8 @@ class _VideoLogPageState extends State { // nav按钮 Widget navBtn() { - return SizedBox( - width: 300.w, + return Container( + constraints: BoxConstraints(maxWidth: 310.w), // color: Colors.white, child: Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart b/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart index e219a237..952f56cd 100755 --- a/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart +++ b/lib/mine/addLock/lockAddress/gaode/lockAddressGaoDe_page.dart @@ -6,6 +6,7 @@ import 'package:amap_flutter_location/amap_flutter_location.dart'; import 'package:amap_flutter_location/amap_location_option.dart'; import 'package:amap_flutter_map/amap_flutter_map.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -175,12 +176,16 @@ class _LockAddressGaoDePageState extends State body: ListView( children: [ Container( - margin: EdgeInsets.only(left: 25.w, top: 40.h, bottom: 40.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text('地理位置'.tr, style: TextStyle(fontSize: 50.sp)), - ], + margin: EdgeInsets.only( + left: 25.w, right: 25.w, top: 40.h, bottom: 40.w), + child: Center( + child: Text( + '地理位置'.tr, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 50.sp), + softWrap: true, + overflow: TextOverflow.visible, + ), ), ), SizedBox( @@ -272,7 +277,9 @@ class _LockAddressGaoDePageState extends State height: 1.sw / 5 * 4 + 65.h * 2, child: Center(child: Text('地图加载中,请稍候。。。'.tr))), ), - SizedBox(height: 200.h), + Container( + constraints: BoxConstraints(maxHeight: 150.h), + ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ diff --git a/lib/mine/addLock/nearbyLock/nearbyLock_page.dart b/lib/mine/addLock/nearbyLock/nearbyLock_page.dart index 25413554..a06d469a 100755 --- a/lib/mine/addLock/nearbyLock/nearbyLock_page.dart +++ b/lib/mine/addLock/nearbyLock/nearbyLock_page.dart @@ -105,6 +105,11 @@ class _NearbyLockPageState extends State with RouteAware { Widget nearbyLockItem( String lockTypeIcon, ScanResult scanResult, Function() action) { + // 如果广播名称为空或空字符串,则不显示该项 + if (scanResult.advertisementData.advName.isEmpty) { + return const SizedBox.shrink(); + } + return GestureDetector( onTap: () { final String? serviceUuid = diff --git a/lib/mine/addLock/saveLock/saveLock_logic.dart b/lib/mine/addLock/saveLock/saveLock_logic.dart index 9290d735..f9e20f38 100755 --- a/lib/mine/addLock/saveLock/saveLock_logic.dart +++ b/lib/mine/addLock/saveLock/saveLock_logic.dart @@ -487,7 +487,7 @@ class SaveLockLogic extends BaseGetXController { void backAction() async { eventBus.fire(RefreshLockListInfoDataEvent(clearScanDevices: true)); - BlueManage().disconnect(); + // BlueManage().disconnect(); // 查询锁设置信息 final LockSetInfoEntity entity = diff --git a/lib/mine/gateway/addGateway/selectGateway/selectGatewayList_logic.dart b/lib/mine/gateway/addGateway/selectGateway/selectGatewayList_logic.dart index 09222b9e..3de08509 100644 --- a/lib/mine/gateway/addGateway/selectGateway/selectGatewayList_logic.dart +++ b/lib/mine/gateway/addGateway/selectGateway/selectGatewayList_logic.dart @@ -121,6 +121,7 @@ class SelectGatewayListLogic extends BaseGetXController { Future stopScanBlueList() async { // BlueManage().disconnect(); + state.devices.clear(); await BlueManage().stopScan(); } diff --git a/lib/mine/gateway/gatewayDetail/gatewayDetail_logic.dart b/lib/mine/gateway/gatewayDetail/gatewayDetail_logic.dart index d7487983..cde446fc 100644 --- a/lib/mine/gateway/gatewayDetail/gatewayDetail_logic.dart +++ b/lib/mine/gateway/gatewayDetail/gatewayDetail_logic.dart @@ -5,6 +5,7 @@ import '../../../login/login/entity/LoginEntity.dart'; import '../../../network/api_repository.dart'; import '../../../tools/eventBusEventManage.dart'; import '../../../tools/showTipView.dart'; +import '../../mineSet/transferGateway/selectGetewayList_entity.dart'; import 'gatewayDetail_state.dart'; class GatewayDetailLogic extends BaseGetXController { @@ -40,4 +41,13 @@ class GatewayDetailLogic extends BaseGetXController { }); } } + + Future getGatewayDetail() async { + final GetewayInfoEntity entity = await ApiRepository.to + .getGatewayDetailData( + gatewayId: state.getewayItemData.value.gatewayId ?? 0, timeout: 60); + if (entity.errorCode!.codeIsSuccessful) { + state.getewayItemData.value = entity.data!; + } + } } diff --git a/lib/mine/gateway/gatewayDetail/gatewayDetail_page.dart b/lib/mine/gateway/gatewayDetail/gatewayDetail_page.dart index b700ba28..795f2923 100755 --- a/lib/mine/gateway/gatewayDetail/gatewayDetail_page.dart +++ b/lib/mine/gateway/gatewayDetail/gatewayDetail_page.dart @@ -42,10 +42,10 @@ class _GatewayDetailPageState extends State { action: () { ShowTipView().showTFViewAlertDialog( state.changeGatewayNameController, - '请输入姓名'.tr, - '请输入姓名'.tr, () { + '请输入名称'.tr, + '请输入名称'.tr, () { if (state.changeGatewayNameController.text.isEmpty) { - logic.showToast('请输入姓名'.tr); + logic.showToast('请输入名称'.tr); return; } Get.back(); @@ -84,6 +84,8 @@ class _GatewayDetailPageState extends State { action: () { Get.toNamed(Routers.gatewayConnectionLockPage, arguments: { 'gatewayId': state.getewayItemData.value.gatewayId ?? 0 + })?.then((value) { + logic.getGatewayDetail(); }); }), // CommonItem( diff --git a/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_logic.dart b/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_logic.dart index 810038cf..f301059f 100755 --- a/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_logic.dart +++ b/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_logic.dart @@ -1,7 +1,7 @@ - import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:image_picker/image_picker.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -13,6 +13,7 @@ import 'package:star_lock/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_ import 'package:star_lock/widget/permission/permission_dialog.dart'; import '../../../../network/api_repository.dart'; import '../../../../tools/baseGetXController.dart'; +import '../../../app_settings/app_settings.dart'; import '../../../tools/eventBusEventManage.dart'; import '../../../tools/storage.dart'; import 'minePersonGetUploadFileInfo_entity.dart'; @@ -31,27 +32,30 @@ class MinePersonInfoLogic extends BaseGetXController { //上传头像 先获取upToken 再调用updateUserInfo Future getUpTokenRequest(String filename, int size) async { - final MinePersonGetUploadFileInfoEntity entity = await ApiRepository.to.getUpToken( - userId: state.mineInfoData.value.uid!.toString(), - filename: filename, - size: size); + final MinePersonGetUploadFileInfoEntity entity = await ApiRepository.to + .getUpToken( + userId: state.mineInfoData.value.uid!.toString(), + filename: filename, + size: size); if (entity.errorCode!.codeIsSuccessful) { uploadFile(entity); } } // 上传头像 - Future uploadFile(MinePersonGetUploadFileInfoEntity minePersonGetUploadFileInfoEntity) async { + Future uploadFile( + MinePersonGetUploadFileInfoEntity + minePersonGetUploadFileInfoEntity) async { final File bytes = File(state.image!.path); final Uint8List enc = await bytes.readAsBytes(); - final FormData form = FormData(minePersonGetUploadFileInfoEntity.data!.formData!); - form.files.add( - MapEntry( - minePersonGetUploadFileInfoEntity.data!.fileField!, - MultipartFile(enc, filename: minePersonGetUploadFileInfoEntity.data!.formData!['key']) - ) - ); + final FormData form = + FormData(minePersonGetUploadFileInfoEntity.data!.formData!); + form.files.add(MapEntry( + minePersonGetUploadFileInfoEntity.data!.fileField!, + MultipartFile(enc, + filename: + minePersonGetUploadFileInfoEntity.data!.formData!['key']))); final LoginEntity entity = await ApiRepository.to.uploadFile( url: minePersonGetUploadFileInfoEntity.data!.uploadUrl!, body: form); @@ -63,7 +67,8 @@ class MinePersonInfoLogic extends BaseGetXController { //更新个人信息-头像 Future updateUserInfoRequest(String headUrl) async { - final PasswordKeyListEntity entity = await ApiRepository.to.updateUserHeadUrlInfo(headUrl: headUrl); + final PasswordKeyListEntity entity = + await ApiRepository.to.updateUserHeadUrlInfo(headUrl: headUrl); if (entity.errorCode!.codeIsSuccessful) { state.headUrl.value = headUrl; state.mineInfoData.value.headUrl = state.headUrl.value; @@ -88,9 +93,9 @@ class MinePersonInfoLogic extends BaseGetXController { ///拍摄照片 Future selectCamera() async { final XFile? photo = await state.imagePicker.pickImage( - source: ImageSource.camera, - maxHeight: 250, - maxWidth: 250, + source: ImageSource.camera, + maxHeight: 250, + maxWidth: 250, ); if (photo != null) { state.image = photo; @@ -117,16 +122,69 @@ class MinePersonInfoLogic extends BaseGetXController { //权限判断 访问相机 Future _checkCameraPermission() async { - final bool status = await PermissionDialog.request(Permission.camera); - if (status) { + final PermissionStatus status = await Permission.camera.status; + if (status.isPermanentlyDenied) { + // 用户永久拒绝了权限,引导用户去设置中心开启 + Get.dialog( + AlertDialog( + title: Text('需要相机权限'.tr), + content: Text('请在设置中允许访问相机'.tr), + actions: [ + TextButton( + onPressed: () => Get.back(), + child: Text('取消'.tr), + ), + TextButton( + onPressed: () { + Get.back(); + openAppSettings(); + }, + child: Text('去设置'.tr), + ), + ], + ), + ); + return; + } + + // 权限未被永久拒绝,尝试请求权限 + final bool granted = await PermissionDialog.request(Permission.camera); + if (granted) { selectCamera(); } } //权限判断 访问相册 Future _checkPhotoPermission() async { - final bool status = await PermissionDialog.requestPhotos(); - if (status) { + final PermissionStatus status = await Permission.photos.status; + AppLog.log('status:$status status:$status'); + if (status.isPermanentlyDenied) { + // 用户永久拒绝了权限,引导用户去设置中心开启 + Get.dialog( + AlertDialog( + title: Text('需要相册权限'.tr), + content: Text('请在设置中允许访问相册'.tr), + actions: [ + TextButton( + onPressed: () => Get.back(), + child: Text('取消'.tr), + ), + TextButton( + onPressed: () { + Get.back(); + openAppSettings(); + }, + child: Text('去设置'.tr), + ), + ], + ), + ); + return; + } + + // 权限未被永久拒绝,尝试请求权限 + final bool granted = await PermissionDialog.requestPhotos(); + if (granted) { selectImage(); } } diff --git a/lib/mine/mineSet/authorizedAdministrator/authorizedAdministrator/authorizedAdministratorList_page.dart b/lib/mine/mineSet/authorizedAdministrator/authorizedAdministrator/authorizedAdministratorList_page.dart index f885fa3a..597ddea1 100755 --- a/lib/mine/mineSet/authorizedAdministrator/authorizedAdministrator/authorizedAdministratorList_page.dart +++ b/lib/mine/mineSet/authorizedAdministrator/authorizedAdministrator/authorizedAdministratorList_page.dart @@ -109,8 +109,10 @@ class _AuthorizedAdministratorListPageState 64.h), Align( alignment: const Alignment(0.0, 0.2), - child: SizedBox( - width: 360.w, + child: Container( + constraints: BoxConstraints( + maxWidth: 0.9.sw, + ), child: SubmitBtn( btnName: '添加授权管理员'.tr, onClick: () { diff --git a/lib/mine/mineSet/google_home/google_home_page.dart b/lib/mine/mineSet/google_home/google_home_page.dart index afdee0e3..1c80ccf1 100644 --- a/lib/mine/mineSet/google_home/google_home_page.dart +++ b/lib/mine/mineSet/google_home/google_home_page.dart @@ -79,7 +79,7 @@ class _GoogleHomePageState extends State { final String instructions = '${'1.用智能锁APP添加锁和网关'.tr}\n\n' '${'2.在APP里开启锁的远程开锁功能(这个功能默认是关闭的)。如果没有这个选项,则锁不支持Google Home'.tr}\n\n' '${'3.安装Google Home APP,点击左上角的加号按钮'.tr}\n\n' - '${'4.在设置页面,选择"与Google协同工作'.tr}\n\n' + '${'4.在设置页面,选择与Google协同工作'.tr}\n\n' '${'5.搜索'.tr}"${state.googleHomeData.value.actionName ?? ''}"${',并用智能锁APP的账号和密码进行授权'.tr}'; return Container( diff --git a/lib/mine/mineSet/transferGateway/selectGetewayList_entity.dart b/lib/mine/mineSet/transferGateway/selectGetewayList_entity.dart index e115265a..b6f476e2 100755 --- a/lib/mine/mineSet/transferGateway/selectGetewayList_entity.dart +++ b/lib/mine/mineSet/transferGateway/selectGetewayList_entity.dart @@ -1,5 +1,4 @@ class GetewayDataEntity { - GetewayDataEntity( {this.errorCode, this.description, this.errorMsg, this.data}); @@ -9,6 +8,7 @@ class GetewayDataEntity { errorMsg = json['errorMsg']; data = json['data'] != null ? GetewayListData.fromJson(json['data']) : null; } + int? errorCode; String? description; String? errorMsg; @@ -27,8 +27,8 @@ class GetewayDataEntity { } class GetewayListData { - - GetewayListData({this.list, this.pageNo, this.pageSize, this.pages, this.total}); + GetewayListData( + {this.list, this.pageNo, this.pageSize, this.pages, this.total}); GetewayListData.fromJson(Map json) { if (json['list'] != null) { @@ -42,6 +42,7 @@ class GetewayListData { pages = json['pages']; total = json['total']; } + List? list; int? pageNo; int? pageSize; @@ -62,20 +63,19 @@ class GetewayListData { } class GetewayItemData { - GetewayItemData( {this.serialNumber, - this.gatewayMac, - this.gatewayName, - this.gatewayType, - this.networkName, - this.networkMac, - this.lockNum, - this.isOnline, - this.firmwareInfo, - this.needUpgrade, - this.version, - this.gatewayId}); + this.gatewayMac, + this.gatewayName, + this.gatewayType, + this.networkName, + this.networkMac, + this.lockNum, + this.isOnline, + this.firmwareInfo, + this.needUpgrade, + this.version, + this.gatewayId}); GetewayItemData.fromJson(Map json) { serialNumber = json['serialNumber']; @@ -96,6 +96,7 @@ class GetewayItemData { version = json['version']; gatewayId = json['gatewayId']; } + String? serialNumber; String? gatewayMac; String? gatewayName; @@ -130,3 +131,30 @@ class GetewayItemData { } } +class GetewayInfoEntity { + GetewayInfoEntity( + {this.errorCode, this.description, this.errorMsg, this.data}); + + GetewayInfoEntity.fromJson(Map json) { + errorCode = json['errorCode']; + description = json['description']; + errorMsg = json['errorMsg']; + data = json['data'] != null ? GetewayItemData.fromJson(json['data']) : null; + } + + int? errorCode; + String? description; + String? errorMsg; + GetewayItemData? data; + + Map toJson() { + final Map data = {}; + data['errorCode'] = errorCode; + data['description'] = description; + data['errorMsg'] = errorMsg; + if (this.data != null) { + data['data'] = this.data!.toJson(); + } + return data; + } +} diff --git a/lib/mine/valueAddedServices/valueAddedServicesRecord/value_added_services_record_page.dart b/lib/mine/valueAddedServices/valueAddedServicesRecord/value_added_services_record_page.dart index 3366fca2..1808074b 100755 --- a/lib/mine/valueAddedServices/valueAddedServicesRecord/value_added_services_record_page.dart +++ b/lib/mine/valueAddedServices/valueAddedServicesRecord/value_added_services_record_page.dart @@ -71,6 +71,7 @@ class _ValueAddedServicesRecordPageState // 购买记录 class _PurchaseRecords extends StatelessWidget { const _PurchaseRecords({required this.buyRecordList, required this.logic}); + final List buyRecordList; final ValueAddedServicesRecordLogic logic; @@ -134,6 +135,7 @@ class _PurchaseRecords extends StatelessWidget { // 使用记录 class _UseRecordsTable extends StatelessWidget { const _UseRecordsTable({required this.useRecordList, required this.logic}); + final List useRecordList; final ValueAddedServicesRecordLogic logic; @@ -172,9 +174,12 @@ class _UseRecordsTable extends StatelessWidget { Text( logic.state.useCountStr.value, style: TextStyle( - fontSize: 24.sp, - color: AppColors.blackColor, - fontWeight: FontWeight.bold), + fontSize: 24.sp, + color: AppColors.blackColor, + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.ellipsis, // 超出显示省略号 + maxLines: 1, // 限制为单行 ), Expanded(child: Container()), if (itemData.authStatus == 0) diff --git a/lib/mine/valueAddedServices/valueAddedServicesSMSTemplate/valueAddedServicesListSMSTemplate/customSMSTemplateList_page.dart b/lib/mine/valueAddedServices/valueAddedServicesSMSTemplate/valueAddedServicesListSMSTemplate/customSMSTemplateList_page.dart index 143de483..e39cb1b1 100755 --- a/lib/mine/valueAddedServices/valueAddedServicesSMSTemplate/valueAddedServicesListSMSTemplate/customSMSTemplateList_page.dart +++ b/lib/mine/valueAddedServices/valueAddedServicesSMSTemplate/valueAddedServicesListSMSTemplate/customSMSTemplateList_page.dart @@ -121,8 +121,13 @@ class _CustomSMSTemplateListPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + // Text( + // '${'当前状态'.tr}:${'试用中'.tr}', + // style: TextStyle( + // fontSize: 20.sp, fontWeight: FontWeight.w600), + // ), Text( - '${'当前状态'.tr}:${'试用中'.tr}', + '该功能是高级功能,请开通后再使用'.tr, style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.w600), ), diff --git a/lib/network/api.dart b/lib/network/api.dart index a1be47c2..db9ccf33 100755 --- a/lib/network/api.dart +++ b/lib/network/api.dart @@ -158,6 +158,7 @@ abstract class Api { final String gatewaykListURL = '/gateway/list'; // 网关列表 final String addGatewayURL = '/gateway/add'; // 添加网关 final String deletGatewayURL = '/gateway/delete'; // 删除网关 + final String gatewayDetailURL = '/gateway/detail'; // 网关列表 final String transferGatewayConfirmURL = '/plug/transferPlugConfirm'; // 转移网关确认 final String transferGatewayURL = '/plug/transfer'; // 转移网关 diff --git a/lib/network/api_provider.dart b/lib/network/api_provider.dart index cf7b064e..4cad97cc 100755 --- a/lib/network/api_provider.dart +++ b/lib/network/api_provider.dart @@ -1742,6 +1742,11 @@ class ApiProvider extends BaseProvider { jsonEncode({'pageNo': pageNo, 'pageSize': pageSize}), timeout: timeout); + // 获取网关详情 + Future getGatewayDetailData(int gatewayId, int timeout) => + post(gatewayDetailURL.toUrl, jsonEncode({'gatewayId': gatewayId}), + timeout: timeout); + // 添加网关 Future addGatewayNetwork( String gatewayName, @@ -1823,7 +1828,8 @@ class ApiProvider extends BaseProvider { post(getGatewayConfigURL.toUrl, jsonEncode({}), timeout: timeout); Future getGatewayConfigurationNotLoading(int timeout) => - post(getGatewayConfigURL.toUrl, jsonEncode({}), timeout: timeout,isUnShowLoading: true); + post(getGatewayConfigURL.toUrl, jsonEncode({}), + timeout: timeout, isUnShowLoading: true); Future gatewayConnectionLockListLoadData( int gatewayId, int timeout) => diff --git a/lib/network/api_repository.dart b/lib/network/api_repository.dart index c2732880..b5e09c33 100755 --- a/lib/network/api_repository.dart +++ b/lib/network/api_repository.dart @@ -496,10 +496,12 @@ class ApiRepository { final res = await apiProvider.getLockSettingInfoData(lockId); return LockSetInfoEntity.fromJson(res.body); } + // 获取所有锁设置信息(不显示加载框) Future getLockSettingInfoDataIsNotLoadingIcon( {required String lockId}) async { - final res = await apiProvider.getLockSettingInfoDataIsNotLoadingIcon(lockId); + final res = + await apiProvider.getLockSettingInfoDataIsNotLoadingIcon(lockId); return LockSetInfoEntity.fromJson(res.body); } @@ -1928,6 +1930,13 @@ class ApiRepository { return GetewayDataEntity.fromJson(res.body); } + // 获取网关详情 + Future getGatewayDetailData( + {required int gatewayId, required int timeout}) async { + final res = await apiProvider.getGatewayDetailData(gatewayId, timeout); + return GetewayInfoEntity.fromJson(res.body); + } + // 添加网关 Future gatewayDistributionNetwork( {required String gatewayName, @@ -2027,7 +2036,6 @@ class ApiRepository { return GetGatewayConfigurationEntity.fromJson(res.body); } - // 移除坏锁 Future removeBrokenLockData( {required List lockIdList}) async { diff --git a/lib/talk/starChart/constant/talk_constant.dart b/lib/talk/starChart/constant/talk_constant.dart index 23b6934f..a3847d50 100644 --- a/lib/talk/starChart/constant/talk_constant.dart +++ b/lib/talk/starChart/constant/talk_constant.dart @@ -3,5 +3,5 @@ class TalkConstant { static const int talkePingOverTime = 10; static const int talkeDataOverTime = 10; // 收到TalkRequest 未处理超时时间(s) - static const int talkeRequestOverTime = 60; + static const int talkeRequestOverTime = 30; } diff --git a/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart b/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart index ac3e8a2f..35412daf 100644 --- a/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart +++ b/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart @@ -189,40 +189,65 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle } Future> _processCompletePayload(Uint8List payload) async { - // 存储找到的所有完整帧 List frames = []; + int startIdx = -1; + final length = payload.length - 1; - // 手动遍历 payload - int i = 0; - while (i < payload.length - 1) { - // 寻找起始标志 0xFFD8 - if (payload[i] == 0xFF && payload[i + 1] == 0xD8) { - int startIdx = i; - i += 2; // 跳过起始标志 + for (int i = 0; i < length; i++) { + final currentByte = payload[i]; + final nextByte = payload[i + 1]; - // 寻找结束标志 0xFFD9 - while (i < payload.length - 1) { - if (payload[i] == 0xFF && payload[i + 1] == 0xD9) { - // 找到结束标志 0xFFD9 - int endIdx = i + 2; - // 使用 Uint8List.view 创建视图,避免内存分配 - frames.add( - Uint8List.view(payload.buffer, startIdx, endIdx - startIdx)); - i = endIdx; // 继续寻找下一个帧 - break; - } else { - i += 1; // 继续寻找结束标志 - } + if (currentByte == 0xFF) { + if (nextByte == 0xD8) { + startIdx = i; + i++; // Skip the next byte + } else if (nextByte == 0xD9 && startIdx != -1) { + frames + .add(Uint8List.view(payload.buffer, startIdx, i + 2 - startIdx)); + startIdx = -1; + i++; // Skip the next byte } - } else { - i += 1; // 继续寻找起始标志 } } - // 返回找到的所有完整帧 return frames; } +// Future> _processCompletePayload(Uint8List payload) async { +// // 存储找到的所有完整帧 +// List frames = []; +// +// // 手动遍历 payload +// int i = 0; +// while (i < payload.length - 1) { +// // 寻找起始标志 0xFFD8 +// if (payload[i] == 0xFF && payload[i + 1] == 0xD8) { +// int startIdx = i; +// i += 2; // 跳过起始标志 +// +// // 寻找结束标志 0xFFD9 +// while (i < payload.length - 1) { +// if (payload[i] == 0xFF && payload[i + 1] == 0xD9) { +// // 找到结束标志 0xFFD9 +// int endIdx = i + 2; +// // 使用 Uint8List.view 创建视图,避免内存分配 +// frames.add( +// Uint8List.view(payload.buffer, startIdx, endIdx - startIdx)); +// i = endIdx; // 继续寻找下一个帧 +// break; +// } else { +// i += 1; // 继续寻找结束标志 +// } +// } +// } else { +// i += 1; // 继续寻找起始标志 +// } +// } +// +// // 返回找到的所有完整帧 +// return frames; +// } + // Future> _processCompletePayload(Uint8List payload) async { // // 存储找到的所有完整帧 // List frames = []; diff --git a/lib/talk/starChart/handle/impl/udp_talk_request_handler.dart b/lib/talk/starChart/handle/impl/udp_talk_request_handler.dart index c55043bc..8517e46b 100644 --- a/lib/talk/starChart/handle/impl/udp_talk_request_handler.dart +++ b/lib/talk/starChart/handle/impl/udp_talk_request_handler.dart @@ -17,9 +17,13 @@ import 'package:star_lock/talk/starChart/proto/talk_expect.pb.dart'; import 'package:star_lock/talk/starChart/proto/talk_request.pb.dart'; import 'package:star_lock/tools/push/xs_jPhush.dart'; import 'package:star_lock/tools/storage.dart'; +import 'package:star_lock/translations/current_locale_tool.dart'; class UdpTalkRequestHandler extends ScpMessageBaseHandle implements ScpMessageHandler { + RxString currentLanguage = + CurrentLocaleTool.getCurrentLocaleString().obs; // 当前选择语言 + @override void handleReq(ScpMessage scpMessage) async { // 回复成功 @@ -50,6 +54,12 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle startChartManage.startTalkExpectTimer(); // 停止发送对讲请求 startChartManage.stopCallRequestMessageTimer(); + // 收到应答后取消超时判断 + talkeRequestOverTimeTimerManager.cancel(); + // 启动发送ping + startChartManage.startTalkPingMessageTimer(); + // 启动ping命令超时判断 + talkePingOverTimeTimerManager.start(); } } @@ -70,8 +80,6 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle _showTalkRequestNotification(talkObjectName: talkObjectName); // 设置为等待接听状态 talkStatus.setPassiveCallWaitingAnswer(); - // 启动对讲请求超时定时器 - talkeRequestOverTimeTimerManager.start(); // 收到呼叫请求,跳转到接听页面 if (startChartManage .getDefaultTalkExpect() @@ -107,7 +115,9 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle } }; - XSJPushProvider().showCustomNotification(message); + if (currentLanguage.value == 'zh_CN') { + XSJPushProvider().showCustomNotification(message); + } } /* const AndroidNotificationDetails androidPlatformChannelSpecifics = diff --git a/lib/talk/starChart/handle/other/talke_request_over_time_timer_manager.dart b/lib/talk/starChart/handle/other/talke_request_over_time_timer_manager.dart index 44bb1630..c4347317 100644 --- a/lib/talk/starChart/handle/other/talke_request_over_time_timer_manager.dart +++ b/lib/talk/starChart/handle/other/talke_request_over_time_timer_manager.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; +import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/talk/starChart/constant/talk_constant.dart'; import 'package:star_lock/talk/starChart/constant/talk_status.dart'; import 'package:star_lock/talk/starChart/star_chart_manage.dart'; @@ -34,6 +35,7 @@ class TalkeRequestOverTimeTimerManager { StartChartManage().startTalkRejectMessageTimer(); StartChartManage().stopSendingRbcuInfoMessages(); StartChartManage().stopSendingRbcuProBeMessages(); + StartChartManage().stopCallRequestMessageTimer(); talkStatus.setInitializationCompleted(); Get.back(); } diff --git a/lib/talk/starChart/handle/scp_message_base_handle.dart b/lib/talk/starChart/handle/scp_message_base_handle.dart index c1225f0e..f4b68024 100644 --- a/lib/talk/starChart/handle/scp_message_base_handle.dart +++ b/lib/talk/starChart/handle/scp_message_base_handle.dart @@ -43,7 +43,7 @@ class ScpMessageBaseHandle { // 存储每个 messageId 对应的分包数据 static Map>> _packetBuffer = {}; final Map _packetTimers = {}; - final Duration _timeoutDuration = Duration(seconds: 10); // 分包组包最大超时时间 + final Duration _timeoutDuration = Duration(seconds: 3); // 分包组包最大超时时间 // 通话数据流的单例流数据处理类 final TalkDataRepository talkDataRepository = TalkDataRepository.instance; @@ -106,40 +106,104 @@ class ScpMessageBaseHandle { required int payloadType, }) { // 初始化分包列表 - String key = '$messageId-$payloadType'; - if (!_packetBuffer.containsKey(key)) { - _packetBuffer[key] = List.filled(spTotal, []); - _startTimer(key); - } + // 使用更高效的key生成方式 + final key = '${messageId}_$payloadType'; + + // 打印每个包的信息 + // AppLog.log( + // '📦 收到分包 - MessageId: $messageId, 总包数: $spTotal, 当前包序号: $spIndex'); // 检查分包索引是否在合法范围内 if (spIndex < 1 || spIndex > spTotal) { - // print( - // 'Invalid spTotal: $spTotal spIndex: $spIndex for messageId: $messageId'); + AppLog.log( + '❌ 分包序号异常 - MessageId: $messageId, 总包数: $spTotal, 无效包序号: $spIndex'); return null; } + // 检查分包索引是否在合法范围内(提前检查可以避免后续无效操作) + if (spIndex < 1 || spIndex > spTotal) return null; + + // 初始化分包列表(使用固定长度列表提高性能) + var packets = _packetBuffer[key]; + if (packets == null) { + // 预分配固定大小的列表,避免动态扩容 + packets = List>.filled(spTotal, const [], growable: false); + _packetBuffer[key] = packets; + _startTimer(key); + // AppLog.log('📝 新建分包缓存 - MessageId: $messageId, 预期总包数: $spTotal'); + } + // 存储当前分包 - _packetBuffer[key]![spIndex - 1] = byte; + packets[spIndex - 1] = byte; - // 检查是否接收到所有分包 - if (_packetBuffer[key]!.every((packet) => packet.isNotEmpty)) { - // 重组所有分包 - Uint8List completePayload = Uint8List.fromList( - _packetBuffer[key]!.expand((packet) => packet).toList()); - // 清除已重组和超时的分包数据 + // 优化检查逻辑,使用循环替代every + var isComplete = true; + var totalLength = 0; + for (var i = 0; i < packets.length; i++) { + if (packets[i].isEmpty) { + isComplete = false; + } else { + totalLength += packets[i].length; + } + } + + if (isComplete) { + // 预分配确切大小的buffer,避免扩容 + final buffer = Uint8List(totalLength); + var offset = 0; + + // 直接复制数据,避免使用expand + for (var packet in packets) { + buffer.setRange(offset, offset + packet.length, packet); + offset += packet.length; + } + + // 清理资源 _clearPacketData(key); - // 使用重组的包构造成TalkData + // 构造TalkData if (payloadType == PayloadTypeConstant.talkData) { final talkData = TalkData(); - talkData.mergeFromBuffer(completePayload); + talkData.mergeFromBuffer(buffer); return talkData; } - } else { - // 如果分包尚未接收完全,返回 null 或其他指示符 - return null; } + + return null; + + // if (!_packetBuffer.containsKey(key)) { + // _packetBuffer[key] = List.filled(spTotal, []); + // _startTimer(key); + // } + // + // // 检查分包索引是否在合法范围内 + // if (spIndex < 1 || spIndex > spTotal) { + // // print( + // // 'Invalid spTotal: $spTotal spIndex: $spIndex for messageId: $messageId'); + // return null; + // } + // + // // 存储当前分包 + // _packetBuffer[key]![spIndex - 1] = byte; + // + // // 检查是否接收到所有分包 + // if (_packetBuffer[key]!.every((packet) => packet.isNotEmpty)) { + // // 重组所有分包 + // Uint8List completePayload = Uint8List.fromList( + // _packetBuffer[key]!.expand((packet) => packet).toList()); + // // 清除已重组和超时的分包数据 + // _clearPacketData(key); + // + // // 使用重组的包构造成TalkData + // if (payloadType == PayloadTypeConstant.talkData) { + // final talkData = TalkData(); + // talkData.mergeFromBuffer(completePayload); + // return talkData; + // } + // } else { + // // 如果分包尚未接收完全,返回 null 或其他指示符 + // return null; + // } } // 启动定时器 diff --git a/lib/talk/starChart/star_chart_manage.dart b/lib/talk/starChart/star_chart_manage.dart index 1e53b7f0..328e80b8 100644 --- a/lib/talk/starChart/star_chart_manage.dart +++ b/lib/talk/starChart/star_chart_manage.dart @@ -123,6 +123,10 @@ class StartChartManage { // 星图服务初始化 Future init() async { + if (F.isXHJ) { + return; + } + // 判断是否登录账户 final loginData = await Storage.getLoginData(); @@ -417,8 +421,7 @@ class StartChartManage { void startCallRequestMessageTimer({required String ToPeerId}) async { // 如果已经处于等待接听状态就不发送 if (talkStatus.status != TalkStatus.proactivelyCallWaitingAnswer) { - // 停止播放铃声 - // AudioPlayerManager().playRingtone(); + // 如果是h264则跳转至webview if (_defaultTalkExpect.videoType.contains(VideoTypeE.H264)) { Get.toNamed( Routers.h264WebView, @@ -429,6 +432,7 @@ class StartChartManage { ); } } + // 启动定时器持续发送对讲请求 talkRequestTimer ??= Timer.periodic( Duration( seconds: _defaultIntervalTime, @@ -438,9 +442,8 @@ class StartChartManage { }, ); talkStatus.setProactivelyCallWaitingAnswer(); - startTalkPingMessageTimer(); - // 启动是否收到ping超时判断定时器 - talkePingOverTimeTimerManager.start(); + // 启动对讲请求应答超时判断 + talkeRequestOverTimeTimerManager.start(); } /// 停止持续发送对讲请求 diff --git a/lib/talk/starChart/views/talkView/talk_view_logic.dart b/lib/talk/starChart/views/talkView/talk_view_logic.dart index 71473bee..a0a79f52 100644 --- a/lib/talk/starChart/views/talkView/talk_view_logic.dart +++ b/lib/talk/starChart/views/talkView/talk_view_logic.dart @@ -36,19 +36,26 @@ class TalkViewLogic extends BaseGetXController { final TalkViewState state = TalkViewState(); final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state; - Timer? _syncTimer; // 音视频播放刷新率定时器 - Timer? _audioTimer; // 音视频播放刷新率定时器 - int _startTime = 0; // 开始播放时间戳,用于判断帧数据中的时间戳位置 - int bufferSize = 40; // 缓冲区大小(以帧为单位) - int audioBufferSize = 500; // 缓冲区大小(以帧为单位) - int frameIntervalMs = 45; // 初始帧间隔设置为45毫秒(约22FPS) - int audioFrameIntervalMs = 20; // 初始帧间隔设置为45毫秒(约22FPS) - int minFrameIntervalMs = 30; // 最小帧间隔(约33 FPS) - int maxFrameIntervalMs = 100; // 最大帧间隔(约1 FPS) + final int minBufferSize = 2; // 最小缓冲2帧,约166ms + final int maxBufferSize = 8; // 最大缓冲8帧,约666ms + int bufferSize = 3; // 初始化为默认大小 + // 修改音频相关的成员变量 + final int minAudioBufferSize = 1; // 音频最小缓冲1帧 + final int maxAudioBufferSize = 3; // 音频最大缓冲3帧 + int audioBufferSize = 2; // 音频默认缓冲2帧 + + // 添加开始时间记录 + int _startTime = 0; // 开始播放时间戳 + int _startAudioTime = 0; // 开始播放时间戳 + bool _isFirstFrame = true; // 是否是第一帧 + bool _isFirstAudioFrame = true; // 是否是第一帧 + // 定义音频帧缓冲和发送函数 final List _bufferedAudioFrames = []; + final Map _imageCache = {}; + /// 初始化音频播放器 void _initFlutterPcmSound() { const int sampleRate = 8000; @@ -83,24 +90,173 @@ class TalkViewLogic extends BaseGetXController { void _startListenTalkData() { state.talkDataRepository.talkDataStream.listen((TalkData talkData) async { final contentType = talkData.contentType; + final currentTime = DateTime.now().millisecondsSinceEpoch; + // 判断数据类型,进行分发处理 switch (contentType) { case TalkData_ContentTypeE.G711: + // 第一帧到达时记录开始时间 + if (_isFirstAudioFrame) { + _startAudioTime = currentTime; + _isFirstAudioFrame = false; + } + + // 计算音频延迟 + final expectedTime = _startAudioTime + talkData.durationMs; + final audioDelay = currentTime - expectedTime; + + // 如果延迟太大,清空缓冲区并直接播放 + if (audioDelay > 500) { + state.audioBuffer.clear(); + if (state.isOpenVoice.value) { + _playAudioFrames(); + } + return; + } if (state.audioBuffer.length >= audioBufferSize) { state.audioBuffer.removeAt(0); // 丢弃最旧的数据 } state.audioBuffer.add(talkData); // 添加新数据 + // 添加音频播放逻辑,与视频类似 + _playAudioFrames(); break; case TalkData_ContentTypeE.Image: - if (state.videoBuffer.length >= bufferSize) { - state.videoBuffer.removeAt(0); // 丢弃最旧的数据 + // 第一帧到达时记录开始时间 + if (_isFirstFrame) { + _startTime = currentTime; + _isFirstFrame = false; + // AppLog.log('记录第一帧的时间戳${currentTime},${talkData.durationMs}'); } - state.videoBuffer.add(talkData); // 添加新数据 + + // 计算实际延迟:当前时间 - 预期播放时间 + final expectedTime = _startTime + talkData.durationMs; + final videoDelay = currentTime - expectedTime; // 修改延迟计算方式 + + // 动态调整缓冲区 + _adjustBufferSize(videoDelay); + // 然后添加到播放缓冲区 + if (state.videoBuffer.length >= bufferSize) { + state.videoBuffer.removeAt(0); + } + state.videoBuffer.add(talkData); + // 先进行解码和缓存 + await _decodeAndCacheFrame(talkData); + // 最后尝试播放 + _playVideoFrames(); break; } }); } + // 修改:视频帧播放逻辑 + void _playVideoFrames() { + // 如果缓冲区为空或未达到目标大小,不进行播放 + if (state.videoBuffer.isEmpty || state.videoBuffer.length < bufferSize) { + // AppLog.log('📊 缓冲中 - 当前缓冲区大小: ${state.videoBuffer.length}/${bufferSize}'); + return; + } + // 找出时间戳最小的帧(最旧的帧) + TalkData? oldestFrame; + int oldestIndex = -1; + for (int i = 0; i < state.videoBuffer.length; i++) { + if (oldestFrame == null || + state.videoBuffer[i].durationMs < oldestFrame.durationMs) { + oldestFrame = state.videoBuffer[i]; + oldestIndex = i; + } + } + // 确保找到了有效帧 + if (oldestFrame != null && oldestIndex != -1) { + final cacheKey = oldestFrame.content.hashCode.toString(); + + // 使用缓存的解码图片更新显示 + if (_imageCache.containsKey(cacheKey)) { + state.currentImage.value = _imageCache[cacheKey]; + state.listData.value = Uint8List.fromList(oldestFrame.content); + state.videoBuffer.removeAt(oldestIndex); // 移除已播放的帧 + + // AppLog.log('🎬 播放帧 - 缓冲区剩余: ${state.videoBuffer.length}/${bufferSize}, ' + // '播放延迟: ${currentTime - oldestFrame.durationMs}ms, ' + // '帧时间戳: ${oldestFrame.durationMs}'); + } else { + // AppLog.log('⚠️ 帧未找到缓存 - Key: $cacheKey'); + state.videoBuffer.removeAt(oldestIndex); // 移除无法播放的帧 + } + } + } + + // 新增:音频帧播放逻辑 + void _playAudioFrames() { + // 如果缓冲区为空或未达到目标大小,不进行播放 + // 音频缓冲区要求更小,以减少延迟 + if (state.audioBuffer.isEmpty || + state.audioBuffer.length < audioBufferSize) { + return; + } + + // 找出时间戳最小的音频帧 + TalkData? oldestFrame; + int oldestIndex = -1; + for (int i = 0; i < state.audioBuffer.length; i++) { + if (oldestFrame == null || + state.audioBuffer[i].durationMs < oldestFrame.durationMs) { + oldestFrame = state.audioBuffer[i]; + oldestIndex = i; + } + } + + // 确保找到了有效帧 + if (oldestFrame != null && oldestIndex != -1) { + if (state.isOpenVoice.value) { + // 播放音频 + _playAudioData(oldestFrame); + } + state.audioBuffer.removeAt(oldestIndex); + } + } + + // 新增:解码和缓存帧的方法 + Future _decodeAndCacheFrame(TalkData talkData) async { + try { + String cacheKey = talkData.content.hashCode.toString(); + + // 如果该帧还没有被缓存,则进行解码和缓存 + if (!_imageCache.containsKey(cacheKey)) { + final Uint8List uint8Data = Uint8List.fromList(talkData.content); + final ui.Image image = await decodeImageFromList(uint8Data); + + // 管理缓存大小 + if (_imageCache.length >= bufferSize) { + _imageCache.remove(_imageCache.keys.first); + } + + // 添加到缓存 + _imageCache[cacheKey] = image; + + // AppLog.log('📥 缓存新帧 - 缓存数: ${_imageCache.length}, Key: $cacheKey'); + } + } catch (e) { + AppLog.log('❌ 帧解码错误: $e'); + } + } + + // 新增:动态调整缓冲区大小的方法 + void _adjustBufferSize(int delay) { + const int delayThresholdHigh = 250; // 高延迟阈值(约3帧的时间) + const int delayThresholdLow = 166; // 低延迟阈值(约2帧的时间) + const int adjustInterval = 1; // 每次调整1帧 + + if (delay > delayThresholdHigh && bufferSize < maxBufferSize) { + // 延迟较大,增加缓冲区 + bufferSize = min(bufferSize + adjustInterval, maxBufferSize); + // AppLog.log('📈 增加缓冲区 - 当前大小: $bufferSize, 延迟: ${delay}ms'); + } else if (delay < delayThresholdLow && bufferSize > minBufferSize) { + // 延迟较小,减少缓冲区 + bufferSize = max(bufferSize - adjustInterval, minBufferSize); + // AppLog.log('📉 减少缓冲区 - 当前大小: $bufferSize, 延迟: ${delay}ms'); + } + } + /// 监听对讲状态 void _startListenTalkStatus() { state.startChartTalkStatus.statusStream.listen((talkStatus) { @@ -148,89 +304,6 @@ class TalkViewLogic extends BaseGetXController { } } - /// 播放视频数据 - void _playVideoData(TalkData talkData) async { - state.listData.value = Uint8List.fromList(talkData.content); - } - - /// 启动播放 - void _startPlayback() { - Future.delayed(Duration(milliseconds: 800), () { - _startTime = DateTime.now().millisecondsSinceEpoch; - _syncTimer ??= - Timer.periodic(Duration(milliseconds: frameIntervalMs), (timer) { - // 动态调整帧间隔 - _adjustFrameInterval(); - }); - }); - } - - /// 动态调整帧间隔 - void _adjustFrameInterval() { - int newFrameIntervalMs = frameIntervalMs; - if (state.videoBuffer.length < 10 && frameIntervalMs < maxFrameIntervalMs) { - // 如果缓冲区较小且帧间隔小于最大值,则增加帧间隔 - frameIntervalMs += 5; - } else if (state.videoBuffer.length > 20 && - frameIntervalMs > minFrameIntervalMs) { - // 如果缓冲区较大且帧间隔大于最小值,则减少帧间隔 - frameIntervalMs -= 5; - } - // 只有在帧间隔发生变化时才重建定时器 - if (newFrameIntervalMs != frameIntervalMs) { - frameIntervalMs = newFrameIntervalMs; - // 取消旧的定时器 - _syncTimer?.cancel(); - _syncTimer = - Timer.periodic(Duration(milliseconds: frameIntervalMs), (timer) { - // 播放视频帧 - _playVideoFrames(); - }); - - _audioTimer?.cancel(); - _audioTimer = - Timer.periodic(Duration(milliseconds: audioFrameIntervalMs), (timer) { - final currentTime = DateTime.now().millisecondsSinceEpoch; - final elapsedTime = currentTime - _startTime; - - // 播放合适的音频帧 - if (state.audioBuffer.isNotEmpty && - state.audioBuffer.first.durationMs <= elapsedTime) { - // 判断音频开关是否打开 - if (state.isOpenVoice.value) { - _playAudioData(state.audioBuffer.removeAt(0)); - } else { - // 如果不播放音频,只从缓冲区中读取数据,但不移除 - // 你可以根据需要调整此处逻辑,例如保留缓冲区的最大长度,防止无限增长 - // 仅移除缓冲区数据但不播放音频,确保音频也是实时更新的 - state.audioBuffer.removeAt(0); - } - } - }); - } - } - - void _playVideoFrames() { - final currentTime = DateTime.now().millisecondsSinceEpoch; - final elapsedTime = currentTime - _startTime; - - // 播放合适的视频帧 - // 跳帧策略:如果缓冲区中有多个帧,且它们的时间戳都在当前时间之前,则播放最新的帧 - int maxFramesToProcess = 5; // 每次最多处理 5 帧 - int processedFrames = 0; - - while (state.videoBuffer.isNotEmpty && - state.videoBuffer.first.durationMs <= elapsedTime && - processedFrames < maxFramesToProcess) { - if (state.videoBuffer.length > 1) { - state.videoBuffer.removeAt(0); - } else { - _playVideoData(state.videoBuffer.removeAt(0)); - } - processedFrames++; - } - } - /// 停止播放音频 void _stopPlayG711Data() async { await FlutterPcmSound.pause(); @@ -396,7 +469,7 @@ class TalkViewLogic extends BaseGetXController { _initFlutterPcmSound(); // 启动播放定时器 - _startPlayback(); + // _startPlayback(); // 初始化录音控制器 _initAudioRecorder(); @@ -410,13 +483,14 @@ class TalkViewLogic extends BaseGetXController { state.listData.value = Uint8List(0); // 清空视频数据 state.audioBuffer.clear(); // 清空音频缓冲区 state.videoBuffer.clear(); // 清空视频缓冲区 - _syncTimer?.cancel(); // 取消定时器 - _syncTimer = null; // 释放定时器引用 - _audioTimer?.cancel(); - _audioTimer = null; // 释放定时器引用 + state.oneMinuteTimeTimer?.cancel(); state.oneMinuteTimeTimer = null; + stopProcessingAudio(); + // 清理图片缓存 + _imageCache.clear(); + super.onClose(); } diff --git a/lib/talk/starChart/views/talkView/talk_view_page.dart b/lib/talk/starChart/views/talkView/talk_view_page.dart index 2059d0ac..021d1616 100644 --- a/lib/talk/starChart/views/talkView/talk_view_page.dart +++ b/lib/talk/starChart/views/talkView/talk_view_page.dart @@ -133,20 +133,16 @@ class _TalkViewPageState extends State child: SizedBox.expand( child: RotatedBox( quarterTurns: -1, - child: Image.memory( - state.listData.value, - width: ScreenUtil().scaleWidth, - height: ScreenUtil().scaleHeight, - gaplessPlayback: true, - fit: BoxFit.cover, - filterQuality: FilterQuality.high, - errorBuilder: ( - BuildContext context, - Object error, - StackTrace? stackTrace, - ) { - return Container(color: Colors.transparent); - }, + child: Obx( + () => state.currentImage.value != null + ? RawImage( + image: state.currentImage.value, + width: ScreenUtil().scaleWidth, + height: ScreenUtil().scaleHeight, + fit: BoxFit.cover, + filterQuality: FilterQuality.high, + ) + : Container(color: Colors.transparent), ), ), ), diff --git a/lib/talk/starChart/views/talkView/talk_view_state.dart b/lib/talk/starChart/views/talkView/talk_view_state.dart index 25538093..1ff29b5e 100644 --- a/lib/talk/starChart/views/talkView/talk_view_state.dart +++ b/lib/talk/starChart/views/talkView/talk_view_state.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:typed_data'; +import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter_voice_processor/flutter_voice_processor.dart'; @@ -54,7 +55,6 @@ class TalkViewState { // 星图对讲相关状态 List audioBuffer = [].obs; - List audioBuffer2 = [].obs; List activeAudioBuffer = [].obs; List activeVideoBuffer = [].obs; @@ -89,4 +89,6 @@ class TalkViewState { RxBool isLongPressing = false.obs; // 旋转角度(以弧度为单位) RxBool hasAudioData = false.obs; // 是否有音频数据 RxInt lastAudioTimestamp = 0.obs; // 最后接收到的音频数据的时间戳 + // 添加图片状态变量 + final Rx currentImage = Rx(null); } diff --git a/lib/tools/advancedCalendar/src/widget.dart b/lib/tools/advancedCalendar/src/widget.dart index 62dac000..7abd3fee 100755 --- a/lib/tools/advancedCalendar/src/widget.dart +++ b/lib/tools/advancedCalendar/src/widget.dart @@ -3,17 +3,24 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:star_lock/tools/eventBusEventManage.dart'; +import 'package:star_lock/translations/current_locale_tool.dart'; import '../../../app_settings/app_settings.dart'; import 'controller.dart'; import 'datetime_util.dart'; part 'date_box.dart'; + part 'handlebar.dart'; + part 'header.dart'; + part 'month_view.dart'; + part 'month_view_bean.dart'; + part 'week_days.dart'; + part 'week_view.dart'; /// Advanced Calendar widget. @@ -162,13 +169,17 @@ class _AdvancedCalendarState extends State // return DateFormat("EEEE").format(list[index]).split('').first; // } // ); - //by DaisyWu 修改源文件为中文环境下 周一到周日 - _weekNames = List.generate(7, (int index) { - String fullWeekName = - DateFormat.E('zh_CN').format(list[index]); // 获取星期的完整形式 - return fullWeekName - .substring(fullWeekName.length - 1); // 获取最后一个字符,即星期的简称 - }); + + final currentLocaleString = CurrentLocaleTool.getCurrentLocaleString(); + if (currentLocaleString == 'zh_CN') { + //by DaisyWu 修改源文件为中文环境下 周一到周日 + _weekNames = List.generate(7, (int index) { + String fullWeekName = + DateFormat.E('zh_CN').format(list[index]); // 获取星期的完整形式 + return fullWeekName + .substring(fullWeekName.length - 1); // 获取最后一个字符,即星期的简称 + }); + } } } diff --git a/lib/tools/commonItem.dart b/lib/tools/commonItem.dart index 2a9d1c1d..b5c40036 100755 --- a/lib/tools/commonItem.dart +++ b/lib/tools/commonItem.dart @@ -20,6 +20,7 @@ class CommonItem extends StatelessWidget { this.rightWidget, this.isTipsImg, this.action, + this.leftTitleMaxWidth, // 新增属性 this.tipsImgAction}) : super(key: key); String? leftTitel; @@ -34,6 +35,7 @@ class CommonItem extends StatelessWidget { bool? setHeight; bool? isTipsImg; bool? isPadding; + final double? leftTitleMaxWidth; // 新增属性声明 @override Widget build(BuildContext context) { @@ -57,7 +59,17 @@ class CommonItem extends StatelessWidget { ), child: Row( children: [ - Text(leftTitel!, style: TextStyle(fontSize: 22.sp)), + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: leftTitleMaxWidth ?? 0.6.sw, // 默认最大宽度为屏幕宽度的40% + ), + child: Text( + leftTitel!, + style: TextStyle(fontSize: 22.sp), + overflow: TextOverflow.ellipsis, // 超出部分显示省略号 + maxLines: 3, // 最多显示2行 + ), + ), SizedBox(width: 6.w), if (isTipsImg == true) GestureDetector( diff --git a/lib/tools/showCupertinoAlertView.dart b/lib/tools/showCupertinoAlertView.dart index d973cc78..cf585bf1 100755 --- a/lib/tools/showCupertinoAlertView.dart +++ b/lib/tools/showCupertinoAlertView.dart @@ -297,7 +297,7 @@ class ShowCupertinoAlertView { builder: (BuildContext context) { return CupertinoAlertDialog( title: Container(), - content: Text('是否要远程开锁?'.tr), + content: Text('是否要远程开锁'.tr), actions: [ CupertinoDialogAction( onPressed: Get.back, diff --git a/lib/tools/submitBtn.dart b/lib/tools/submitBtn.dart index 57b6ea69..01511077 100755 --- a/lib/tools/submitBtn.dart +++ b/lib/tools/submitBtn.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -9,9 +8,9 @@ import '../app_settings/app_colors.dart'; * */ class SubmitBtn extends StatelessWidget { - SubmitBtn({ - required this.btnName, Key? key, + required this.btnName, + Key? key, this.borderRadius, this.color, this.padding, @@ -49,7 +48,9 @@ class SubmitBtn extends StatelessWidget { Widget build(BuildContext context) { return Container( width: ScreenUtil().screenWidth - 40.w, - height: 60.h, + constraints: BoxConstraints( + minHeight: 60.h, // 设置最小高度 + ), child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: isDisabled == false @@ -63,7 +64,14 @@ class SubmitBtn extends StatelessWidget { }, child: Text( btnName!, - style: TextStyle(color: Colors.white, fontSize: 24.sp), + textAlign: TextAlign.center, // 文本居中对齐 + softWrap: true, // 允许换行 + overflow: TextOverflow.visible, // 文本溢出时显示 + style: TextStyle( + color: Colors.white, + fontSize: 24.sp, + height: 1.2, // 行高 + ), )), ); /* @@ -111,9 +119,9 @@ class SubmitBtn extends StatelessWidget { * */ class AddBottomWhiteBtn extends StatelessWidget { - AddBottomWhiteBtn({ - required this.btnName, Key? key, + required this.btnName, + Key? key, this.onClick, }) : super(key: key); String? btnName; @@ -164,9 +172,9 @@ class AddBottomWhiteBtn extends StatelessWidget { * */ class OutLineBtn extends StatelessWidget { - OutLineBtn({ - required this.btnName, Key? key, + required this.btnName, + Key? key, this.onClick, }) : super(key: key); String? btnName; diff --git a/lib/tools/tf_loginInput.dart b/lib/tools/tf_loginInput.dart index ba08fb72..3ab4c6b8 100755 --- a/lib/tools/tf_loginInput.dart +++ b/lib/tools/tf_loginInput.dart @@ -93,7 +93,7 @@ class _LoginInputState extends State { onTap: widget.onTapAction, autofocus: false, inputFormatters: widget.inputFormatters, - textInputAction: TextInputAction.next, + textInputAction: isPwd ? TextInputAction.done : TextInputAction.next, // 修改键盘类型为密码类型 keyboardType: isPwd ? TextInputType.visiblePassword diff --git a/lib/translations/app_dept.dart b/lib/translations/app_dept.dart index c58d5de8..1d60fe75 100755 --- a/lib/translations/app_dept.dart +++ b/lib/translations/app_dept.dart @@ -54,6 +54,8 @@ extension ExtensionAppDept on AppDept { const Locale fiL = Locale('fi', 'FI'); const Locale daL = Locale('da', 'DK'); const Locale ukL = Locale('uk', 'UA'); + const Locale hiL = Locale('hi', 'HI'); + const Locale urL = Locale('ur', 'UR'); const Locale srCyrillic = Locale('sr', 'RS'); return [ @@ -93,6 +95,8 @@ extension ExtensionAppDept on AppDept { fiL, daL, ukL, + hiL, + urL, srCyrillic ]; } @@ -177,7 +181,12 @@ enum LanguageType { // 丹麦语 danish, // 乌克兰语 - ukrainian + ukrainian, + //印地语、 + hindi, + //乌尔都语 + urdu, + } extension ExtensionLanguageType on LanguageType { @@ -295,6 +304,12 @@ extension ExtensionLanguageType on LanguageType { case LanguageType.ukrainian: str = '乌克兰语'.tr; break; + case LanguageType.hindi: + str = '印地语'.tr; + break; + case LanguageType.urdu: + str = '乌尔都语'.tr; + break; } return str; } @@ -415,6 +430,12 @@ extension ExtensionLanguageType on LanguageType { case 'uk': languageType = LanguageType.ukrainian; break; + case 'hi': + languageType = LanguageType.hindi; + break; + case 'ur': + languageType = LanguageType.urdu; + break; default: languageType = LanguageType.english; break; @@ -610,6 +631,16 @@ extension ExtensionLanguageType on LanguageType { return locale; } break; + case LanguageType.hindi: + if (locale.languageCode == 'hi' && locale.countryCode == 'HI') { + return locale; + } + break; + case LanguageType.urdu: + if (locale.languageCode == 'ur' && locale.countryCode == 'UR') { + return locale; + } + break; case LanguageType.system: // TODO: Handle this case. break; diff --git a/lib/widget/permission/permission_dialog.dart b/lib/widget/permission/permission_dialog.dart index 998eab8c..3d74e1bd 100755 --- a/lib/widget/permission/permission_dialog.dart +++ b/lib/widget/permission/permission_dialog.dart @@ -132,9 +132,7 @@ class PermissionDialog { List permissions; if (isAndroid33) { permissions = [ - Permission.mediaLibrary, Permission.photos, - Permission.videos, ]; } else { permissions = [ @@ -150,11 +148,11 @@ class PermissionDialog { isGranted = isGranted && (await permission.status) == PermissionStatus.granted; } - if (isAndroid33) { - // android 33以上需要申请媒体库权限 - isGranted = - (await Permission.mediaLibrary.status) == PermissionStatus.granted; - } + // if (isAndroid33) { + // // android 33以上需要申请媒体库权限 + // isGranted = + // (await Permission.mediaLibrary.status) == PermissionStatus.granted; + // } return isGranted; } @@ -213,10 +211,15 @@ class PermissionDialog { if (Get.context == null) { return false; } - final AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo; - final bool isAndroid33 = - AppPlatform.isAndroid && androidInfo.version.sdkInt >= 33; - + bool isAndroid33 = false; + try { + final AndroidDeviceInfo androidInfo = + await DeviceInfoPlugin().androidInfo; + isAndroid33 = AppPlatform.isAndroid && androidInfo.version.sdkInt >= 33; + } catch (e) { + // 如果获取设备信息失败,默认使用旧版本权限申请方式 + isAndroid33 = false; + } //通用的局部函数 List requestPermission() { List permissions; diff --git a/pubspec.lock b/pubspec.lock index 3eff3ffe..9b40c4b0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1045,6 +1045,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.13" + jverify: + dependency: "direct main" + description: + name: jverify + sha256: "26d1667d8c71403b77a2620a8c618625f8b4bfc950dac285b8f35ebc5e60fa5a" + url: "https://pub.dev" + source: hosted + version: "3.0.0" leak_tracker: dependency: transitive description: