commit 648c392796e6058f653fa64895ec7a75cd3b097f
Author: 彭真涛 <16362733+peng-zhentao@user.noreply.gitee.com>
Date: Thu Aug 27 13:33:14 2026 +0800
初始化仓库
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3b550dd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+/.vs/AIK_WPFWin7/config/applicationhost.config
+/.vs/AIK_WPFWin7/DesignTimeBuild/.dtbcache.v2
+/.vs/AIK_WPFWin7/FileContentIndex/220b08dd-7cab-4b06-b9ce-e2ff55f551fb.vsidx
+/.vs/AIK_WPFWin7/FileContentIndex/7e16a2b3-374f-48b6-9586-0bfc63662446.vsidx
+/.vs/AIK_WPFWin7/FileContentIndex/c1197851-d2be-4a27-a29f-f6dc9281684b.vsidx
+/.vs/AIK_WPFWin7/FileContentIndex/e63df965-b67f-4efb-8b76-73728081e2d1.vsidx
+/.vs/AIK_WPFWin7/FileContentIndex/ffe84a3e-16f3-47c8-9ac2-14fa66df514f.vsidx
+/.vs/AIK_WPFWin7/v17/.futdcache.v2
+/.vs/AIK_WPFWin7/v17/.suo
+/.vs/AIK_WPFWin7/v17/DocumentLayout.json
+/.vs/AIK_WPFWin7/v17/fileList.bin
+/.vs/AIK_WPFWin7/v18/.futdcache.v2
+/.vs/AIK_WPFWin7/v18/.suo
+/.vs/AIK_WPFWin7/v18/DocumentLayout.backup.json
+/.vs/AIK_WPFWin7/v18/DocumentLayout.json
+/.vs/AIK_WPFWin7/v18/fileList.bin
+/.vs/ProjectEvaluation/aik_wpfwin7.metadata.v10.bin
+/.vs/ProjectEvaluation/aik_wpfwin7.projects.v10.bin
+/.vs/ProjectEvaluation/aik_wpfwin7.strings.v10.bin
+
+# 编译生成目录(bin/obj)
+[Bb]in/
+[Oo]bj/
+[Dd]ebug/
+[Rr]elease/
+x64/
+x86/
+bld/
+[Bb]uild/
+GeneratedFiles/
+*.user
+*.suo
+*.userosscache
+*.sln.docstates
diff --git a/AIK.Assets/AIK.Assets.csproj b/AIK.Assets/AIK.Assets.csproj
new file mode 100644
index 0000000..9cea83d
--- /dev/null
+++ b/AIK.Assets/AIK.Assets.csproj
@@ -0,0 +1,88 @@
+
+
+
+ net48
+ enable
+ true
+ AIK.Assets
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Never
+
+
+ Always
+
+
+ Never
+
+
+
+ Always
+
+
+ Never
+
+
+
+
+
+ Never
+
+
+ Never
+
+
+ Always
+
+
+ Always
+
+
+ Never
+
+
+ Always
+
+
+
+
+
+ Always
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Assets/Fonts/AlimamaShuHeiTi-Bold.ttf b/AIK.Assets/Fonts/AlimamaShuHeiTi-Bold.ttf
new file mode 100644
index 0000000..b20919e
Binary files /dev/null and b/AIK.Assets/Fonts/AlimamaShuHeiTi-Bold.ttf differ
diff --git a/AIK.Assets/Fonts/digital_display.ttf b/AIK.Assets/Fonts/digital_display.ttf
new file mode 100644
index 0000000..a006032
Binary files /dev/null and b/AIK.Assets/Fonts/digital_display.ttf differ
diff --git a/AIK.Assets/Fonts/iconfont.ttf b/AIK.Assets/Fonts/iconfont.ttf
new file mode 100644
index 0000000..7aa3ceb
Binary files /dev/null and b/AIK.Assets/Fonts/iconfont.ttf differ
diff --git a/AIK.Assets/Fonts/iconfont1.ttf b/AIK.Assets/Fonts/iconfont1.ttf
new file mode 100644
index 0000000..a8e7367
Binary files /dev/null and b/AIK.Assets/Fonts/iconfont1.ttf differ
diff --git a/AIK.Assets/Images/AIK.png b/AIK.Assets/Images/AIK.png
new file mode 100644
index 0000000..ba5cc23
Binary files /dev/null and b/AIK.Assets/Images/AIK.png differ
diff --git a/AIK.Assets/Images/AIKChina.ico b/AIK.Assets/Images/AIKChina.ico
new file mode 100644
index 0000000..564db41
Binary files /dev/null and b/AIK.Assets/Images/AIKChina.ico differ
diff --git a/AIK.Assets/Images/AIKChina.png b/AIK.Assets/Images/AIKChina.png
new file mode 100644
index 0000000..d9fd87d
Binary files /dev/null and b/AIK.Assets/Images/AIKChina.png differ
diff --git a/AIK.Assets/Images/AIKInternationl.ico b/AIK.Assets/Images/AIKInternationl.ico
new file mode 100644
index 0000000..9027bb9
Binary files /dev/null and b/AIK.Assets/Images/AIKInternationl.ico differ
diff --git a/AIK.Assets/Images/AIKInternationl.png b/AIK.Assets/Images/AIKInternationl.png
new file mode 100644
index 0000000..203efd4
Binary files /dev/null and b/AIK.Assets/Images/AIKInternationl.png differ
diff --git a/AIK.Assets/Images/k3-tpms.png b/AIK.Assets/Images/k3-tpms.png
new file mode 100644
index 0000000..9fc86e8
Binary files /dev/null and b/AIK.Assets/Images/k3-tpms.png differ
diff --git a/AIK.Assets/Images/k3_tool.png b/AIK.Assets/Images/k3_tool.png
new file mode 100644
index 0000000..080ac04
Binary files /dev/null and b/AIK.Assets/Images/k3_tool.png differ
diff --git a/AIK.Assets/Images/k3_tool_logo.png b/AIK.Assets/Images/k3_tool_logo.png
new file mode 100644
index 0000000..03adb3f
Binary files /dev/null and b/AIK.Assets/Images/k3_tool_logo.png differ
diff --git a/AIK.Assets/Images/logo.ico b/AIK.Assets/Images/logo.ico
new file mode 100644
index 0000000..58bb011
Binary files /dev/null and b/AIK.Assets/Images/logo.ico differ
diff --git a/AIK.Assets/Images/logo.png b/AIK.Assets/Images/logo.png
new file mode 100644
index 0000000..1fcaccf
Binary files /dev/null and b/AIK.Assets/Images/logo.png differ
diff --git a/AIK.Assets/Images/useravatar.png b/AIK.Assets/Images/useravatar.png
new file mode 100644
index 0000000..7249f29
Binary files /dev/null and b/AIK.Assets/Images/useravatar.png differ
diff --git a/AIK.Assets/Languages/Strings.de.xaml b/AIK.Assets/Languages/Strings.de.xaml
new file mode 100644
index 0000000..c70ce61
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.de.xaml
@@ -0,0 +1,119 @@
+
+ AIK. Intelligentes Schluesselwerkzeug
+ Einstellungen
+ Sprache
+ App-Einstellungen
+ Grundparameter und Praeferenzen der Anwendung konfigurieren
+
+ Oberflaecheneinstellungen
+ Cache-Einstellungen
+ Daten-Cache leeren
+ Oberflaechensprache:
+ Schluesselmodellliste
+
+ Speichern
+ Abbrechen
+ Bestaetigen
+
+ Nach Markenname, Englisch oder Pinyin suchen...
+ Nach Fahrzeugschluesselname, Englisch oder Pinyin suchen...
+
+ Untergeraet:
+ Frequenz:
+ Chip:
+ Zeit:
+ ID:
+
+ Informationen
+
+ Einstellungen erfolgreich gespeichert
+
+ Kontakt per WeChat
+ Kontakt per E-Mail
+ WeChat kopiert
+ E-Mail kopiert
+ Telefonnummer
+ Punkte
+ Abmelden
+
+ Geraeteaktualisierung
+ Aktuelle Version
+ Neue Version
+ Geraetestatus
+ Geraetename
+ Jetzt aktualisieren
+ Version abrufen
+ App-Version
+ Serverversion
+ Geraeteversion
+ Versionsaktualisierung
+ Aktualisierungen fuer Firmware, Anwendung und Geraeteversionen
+ Schreibprotokoll
+ Schluesselschreibprotokoll
+ Punkte aufladen
+ Mitgliedschaft
+ Punkteverlauf
+ Ihre Punkte
+ Aufladebetrag eingeben
+ Zahlungsmethode auswählen
+ WeChat Pay
+ PayPal
+ Bezahlen
+
+ Fernbedienungserkennung
+ Fernbedienung kopieren
+ HCS / Festcode kopieren
+ Klicken Sie unten auf die Test-Schaltflaeche, um die Frequenz zu erkennen. Nachdem das Geraet verbunden ist, druecken Sie eine Taste am Untergeraet innerhalb der Testreichweite. Danach wird die Frequenz angezeigt.
+ Klicken Sie unten auf die Test-Schaltflaeche, um die Frequenz zu erkennen. Nachdem das Geraet verbunden ist, druecken Sie eine Taste am Untergeraet innerhalb der Testreichweite. Danach wird die Frequenz angezeigt.
+ Modus:
+
+ Erkennung
+ Diese Taste ueberspringen
+ Erneut pruefen
+ Kopieren starten
+ Verriegeln
+ Entriegeln
+ Kofferraum
+ Panik
+
+ Keine passende Marke gefunden
+ Kein passender Suchbegriff gefunden
+ Keine Schluesseldaten verfuegbar
+
+ Daten:
+ Typ:
+ Bitrate:
+ Bitlaenge:
+
+ Programmierung starten
+ Hinweis
+ Empfehlen Sie es Ihren Freunden! Scannen Sie den QR-Code mit WeChat, QQ usw., um die App herunterzuladen und zu installieren.
+ Wir werden Schlosser auch weiterhin wie gewohnt unterstuetzen.
+ Scannen Sie, um die mobile App herunterzuladen
+ Neueste Informationen und Support erhalten
+ Mehr anzeigen
+ Laden...
+ Cloud-Daten
+ Jetzt aktualisieren
+ Spaeter aktualisieren
+ Neue Version gefunden
+ Update-Hinweise
+
+ Cloud-Daten-Synchronisierung
+ Waehrend der Synchronisierung der Cloud-Daten wird das Geraet neu gestartet und die Verbindung wird voruebergehend getrennt. Das ist normal. Bitte warten Sie, bis das System die Geraetefunktionen erneut initialisiert hat.
+ Zur Verbesserung der Geraetestabilitaet koennen Sie die Systemeinstellungen anpassen: Systemsteuerung -> Energieoptionen -> Energiesparplaneinstellungen aendern -> Erweiterte Energieeinstellungen aendern -> USB-Einstellungen -> Einstellung fuer selektives USB-Energiesparen -> [Deaktiviert]
+ Hinweis: Fuehren Sie den Vorgang nur bei verbundenem Geraet aus
+ USB-Laufwerk oeffnen (Test)
+ USB-Laufwerk schliessen (Test)
+ Datei auswaehlen
+ Ordner auswaehlen
+ Geraet aktiv halten
+ Cloud-Daten synchronisieren
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.en.xaml b/AIK.Assets/Languages/Strings.en.xaml
new file mode 100644
index 0000000..8597137
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.en.xaml
@@ -0,0 +1,117 @@
+
+
+ AIK.Smart Key Tool
+ Settings
+ Language
+ App Settings
+ Configure the basic parameters and preferences of the application
+
+ Interface Settings
+ Cache Settings
+ ClearCache
+ Interface Language:
+ Key Model List
+
+ Save
+ Cancel
+ Confirm
+
+ Search by brand name, English, or pinyin...
+ Search vehicle key name, English, or pinyin...
+
+ Series:
+ Frequency:
+ Chip:
+ Time:
+ ID:
+
+ Information
+
+
+ Settings saved successfully
+
+ Contact us on wechat
+ Contact us by email
+ Contact us by email Copy Success
+ Contact us by email Copy Success
+ PhoneNumber
+ Integral
+ Log out
+ DeviceUpdate
+ CurrentVersion
+ NewVersion
+ DeviceStatus
+ DeviceName
+ Upgrade
+ get version
+ AppVersion
+ ServerVersion
+ DeviceVersion
+ Version upgrade
+ Upgrades for firmware, application and device versions
+ Burn Log
+ Key Burn Log
+ Integral Recharge
+ Membership
+ Integral Record
+ Your Points
+ Enter recharge amount
+ Select payment method
+ WeChat Pay
+ PayPal
+ Pay
+ Remote Detection
+ Remote Copy
+ HCS / Fixed-Code Copy
+ Click the Test button below to detect the frequency. After connecting the device, press a button on the sub-unit within the testable range, and the frequency will be displayed.
+ Click the Test button below to detect the frequency. After connecting the device, press a button on the sub-unit within the testable range, and the frequency will be displayed.
+ Mode:
+
+ Detection
+ Skip this key
+ Recheck
+ Start copying
+ Lock
+ Unlock
+ Trunk
+ Panic
+
+ No matching brand found
+ No matching brand found
+ No key data available
+
+ Data:
+ Type:
+ Bitrate:
+ Bit length:
+ Start Burning
+ Tip
+ Recommend it to your friends! Scan the QR code with WeChat, QQ, etc. to download and install.
+ We will continue to support locksmiths as always.
+ Scan to download the mobile app
+ Get the latest news and support
+ View More
+ Loading...
+ Cloud Data
+ Update Now
+ Update Later
+ New Version Found
+ Update Tips
+ Cloud Data Sync
+ During cloud data sync, the device will restart and the connection will temporarily disconnect. This is normal. Please wait for the system to reinitialize the device functions.
+ To improve device stability, adjust the system settings: Control Panel -> Power Options -> Change plan settings -> Change advanced power settings -> USB settings -> USB selective suspend setting -> [Disabled]
+ Reminder: Please operate while the device is connected
+ Open USB Drive (Test)
+ Close USB Drive (Test)
+ 📁 Select File
+ 📂 Select Folder
+ Keep Device Alive
+ Sync Cloud Data
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.es.xaml b/AIK.Assets/Languages/Strings.es.xaml
new file mode 100644
index 0000000..abb19a9
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.es.xaml
@@ -0,0 +1,116 @@
+
+
+ AIK.Herramienta de Llave Inteligente
+ Configuración
+ Idioma
+ Configuración de la Aplicación
+ Configurar los parámetros básicos y preferencias de la aplicación
+
+ Configuración de Interfaz
+ Configuración de Caché
+ Limpiar Caché de Datos
+ Idioma de la interfaz:
+ Lista de Modelos de Llave
+
+ Guardar
+ Cancelar
+ Confirmar
+
+ Buscar nombre de marca, inglés o pinyin...
+ Buscar nombre de llave de vehículo, inglés o pinyin...
+
+ Llave Remota:
+ Frecuencia:
+ Información de Referencia:
+ Hora:
+ ID:
+
+ Información de Referencia
+
+ Configuración guardada correctamente
+
+ Contáctanos por WeChat
+ Contáctanos por Correo Electrónico
+ Copiar WeChat
+ Copiar Correo Electrónico
+ Teléfono Móvil
+ Puntos
+ Cerrar sesión
+ Actualización de Dispositivo
+ Versión Actual
+ Última Versión
+ Estado del Dispositivo
+ Nombre del Dispositivo
+ Actualizar Ahora
+ Obtener Versión
+ Versión de la APP
+ Versión del Servidor
+ Versión del Dispositivo
+ Centro de Actualización
+ Actualización de firmware, aplicación, dispositivo, etc.
+ Registro de grabación
+ Registro de grabación de llaves
+ Recarga de puntos
+ Membresía
+ Registro de puntos
+ Tus puntos
+ Ingrese el importe de recarga
+ Seleccione método de pago
+ WeChat Pay
+ PayPal
+ Pagar
+ Detección Remota
+ Copia Remota
+ Copia HCS / Código Fijo
+ Haga clic en el botón Probar de abajo para detectar la frecuencia. Tras conectar el dispositivo, pulse un botón en la unidad secundaria dentro del rango de prueba y se mostrará la frecuencia.
+ Haga clic en el botón Probar de abajo para detectar la frecuencia. Tras conectar el dispositivo, pulse un botón en la unidad secundaria dentro del rango de prueba y se mostrará la frecuencia.
+ Modo:
+
+ Detección
+ Omitir esta tecla
+ Volver a comprobar
+ Iniciar copia
+ Cerrar con llave
+ Desbloquear
+ Maletero
+ Buscar vehículo
+
+ No se encontró ninguna marca coincidente
+ No se encontró ninguna marca coincidente
+ Sin datos de la llave disponibles
+
+ Datos:
+ Tipo:
+ Tasa de bits:
+ Longitud en bits:
+ Iniciar Programación
+ Consejo
+ ¡Recomiéndalo a tus amigos! Escanea el código QR con WeChat, QQ, etc. para descargar e instalar.
+ Seguiremos apoyando a los cerrajeros como siempre.
+ Escanea para descargar la aplicación móvil
+ Obtén las últimas noticias y soporte
+ Ver más
+ Cargando...
+ Datos en la Nube
+ Actualizar Ahora
+ Actualizar Más Tarde
+ Nueva Versión Encontrada
+ Consejos de Actualización
+ Sincronización de datos en la nube
+ Durante la sincronización de datos en la nube, el dispositivo se reiniciará y la conexión se desconectará temporalmente. Esto es normal. Espere pacientemente a que el sistema reinicialice las funciones del dispositivo.
+ Para mejorar la estabilidad del dispositivo, ajuste la configuración del sistema: Panel de control -> Opciones de energía -> Cambiar la configuración del plan -> Cambiar la configuración avanzada de energía -> Configuración de USB -> Configuración de suspensión selectiva de USB -> [Deshabilitado]
+ Recordatorio: realice la operación mientras el dispositivo esté conectado
+ Abrir unidad USB (prueba)
+ Cerrar unidad USB (prueba)
+ 📁 Seleccionar archivo
+ 📂 Seleccionar carpeta
+ Mantener el dispositivo activo
+ Sincronizar datos en la nube
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.fa.xaml b/AIK.Assets/Languages/Strings.fa.xaml
new file mode 100644
index 0000000..6c1bfc9
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.fa.xaml
@@ -0,0 +1,116 @@
+
+ AIK. ابزار کلید هوشمند
+ تنظیمات
+ زبان
+ تنظیمات برنامه
+ پیکربندی پارامترهای اصلی و ترجیحات برنامه
+
+ تنظیمات رابط
+ تنظیمات کش
+ پاک کردن کش دادهها
+ زبان رابط:
+ لیست مدلهای کلید
+
+ ذخیره
+ لغو
+ تایید
+
+ جستجوی نام برند، انگلیسی یا پینیین...
+ جستجوی نام کلید خودرو، انگلیسی یا پینیین...
+
+ دستگاه فرعی:
+ فرکانس:
+ اطلاعات مرجع:
+ زمان:
+ شناسه:
+
+ اطلاعات مرجع
+
+ تنظیمات با موفقیت ذخیره شد
+
+ تماس با ما از طریق ویچت
+ تماس با ما از طریق ایمیل
+ کپی ویچت
+ کپی ایمیل
+ تلفن همراه
+ امتیاز
+ خروج
+
+ بهروزرسانی دستگاه
+ نسخه فعلی
+ آخرین نسخه
+ وضعیت دستگاه
+ نام دستگاه
+ اکنون بهروزرسانی کنید
+ دریافت نسخه
+ نسخه برنامه
+ نسخه سرور
+ نسخه دستگاه
+ مرکز بهروزرسانی
+ بهروزرسانی فیلموار، برنامه، دستگاه و غیره
+ گزارش سوزنده
+ تاریخچه سوزنده کلید
+ شارژ امتیاز
+ عضویت
+ سابقه امتیاز
+ امتیازهای شما
+ مبلغ شارژ را وارد کنید
+ روش پرداخت را انتخاب کنید
+ پرداخت ویچت
+ PayPal
+ پرداخت
+ تشخیص از راه دور
+ کپی از راه دور
+ کپی HCS / کد ثابت
+ برای تشخیص فرکانس، روی دکمهٔ تست زیر کلیک کنید. پس از اتصال دستگاه، یکی از دکمههای واحد فرعی را در محدودهٔ قابل تست فشار دهید تا فرکانس نمایش داده شود.
+ برای تشخیص فرکانس، روی دکمهٔ تست زیر کلیک کنید. پس از اتصال دستگاه، یکی از دکمههای واحد فرعی را در محدودهٔ قابل تست فشار دهید تا فرکانس نمایش داده شود.
+ حالت:
+
+ تشخیص
+ رد کردن این کلید
+ بررسی مجدد
+ شروع کپی
+ قفل کردن
+ باز کردن قفل
+ صندوق عقب
+ دکمه پانیک
+
+ هیچ برند مطابقی یافت نشد
+ هیچ برند مطابقی یافت نشد
+ دادههای کلید در دسترس نیست
+
+ دادهها:
+ نوع:
+ نرخ بیت:
+ طول بیت:
+ شروع برنامهریزی
+ نکته
+ به دوستان خود پیشنهاد دهید! با استفاده از ویچت، کیوکیو و غیره کد QR را اسکن کنید تا دانلود و نصب شود.
+ همچون گذشته، همچنان از قفلسازان عزیز حمایت خواهیم کرد.
+ برای دانلود برنامه موبایل اسکن کنید
+ جدیدترین اخبار و پشتیبانی را دریافت کنید
+ مشاهده بیشتر
+ در حال بارگذاری...
+ دادههای ابری
+ اکنون بهروزرسانی کنید
+ بعداً بهروزرسانی کنید
+ نسخه جدید پیدا شد
+ نکات بهروزرسانی
+ همگامسازی دادههای ابری
+ در هنگام همگامسازی دادههای ابری، دستگاه راهاندازی مجدد میشود و اتصال بهطور موقت قطع خواهد شد. این طبیعی است. لطفاً با حوصله منتظر بمانید تا سیستم عملکردهای دستگاه را دوباره مقداردهی کند.
+ برای افزایش پایداری دستگاه، تنظیمات سیستم را تغییر دهید: کنترل پنل -> گزینههای برق -> تغییر تنظیمات طرح -> تغییر تنظیمات پیشرفته برق -> تنظیمات USB -> تنظیم تعلیق انتخابی USB -> [غیرفعال]
+ یادآوری: لطفاً عملیات را زمانی انجام دهید که دستگاه متصل است
+ باز کردن درایو USB (آزمایشی)
+ بستن درایو USB (آزمایشی)
+ 📁 انتخاب فایل
+ 📂 انتخاب پوشه
+ دستگاه را فعال نگه دارید
+ همگامسازی دادههای ابری
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.fr.xaml b/AIK.Assets/Languages/Strings.fr.xaml
new file mode 100644
index 0000000..ae83d81
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.fr.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Outil de clés intelligent
+ Paramètres
+ Langue
+ Paramètres de l'application
+ Configurer les paramètres de base et les préférences de l'application
+
+ Paramètres d'interface
+ Paramètres du cache
+ Effacer le cache de données
+ Langue de l'interface :
+ Liste des modèles de clés
+
+ Enregistrer
+ Annuler
+ Confirmer
+
+ Rechercher un nom de marque, en anglais ou en pinyin...
+ Rechercher un nom de clé de véhicule, en anglais ou en pinyin...
+
+ Sous-unité :
+ Fréquence :
+ Informations de référence :
+ Heure :
+ ID :
+
+ Informations de référence
+
+ Paramètres enregistrés avec succès
+
+ Contactez-nous sur WeChat
+ Contactez-nous par e-mail
+ Copier WeChat
+ Copier l'e-mail
+ Téléphone
+ Points
+ Déconnexion
+
+ Mise à jour de l'appareil
+ Version actuelle
+ Dernière version
+ État de l'appareil
+ Nom de l'appareil
+ Mettre à jour maintenant
+ Obtenir la version
+ Version de l'application
+ Version du serveur
+ Version de l'appareil
+ Mises à jour de version
+ Mises à jour du firmware, de l'application, de l'appareil, etc.
+ Journal d'écriture
+ Historique d'écriture des clés
+ Recharger des points
+ Adhésion
+ Historique des points
+ Vos points
+ Saisir le montant de recharge
+ Sélectionnez le mode de paiement
+ WeChat Pay
+ PayPal
+ Payer
+ Détection à distance
+ Copie à distance
+ Copie HCS / Code fixe
+ Cliquez sur le bouton Tester ci-dessous pour détecter la fréquence. Après avoir connecté l’appareil, appuyez sur un bouton de l’unité secondaire à portée de test, et la fréquence s’affichera.
+ Cliquez sur le bouton Tester ci-dessous pour détecter la fréquence. Après avoir connecté l’appareil, appuyez sur un bouton de l’unité secondaire à portée de test, et la fréquence s’affichera.
+ Mode :
+
+ Détection
+ Ignorer cette touche
+ Revérifier
+ Commencer la copie
+ Verrouiller
+ Déverrouiller
+ Coffre
+ Recherche de véhicule
+
+ Aucune marque correspondante trouvée
+ Aucune marque correspondante trouvée
+ Aucune donnée de clé disponible
+
+ Données :
+ Type :
+ Débit binaire :
+ Longueur en bits :
+ Démarrer la programmation
+ Astuce
+ Recommandez-le à vos amis ! Scannez le code QR avec WeChat, QQ, etc. pour télécharger et installer.
+ Nous continuerons à accompagner les serruriers comme toujours.
+ Scannez pour télécharger l’application mobile
+ Obtenez les dernières actualités et le support
+ Voir plus
+ Chargement...
+ Données Cloud
+ Mettre à Jour Maintenant
+ Mettre à Jour Plus Tard
+ Nouvelle Version Trouvée
+ Conseils de Mise à Jour
+ Synchronisation des données cloud
+ Pendant la synchronisation des données cloud, l'appareil redémarrera et la connexion sera temporairement interrompue. C'est normal. Veuillez patienter pendant que le système réinitialise les fonctions de l'appareil.
+ Pour améliorer la stabilité de l'appareil, ajustez les paramètres système : Panneau de configuration -> Options d’alimentation -> Modifier les paramètres du mode -> Modifier les paramètres d’alimentation avancés -> Paramètres USB -> Paramètre de suspension sélective USB -> [Désactivé]
+ Rappel : veuillez effectuer l’opération lorsque l'appareil est connecté
+ Ouvrir la clé USB (test)
+ Fermer la clé USB (test)
+ 📁 Sélectionner un fichier
+ 📂 Sélectionner un dossier
+ Maintenir l'appareil actif
+ Synchroniser les données cloud
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.he.xaml b/AIK.Assets/Languages/Strings.he.xaml
new file mode 100644
index 0000000..5147bc9
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.he.xaml
@@ -0,0 +1,116 @@
+
+ AIK. כלי מפתח חכם
+ הגדרות
+ שפה
+ הגדרות אפליקציה
+ הגדרת פרמטרים ו העדפות בסיסיות לאפליקציה
+
+ הגדרות ממשק
+ הגדרות מטמון
+ נקה מטמון נתונים
+ שפת ממשק:
+ רשימת דגמי מפתחות
+
+ שמור
+ בטל
+ אישור
+
+ חפש שם מותג, אנגלית או פיניין...
+ חפש שם מפתח רכב, אנגלית או פיניין...
+
+ יחידת משנה:
+ תדר:
+ מידע רפרנטי:
+ זמן:
+ מזהה:
+
+ מידע רפרנטי
+
+ ההגדרות נשמרו בהצלחה
+
+ צור איתנו קשר בויצ'אט
+ צור איתנו קשר באימייל
+ העתק ויצ'אט
+ העתק אימייל
+ טלפון
+ נקודות
+ התנתק
+
+ עדכון התקן
+ גרסה נוכחית
+ גרסה חדשה
+ מצב התקן
+ שם התקן
+ עדכן כעת
+ קבל גרסה
+ גרסה של האפליקציה
+ גרסה של השרת
+ גרסה של ההתקן
+ מרכז עדכונים
+ עדכוני פירמה, אפליקציה, התקן וכו'
+ יומן תהליך
+ היסטוריה של תהליך מפתחות
+ טעינת נקודות
+ מנוי
+ רשומת נקודות
+ הנקודות שלך
+ הזן סכום טעינה
+ בחר אמצעי תשלום
+ WeChat Pay
+ PayPal
+ שלם
+ זיהוי מרחוק
+ העתקה מרחוק
+ העתקת HCS / קוד קבוע
+ לחצו על כפתור הבדיקה להלן כדי לזהות את התדר. לאחר חיבור המכשיר, לחצו על כפתור ביחידת המשנה בתוך טווח הבדיקה, והתדר יוצג.
+ לחצו על כפתור הבדיקה להלן כדי לזהות את התדר. לאחר חיבור המכשיר, לחצו על כפתור ביחידת המשנה בתוך טווח הבדיקה, והתדר יוצג.
+ מצב:
+
+ זיהוי
+ דלג על מקש זה
+ בדוק שוב
+ התחל העתקה
+ לנעול
+ פתח נעילה
+ תא מטען
+ מצא רכב
+
+ לא נמצאה מותג תואם
+ לא נמצאה מותג תואם
+ אין נתוני מפתח זמינים
+
+ נתונים:
+ סוג:
+ קצב סיביות:
+ אורך הסיביות:
+ התחל תכנות
+ טיפ
+ המלץ לחבריך! סרוק את קוד ה-QR עם WeChat, QQ וכו' כדי להוריד ולהתקין.
+ נמשיך לתמוך בנגרי המפתחות כרגיל.
+ סרוק כדי להוריד את האפליקציה לנייד
+ קבל את העדכונים והתמיכה האחרונים
+ הצג עוד
+ טוען...
+ נתונים בענן
+ עדכן עכשיו
+ עדכן מאוחר יותר
+ נמצאה גרסה חדשה
+ טיפים לעדכון
+ סנכרון נתוני ענן
+ במהלך סנכרון נתוני הענן, המכשיר יופעל מחדש והחיבור יתנתק באופן זמני. זה תקין. אנא המתן בסבלנות בזמן שהמערכת מאתחלת מחדש את פונקציות המכשיר.
+ כדי לשפר את יציבות המכשיר, שנה את הגדרות המערכת: לוח הבקרה -> אפשרויות צריכת חשמל -> שנה הגדרות תוכנית -> שנה הגדרות צריכת חשמל מתקדמות -> הגדרות USB -> הגדרת השהיה סלקטיבית של USB -> [מושבת]
+ תזכורת: יש לבצע את הפעולה כשהמכשיר מחובר
+ פתח כונן USB (בדיקה)
+ סגור כונן USB (בדיקה)
+ 📁 בחר קובץ
+ 📂 בחר תיקייה
+ השאר את המכשיר פעיל
+ סנכרן נתוני ענן
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.hi.xaml b/AIK.Assets/Languages/Strings.hi.xaml
new file mode 100644
index 0000000..026f918
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.hi.xaml
@@ -0,0 +1,116 @@
+
+ AIK. स्मार्ट की टूल
+ सेटिंग्स
+ भाषा
+ ऐप सेटिंग्स
+ ऐप के मूल पैरामीटर और पसंद कॉन्फ़िगर करें
+
+ इंटरफ़ेस सेटिंग्स
+ कैश सेटिंग्स
+ डेटा कैश साफ़ करें
+ इंटरफ़ेस भाषा:
+ की मॉडल सूची
+
+ सहेजें
+ रद्द करें
+ पुष्टि करें
+
+ ब्रांड नाम, अंग्रेजी या पिनयिन में खोजें...
+ वाहन की नाम, अंग्रेजी या पिनयिन में खोजें...
+
+ उपकरण:
+ आवृत्ति:
+ संदर्भ जानकारी:
+ समय:
+ ID:
+
+ संदर्भ जानकारी
+
+ सेटिंग्स सफलतापूर्वक सहेजी गई
+
+ हमसे वीचैट पर संपर्क करें
+ हमसे ईमेल पर संपर्क करें
+ वीचैट कॉपी करें
+ ईमेल कॉपी करें
+ मोबाइल
+ अंक
+ लॉग आउट
+
+ डिवाइस अपडेट
+ वर्तमान संस्करण
+ नवीनतम संस्करण
+ डिवाइस स्थिति
+ डिवाइस नाम
+ अभी अपडेट करें
+ संस्करण प्राप्त करें
+ ऐप संस्करण
+ सर्वर संस्करण
+ डिवाइस संस्करण
+ संस्करण अपडेट
+ फ़र्मवेयर, ऐप, डिवाइस आदि के अपडेट
+ बर्न लॉग
+ की बर्न लॉग
+ पॉइंट रिचार्ज
+ सदस्यता
+ पॉइंट रिकॉर्ड
+ आपके पॉइंट
+ रिचार्ज राशि दर्ज करें
+ भुगतान विधि चुनें
+ WeChat Pay
+ PayPal
+ भुगतान
+ रिमोट डिटेक्शन
+ रिमोट कॉपी
+ HCS / फिक्स्ड-कोड कॉपी
+ आवृत्ति का पता लगाने के लिए नीचे दिए गए टेस्ट बटन पर क्लिक करें। डिवाइस कनेक्ट करने के बाद, टेस्ट रेंज के भीतर सब-यूनिट का कोई बटन दबाएं, और आवृत्ति दिखाई देगी।
+ आवृत्ति का पता लगाने के लिए नीचे दिए गए टेस्ट बटन पर क्लिक करें। डिवाइस कनेक्ट करने के बाद, टेस्ट रेंज के भीतर सब-यूनिट का कोई बटन दबाएं, और आवृत्ति दिखाई देगी।
+ मोड:
+
+ पता लगाना
+ इस कुंजी को छोड़ें
+ फिर से जांचें
+ कॉपी करना शुरू करें
+ ताला लगाएं
+ ताला खोलें
+ ट्रंक
+ आपातकालीन बजर
+
+ कोई मेल खाने वाला ब्रांड नहीं मिला
+ कोई मेल खाने वाला ब्रांड नहीं मिला
+ कुंजी डेटा उपलब्ध नहीं है
+
+ डेटा:
+ प्रकार:
+ बिटरेट:
+ बिट लंबाई:
+ प्रोग्रामिंग शुरू करें
+ सुझाव
+ इसे अपने दोस्तों को अवश्य बताएं! WeChat, QQ आदि से QR कोड स्कैन करके डाउनलोड और इंस्टॉल करें।
+ हम हमेशा की तरह लॉकस्मिथ्स का समर्थन करते रहेंगे।
+ मोबाइल ऐप डाउनलोड करने के लिए स्कैन करें
+ नवीनतम जानकारी और सहायता प्राप्त करें
+ अधिक देखें
+ लोड हो रहा है...
+ क्लाउड डेटा
+ अभी अपडेट करें
+ बाद में अपडेट करें
+ नew वर्जन पाया गया
+ अपडेट टिप्स
+ क्लाउड डेटा सिंक
+ क्लाउड डेटा सिंक करते समय, डिवाइस रीस्टार्ट होगा और कनेक्शन अस्थायी रूप से टूट जाएगा। यह सामान्य है। सिस्टम के डिवाइस फ़ंक्शन को दोबारा प्रारंभ करने तक कृपया धैर्य रखें।
+ डिवाइस की स्थिरता बढ़ाने के लिए सिस्टम सेटिंग समायोजित करें: कंट्रोल पैनल -> पावर ऑप्शंस -> प्लान सेटिंग बदलें -> उन्नत पावर सेटिंग बदलें -> USB सेटिंग्स -> USB सेलेक्टिव सस्पेंड सेटिंग -> [अक्षम]
+ याद दिलाना: कृपया डिवाइस कनेक्टेड होने पर ही ऑपरेशन करें
+ USB ड्राइव खोलें (परीक्षण)
+ USB ड्राइव बंद करें (परीक्षण)
+ 📁 फ़ाइल चुनें
+ 📂 फ़ोल्डर चुनें
+ डिवाइस को सक्रिय रखें
+ क्लाउड डेटा सिंक करें
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.id.xaml b/AIK.Assets/Languages/Strings.id.xaml
new file mode 100644
index 0000000..a7398bb
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.id.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Alat Kunci Cerdas
+ Pengaturan
+ Bahasa
+ Pengaturan Aplikasi
+ Konfigurasi parameter dasar dan preferensi aplikasi
+
+ Pengaturan Antarmuka
+ Pengaturan Cache
+ Hapus cache data
+ Bahasa antarmuka:
+ Daftar Model Kunci
+
+ Simpan
+ Batal
+ Konfirmasi
+
+ Cari nama merek, bahasa Inggris, atau pinyin...
+ Cari nama kunci kendaraan, bahasa Inggris, atau pinyin...
+
+ Subunit:
+ Frekuensi:
+ Informasi Referensi:
+ Waktu:
+ ID:
+
+ Informasi Referensi
+
+ Pengaturan berhasil disimpan
+
+ Hubungi kami via WeChat
+ Hubungi kami via Email
+ Salin WeChat
+ Salin Email
+ Telepon Seluler
+ Poin
+ Keluar
+
+ Pembaruan Perangkat
+ Versi Saat Ini
+ Versi Terbaru
+ Status Perangkat
+ Nama Perangkat
+ Perbarui Sekarang
+ Dapatkan Versi
+ Versi Aplikasi
+ Versi Server
+ Versi Perangkat
+ Pembaruan Versi
+ Pembaruan firmware, aplikasi, perangkat, dll.
+ Log Pembakaran
+ Riwayat Pembakaran Kunci
+ Isi ulang poin
+ Keanggotaan
+ Riwayat poin
+ Poin Anda
+ Masukkan jumlah isi ulang
+ Pilih metode pembayaran
+ WeChat Pay
+ PayPal
+ Bayar
+ Deteksi Jarak Jauh
+ Salin Remote
+ Salin HCS / Kode Tetap
+ Klik tombol Uji di bawah untuk mendeteksi frekuensi. Setelah menghubungkan perangkat, tekan tombol pada unit sekunder dalam jangkauan pengujian, dan frekuensinya akan ditampilkan.
+ Klik tombol Uji di bawah untuk mendeteksi frekuensi. Setelah menghubungkan perangkat, tekan tombol pada unit sekunder dalam jangkauan pengujian, dan frekuensinya akan ditampilkan.
+ Mode:
+
+ Deteksi
+ Lewati kunci ini
+ Periksa ulang
+ Mulai menyalin
+ Kunci
+ Buka kunci
+ Bagasi
+ Cari mobil
+
+ Tidak ada merek yang cocok ditemukan
+ Tidak ada merek yang cocok ditemukan
+ Tidak ada data kunci tersedia
+
+ Data:
+ Jenis:
+ Laju bit:
+ Panjang bit:
+ Mulai Pemrograman
+ Tips
+ Rekomendasikan ke teman Anda! Pindai kode QR dengan WeChat, QQ, dll. untuk mengunduh dan menginstal.
+ Kami akan terus mendukung para tukang kunci seperti biasa.
+ Pindai untuk mengunduh aplikasi seluler
+ Dapatkan berita terbaru dan dukungan
+ Lihat lainnya
+ Memuat...
+ Data Cloud
+ Perbarui Sekarang
+ Perbarui Nanti
+ Versi Baru Ditemukan
+ Tips Pembaruan
+ Sinkronisasi data cloud
+ Saat menyinkronkan data cloud, perangkat akan dimulai ulang dan koneksi akan terputus sementara. Ini normal. Harap tunggu dengan sabar hingga sistem menginisialisasi ulang fungsi perangkat.
+ Untuk meningkatkan stabilitas perangkat, sesuaikan pengaturan sistem: Control Panel -> Opsi Daya -> Ubah pengaturan paket -> Ubah pengaturan daya lanjutan -> Pengaturan USB -> Pengaturan penangguhan selektif USB -> [Dinonaktifkan]
+ Pengingat: Harap lakukan operasi saat perangkat terhubung
+ Buka drive USB (uji)
+ Tutup drive USB (uji)
+ 📁 Pilih file
+ 📂 Pilih folder
+ Jaga perangkat tetap aktif
+ Sinkronkan data cloud
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.in.xaml b/AIK.Assets/Languages/Strings.in.xaml
new file mode 100644
index 0000000..026f918
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.in.xaml
@@ -0,0 +1,116 @@
+
+ AIK. स्मार्ट की टूल
+ सेटिंग्स
+ भाषा
+ ऐप सेटिंग्स
+ ऐप के मूल पैरामीटर और पसंद कॉन्फ़िगर करें
+
+ इंटरफ़ेस सेटिंग्स
+ कैश सेटिंग्स
+ डेटा कैश साफ़ करें
+ इंटरफ़ेस भाषा:
+ की मॉडल सूची
+
+ सहेजें
+ रद्द करें
+ पुष्टि करें
+
+ ब्रांड नाम, अंग्रेजी या पिनयिन में खोजें...
+ वाहन की नाम, अंग्रेजी या पिनयिन में खोजें...
+
+ उपकरण:
+ आवृत्ति:
+ संदर्भ जानकारी:
+ समय:
+ ID:
+
+ संदर्भ जानकारी
+
+ सेटिंग्स सफलतापूर्वक सहेजी गई
+
+ हमसे वीचैट पर संपर्क करें
+ हमसे ईमेल पर संपर्क करें
+ वीचैट कॉपी करें
+ ईमेल कॉपी करें
+ मोबाइल
+ अंक
+ लॉग आउट
+
+ डिवाइस अपडेट
+ वर्तमान संस्करण
+ नवीनतम संस्करण
+ डिवाइस स्थिति
+ डिवाइस नाम
+ अभी अपडेट करें
+ संस्करण प्राप्त करें
+ ऐप संस्करण
+ सर्वर संस्करण
+ डिवाइस संस्करण
+ संस्करण अपडेट
+ फ़र्मवेयर, ऐप, डिवाइस आदि के अपडेट
+ बर्न लॉग
+ की बर्न लॉग
+ पॉइंट रिचार्ज
+ सदस्यता
+ पॉइंट रिकॉर्ड
+ आपके पॉइंट
+ रिचार्ज राशि दर्ज करें
+ भुगतान विधि चुनें
+ WeChat Pay
+ PayPal
+ भुगतान
+ रिमोट डिटेक्शन
+ रिमोट कॉपी
+ HCS / फिक्स्ड-कोड कॉपी
+ आवृत्ति का पता लगाने के लिए नीचे दिए गए टेस्ट बटन पर क्लिक करें। डिवाइस कनेक्ट करने के बाद, टेस्ट रेंज के भीतर सब-यूनिट का कोई बटन दबाएं, और आवृत्ति दिखाई देगी।
+ आवृत्ति का पता लगाने के लिए नीचे दिए गए टेस्ट बटन पर क्लिक करें। डिवाइस कनेक्ट करने के बाद, टेस्ट रेंज के भीतर सब-यूनिट का कोई बटन दबाएं, और आवृत्ति दिखाई देगी।
+ मोड:
+
+ पता लगाना
+ इस कुंजी को छोड़ें
+ फिर से जांचें
+ कॉपी करना शुरू करें
+ ताला लगाएं
+ ताला खोलें
+ ट्रंक
+ आपातकालीन बजर
+
+ कोई मेल खाने वाला ब्रांड नहीं मिला
+ कोई मेल खाने वाला ब्रांड नहीं मिला
+ कुंजी डेटा उपलब्ध नहीं है
+
+ डेटा:
+ प्रकार:
+ बिटरेट:
+ बिट लंबाई:
+ प्रोग्रामिंग शुरू करें
+ सुझाव
+ इसे अपने दोस्तों को अवश्य बताएं! WeChat, QQ आदि से QR कोड स्कैन करके डाउनलोड और इंस्टॉल करें।
+ हम हमेशा की तरह लॉकस्मिथ्स का समर्थन करते रहेंगे।
+ मोबाइल ऐप डाउनलोड करने के लिए स्कैन करें
+ नवीनतम जानकारी और सहायता प्राप्त करें
+ अधिक देखें
+ लोड हो रहा है...
+ क्लाउड डेटा
+ अभी अपडेट करें
+ बाद में अपडेट करें
+ नew वर्जन पाया गया
+ अपडेट टिप्स
+ क्लाउड डेटा सिंक
+ क्लाउड डेटा सिंक करते समय, डिवाइस रीस्टार्ट होगा और कनेक्शन अस्थायी रूप से टूट जाएगा। यह सामान्य है। सिस्टम के डिवाइस फ़ंक्शन को दोबारा प्रारंभ करने तक कृपया धैर्य रखें।
+ डिवाइस की स्थिरता बढ़ाने के लिए सिस्टम सेटिंग समायोजित करें: कंट्रोल पैनल -> पावर ऑप्शंस -> प्लान सेटिंग बदलें -> उन्नत पावर सेटिंग बदलें -> USB सेटिंग्स -> USB सेलेक्टिव सस्पेंड सेटिंग -> [अक्षम]
+ याद दिलाना: कृपया डिवाइस कनेक्टेड होने पर ही ऑपरेशन करें
+ USB ड्राइव खोलें (परीक्षण)
+ USB ड्राइव बंद करें (परीक्षण)
+ 📁 फ़ाइल चुनें
+ 📂 फ़ोल्डर चुनें
+ डिवाइस को सक्रिय रखें
+ क्लाउड डेटा सिंक करें
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.it.xaml b/AIK.Assets/Languages/Strings.it.xaml
new file mode 100644
index 0000000..c438351
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.it.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Strumente Chiave Intelligente
+ Impostazioni
+ Lingua
+ Impostazioni App
+ Configura parametri di base e preferenze dell'app
+
+ Impostazioni Interfaccia
+ Impostazioni Cache
+ Cancella cache dati
+ Lingua interfaccia:
+ Elenco Modelli Chiave
+
+ Salva
+ Annulla
+ Conferma
+
+ Cerca nome marca, inglese o pinyin...
+ Cerca nome chiave veicolo, inglese o pinyin...
+
+ Sottounità:
+ Frequenza:
+ Informazioni Riferimento:
+ Ora:
+ ID:
+
+ Informazioni Riferimento
+
+ Impostazioni salvate correttamente
+
+ Contattaci via WeChat
+ Contattaci via Email
+ Copia WeChat
+ Copia Email
+ Telefono
+ Punti
+ Esci
+
+ Aggiornamento Dispositivo
+ Versione Corrente
+ Ultima Versione
+ Stato Dispositivo
+ Nome Dispositivo
+ Aggiorna Ora
+ Ottieni Versione
+ Versione App
+ Versione Server
+ Versione Dispositivo
+ Aggiornamenti Versione
+ Aggiornamenti firmware, app, dispositivo ecc.
+ Log Scrittura
+ Cronologia Scrittura Chiave
+ Ricarica punti
+ Abbonamento
+ Storico punti
+ I tuoi punti
+ Inserisci importo ricarica
+ Seleziona metodo di pagamento
+ WeChat Pay
+ PayPal
+ Paga
+ Rilevamento Remoto
+ Copia Telecomando
+ Copia HCS / Codice Fisso
+ Fai clic sul pulsante Test qui sotto per rilevare la frequenza. Dopo aver collegato il dispositivo, premi un tasto sull'unità secondaria entro la distanza di test e la frequenza verrà visualizzata.
+ Fai clic sul pulsante Test qui sotto per rilevare la frequenza. Dopo aver collegato il dispositivo, premi un tasto sull'unità secondaria entro la distanza di test e la frequenza verrà visualizzata.
+ Modalità:
+
+ Rilevamento
+ Salta questo tasto
+ Ricontrolla
+ Avvia copia
+ Blocca
+ Sblocca
+ Baule
+ Cerca veicolo
+
+ Nessun marchio corrispondente trovato
+ Nessun marchio corrispondente trovato
+ Nessun dato chiave disponibile
+
+ Dati:
+ Tipo:
+ Bitrate:
+ Lunghezza in bit:
+ Avvia Programmazione
+ Suggerimento
+ Consiglalo ai tuoi amici! Scansiona il codice QR con WeChat, QQ, ecc. per scaricare e installare.
+ Continueremo a supportare i fabbri come sempre.
+ Scansiona per scaricare l’app mobile
+ Ottieni le ultime novità e il supporto
+ Visualizza altro
+ Caricamento...
+ Dati Cloud
+ Aggiorna Ora
+ Aggiorna Più Tardi
+ Nuova Versione Trovata
+ Suggerimenti per l'Aggiornamento
+ Sincronizzazione dati cloud
+ Durante la sincronizzazione dei dati cloud, il dispositivo si riavvierà e la connessione verrà temporaneamente interrotta. È normale. Attendere pazientemente che il sistema reinizializzi le funzioni del dispositivo.
+ Per migliorare la stabilità del dispositivo, regolare le impostazioni di sistema: Pannello di controllo -> Opzioni risparmio energia -> Modifica impostazioni combinazione -> Cambia impostazioni avanzate risparmio energia -> Impostazioni USB -> Impostazione sospensione selettiva USB -> [Disattivato]
+ Promemoria: eseguire l’operazione mentre il dispositivo è connesso
+ Apri unità USB (test)
+ Chiudi unità USB (test)
+ 📁 Seleziona file
+ 📂 Seleziona cartella
+ Mantieni attivo il dispositivo
+ Sincronizza dati cloud
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.ko.xaml b/AIK.Assets/Languages/Strings.ko.xaml
new file mode 100644
index 0000000..86c7f6b
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.ko.xaml
@@ -0,0 +1,116 @@
+
+ AIK. 스마트 키 도구
+ 설정
+ 언어
+ 앱 설정
+ 앱의 기본 매개변수 및 환경설정 구성
+
+ 인터페이스 설정
+ 캐시 설정
+ 데이터 캐시 삭제
+ 인터페이스 언어:
+ 키 모델 목록
+
+ 저장
+ 취소
+ 확인
+
+ 브랜드 이름, 영어 또는 병음 검색...
+ 차량 키 이름, 영어 또는 병음 검색...
+
+ 서브 유닛:
+ 주파수:
+ 참조 정보:
+ 시간:
+ ID:
+
+ 참조 정보
+
+ 설정이 성공적으로 저장되었습니다
+
+ 위챗으로 문의하기
+ 이메일로 문의하기
+ 위챗 복사
+ 이메일 복사
+ 휴대폰
+ 포인트
+ 로그아웃
+
+ 장치 업데이트
+ 현재 버전
+ 최신 버전
+ 장치 상태
+ 장치 이름
+ 지금 업그레이드
+ 버전 확인
+ 앱 버전
+ 서버 버전
+ 장치 버전
+ 버전 업데이트
+ 펌웨어, 앱, 장치 등 업데이트
+ 소각 로그
+ 키 소각 기록
+ 포인트 충전
+ 멤버십
+ 포인트 기록
+ 내 포인트
+ 충전 금액 입력
+ 결제 방법 선택
+ WeChat Pay
+ PayPal
+ 결제
+ 원격 감지
+ 리모컨 복사
+ HCS / 고정 코드 복사
+ 아래의 테스트 버튼을 클릭하여 주파수를 감지하세요. 장치를 연결한 후, 테스트 가능 거리 내에서 서브 유닛의 버튼을 누르면 주파수가 표시됩니다.
+ 아래의 테스트 버튼을 클릭하여 주파수를 감지하세요. 장치를 연결한 후, 테스트 가능 거리 내에서 서브 유닛의 버튼을 누르면 주파수가 표시됩니다.
+ 모드:
+
+ 감지
+ 이 키 건너뛰기
+ 재확인
+ 복사 시작
+ 잠금
+ 잠금 해제
+ 트렁크
+ 찾기
+
+ 일치하는 브랜드 없음
+ 일치하는 브랜드 없음
+ 키 데이터 없음
+
+ 데이터:
+ 유형:
+ 비트레이트:
+ 비트 길이:
+ 프로그래밍 시작
+ 팁
+ 친구들에게 추천하세요! 위챗, QQ 등으로 QR 코드를 스캔하여 다운로드 및 설치하세요.
+ 앞으로도 자물쇠 기술자 여러분을 항상 지원하겠습니다.
+ 모바일 앱 다운로드를 위해 스캔하세요
+ 최신 소식과 지원 정보를 확인하세요
+ 더 보기
+ 로딩 중...
+ 클라우드 데이터
+ 지금 업데이트
+ 나중에 업데이트
+ 새 버전 발견
+ 업데이트 팁
+ 클라우드 데이터 동기화
+ 클라우드 데이터를 동기화하는 동안 장치가 재시작되고 연결이 일시적으로 끊어집니다. 이는 정상적인 현상입니다. 시스템이 장치 기능을 다시 초기화할 때까지 잠시 기다려 주세요.
+ 장치 안정성을 높이려면 시스템 설정을 조정하세요: 제어판 -> 전원 옵션 -> 절전 계획 설정 변경 -> 고급 전원 관리 옵션 설정 변경 -> USB 설정 -> USB 선택적 절전 모드 설정 -> [사용 안 함]
+ 알림: 장치가 연결된 상태에서 작업해 주세요
+ USB 드라이브 열기(테스트)
+ USB 드라이브 닫기(테스트)
+ 📁 파일 선택
+ 📂 폴더 선택
+ 장치 활성 상태 유지
+ 클라우드 데이터 동기화
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.ms.xaml b/AIK.Assets/Languages/Strings.ms.xaml
new file mode 100644
index 0000000..1bc6f1b
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.ms.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Alat Kunci Pintar
+ Tetapan
+ Bahasa
+ Tetapan Aplikasi
+ Konfigurasi parameter asas dan keutamaan aplikasi
+
+ Tetapan Antara Muka
+ Tetapan Cache
+ Padam cache data
+ Bahasa antara muka:
+ Senarai Model Kunci
+
+ Simpan
+ Batal
+ Sahkan
+
+ Cari nama jenama, Bahasa Inggeris atau pinyin...
+ Cari nama kunci kenderaan, Bahasa Inggeris atau pinyin...
+
+ Subunit:
+ Frekuensi:
+ Maklumat Rujukan:
+ Masa:
+ ID:
+
+ Maklumat Rujukan
+
+ Tetapan berjaya disimpan
+
+ Hubungi kami melalui WeChat
+ Hubungi kami melalui Emel
+ Salin WeChat
+ Salin Emel
+ Telefon Bimbit
+ Poin
+ Log Keluar
+
+ Kemas Kini Peranti
+ Versi Semasa
+ Versi Terkini
+ Status Peranti
+ Nama Peranti
+ Kemas Kini Sekarang
+ Dapatkan Versi
+ Versi Aplikasi
+ Versi Pelayan
+ Versi Peranti
+ Kemas Kini Versi
+ Kemas kini firmware, aplikasi, peranti dan lain-lain
+ Log Penulisan
+ Sejarah Penulisan Kunci
+ Tambah nilai mata
+ Keahlian
+ Rekod mata
+ Mata anda
+ Masukkan jumlah tambah nilai
+ Pilih kaedah pembayaran
+ WeChat Pay
+ PayPal
+ Bayar
+ Pengesanan Jauh
+ Salinan Remote
+ Salinan HCS / Kod Tetap
+ Klik butang Uji di bawah untuk mengesan frekuensi. Selepas menyambungkan peranti, tekan but pada unit sekunder dalam julat ujian, dan frekuensi akan dipaparkan.
+ Klik butang Uji di bawah untuk mengesan frekuensi. Selepas menyambungkan peranti, tekan but pada unit sekunder dalam julat ujian, dan frekuensi akan dipaparkan.
+ Mod:
+
+ Pengesanan
+ Langkau kekunci ini
+ Semak semula
+ Mula menyalin
+ Kunci
+ Buka kunci
+ But
+ Cari kereta
+
+ Tiada jenama sepadan dijumpai
+ Tiada jenama sepadan dijumpai
+ Tiada data kunci tersedia
+
+ Data:
+ Jenis:
+ Kadar bit:
+ Panjang bit:
+ Mulakan Pengaturcaraan
+ Petua
+ Cadangkan kepada rakan anda! Imbas kod QR dengan WeChat, QQ, dsb. untuk muat turun dan pasang.
+ Kami akan terus menyokong tukang kunci seperti biasa.
+ Imbas untuk memuat turun aplikasi mudah alih
+ Dapatkan maklumat terkini dan sokongan
+ Lihat Lebih Banyak
+ Memuat...
+ Data Awan
+ Kemas Kini Sekarang
+ Kemas Kini Kemudian
+ Versi Baru Ditemui
+ Tips Kemas Kini
+ Penyegerakan data awan
+ Semasa menyegerakkan data awan, peranti akan dimulakan semula dan sambungan akan terputus buat sementara waktu. Ini adalah perkara biasa. Sila tunggu dengan sabar sehingga sistem memulakan semula fungsi peranti.
+ Untuk meningkatkan kestabilan peranti, laraskan tetapan sistem: Panel Kawalan -> Pilihan Kuasa -> Tukar tetapan pelan -> Tukar tetapan kuasa lanjutan -> Tetapan USB -> Tetapan penggantungan terpilih USB -> [Dilumpuhkan]
+ Peringatan: Sila lakukan operasi semasa peranti disambungkan
+ Buka pemacu USB (ujian)
+ Tutup pemacu USB (ujian)
+ 📁 Pilih fail
+ 📂 Pilih folder
+ Pastikan peranti kekal aktif
+ Segerakkan data awan
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.pl.xaml b/AIK.Assets/Languages/Strings.pl.xaml
new file mode 100644
index 0000000..b02679e
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.pl.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Inteligentne Narzędzie do Kluczy
+ Ustawienia
+ Język
+ Ustawienia aplikacji
+ Skonfiguruj podstawowe parametry i preferencje aplikacji
+
+ Ustawienia interfejsu
+ Ustawienia pamięci podręcznej
+ Wyczyść dane w pamięci podręcznej
+ Język interfejsu:
+ Lista modeli kluczy
+
+ Zapisz
+ Anuluj
+ Potwierdź
+
+ Szukaj marki, nazwy angielskiej lub pinyin...
+ Szukaj nazwy klucza pojazdu, nazwy angielskiej lub pinyin...
+
+ Podrzędny:
+ Częstotliwość:
+ Informacje referencyjne:
+ Czas:
+ ID:
+
+ Informacje referencyjne
+
+ Ustawienia zapisane pomyślnie
+
+ Skontaktuj się z nami przez WeChat
+ Skontaktuj się z nami przez e-mail
+ Kopiuj WeChat
+ Kopiuj e-mail
+ Telefon
+ Punkty
+ Wyloguj
+
+ Aktualizacja urządzenia
+ Bieżąca wersja
+ Najnowsza wersja
+ Stan urządzenia
+ Nazwa urządzenia
+ Aktualizuj teraz
+ Pobierz wersję
+ Wersja aplikacji
+ Wersja serwera
+ Wersja urządzenia
+ Aktualizacje wersji
+ Aktualizacje oprogramowania sprzętowego (firmware), aplikacji oraz urządzeń
+ Dziennik programowania
+ Dziennik programowania kluczy
+ Doładuj punkty
+ Członkostwo
+ Historia punktów
+ Twoje punkty
+ Wprowadź kwotę doładowania
+ Wybierz metodę płatności
+ WeChat Pay
+ PayPal
+ Zapłać
+ Wykrywanie zdalne
+ Kopiowanie pilota
+ Kopiowanie HCS / kodu stałego
+ Kliknij poniższy przycisk Test, aby wykryć częstotliwość. Po podłączeniu urządzenia naciśnij przycisk na jednostce podrzędnej w zasięgu testowym, a częstotliwość zostanie wyświetlona.
+ Kliknij poniższy przycisk Test, aby wykryć częstotliwość. Po podłączeniu urządzenia naciśnij przycisk na jednostce podrzędnej w zasięgu testowym, a częstotliwość zostanie wyświetlona.
+ Tryb:
+
+ Wykrywanie
+ Pomiń ten klucz
+ Sprawdź ponownie
+ Rozpocznij kopiowanie
+ Zablokuj
+ Odblokuj
+ Bagażnik
+ Szukaj samochodu
+
+ Nie znaleziono pasującej marki
+ Nie znaleziono pasującej marki
+ Brak danych klucza
+
+ Dane:
+ Typ:
+ Szybkość transmisji:
+ Długość bitowa:
+ Rozpocznij programowanie
+ Wskazówka
+ Poleć znajomym! Zeskanuj kod QR za pomocą WeChat, QQ itp., aby pobrać i zainstalować.
+ Będziemy nadal wspierać ślusarzy tak jak dotychczas.
+ Zeskanuj, aby pobrać aplikację mobilną
+ Uzyskaj najnowsze informacje i wsparcie
+ Pokaż więcej
+ Ładowanie...
+ Dane Chmurowe
+ Aktualizuj Teraz
+ Aktualizuj Później
+ Znaleziono Nową Wersję
+ Wskazówki Dotyczące Aktualizacji
+ Synchronizacja danych w chmurze
+ Podczas synchronizacji danych w chmurze urządzenie uruchomi się ponownie, a połączenie zostanie tymczasowo przerwane. To normalne. Proszę cierpliwie poczekać, aż system ponownie zainicjalizuje funkcje urządzenia.
+ Aby zwiększyć stabilność urządzenia, dostosuj ustawienia systemowe: Panel sterowania -> Opcje zasilania -> Zmień ustawienia planu -> Zmień zaawansowane ustawienia zasilania -> Ustawienia USB -> Ustawienie wstrzymania selektywnego USB -> [Wyłączone]
+ Przypomnienie: wykonuj operację, gdy urządzenie jest podłączone
+ Otwórz dysk USB (test)
+ Zamknij dysk USB (test)
+ 📁 Wybierz plik
+ 📂 Wybierz folder
+ Utrzymuj urządzenie aktywne
+ Synchronizuj dane w chmurze
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.pt-BR.xaml b/AIK.Assets/Languages/Strings.pt-BR.xaml
new file mode 100644
index 0000000..2e49152
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.pt-BR.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Ferramenta Inteligente de Chaves
+ Configurações
+ Idioma
+ Configurações do Aplicativo
+ Configure os parâmetros básicos e preferências do aplicativo
+
+ Configurações da Interface
+ Configurações de Cache
+ Limpar cache de dados
+ Idioma da interface:
+ Lista de Modelos de Chaves
+
+ Salvar
+ Cancelar
+ Confirmar
+
+ Buscar marca, nome em inglês ou pinyin...
+ Buscar nome da chave, termo em inglês ou pinyin...
+
+ Subunidade:
+ Frequência:
+ Informações de referência:
+ Hora:
+ ID:
+
+ Informações de Referência
+
+ Configurações salvas com sucesso
+
+ Contate-nos pelo WeChat
+ Contate-nos por e-mail
+ Copiar WeChat
+ Copiar e-mail
+ Celular
+ Pontos
+ Sair
+
+ Atualização do Dispositivo
+ Versão Atual
+ Nova Versão
+ Status do Dispositivo
+ Nome do Dispositivo
+ Atualizar Agora
+ Obter Versão
+ Versão do Aplicativo
+ Versão do Servidor
+ Versão do Dispositivo
+ Atualizações de Versão
+ Atualizações de firmware, aplicativo, dispositivo, etc.
+ Registro de Gravação
+ Histórico de Gravação de Chaves
+ Recarga de pontos
+ Assinatura
+ Registro de pontos
+ Seus pontos
+ Insira o valor da recarga
+ Selecione a forma de pagamento
+ WeChat Pay
+ PayPal
+ Pagar
+ Detecção Remota
+ Cópia Remota
+ Cópia HCS / Código Fixo
+ Clique no botão Testar abaixo para detectar a frequência. Após conectar o dispositivo, pressione um botão na unidade secundária dentro do alcance testável e a frequência será exibida.
+ Clique no botão Testar abaixo para detectar a frequência. Após conectar o dispositivo, pressione um botão na unidade secundária dentro do alcance testável e a frequência será exibida.
+ Modo:
+
+ Detecção
+ Ignorar esta tecla
+ Reverificar
+ Iniciar cópia
+ Travar
+ Destravar
+ Porta-malas
+ Busca-carro
+
+ Nenhuma marca correspondente encontrada
+ Nenhuma marca correspondente encontrada
+ Sem dados da chave disponíveis
+
+ Dados:
+ Tipo:
+ Taxa de bits:
+ Comprimento em bits:
+ Iniciar Gravação
+ Dica
+ Indique aos seus amigos! Escaneie o QR Code com WeChat, QQ, etc. para baixar e instalar.
+ Continuaremos apoiando os chaveiros como sempre.
+ Escaneie para baixar o app móvel
+ Receba as últimas novidades e suporte
+ Ver mais
+ Carregando...
+ Dados na Nuvem
+ Atualizar Agora
+ Atualizar Mais Tarde
+ Nova Versão Encontrada
+ Dicas de Atualização
+ Sincronização de dados na nuvem
+ Durante a sincronização de dados na nuvem, o dispositivo será reiniciado e a conexão será temporariamente interrompida. Isso é normal. Aguarde pacientemente enquanto o sistema reinicializa as funções do dispositivo.
+ Para melhorar a estabilidade do dispositivo, ajuste as configurações do sistema: Painel de Controle -> Opções de Energia -> Alterar configurações do plano -> Alterar configurações avançadas de energia -> Configurações USB -> Configuração de suspensão seletiva de USB -> [Desabilitado]
+ Lembrete: execute a operação com o dispositivo conectado
+ Abrir unidade USB (teste)
+ Fechar unidade USB (teste)
+ 📁 Selecionar arquivo
+ 📂 Selecionar pasta
+ Manter dispositivo ativo
+ Sincronizar dados na nuvem
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.pt.xaml b/AIK.Assets/Languages/Strings.pt.xaml
new file mode 100644
index 0000000..808cbdf
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.pt.xaml
@@ -0,0 +1,116 @@
+
+
+ AIK.Ferramenta de Chave Inteligente
+ Configurações
+ Idioma
+ Configurações do Aplicativo
+ Configurar parâmetros básicos e preferências do aplicativo
+
+ Configurações de Interface
+ Configurações de Cache
+ Limpar Cache de Dados
+ Idioma da Interface:
+ Lista de Modelos de Chave
+
+ Salvar
+ Cancelar
+ Confirmar
+
+ Pesquisar nome da marca, inglês ou pinyin...
+ Pesquisar nome da chave do veículo, inglês ou pinyin...
+
+ Chave Remota:
+ Frequência:
+ Informações de Referência:
+ Hora:
+ ID:
+
+ Informações de Referência
+
+ Configurações salvas com sucesso
+
+ Contate-nos pelo WeChat
+ Contate-nos pelo E-mail
+ Copiar WeChat
+ Copiar E-mail
+ Telefone Celular
+ Pontos
+ Sair
+ Atualização do Dispositivo
+ Versão Atual
+ Última Versão
+ Status do Dispositivo
+ Nome do Dispositivo
+ Atualizar Agora
+ Obter Versão
+ Versão do APP
+ Versão do Servidor
+ Versão do Dispositivo
+ Centro de Atualização
+ Atualização de firmware, aplicativo, dispositivo, etc.
+ Registro de gravação
+ Registro de gravação de chaves
+ Recarga de pontos
+ Assinatura
+ Registro de pontos
+ Os seus pontos
+ Introduza o valor da recarga
+ Selecione o método de pagamento
+ WeChat Pay
+ PayPal
+ Pagar
+ Detecção Remota
+ Cópia Remota
+ Cópia HCS / Código Fixo
+ Clique no botão Testar abaixo para detetar a frequência. Após ligar o dispositivo, prima um botão na unidade secundária dentro do alcance testável e a frequência será exibida.
+ Clique no botão Testar abaixo para detetar a frequência. Após ligar o dispositivo, prima um botão na unidade secundária dentro do alcance testável e a frequência será exibida.
+ Modo:
+
+ Detecção
+ Ignorar esta tecla
+ Reverificar
+ Iniciar cópia
+ Trancar
+ Destrancar
+ Porta-malas
+ Busca-carro
+
+ Nenhuma marca correspondente encontrada
+ Nenhuma marca correspondente encontrada
+ Sem dados da chave disponíveis
+
+ Dados:
+ Tipo:
+ Taxa de bits:
+ Comprimento em bits:
+ Iniciar Programação
+ Dica
+ Recomende aos seus amigos! Digitalize o código QR com WeChat, QQ, etc. para descarregar e instalar.
+ Continuaremos a apoiar os serralheiros como sempre.
+ Digitalize para descarregar a aplicação móvel
+ Obtenha as últimas notícias e suporte
+ Ver mais
+ Carregando...
+ Dados na Nuvem
+ Atualizar Agora
+ Atualizar Mais Tarde
+ Nova Versão Encontrada
+ Dicas de Atualização
+ Sincronização de dados na nuvem
+ Durante a sincronização de dados na nuvem, o dispositivo irá reiniciar e a ligação será temporariamente interrompida. Isto é normal. Aguarde pacientemente enquanto o sistema reinicializa as funções do dispositivo.
+ Para melhorar a estabilidade do dispositivo, ajuste as definições do sistema: Painel de Controlo -> Opções de Energia -> Alterar definições do plano -> Alterar definições avançadas de energia -> Definições USB -> Definição de suspensão seletiva de USB -> [Desativado]
+ Lembrete: execute a operação com o dispositivo ligado
+ Abrir unidade USB (teste)
+ Fechar unidade USB (teste)
+ 📁 Selecionar ficheiro
+ 📂 Selecionar pasta
+ Manter dispositivo ativo
+ Sincronizar dados na nuvem
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.ru.xaml b/AIK.Assets/Languages/Strings.ru.xaml
new file mode 100644
index 0000000..24e2e56
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.ru.xaml
@@ -0,0 +1,115 @@
+
+ AIK. Интеллектуальный инструмент для ключей
+ Настройки
+ Язык
+ Настройки приложения
+ Настройка основных параметров и предпочтений приложения
+
+ Настройки интерфейса
+ Настройки кэша
+ Очистить кэш данных
+ Язык интерфейса:
+ Список моделей ключей
+
+ Сохранить
+ Отмена
+ Подтвердить
+
+ Поиск по названию бренда, английскому или пиньиню...
+ Поиск по названию автомобильного ключа, английскому или пиньиню...
+
+ Подчинённое устройство:
+ Частота:
+ Справочная информация:
+ Время:
+ ID:
+
+ Справочная информация
+
+ Настройки успешно сохранены
+
+ Связаться через WeChat
+ Связаться по электронной почте
+ Копировать WeChat
+ Копировать email
+ Телефон
+ Баллы
+ Выйти
+ Обновление устройства
+ Текущая версия
+ Последняя версия
+ Состояние устройства
+ Название устройства
+ Обновить сейчас
+ Получить версию
+ Версия приложения
+ Версия сервера
+ Версия устройства
+ Центр обновлений
+ Обновление прошивки, приложения, устройства и др.
+ Журнал записи
+ Журнал записи ключей
+ Пополнение баллов
+ Подписка
+ История баллов
+ Ваши баллы
+ Введите сумму пополнения
+ Выберите способ оплаты
+ WeChat Pay
+ PayPal
+ Оплатить
+ Удаленное обнаружение
+ Копирование пульта
+ Копирование HCS / фиксированного кода
+ Нажмите кнопку «Тест» ниже, чтобы определить частоту. После подключения устройства нажмите кнопку на дочернем блоке в пределах тестового диапазона, и частота отобразится.
+ Нажмите кнопку «Тест» ниже, чтобы определить частоту. После подключения устройства нажмите кнопку на дочернем блоке в пределах тестового диапазона, и частота отобразится.
+ Режим:
+
+ Обнаружение
+ Пропустить эту кнопку
+ Повторная проверка
+ Начать копирование
+ Заблокировать
+ Разблокировать
+ Багажник
+ Поиск автомобиля
+
+ Соответствующий бренд не найден
+ Соответствующий бренд не найден
+ Данные ключа недоступны
+
+ Данные:
+ Тип:
+ Битрейт:
+ Длина в битах:
+ Начать программирование
+ Совет
+ Порекомендуйте друзьям! Отсканируйте QR-код с помощью WeChat, QQ и т.д., чтобы скачать и установить.
+ Мы и дальше будем надежно поддерживать мастеров-ключников, как всегда.
+ Отсканируйте, чтобы скачать мобильное приложение
+ Получайте последние новости и поддержку
+ Показать ещё
+ Загрузка...
+ Облачные Данные
+ Обновить Сейчас
+ Обновить Позже
+ Найдена Новая Версия
+ Советы по Обновлению
+ Синхронизация облачных данных
+ Во время синхронизации облачных данных устройство перезагрузится, а соединение будет временно прервано. Это нормально. Пожалуйста, подождите, пока система повторно инициализирует функции устройства.
+ Чтобы повысить стабильность устройства, измените параметры системы: Панель управления -> Электропитание -> Настройка схемы электропитания -> Изменить дополнительные параметры питания -> Параметры USB -> Параметр временного отключения USB-порта -> [Отключено]
+ Напоминание: выполняйте операцию, когда устройство подключено
+ Открыть USB-накопитель (тест)
+ Закрыть USB-накопитель (тест)
+ 📁 Выбрать файл
+ 📂 Выбрать папку
+ Поддерживать устройство активным
+ Синхронизировать облачные данные
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.th.xaml b/AIK.Assets/Languages/Strings.th.xaml
new file mode 100644
index 0000000..216bc64
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.th.xaml
@@ -0,0 +1,116 @@
+
+ AIK. เครื่องมือกุญแจอัจฉริยะ
+ การตั้งค่า
+ ภาษา
+ การตั้งค่าแอป
+ กำหนดค่าพารามิเตอร์และตัวเลือกพื้นฐานของแอป
+
+ การตั้งค่าอินเตอร์เฟซ
+ การตั้งค่าแคช
+ ล้างแคชข้อมูล
+ ภาษาอินเตอร์เฟซ:
+ รายการรุ่นกุญแจ
+
+ บันทึก
+ ยกเลิก
+ ยืนยัน
+
+ ค้นหาชื่อแบรนด์ ภาษาอังกฤษ หรือ พินอิน...
+ ค้นหาชื่อกุญแจรถ ภาษาอังกฤษ หรือ พินอิน...
+
+ หน่วยย่อย:
+ ความถี่:
+ ข้อมูลอ้างอิง:
+ เวลา:
+ ID:
+
+ ข้อมูลอ้างอิง
+
+ บันทึกการตั้งค่าเรียบร้อยแล้ว
+
+ ติดต่อเราผ่าน WeChat
+ ติดต่อเราผ่านอีเมล
+ คัดลอก WeChat
+ คัดลอกอีเมล
+ โทรศัพท์มือถือ
+ คะแนน
+ ออกจากระบบ
+
+ อัปเดตอุปกรณ์
+ เวอร์ชันปัจจุบัน
+ เวอร์ชันล่าสุด
+ สถานะอุปกรณ์
+ ชื่ออุปกรณ์
+ อัปเดตเดี๋ยวนี้
+ ดูเวอร์ชัน
+ เวอร์ชันแอป
+ เวอร์ชันเซิร์ฟเวอร์
+ เวอร์ชันอุปกรณ์
+ ศูนย์อัปเดตเวอร์ชัน
+ อัปเดตเฟิร์มแวร์ แอป อุปกรณ์ เป็นต้น
+ บันทึกการเขียนข้อมูล
+ ประวัติการเขียนข้อมูลกุญแจ
+ เติมคะแนน
+ สมาชิก
+ ประวัติคะแนน
+ คะแนนของคุณ
+ ป้อนจำนวนเงินที่ต้องการเติม
+ เลือกวิธีการชำระเงิน
+ WeChat Pay
+ PayPal
+ ชำระเงิน
+ ตรวจจับระยะไกล
+ คัดลอกสัญญาณรีโมท
+ คัดลอก HCS / รหัสคงที่
+ คลิกปุ่มทดสอบด้านล่างเพื่อตรวจจับความถี่ เมื่อเชื่อมต่ออุปกรณ์แล้ว กดปุ่มบนยูนิตย่อยภายในระยะที่สามารถทดสอบได้ ความถี่จะแสดงขึ้นทันที
+ คลิกปุ่มทดสอบด้านล่างเพื่อตรวจจับความถี่ เมื่อเชื่อมต่ออุปกรณ์แล้ว กดปุ่มบนยูนิตย่อยภายในระยะที่สามารถทดสอบได้ ความถี่จะแสดงขึ้นทันที
+ โหมด:
+
+ การตรวจจับ
+ ข้ามปุ่มนี้
+ ตรวจสอบอีกครั้ง
+ เริ่มคัดลอก
+ ล็อก
+ เปิดล็อก
+ ท้ายรถ
+ ค้นหารถ
+
+ ไม่พบยี่ห้อที่ตรงกัน
+ ไม่พบยี่ห้อที่ตรงกัน
+ ไม่มีข้อมูลกุญแจ
+
+ ข้อมูล:
+ ประเภท:
+ อัตราบิต:
+ ความยาวบิต:
+ เริ่มการโปรแกรม
+ เคล็ดลับ
+ แนะนำให้เพื่อนของคุณ! สแกนรหัส QR ด้วย WeChat, QQ ฯลฯ เพื่อดาวน์โหลดและติดตั้ง
+ เราจะยังคงสนับสนุนช่างกุญแจทุกท่านอย่างเต็มที่เหมือนเช่นเคย
+ สแกนเพื่อดาวน์โหลดแอปมือถือ
+ รับข่าวสารและบริการสนับสนุนล่าสุด
+ ดูเพิ่มเติม
+ กำลังโหลด...
+ ข้อมูลในคลาวด์
+ อัปเดตตอนนี้
+ อัปเดตภายหลัง
+ พบเวอร์ชั่นใหม่
+ คำแนะนำในการอัปเดต
+ ซิงค์ข้อมูลคลาวด์
+ ระหว่างการซิงค์ข้อมูลคลาวด์ อุปกรณ์จะรีสตาร์ตและการเชื่อมต่อจะถูกตัดชั่วคราว ซึ่งเป็นเรื่องปกติ โปรดรออย่างอดทนให้ระบบเริ่มต้นฟังก์ชันของอุปกรณ์ใหม่
+ เพื่อเพิ่มความเสถียรของอุปกรณ์ ให้ปรับการตั้งค่าระบบ: แผงควบคุม -> ตัวเลือกการใช้พลังงาน -> เปลี่ยนการตั้งค่าแผน -> เปลี่ยนการตั้งค่าพลังงานขั้นสูง -> การตั้งค่า USB -> การตั้งค่าการระงับแบบเลือกได้ของ USB -> [ปิดใช้งาน]
+ คำเตือน: โปรดดำเนินการขณะอุปกรณ์เชื่อมต่ออยู่
+ เปิดไดรฟ์ USB (ทดสอบ)
+ ปิดไดรฟ์ USB (ทดสอบ)
+ 📁 เลือกไฟล์
+ 📂 เลือกโฟลเดอร์
+ คงการทำงานของอุปกรณ์
+ ซิงค์ข้อมูลคลาวด์
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.tr.xaml b/AIK.Assets/Languages/Strings.tr.xaml
new file mode 100644
index 0000000..53d3b94
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.tr.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Akıllı Anahtar Aracı
+ Ayarlar
+ Dil
+ Uygulama Ayarları
+ Uygulamanın temel parametrelerini ve tercihlerini yapılandırın
+
+ Arayüz Ayarları
+ Önbellek Ayarları
+ Veri önbelleğini temizle
+ Arayüz dili:
+ Anahtar Modeli Listesi
+
+ Kaydet
+ İptal
+ Onayla
+
+ Marka adı, İngilizce veya pinyin ile arama...
+ Araç anahtarı adı, İngilizce veya pinyin ile arama...
+
+ Alt birim:
+ Frekans:
+ Referans bilgileri:
+ Zaman:
+ ID:
+
+ Referans Bilgileri
+
+ Ayarlar başarıyla kaydedildi
+
+ WeChat üzerinden bizimle iletişime geçin
+ E-posta ile bizimle iletişime geçin
+ WeChat'i kopyala
+ E-postayı kopyala
+ Cep telefonu
+ Puan
+ Çıkış yap
+
+ Cihaz Güncellemesi
+ Geçerli Sürüm
+ En Son Sürüm
+ Cihaz Durumu
+ Cihaz Adı
+ Şimdi Güncelle
+ Sürümü Al
+ Uygulama Sürümü
+ Sunucu Sürümü
+ Cihaz Sürümü
+ Sürüm Güncellemeleri
+ Firmware, uygulama, cihaz güncellemeleri vb.
+ Yazma Kaydı
+ Anahtar Yazma Geçmişi
+ Puan yükleme
+ Üyelik
+ Puan geçmişi
+ Puanlarınız
+ Yükleme tutarını girin
+ Ödeme yöntemini seçin
+ WeChat Pay
+ PayPal
+ Öde
+ Uzaktan Algılama
+ Uzaktan Kopyalama
+ HCS / Sabit Kod Kopyalama
+ Frekansı algılamak için aşağıdaki Test düğmesine tıklayın. Cihazı bağladıktan sonra, test edilebilir mesafe içinde alt ünitenin bir tuşuna basın; frekans ekranda gösterilecektir.
+ Frekansı algılamak için aşağıdaki Test düğmesine tıklayın. Cihazı bağladıktan sonra, test edilebilir mesafe içinde alt ünitenin bir tuşuna basın; frekans ekranda gösterilecektir.
+ Mod:
+
+ Tespit
+ Bu tuşu atla
+ Yeniden kontrol et
+ Kopyalamayı başlat
+ Kilitle
+ Kilidi aç
+ Bagajlık
+ Araç bulma
+
+ Eşleşen marka bulunamadı
+ Eşleşen marka bulunamadı
+ Anahtar verisi yok
+
+ Veri:
+ Tür:
+ Bit hızı:
+ Bit uzunluğu:
+ Programlamayı Başlat
+ İpucu
+ Arkadaşlarınıza önerin! WeChat, QQ vb. ile QR kodunu tarayarak indirip kurun.
+ Çilingirlere her zaman olduğu gibi destek vermeye devam edeceğiz.
+ Mobil uygulamayı indirmek için tarayın
+ En son haberleri ve desteği alın
+ Daha fazla görüntüle
+ Yükleniyor...
+ Bulut Verileri
+ Şimdi Güncelle
+ Daha Sonra Güncelle
+ Yeni Sürüm Bulundu
+ Güncelleme İpuçları
+ Bulut veri senkronizasyonu
+ Bulut verileri senkronize edilirken cihaz yeniden başlatılır ve bağlantı geçici olarak kesilir. Bu normaldir. Lütfen sistem cihaz işlevlerini yeniden başlatırken sabırla bekleyin.
+ Cihaz kararlılığını artırmak için sistem ayarlarını düzenleyin: Denetim Masası -> Güç Seçenekleri -> Plan ayarlarını değiştir -> Gelişmiş güç ayarlarını değiştir -> USB ayarları -> USB seçmeli askıya alma ayarı -> [Devre Dışı]
+ Uyarı: Lütfen işlemi cihaz bağlıyken gerçekleştirin
+ USB sürücüsünü aç (test)
+ USB sürücüsünü kapat (test)
+ 📁 Dosya seç
+ 📂 Klasör seç
+ Cihazı etkin tut
+ Bulut verilerini senkronize et
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.uk.xaml b/AIK.Assets/Languages/Strings.uk.xaml
new file mode 100644
index 0000000..8ba4fc4
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.uk.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Інтелектуальні ключі. Інструменти
+ Налаштування
+ Мова
+ Налаштування додатка
+ Налаштування базових параметрів та вподобань додатка
+
+ Налаштування інтерфейсу
+ Налаштування кешу
+ Очистити кеш даних
+ Мова інтерфейсу:
+ Список моделей ключів
+
+ Зберегти
+ Скасувати
+ Підтвердити
+
+ Пошук назви бренду, англійською або піньїном...
+ Пошук назви автомобільного ключа, англійською або піньїном...
+
+ Підмодуль:
+ Частота:
+ Довідкові відомості:
+ Час:
+ ID:
+
+ Довідкові відомості
+
+ Налаштування успішно збережено
+
+ Зв'яжіться з нами через WeChat
+ Зв'яжіться з нами через Email
+ Копіювати WeChat
+ Копіювати Email
+ Мобільний телефон
+ Бали
+ Вийти
+
+ Оновлення пристрою
+ Поточна версія
+ Остання версія
+ Стан пристрою
+ Назва пристрою
+ Оновити зараз
+ Перевірити версію
+ Версія додатка
+ Версія сервера
+ Версія пристрою
+ Центр оновлень
+ Оновлення прошивки, додатка, пристроїв тощо
+ Журнал запису
+ Історія запису ключа
+ Поповнення балів
+ Підписка
+ Історія балів
+ Ваші бали
+ Введіть суму поповнення
+ Виберіть спосіб оплати
+ WeChat Pay
+ PayPal
+ Оплатити
+ Віддалене виявлення
+ Копіювання пульта
+ Копіювання HCS / фіксованого коду
+ Натисніть кнопку «Тест» нижче, щоб визначити частоту. Після підключення пристрою натисніть кнопку на дочірньому пристрої в межах тестової дистанції — частота буде відображена.
+ Натисніть кнопку «Тест» нижче, щоб визначити частоту. Після підключення пристрою натисніть кнопку на дочірньому пристрої в межах тестової дистанції — частота буде відображена.
+ Режим:
+
+ Виявлення
+ Пропустити цю клавішу
+ Перевірити знову
+ Почати копіювання
+ Заблокувати
+ Розблокувати
+ Багажник
+ Пошук автомобіля
+
+ Відповідний бренд не знайдено
+ Відповідний бренд не знайдено
+ Дані ключа недоступні
+
+ Дані:
+ Тип:
+ Бітрейт:
+ Довжина в бітах:
+ Bắt đầu lập trình
+ Порада
+ Рекомендуйте друзям! Відскануйте QR-код за допомогою WeChat, QQ тощо, щоб завантажити та встановити.
+ Ми й надалі будемо підтримувати слюсарів, як і раніше.
+ Відскануйте, щоб завантажити мобільний додаток
+ Отримуйте останні новини та підтримку
+ Показати більше
+ Завантаження...
+ Хмарні Дані
+ Оновити Тепер
+ Оновити Пізніше
+ Знайдено Нову Версію
+ Поради з Оновлення
+ Синхронізація хмарних даних
+ Під час синхронізації хмарних даних пристрій перезавантажиться, а з’єднання буде тимчасово перервано. Це нормально. Будь ласка, зачекайте, доки система повторно ініціалізує функції пристрою.
+ Щоб підвищити стабільність пристрою, змініть параметри системи: Панель керування -> Електроживлення -> Змінити параметри плану -> Змінити додаткові параметри живлення -> Параметри USB -> Параметр вибіркового призупинення USB -> [Вимкнено]
+ Нагадування: виконуйте операцію, коли пристрій підключено
+ Відкрити USB-накопичувач (тест)
+ Закрити USB-накопичувач (тест)
+ 📁 Вибрати файл
+ 📂 Вибрати папку
+ Підтримувати пристрій активним
+ Синхронізувати хмарні дані
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.vi.xaml b/AIK.Assets/Languages/Strings.vi.xaml
new file mode 100644
index 0000000..67b4af4
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.vi.xaml
@@ -0,0 +1,116 @@
+
+ AIK. Công cụ khóa thông minh
+ Cài đặt
+ Ngôn ngữ
+ Cài đặt ứng dụng
+ Cấu hình tham số cơ bản và tùy chọn ứng dụng
+
+ Cài đặt giao diện
+ Cài đặt bộ nhớ đệm
+ Xóa bộ nhớ đệm dữ liệu
+ Ngôn ngữ giao diện:
+ Danh sách mô hình khóa
+
+ Lưu
+ Hủy
+ Xác nhận
+
+ Tìm kiếm tên thương hiệu, tiếng Anh hoặc pinyin...
+ Tìm kiếm tên khóa xe, tiếng Anh hoặc pinyin...
+
+ Đơn vị phụ:
+ Tần số:
+ Thông tin tham chiếu:
+ Thời gian:
+ ID:
+
+ Thông tin tham chiếu
+
+ Cài đặt đã được lưu thành công
+
+ Liên hệ chúng tôi qua WeChat
+ Liên hệ chúng tôi qua Email
+ Sao chép WeChat
+ Sao chép Email
+ Điện thoại di động
+ Điểm
+ Đăng xuất
+
+ Cập nhật thiết bị
+ Phiên bản hiện tại
+ Phiên bản mới nhất
+ Trạng thái thiết bị
+ Tên thiết bị
+ Nâng cấp ngay
+ Lấy phiên bản
+ Phiên bản ứng dụng
+ Phiên bản máy chủ
+ Phiên bản thiết bị
+ Trung tâm cập nhật phiên bản
+ Cập nhật firmware, ứng dụng, thiết bị, v.v.
+ Nhật ký ghi
+ Lịch sử ghi khóa
+ Nạp điểm
+ Thành viên
+ Lịch sử điểm
+ Điểm của bạn
+ Nhập số tiền nạp
+ Chọn phương thức thanh toán
+ WeChat Pay
+ PayPal
+ Thanh toán
+ Phát hiện từ xa
+ Sao chép điều khiển từ xa
+ Sao chép HCS / Mã cố định
+ Nhấp vào nút Kiểm tra bên dưới để phát hiện tần số. Sau khi kết nối thiết bị, nhấn một phím trên thiết bị phụ trong phạm vi kiểm tra được, tần số sẽ hiển thị ngay lập tức.
+ Nhấp vào nút Kiểm tra bên dưới để phát hiện tần số. Sau khi kết nối thiết bị, nhấn một phím trên thiết bị phụ trong phạm vi kiểm tra được, tần số sẽ hiển thị ngay lập tức.
+ Chế độ:
+
+ Phát hiện
+ Bỏ qua phím này
+ Kiểm tra lại
+ Bắt đầu sao chép
+ Khóa
+ Mở khóa
+ Cốp xe
+ Tìm xe
+
+ Không tìm thấy thương hiệu phù hợp
+ Không tìm thấy thương hiệu phù hợp
+ Không có dữ liệu chìa khóa
+
+ Dữ liệu:
+ Loại:
+ Tốc độ bit:
+ Độ dài bit:
+ Bắt đầu lập trình
+ Mẹo
+ Giới thiệu cho bạn bè của bạn! Quét mã QR bằng WeChat, QQ, v.v. để tải về và cài đặt.
+ Chúng tôi sẽ tiếp tục đồng hành cùng thợ khóa như vẫn thường làm.
+ Quét để tải ứng dụng di động
+ Nhận thông tin mới nhất và hỗ trợ
+ Xem thêm
+ Đang tải...
+ Dữ Liệu Điện Tử
+ Cập Nhật Ngay
+ Cập Nhật Sau
+ Tìm Thấy Phiên Bản Mới
+ Mẹo Cập Nhật
+ Đồng bộ dữ liệu đám mây
+ Trong quá trình đồng bộ dữ liệu đám mây, thiết bị sẽ khởi động lại và kết nối sẽ tạm thời bị ngắt. Đây là hiện tượng bình thường. Vui lòng kiên nhẫn chờ hệ thống khởi tạo lại các chức năng của thiết bị.
+ Để tăng độ ổn định của thiết bị, hãy điều chỉnh cài đặt hệ thống: Bảng điều khiển -> Tùy chọn nguồn -> Thay đổi cài đặt gói -> Thay đổi cài đặt nguồn nâng cao -> Cài đặt USB -> Cài đặt tạm ngưng chọn lọc USB -> [Đã tắt]
+ Nhắc nhở: Vui lòng thao tác khi thiết bị đã được kết nối
+ Mở ổ USB (thử nghiệm)
+ Đóng ổ USB (thử nghiệm)
+ 📁 Chọn tệp
+ 📂 Chọn thư mục
+ Giữ thiết bị hoạt động
+ Đồng bộ dữ liệu đám mây
+
+
+
+
+
+
diff --git a/AIK.Assets/Languages/Strings.zh.xaml b/AIK.Assets/Languages/Strings.zh.xaml
new file mode 100644
index 0000000..7ffdf7d
--- /dev/null
+++ b/AIK.Assets/Languages/Strings.zh.xaml
@@ -0,0 +1,118 @@
+
+ AIK.智能钥匙工具
+ 设置
+ 语言
+ 应用设置
+ 配置应用程序的基本参数和偏好设置
+
+ 界面设置
+ 缓存设置
+ 清除数据缓存
+ 界面语言:
+ 钥匙型号列表
+
+ 保存
+ 取消
+ 确认
+
+ 搜索品牌名称、英文或拼音...
+ 搜索车辆钥匙名称、英文或拼音...
+
+ 子机:
+ 频率:
+ 参考信息:
+ 时间:
+ ID:
+
+ 参考信息
+
+ 设置保存成功
+
+ 微信联系我们
+ 邮箱联系我们
+ 微信复制
+ 邮箱复制
+ 手机
+ 积分
+ 登出
+
+ 设备升级
+ 当前版本
+ 最新版本
+ 设备状态
+ 设备名称
+ 立即升级
+ 获取版本
+ APP版本
+ 服务器版本
+ 设备版本
+ 版本升级
+ 固件、应用、设备等版本升级
+ 烧录记录
+ 钥匙烧录记录
+ 积分充值
+ 会员开通
+ 积分记录
+ 您的积分
+ 请输入充值金额
+ 请选择支付方式
+ 微信支付
+ PayPal
+ 支付
+
+ 遥控检测
+ 遥控拷贝
+ HCS/固定码拷贝
+ 点击下方检测按钮检测频率,连接设备后,按下子机按键并在可测试距离内,即能显示频率
+ 点击下方检测按钮检测频率,连接设备后,按下子机按键并在可测试距离内,即能显示频率
+ 模式:
+
+ 检测
+ 跳过此键
+ 重新检测
+ 开始拷贝
+ 锁车
+ 开锁
+ 后备箱
+ 寻车
+
+ 没有找到匹配的品牌
+ 没有找到匹配的品牌
+ 暂无钥匙数据
+
+ 数据:
+ 类型:
+ 码率:
+ 位数:
+
+ 开始烧录
+ 提示
+ 推荐给你的朋友吧,使用微信、qq等扫描二维码,即可下载安装
+ 我们将一如既往的为广大锁匠保驾护航
+ 扫码下载移动端
+ 获取最新资讯与服务支持
+ 查看更多
+ 加载中...
+ 云数据
+ 立即更新
+ 稍后更新
+ 发现新版本
+ 更新提示
+ 云数据同步
+ 同步云数据时,设备会重启,连接会暂时断开属于正常现象,请耐心等待系统初始化设备功能
+ 增加设备稳定性,可调系统设置:控制面板 -> 电源选项 -> 更改计划设置 -> 更改高级电源设置 -> USB 设置 -> USB 选择性暂停设置 -> [已禁用]
+ 提醒:请在设备已连接状态下进行操作
+ 打开U盘(测试)
+ 关闭U盘(测试)
+ 📁 选择文件
+ 📂 选择文件夹
+ 持续保活(设备)
+ 同步云数据
+
+
+
+
+
+
diff --git a/AIK.Assets/Styles/BannerStyle.xaml b/AIK.Assets/Styles/BannerStyle.xaml
new file mode 100644
index 0000000..bfae906
--- /dev/null
+++ b/AIK.Assets/Styles/BannerStyle.xaml
@@ -0,0 +1,29 @@
+
+
+
\ No newline at end of file
diff --git a/AIK.Assets/Styles/ButtonStyles.xaml b/AIK.Assets/Styles/ButtonStyles.xaml
new file mode 100644
index 0000000..679aeb9
--- /dev/null
+++ b/AIK.Assets/Styles/ButtonStyles.xaml
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Assets/Styles/HintTitleStyle.xaml b/AIK.Assets/Styles/HintTitleStyle.xaml
new file mode 100644
index 0000000..ccd7c2c
--- /dev/null
+++ b/AIK.Assets/Styles/HintTitleStyle.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Assets/Styles/LoadingStyle.xaml b/AIK.Assets/Styles/LoadingStyle.xaml
new file mode 100644
index 0000000..c724670
--- /dev/null
+++ b/AIK.Assets/Styles/LoadingStyle.xaml
@@ -0,0 +1,343 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Assets/Styles/ScrollViewerStyle.xaml b/AIK.Assets/Styles/ScrollViewerStyle.xaml
new file mode 100644
index 0000000..59871ea
--- /dev/null
+++ b/AIK.Assets/Styles/ScrollViewerStyle.xaml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Assets/Styles/StateStyle.xaml b/AIK.Assets/Styles/StateStyle.xaml
new file mode 100644
index 0000000..ad5bfa8
--- /dev/null
+++ b/AIK.Assets/Styles/StateStyle.xaml
@@ -0,0 +1,209 @@
+
+
+
+ #0078D7
+ #E3F2FD
+ #BBDEFB
+ #2196F3
+ #FF9800
+ #F44336
+ #4CAF50
+ #607D8B
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Assets/Styles/VideoControlButtonStyle.xaml b/AIK.Assets/Styles/VideoControlButtonStyle.xaml
new file mode 100644
index 0000000..fd1a89f
--- /dev/null
+++ b/AIK.Assets/Styles/VideoControlButtonStyle.xaml
@@ -0,0 +1,52 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Behaviors/AIK.Behaviors.csproj b/AIK.Behaviors/AIK.Behaviors.csproj
new file mode 100644
index 0000000..0c82216
--- /dev/null
+++ b/AIK.Behaviors/AIK.Behaviors.csproj
@@ -0,0 +1,29 @@
+
+
+
+ net48
+ enable
+ true
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Behaviors/ClickBehavior.cs b/AIK.Behaviors/ClickBehavior.cs
new file mode 100644
index 0000000..c392f86
--- /dev/null
+++ b/AIK.Behaviors/ClickBehavior.cs
@@ -0,0 +1,63 @@
+using Microsoft.Xaml.Behaviors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+
+namespace AIK.Behaviors
+{
+ public class ClickBehavior : Behavior
+ {
+ public static readonly DependencyProperty CommandProperty =
+ DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(ClickBehavior));
+
+ public static readonly DependencyProperty CommandParameterProperty =
+ DependencyProperty.Register(nameof(CommandParameter), typeof(object), typeof(ClickBehavior));
+
+ public ICommand Command
+ {
+ get => (ICommand)GetValue(CommandProperty);
+ set => SetValue(CommandProperty, value);
+ }
+
+ public object CommandParameter
+ {
+ get => GetValue(CommandParameterProperty);
+ set => SetValue(CommandParameterProperty, value);
+ }
+
+ protected override void OnAttached()
+ {
+ base.OnAttached();
+ AssociatedObject.MouseLeftButtonDown += OnMouseLeftButtonDown;
+ AssociatedObject.Loaded += OnLoaded;
+ }
+
+ protected override void OnDetaching()
+ {
+ base.OnDetaching();
+ AssociatedObject.MouseLeftButtonDown -= OnMouseLeftButtonDown;
+ AssociatedObject.Loaded -= OnLoaded;
+ }
+
+ private void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ // 调试信息
+ //System.Diagnostics.Debug.WriteLine($"ClickBehavior loaded on {AssociatedObject.GetType().Name}");
+ //System.Diagnostics.Debug.WriteLine($"Command: {Command}");
+ //System.Diagnostics.Debug.WriteLine($"CommandParameter: {CommandParameter}");
+ }
+
+ private void OnMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (Command?.CanExecute(CommandParameter) == true)
+ {
+ Command.Execute(CommandParameter);
+ e.Handled = true;
+ }
+ }
+ }
+}
diff --git a/AIK.Behaviors/PlaceholderBehavior.cs b/AIK.Behaviors/PlaceholderBehavior.cs
new file mode 100644
index 0000000..dc93f2b
--- /dev/null
+++ b/AIK.Behaviors/PlaceholderBehavior.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace AIK.Behaviors
+{
+ public static class PlaceholderBehavior
+ {
+ #region 依赖属性定义
+ private static readonly DependencyPropertyKey IsPlaceholderActivePropertyKey =
+ DependencyProperty.RegisterAttachedReadOnly(
+ "IsPlaceholderActive",
+ typeof(bool),
+ typeof(PlaceholderBehavior),
+ new PropertyMetadata(false));
+
+ public static readonly DependencyProperty IsPlaceholderActiveProperty = IsPlaceholderActivePropertyKey.DependencyProperty;
+
+ public static readonly DependencyProperty PlaceholderTextProperty =
+ DependencyProperty.RegisterAttached(
+ "PlaceholderText",
+ typeof(string),
+ typeof(PlaceholderBehavior),
+ new PropertyMetadata(string.Empty, OnPlaceholderTextChanged));
+
+ // 添加一个属性来存储原始绑定
+ private static readonly DependencyProperty OriginalBindingProperty =
+ DependencyProperty.RegisterAttached(
+ "OriginalBinding",
+ typeof(Binding),
+ typeof(PlaceholderBehavior));
+
+ // 添加一个属性来标记是否正在设置Placeholder
+ private static readonly DependencyProperty IsSettingPlaceholderProperty =
+ DependencyProperty.RegisterAttached(
+ "IsSettingPlaceholder",
+ typeof(bool),
+ typeof(PlaceholderBehavior),
+ new PropertyMetadata(false));
+ #endregion
+
+ #region 公共方法
+ public static bool GetIsPlaceholderActive(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(IsPlaceholderActiveProperty);
+ }
+
+ public static string GetPlaceholderText(DependencyObject obj)
+ {
+ return (string)obj.GetValue(PlaceholderTextProperty);
+ }
+
+ public static void SetPlaceholderText(DependencyObject obj, string value)
+ {
+ obj.SetValue(PlaceholderTextProperty, value);
+ }
+ #endregion
+
+ #region 私有方法
+ private static bool GetIsSettingPlaceholder(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(IsSettingPlaceholderProperty);
+ }
+
+ private static void SetIsSettingPlaceholder(DependencyObject obj, bool value)
+ {
+ obj.SetValue(IsSettingPlaceholderProperty, value);
+ }
+
+ private static Binding GetOriginalBinding(DependencyObject obj)
+ {
+ return (Binding)obj.GetValue(OriginalBindingProperty);
+ }
+
+ private static void SetOriginalBinding(DependencyObject obj, Binding value)
+ {
+ obj.SetValue(OriginalBindingProperty, value);
+ }
+ #endregion
+
+ #region 事件处理
+ private static void OnPlaceholderTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is TextBox textBox)
+ {
+ // 确保只注册一次事件
+ textBox.Loaded -= OnTextBoxLoaded;
+ textBox.GotFocus -= OnTextBoxGotFocus;
+ textBox.LostFocus -= OnTextBoxLostFocus;
+ textBox.TextChanged -= OnTextBoxTextChanged;
+
+ textBox.Loaded += OnTextBoxLoaded;
+ textBox.GotFocus += OnTextBoxGotFocus;
+ textBox.LostFocus += OnTextBoxLostFocus;
+ textBox.TextChanged += OnTextBoxTextChanged;
+
+ // 保存原始绑定
+ var binding = BindingOperations.GetBinding(textBox, TextBox.TextProperty);
+ if (binding != null)
+ {
+ SetOriginalBinding(textBox, binding);
+ }
+
+ // 如果已经加载,立即初始化
+ if (textBox.IsLoaded)
+ {
+ InitializePlaceholder(textBox);
+ }
+ }
+ }
+
+ private static void OnTextBoxLoaded(object sender, RoutedEventArgs e)
+ {
+ InitializePlaceholder((TextBox)sender);
+ }
+
+ private static void OnTextBoxGotFocus(object sender, RoutedEventArgs e)
+ {
+ var textBox = (TextBox)sender;
+ if (GetIsPlaceholderActive(textBox))
+ {
+ // 标记开始设置Placeholder,避免触发数据源更新
+ SetIsSettingPlaceholder(textBox, true);
+
+ // 移除placeholder
+ textBox.Text = string.Empty;
+ textBox.SetValue(IsPlaceholderActivePropertyKey, false);
+ textBox.Foreground = Brushes.Black;
+
+ // 恢复数据绑定
+ RestoreBinding(textBox);
+
+ SetIsSettingPlaceholder(textBox, false);
+ }
+ }
+
+ private static void OnTextBoxLostFocus(object sender, RoutedEventArgs e)
+ {
+ var textBox = (TextBox)sender;
+ if (string.IsNullOrEmpty(textBox.Text))
+ {
+ ShowPlaceholder(textBox);
+ }
+ }
+
+ private static void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
+ {
+ var textBox = (TextBox)sender;
+
+ // 如果正在设置Placeholder,不处理TextChanged事件
+ if (GetIsSettingPlaceholder(textBox))
+ return;
+
+ // 只有在不是placeholder状态时才处理
+ if (!GetIsPlaceholderActive(textBox))
+ {
+ // 如果文本变为空,显示placeholder
+ if (string.IsNullOrEmpty(textBox.Text) && !textBox.IsFocused)
+ {
+ ShowPlaceholder(textBox);
+ }
+ else
+ {
+ // 正常文本变化,确保数据绑定是激活的
+ EnsureBindingActive(textBox);
+ }
+ }
+ }
+ #endregion
+
+ #region 核心方法
+ private static void InitializePlaceholder(TextBox textBox)
+ {
+ // 检查当前文本是否为空或者就是Placeholder文本
+ var currentText = textBox.Text;
+ var placeholderText = GetPlaceholderText(textBox);
+
+ if (string.IsNullOrEmpty(currentText) || currentText == placeholderText)
+ {
+ ShowPlaceholder(textBox);
+ }
+ }
+
+ private static void ShowPlaceholder(TextBox textBox)
+ {
+ var placeholderText = GetPlaceholderText(textBox);
+ if (!string.IsNullOrEmpty(placeholderText))
+ {
+ // 标记开始设置Placeholder
+ SetIsSettingPlaceholder(textBox, true);
+
+ // 临时解除数据绑定,避免触发数据源更新
+ SuspendBinding(textBox);
+
+ // 设置Placeholder文本
+ textBox.Text = placeholderText;
+ textBox.SetValue(IsPlaceholderActivePropertyKey, true);
+ textBox.Foreground = new SolidColorBrush(Color.FromArgb(0xFF, 0xA0, 0xAE, 0xC0));
+
+ SetIsSettingPlaceholder(textBox, false);
+ }
+ }
+
+ // 临时解除数据绑定
+ private static void SuspendBinding(TextBox textBox)
+ {
+ // 清除绑定,但保留绑定表达式
+ var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
+ if (bindingExpression != null)
+ {
+ // 保存原始绑定(如果还没有保存的话)
+ if (GetOriginalBinding(textBox) == null)
+ {
+ var binding = BindingOperations.GetBinding(textBox, TextBox.TextProperty);
+ SetOriginalBinding(textBox, binding);
+ }
+
+ // 清除绑定,这样设置文本就不会更新数据源
+ BindingOperations.ClearBinding(textBox, TextBox.TextProperty);
+ }
+ }
+
+ // 恢复数据绑定
+ private static void RestoreBinding(TextBox textBox)
+ {
+ var originalBinding = GetOriginalBinding(textBox);
+ if (originalBinding != null)
+ {
+ // 恢复原始绑定
+ textBox.SetBinding(TextBox.TextProperty, originalBinding);
+
+ // 立即更新数据源为空值
+ var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
+ bindingExpression?.UpdateSource();
+ }
+ }
+
+ // 确保数据绑定是激活的
+ private static void EnsureBindingActive(TextBox textBox)
+ {
+ var currentBinding = BindingOperations.GetBinding(textBox, TextBox.TextProperty);
+ var originalBinding = GetOriginalBinding(textBox);
+
+ // 如果没有当前绑定但有原始绑定,恢复绑定
+ if (currentBinding == null && originalBinding != null)
+ {
+ textBox.SetBinding(TextBox.TextProperty, originalBinding);
+ }
+ }
+ #endregion
+ }
+}
+
diff --git a/AIK.Behaviors/ViewModelInitializationBehavior.cs b/AIK.Behaviors/ViewModelInitializationBehavior.cs
new file mode 100644
index 0000000..05acf7b
--- /dev/null
+++ b/AIK.Behaviors/ViewModelInitializationBehavior.cs
@@ -0,0 +1,38 @@
+using AIK.Service.IService;
+using Microsoft.Xaml.Behaviors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace AIK.Behaviors
+{
+ public class ViewModelInitializationBehavior : Behavior
+ {
+ protected override void OnAttached()
+ {
+ base.OnAttached();
+ AssociatedObject.Loaded += OnViewLoaded;
+ }
+
+ protected override void OnDetaching()
+ {
+ AssociatedObject.Loaded -= OnViewLoaded;
+ base.OnDetaching();
+ }
+
+ private async void OnViewLoaded(object sender, RoutedEventArgs e)
+ {
+ if (AssociatedObject.DataContext is ILoadAware loadAware)
+ {
+ await loadAware.OnLoadedAsync();
+ }
+ //else if (AssociatedObject.DataContext is IInitializable initializable)
+ //{
+ // await initializable.InitializeAsync();
+ //}
+ }
+ }
+}
diff --git a/AIK.Behaviors/ViewModelInitializationWindowBehavior.cs b/AIK.Behaviors/ViewModelInitializationWindowBehavior.cs
new file mode 100644
index 0000000..4f96355
--- /dev/null
+++ b/AIK.Behaviors/ViewModelInitializationWindowBehavior.cs
@@ -0,0 +1,44 @@
+using AIK.Service.IService;
+using Microsoft.Xaml.Behaviors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace AIK.Behaviors
+{
+ public class ViewModelInitializationWindowBehavior : Behavior
+ {
+ protected override void OnAttached()
+ {
+ base.OnAttached();
+ AssociatedObject.Loaded += OnViewLoaded;
+ AssociatedObject.Loaded += OnViewModelRequestClose;
+ }
+
+ protected override void OnDetaching()
+ {
+ AssociatedObject.Loaded -= OnViewLoaded;
+ AssociatedObject.Loaded -= OnViewModelRequestClose;
+ base.OnDetaching();
+ }
+
+ private async void OnViewLoaded(object sender, RoutedEventArgs e)
+ {
+ if (AssociatedObject.DataContext is ILoadAware loadAware)
+ {
+ await loadAware.OnLoadedAsync();
+ }
+ }
+ private void OnViewModelRequestClose(object? sender, EventArgs e)
+ {
+ AssociatedObject?.Dispatcher.Invoke(() =>
+ {
+ if (AssociatedObject.IsVisible)
+ AssociatedObject.Close();
+ });
+ }
+ }
+}
diff --git a/AIK.Common/AIK.Common.csproj b/AIK.Common/AIK.Common.csproj
new file mode 100644
index 0000000..ffc03f9
--- /dev/null
+++ b/AIK.Common/AIK.Common.csproj
@@ -0,0 +1,68 @@
+
+
+
+ net48
+ enable
+ true
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Settings.settings
+
+
+
+
+
+ PublicSettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Common/AIKProtocol/AIKCommunication.cs b/AIK.Common/AIKProtocol/AIKCommunication.cs
new file mode 100644
index 0000000..bcdd979
--- /dev/null
+++ b/AIK.Common/AIKProtocol/AIKCommunication.cs
@@ -0,0 +1,240 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.AIKProtocol
+{
+ public class AIKCommunication
+ {
+ ///
+ /// 数据包总包数
+ ///
+ public int TotalPackets { get; set; } = 0;
+ ///
+ /// 发送的文件数据(bin文件)
+ ///
+ public byte[] FileData { get; set; }
+ ///
+ /// 当前正在发送包的索引
+ ///
+ public int CurrentIndex { get; set; } = 0;
+
+ private readonly object _sendLock = new object();
+ private bool _isSending = false;
+ ///
+ /// 所有数据包是否完成发送
+ ///
+ private bool _isAllSendSuccess = false;
+ #region 数据包发送
+ ///
+ /// 发送起始码,建立连接使用
+ ///
+ ///
+ public byte[] GetStartFrame()
+ {
+ var buf = new byte[8] { 0XA5, 0X5E, 0XAA, 0XBB, 0XCC, 0XDD, 0X00, 0X00 };
+ return buf;
+ }
+
+ ///
+ /// 发送头帧
+ ///
+ ///
+ public async Task SendHeader(string sourceitem)
+ {
+ List bytes = new List();
+ bytes.Add(0x01);
+ bytes.Add(0x00);
+ bytes.Add(0xFF);
+ int lastSlashIndex = sourceitem.LastIndexOf('/');
+ string fileName = lastSlashIndex >= 0 ? sourceitem.Substring(lastSlashIndex + 1) : sourceitem;
+ byte[] filenamedata = Encoding.Default.GetBytes(fileName);
+ bytes.AddRange(filenamedata);
+ bytes.Add(0x00);
+ //string sourceitem = "/keys/bin/1.bin";
+ //string sourceitem = "/keys/bin/(7926)AiLiSheng47DaiA_DaiZuoYouCeHuaMen13NianHou.bin";
+ //FileData = await WebHelper.GetVehKeyBin(sourceitem);
+ if (FileData == null)
+ {
+ return;
+ }
+ TotalPackets = FileData.Length / 1024;
+ byte[] DataBuffdata = Encoding.Default.GetBytes(FileData.Length.ToString());
+ bytes.AddRange(DataBuffdata);
+ bytes.Add(0x00);
+ if (bytes.Count < 128)
+ {
+ int copi = 128 + 3 - bytes.Count;
+ for (int i = 0; i < copi; i++)
+ {
+ bytes.Add(0x00);
+ }
+ }
+ var cdata = new byte[128];
+ Array.Copy(bytes.ToArray(), 3, cdata, 0, 128);
+ var crc = ProtocolHelper.CalculateCRC16(cdata);
+ var CRCHigh = (byte)((crc >> 8) & 0xFF);
+ var CRCLow = (byte)(crc & 0xFF);
+ bytes.Add((byte)CRCHigh);
+ bytes.Add((byte)CRCLow);
+
+ var rdata = bytes.ToArray();
+ await WriteLargeDataFrame(rdata, 100);
+ }
+ ///
+ /// 发送数据帧
+ ///
+ ///
+ ///
+ public async Task SendDataFrame(int page)
+ {
+ bool flag = false;
+ var rdata = GetSendDataFrame(page, FileData);
+ bool success = await WriteLargeDataFrame(rdata.ToArray(), 100);
+ if (success)
+ {
+ flag = true;
+ }
+ else
+ {
+ Debug.WriteLine("TestData发送失败");
+ }
+ return flag;
+ }
+
+ ///
+ /// 发送结束帧
+ ///
+ ///
+ public async Task SendEOTFrame()
+ {
+ var rdata = new byte[133];
+ rdata[0] = 0x01;
+ rdata[1] = 0x00;
+ rdata[2] = 0xFF;
+ await WriteLargeDataFrame(rdata, 100);
+ }
+
+ ///
+ /// 根据包页及文件数据获取数据帧
+ ///
+ ///
+ ///
+ ///
+ private List GetSendDataFrame(int page, byte[] filedata)
+ {
+ try
+ {
+ var bytes = new List();
+ if (page == filedata.Length / 1024 && filedata.Length % 1024 == 0)
+ {
+ return bytes;
+ }
+ bytes.Add(0x02);
+ bytes.Add((byte)(page));
+ bytes.Add((byte)~(page));
+ if (page == filedata.Length / 1024 - 1 && filedata.Length % 1024 <= 128 && filedata.Length % 1024 > 0)
+ {
+ var cdata = new byte[128];
+ Array.Copy(filedata, page * 1024, cdata, 0, filedata.Length - page * 1024);
+ var crc = ProtocolHelper.CalculateCRC16(cdata);
+ var CRCHigh = (byte)((crc >> 8) & 0xFF);
+ var CRCLow = (byte)(crc & 0xFF);
+ bytes.AddRange(cdata);
+ bytes.Add((byte)CRCHigh);
+ bytes.Add((byte)CRCLow);
+ }
+ else
+ {
+ var cdata = new byte[1024];
+ var arrarycount = 1024;
+ if (filedata.Length - page * 1024 > 0 && filedata.Length - page * 1024 < 1024)
+ {
+ arrarycount = filedata.Length - page * 1024;
+ }
+ Array.Copy(filedata, page * 1024, cdata, 0, arrarycount);
+ var crc = ProtocolHelper.CalculateCRC16(cdata);
+ var CRCHigh = (byte)((crc >> 8) & 0xFF);
+ var CRCLow = (byte)(crc & 0xFF);
+ bytes.AddRange(cdata);
+ bytes.Add((byte)CRCHigh);
+ bytes.Add((byte)CRCLow);
+ }
+ return bytes;
+ }
+ catch (Exception ex)
+ {
+ throw;
+ }
+
+ }
+ #endregion
+
+ #region 写入数据帧
+ ///
+ /// 分包发送大数据
+ ///
+ public async Task WriteLargeDataFrame(byte[] data, int maxPacketSize = 100)
+ {
+ try
+ {
+ Debug.WriteLine($"开始发送数据,总长度: {data.Length} 字节,分包大小: {maxPacketSize} 字节");
+
+ int totalPackets = (int)Math.Ceiling((double)data.Length / maxPacketSize);
+ int successfulPackets = 0;
+
+ for (int i = 0; i < totalPackets; i++)
+ {
+ int offset = i * maxPacketSize;
+ int length = Math.Min(maxPacketSize, data.Length - offset);
+ byte[] packet = new byte[length];
+ Array.Copy(data, offset, packet, 0, length);
+
+ bool packetSuccess = await WritePacketDataFrame(packet, i + 1, totalPackets);
+ if (packetSuccess)
+ {
+ successfulPackets++;
+ }
+ else
+ {
+ Debug.WriteLine($"第 {i + 1} 包发送失败");
+ // 可以选择重试或直接失败
+ // return false;
+ }
+
+ // 添加小延迟,避免发送过快
+ await Task.Delay(30);
+ }
+
+ bool overallSuccess = successfulPackets == totalPackets;
+ Debug.WriteLine($"数据发送完成: {successfulPackets}/{totalPackets} 包成功");
+ return overallSuccess;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"发送大数据异常: {ex.Message}");
+ return false;
+ }
+ }
+ ///
+ /// 发送单个数据包
+ ///
+ private async Task WritePacketDataFrame(byte[] packet, int packetNumber, int totalPackets)
+ {
+ try
+ {
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"发送第 {packetNumber} 包异常: {ex.Message}");
+ return false;
+ }
+ }
+ #endregion
+
+ }
+}
diff --git a/AIK.Common/AIKProtocol/K3ToolUSBProtocol.cs b/AIK.Common/AIKProtocol/K3ToolUSBProtocol.cs
new file mode 100644
index 0000000..237dc7a
--- /dev/null
+++ b/AIK.Common/AIKProtocol/K3ToolUSBProtocol.cs
@@ -0,0 +1,476 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.AIKProtocol
+{
+ public static class K3ToolUSBProtocol
+ {
+ private static int _totalPackets;
+ private static byte[]? _fileData;
+ private static byte[]? _endEOTData;
+ private static byte[]? _connectData;
+ private static byte[]? _createRemoteData;
+ private static byte[]? _closetheUdiskData;
+ private static byte[]? _opentheUdiskData;
+ private static readonly object _lockObject = new object();
+ public static readonly string ConnectFileName = "usb connect.bin";
+ public static readonly string CreateRemoteFileName = "usb create remote.bin";
+ public static int TotalPackets
+ {
+ get => _totalPackets;
+ set => _totalPackets = value;
+ }
+
+ public static byte[] FileData
+ {
+ get => _fileData ?? Array.Empty();
+ set
+ {
+ lock (_lockObject)
+ {
+ _fileData = value;
+ // 当 FileData 不为空时,自动计算 TotalPackets
+ if (_fileData != null && _fileData.Length > 0)
+ {
+ _totalPackets = (int)Math.Ceiling(_fileData.Length / 1024.0);
+ }
+ else
+ {
+ _totalPackets = 0;
+ }
+ }
+ }
+ }
+
+ public static byte[] EndEOTData
+ {
+ get
+ {
+ if (_endEOTData == null || _endEOTData.Length == 0)
+ {
+ lock (_lockObject)
+ {
+ // 双重检查锁定
+ if (_endEOTData == null || _endEOTData.Length == 0)
+ {
+ _endEOTData = GetBinData(ResourceEOTName);
+ }
+ }
+ }
+ return _endEOTData;
+ }
+ set => _endEOTData = value;
+ }
+
+ public static byte[] ConnectData
+ {
+ get
+ {
+ if (_connectData == null || _connectData.Length == 0)
+ {
+ lock (_lockObject)
+ {
+ // 双重检查锁定
+ if (_connectData == null || _connectData.Length == 0)
+ {
+ _connectData = GetBinData(ResourceConnectName);
+ }
+ }
+ }
+ return _connectData;
+ }
+ set => _connectData = value;
+ }
+
+ public static byte[] CreateRemoteData
+ {
+ get
+ {
+ if (_createRemoteData == null || _createRemoteData.Length == 0)
+ {
+ lock (_lockObject)
+ {
+ // 双重检查锁定
+ if (_createRemoteData == null || _createRemoteData.Length == 0)
+ {
+ _createRemoteData = GetBinData(ResourceCreateRemoteName);
+ }
+ }
+ }
+ return _createRemoteData;
+ }
+ set => _createRemoteData = value;
+ }
+
+ public static byte[] ClosetheUdiskData
+ {
+ get
+ {
+ if (_closetheUdiskData == null || _closetheUdiskData.Length == 0)
+ {
+ lock (_lockObject)
+ {
+ // 双重检查锁定
+ if (_closetheUdiskData == null || _closetheUdiskData.Length == 0)
+ {
+ _closetheUdiskData = GetBinData(ResourceClosetheUdiskName);
+ }
+ }
+ }
+ return _closetheUdiskData;
+ }
+ set => _closetheUdiskData = value;
+ }
+
+ public static byte[] OpentheUdiskData
+ {
+ get
+ {
+ if (_opentheUdiskData == null || _opentheUdiskData.Length == 0)
+ {
+ lock (_lockObject)
+ {
+ // 双重检查锁定
+ if (_opentheUdiskData == null || _opentheUdiskData.Length == 0)
+ {
+ _opentheUdiskData = GetBinData(ResourceOpentheUdiskName);
+ }
+ }
+ }
+ return _opentheUdiskData;
+ }
+ set => _opentheUdiskData = value;
+ }
+
+ public static string ResourceEOTName { get; set; } = "AIK.Common.Resources.eot.bin";
+ public static string ResourceConnectName { get; set; } = "AIK.Common.Resources.usb connect.bin";
+ public static string ResourceCreateRemoteName { get; set; } = "AIK.Common.Resources.usb create remote.bin";
+
+ public static string ResourceClosetheUdiskName { get; set; } = "AIK.Common.Resources.Close the U disk.bin";
+
+ public static string ResourceOpentheUdiskName { get; set; } = "AIK.Common.Resources.Open the U disk.bin";
+ #region 头帧
+ public static byte[] GetSendHeader(string sourceitem)
+ {
+ // 保持原有实现
+ List bytes = new List();
+ bytes.Add(0x01);
+ bytes.Add(0x00);
+ bytes.Add(0xFF);
+
+ int lastSlashIndex = sourceitem.LastIndexOf('/');
+ string fileName = lastSlashIndex >= 0 ? sourceitem.Substring(lastSlashIndex + 1) : sourceitem;
+ byte[] filenamedata = Encoding.GetEncoding(936).GetBytes(fileName);
+ bytes.AddRange(filenamedata);
+ bytes.Add(0x00);
+
+ if (FileData == null) return new byte[0];
+
+ TotalPackets = (int)Math.Ceiling(FileData.Length / 1024.0);
+ byte[] dataLengthData = Encoding.GetEncoding(936).GetBytes(FileData.Length.ToString());
+ bytes.AddRange(dataLengthData);
+ bytes.Add(0x00);
+
+ // 填充到128字节
+ if (bytes.Count < 128 + 3)
+ {
+ bytes.AddRange(new byte[128 + 3 - bytes.Count]);
+ }
+
+ var cdata = new byte[128];
+ Array.Copy(bytes.ToArray(), 3, cdata, 0, 128);
+ var crc = ProtocolHelper.CalculateCRC16(cdata);
+ bytes.Add((byte)((crc >> 8) & 0xFF));
+ bytes.Add((byte)(crc & 0xFF));
+
+ return bytes.ToArray();
+ }
+ #endregion
+
+ #region 数据帧
+ public static List GetSendDataFrame(int page, byte[] filedata)
+ {
+ try
+ {
+ var bytes = new List();
+ if (page >= TotalPackets) return bytes;
+
+ bytes.Add(0x02);
+ bytes.Add((byte)(page + 1));
+ bytes.Add((byte)~(page + 1));
+
+ int dataStart = page * 1024;
+ int dataLength = Math.Min(1024, filedata.Length - dataStart);
+ var frameData = new byte[1024];
+ Array.Copy(filedata, dataStart, frameData, 0, dataLength);
+
+ var crc = ProtocolHelper.CalculateCRC16(frameData);
+ bytes.AddRange(frameData);
+ bytes.Add((byte)((crc >> 8) & 0xFF));
+ bytes.Add((byte)(crc & 0xFF));
+
+ return bytes;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"生成数据帧错误: {ex.Message}");
+ return new List();
+ }
+ }
+ #endregion
+
+ #region 资源文件帧
+ ///
+ /// 获取bin文件转成byte数组
+ ///
+ ///
+ ///
+ private static byte[] GetBinData(string resourceName)
+ {
+ try
+ {
+ var assembly = Assembly.GetExecutingAssembly();
+
+ // 查看所有资源名称(调试用)
+ // var names = assembly.GetManifestResourceNames();
+
+ using var stream = assembly.GetManifestResourceStream(resourceName);
+ if (stream == null)
+ throw new FileNotFoundException($"未找到嵌入资源: {resourceName}");
+ using var ms = new MemoryStream();
+ stream.CopyTo(ms);
+ return ms.ToArray();
+ }
+ catch (Exception ex)
+ {
+ return Array.Empty();
+ }
+
+ }
+
+ #region Connect帧
+ ///
+ /// 手动刷新 Connect 数据(强制重新加载)
+ ///
+ public static void RefreshConnectData()
+ {
+ lock (_lockObject)
+ {
+ _connectData = GetBinData(ResourceConnectName);
+ }
+ }
+
+ ///
+ /// 清除缓存的 Connect 数据(下次访问时会重新加载)
+ ///
+ public static void ClearConnectDataCache()
+ {
+ lock (_lockObject)
+ {
+ _connectData = null;
+ }
+ }
+ #endregion
+
+ #region CreateRemote帧
+ ///
+ /// 手动刷新 CreateRemote 数据(强制重新加载)
+ ///
+ public static void RefreshCreateRemoteData()
+ {
+ lock (_lockObject)
+ {
+ _createRemoteData = GetBinData(ResourceCreateRemoteName);
+ }
+ }
+
+ ///
+ /// 清除缓存的 CreateRemote数据(下次访问时会重新加载)
+ ///
+ public static void ClearCreateRemoteDataCache()
+ {
+ lock (_lockObject)
+ {
+ _createRemoteData = null;
+ }
+ }
+ #endregion
+
+ #region EOT帧
+ ///
+ /// 手动刷新 EOT 数据(强制重新加载)
+ ///
+ public static void RefreshEndEOTData()
+ {
+ lock (_lockObject)
+ {
+ _endEOTData = GetBinData(ResourceEOTName);
+ }
+ }
+
+ ///
+ /// 清除缓存的 EOT 数据(下次访问时会重新加载)
+ ///
+ public static void ClearEndEOTDataCache()
+ {
+ lock (_lockObject)
+ {
+ _endEOTData = null;
+ }
+ }
+ #endregion
+ #endregion
+
+ #region 最终结束帧
+ ///
+ /// 最终结束帧
+ ///
+ ///
+ public static byte[] GetEndDataFrame()
+ {
+ var bytes = new byte[133];
+ bytes[0] = 0x01;
+ bytes[1] = 0x00;
+ bytes[2] = 0xFF;
+ // 其余128字节默认为0,无需手动设置
+ return bytes;
+ }
+ #endregion
+
+ #region 工具方法
+ ///
+ /// 设置文件数据(自动计算 TotalPackets)
+ ///
+ /// 文件数据
+ public static void SetFileData(byte[] fileData)
+ {
+ FileData = fileData; // 这会自动触发 TotalPackets 计算
+ }
+
+ ///
+ /// 从文件路径加载数据(自动计算 TotalPackets)
+ ///
+ /// 文件路径
+ public static void LoadFileData(string filePath)
+ {
+ if (!File.Exists(filePath))
+ throw new FileNotFoundException($"文件不存在: {filePath}");
+
+ var fileData = File.ReadAllBytes(filePath);
+ FileData = fileData; // 自动计算 TotalPackets
+ }
+
+ ///
+ /// 获取指定文件的总包数(不设置到全局状态)
+ ///
+ /// 文件数据
+ /// 总包数
+ public static int GetTotalPackets(byte[] fileData)
+ {
+ return (int)Math.Ceiling(fileData.Length / 1024.0);
+ }
+
+ ///
+ /// 重置所有状态
+ ///
+ public static void Reset()
+ {
+ lock (_lockObject)
+ {
+ _totalPackets = 0;
+ _fileData = null;
+ _endEOTData = null;
+ }
+ }
+
+ ///
+ /// 将 UTF-8 字符串转换为 GBK 编码的字节数组
+ ///
+ public static byte[] Utf8StringToGbkBytes(string utf8Text)
+ {
+ if (utf8Text == null) return null;
+ return Encoding.GetEncoding(936).GetBytes(utf8Text);
+ }
+
+ ///
+ /// 将 UTF-8 字节数组转换为 GBK 字节数组
+ ///
+ public static byte[] Utf8BytesToGbkBytes(byte[] utf8Bytes)
+ {
+ if (utf8Bytes == null || utf8Bytes.Length == 0) return utf8Bytes;
+
+ // 1. UTF-8 字节 → 字符串(Unicode)
+ string text = Encoding.UTF8.GetString(utf8Bytes);
+
+ // 2. 字符串 → GBK 字节
+ return Encoding.GetEncoding(936).GetBytes(text);
+ }
+ #endregion
+
+ #region 验证设备响应数据包
+
+ private static readonly byte[] NakSignature = { 0x6E, 0x61, 0x6B, 0x00 }; // "nak"
+ private static readonly byte[] AckSignature = { 0x61, 0x63, 0x6B, 0x00 }; // "ack"
+ private static readonly byte[] AckcSignature = { 0x61, 0x63, 0x6B, 0x63, 0x00 }; // "ackc"
+ ///
+ /// NAK响应结果
+ ///
+ /// usb hid 返回包
+ ///
+ public static bool IsNakResponse(List buffer) => ContainsSubsequence(buffer.ToArray(), NakSignature);
+
+ ///
+ /// ACKC响应结果
+ ///
+ /// usb hid 返回包
+ ///
+ public static bool IsAckcResponse(List buffer) => ContainsSubsequence(buffer.ToArray(), AckcSignature);
+
+ ///
+ /// ACK响应结果
+ ///
+ /// usb hid 返回包
+ ///
+ public static bool IsReadyForDataFrameResponse(List buffer) => ContainsSubsequence(buffer.ToArray(), AckSignature);
+
+ private static bool ContainsSubsequence(ReadOnlySpan buffer, ReadOnlySpan pattern)
+ {
+ if (buffer.Length != 195) return false;
+ if (pattern.Length == 0) return false;
+ if (buffer.Length < pattern.Length) return false;
+
+ for (int i = 0; i <= buffer.Length - pattern.Length; i++)
+ {
+ if (buffer.Slice(i, pattern.Length).SequenceEqual(pattern))
+ return true;
+ }
+ return false;
+ }
+ #endregion
+
+ #region 查询固件版本
+ ///
+ /// 查询固件版本version query
+ ///
+ ///
+ public static byte[] VersionQuery()
+ {
+ string str = "0100FF6765742076657200300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CC85";
+ byte[] content = new byte[str.Length / 2];
+ for (int i = 0; i < content.Length; i++)
+ {
+ content[i] = Convert.ToByte(str.Substring(i * 2, 2), 16);
+ }
+ return content;
+ }
+ #endregion
+
+
+ }
+}
diff --git a/AIK.Common/AIKProtocol/ProtocolHelper.cs b/AIK.Common/AIKProtocol/ProtocolHelper.cs
new file mode 100644
index 0000000..0ede3f5
--- /dev/null
+++ b/AIK.Common/AIKProtocol/ProtocolHelper.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.AIKProtocol
+{
+ public static class ProtocolHelper
+ {
+ public static ushort CalculateCRC16(IEnumerable data)
+ {
+ if (data == null || !data.Any())
+ return 0;
+
+ ushort crc = 0;
+ foreach (byte b in data)
+ {
+ crc ^= (ushort)(b << 8);
+ for (int i = 0; i < 8; i++)
+ {
+ if ((crc & 0x8000) != 0)
+ {
+ crc = (ushort)((crc << 1) ^ 0x1021);
+ }
+ else
+ {
+ crc = (ushort)(crc << 1);
+ }
+ }
+ }
+ return crc;
+ }
+ }
+}
diff --git a/AIK.Common/CommonString.cs b/AIK.Common/CommonString.cs
new file mode 100644
index 0000000..5150eae
--- /dev/null
+++ b/AIK.Common/CommonString.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common
+{
+ public static class CommonString
+ {
+ public static string BinCacheDirectory = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "AIKKey",
+ "BinCache"
+ );
+ public static string ImageCacheDirectory = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "AIKKey",
+ "ImageCache"
+ );
+ public static string CloudCacheDirectory = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "AIKKey",
+ "CloudCache"
+ );
+ }
+}
diff --git a/AIK.Common/Enum/FileServiceType.cs b/AIK.Common/Enum/FileServiceType.cs
new file mode 100644
index 0000000..bdc5858
--- /dev/null
+++ b/AIK.Common/Enum/FileServiceType.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Enum
+{
+ public enum FileServiceType
+ {
+ OBD,
+ BIN,
+ CloudData
+ }
+}
diff --git a/AIK.Common/Enum/HidConnectionState.cs b/AIK.Common/Enum/HidConnectionState.cs
new file mode 100644
index 0000000..8f92b30
--- /dev/null
+++ b/AIK.Common/Enum/HidConnectionState.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Enum
+{
+ public enum HidConnectionState
+ {
+ Disconnected, // 初始/断开状态
+ DeviceOpened, // HID 打开成功,待发 Connect
+ AwaitingResponse, // 已发 Connect,等待应答
+ Ready // 握手完成,可传业务数据
+ }
+}
diff --git a/AIK.Common/Enum/HidOperationTypeEnum.cs b/AIK.Common/Enum/HidOperationTypeEnum.cs
new file mode 100644
index 0000000..caedb66
--- /dev/null
+++ b/AIK.Common/Enum/HidOperationTypeEnum.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Enum
+{
+ public enum HidOperationTypeEnum
+ {
+ None = 0,
+ DeviceUpdate,
+ DeviceVersion,
+ RemoteGeneration
+ }
+}
diff --git a/AIK.Common/Enum/MenuFunction.cs b/AIK.Common/Enum/MenuFunction.cs
new file mode 100644
index 0000000..c4f713f
--- /dev/null
+++ b/AIK.Common/Enum/MenuFunction.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Enum
+{
+ public enum MenuFunction
+ {
+ RemoteGeneration, // 遥控生成
+ RemoteCopy, // 遥控拷贝
+ RemoteDetection, // 遥控检测
+ ChipIdentificationCopy, // 芯片识别拷贝
+ ChipGeneration, // 芯片生成
+ AccessCardCopy, // 门禁卡拷贝
+ KeyUnlock, // 钥匙解锁
+ TirePressure, // 胎压功能
+ MatchingFunction, // 匹配功能
+ ChipWriteStart, // 芯片写启动
+ Programmer, // 编程器
+ AntiTheftData // 防盗资料
+ }
+}
diff --git a/AIK.Common/Enum/MessageTypeEnum.cs b/AIK.Common/Enum/MessageTypeEnum.cs
new file mode 100644
index 0000000..d0cad39
--- /dev/null
+++ b/AIK.Common/Enum/MessageTypeEnum.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Enum
+{
+ public enum MessageTypeEnum
+ {
+ Info,
+ Warning,
+ Error,
+ Success
+ }
+}
diff --git a/AIK.Common/Enum/TransferPhase.cs b/AIK.Common/Enum/TransferPhase.cs
new file mode 100644
index 0000000..54a0694
--- /dev/null
+++ b/AIK.Common/Enum/TransferPhase.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Enum
+{
+ ///
+ /// USB协议流转小阶段
+ ///
+ public enum TransferPhase
+ {
+ Idle,
+ Phase1_SendingHeader, // 发送头帧
+ Phase2_WaitingForHeaderAck, // 等待头帧确认
+ Phase3_SendingDataFrames, // 发送数据帧
+ Phase4_WaitingForDataFrameAck, // 等待数据帧确认
+ Phase5_WaitingForFinalDataAck, // 等待最后一个数据帧确认
+ Phase6_SendingEOT, // 发送 EOT
+ Phase7_WaitingForNak, // 等待 NAK
+ Phase8_SendingFinalEOT, // 发送最终 EOT
+ Phase9_WaitingForAckc, // 等待 ACKC
+ Phase10_SendEndFrame, // 发送结束帧
+ Phase11_WaitingForComplete, // 等待最终确认
+ Completed
+ }
+ public enum ResponseType
+ {
+ ReadyForData,
+ Nak,
+ Ackc,
+ Unknown
+ }
+ ///
+ /// 连接流程大阶段(每个大阶段都会走完小阶段)
+ ///
+ public enum BigTransferPhase
+ {
+ None,
+ Phase1_Connect, // 大阶段1:设备连接(含初始化/校验)
+ Phase2_Generate, // 大阶段2:数据生成(遥控生成)
+ Phase3_Write, // 大阶段3:数据写入(将生成的数据写入设备)
+ }
+ public record HidResponseReceivedEventArgs(byte[] Data);
+ public record HidLogMessageEventArgs(string Message, bool IsError = false);
+
+ public class BigPhaseChangedEventArgs : EventArgs
+ {
+ public BigTransferPhase CurrentPhase { get; }
+ public BigTransferPhase PreviousPhase { get; }
+ public int CompletedPhases { get; }
+ public int TotalPhases { get; }
+
+ public BigPhaseChangedEventArgs(BigTransferPhase current, BigTransferPhase previous, int completed, int total)
+ {
+ CurrentPhase = current;
+ PreviousPhase = previous;
+ CompletedPhases = completed;
+ TotalPhases = total;
+ }
+ }
+
+}
diff --git a/AIK.Common/Enum/UserStatus.cs b/AIK.Common/Enum/UserStatus.cs
new file mode 100644
index 0000000..03a22cf
--- /dev/null
+++ b/AIK.Common/Enum/UserStatus.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Enum
+{
+ public enum UserStatus
+ {
+ NotLoggedIn, // 未登录
+ LoggedInOffline, // 已登录但离线
+ LoggedInOnline // 已登录且在线
+ }
+}
diff --git a/AIK.Common/Event/ConnectionStateChangedEventArgs.cs b/AIK.Common/Event/ConnectionStateChangedEventArgs.cs
new file mode 100644
index 0000000..2763796
--- /dev/null
+++ b/AIK.Common/Event/ConnectionStateChangedEventArgs.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Event
+{
+ public class ConnectionStateChangedEventArgs : EventArgs
+ {
+ public bool IsConnected { get; }
+ public string Message { get; }
+
+ public ConnectionStateChangedEventArgs(bool isConnected, string message)
+ {
+ IsConnected = isConnected;
+ Message = message;
+ }
+ }
+}
diff --git a/AIK.Common/Event/HidReconnectEventArgs.cs b/AIK.Common/Event/HidReconnectEventArgs.cs
new file mode 100644
index 0000000..14564a8
--- /dev/null
+++ b/AIK.Common/Event/HidReconnectEventArgs.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Event
+{
+ public class HidReconnectEventArgs : EventArgs
+ {
+ public int CurrentAttempt { get; }
+ public int MaxAttempts { get; }
+
+ public HidReconnectEventArgs(int currentAttempt, int maxAttempts)
+ {
+ CurrentAttempt = currentAttempt;
+ MaxAttempts = maxAttempts;
+ }
+ }
+}
diff --git a/AIK.Common/GlobalImageCache.cs b/AIK.Common/GlobalImageCache.cs
new file mode 100644
index 0000000..52992bf
--- /dev/null
+++ b/AIK.Common/GlobalImageCache.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Common
+{
+ public static class GlobalImageCache
+ {
+ private static readonly ConcurrentDictionary _imgListKey = new ConcurrentDictionary();
+
+ public static BitmapImage GetOrAdd(string url, Func valueFactory)
+ {
+ return _imgListKey.GetOrAdd(url, valueFactory);
+ }
+
+ public static bool TryGetValue(string key, out BitmapImage value)
+ {
+ return _imgListKey.TryGetValue(key, out value);
+ }
+ }
+}
diff --git a/AIK.Common/IconString/IconStringHelper.cs b/AIK.Common/IconString/IconStringHelper.cs
new file mode 100644
index 0000000..db271da
--- /dev/null
+++ b/AIK.Common/IconString/IconStringHelper.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.IconString
+{
+ public static class IconStringHelper
+ {
+ public static string InfoIcon => "\uE616"; // 信息图标
+ public static string WarningIcon => "\uE604";
+ public static string ErrorIcon => "\uE603";
+ public static string SuccessIcon => "\uE703";
+
+ }
+}
diff --git a/AIK.Common/IconString/MessageColors.cs b/AIK.Common/IconString/MessageColors.cs
new file mode 100644
index 0000000..57e61c0
--- /dev/null
+++ b/AIK.Common/IconString/MessageColors.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.IconString
+{
+ public static class MessageColors
+ {
+ // 建议使用十六进制或 Brush(根据 UI 框架)
+ public static string Info => "#1890FF"; // 蓝色
+ public static string Warning => "#FAAD14"; // 橙色
+ public static string Error => "#FF4D4F"; // 红色
+ public static string Success => "#52C41A"; // 绿色
+ }
+}
diff --git a/AIK.Common/IconString/MessageStyle.cs b/AIK.Common/IconString/MessageStyle.cs
new file mode 100644
index 0000000..34d64aa
--- /dev/null
+++ b/AIK.Common/IconString/MessageStyle.cs
@@ -0,0 +1,24 @@
+using AIK.Common.Enum;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.IconString
+{
+ public static class MessageStyle
+ {
+ public static (string Icon, string Color) GetByType(MessageTypeEnum type)
+ {
+ return type switch
+ {
+ MessageTypeEnum.Info => (IconStringHelper.InfoIcon, MessageColors.Info),
+ MessageTypeEnum.Warning => (IconStringHelper.WarningIcon, MessageColors.Warning),
+ MessageTypeEnum.Error => (IconStringHelper.ErrorIcon, MessageColors.Error),
+ MessageTypeEnum.Success => (IconStringHelper.SuccessIcon, MessageColors.Success),
+ _ => (IconStringHelper.InfoIcon, MessageColors.Info), // 默认 info
+ };
+ }
+ }
+}
diff --git a/AIK.Common/ImageUtils.cs b/AIK.Common/ImageUtils.cs
new file mode 100644
index 0000000..fdb3cab
--- /dev/null
+++ b/AIK.Common/ImageUtils.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Common
+{
+ public class ImageUtils
+ {
+ ///
+ /// 从文件路径加载图像(同步)
+ ///
+ public static BitmapImage LoadFromFile(string filePath)
+ {
+ var bitmap = new BitmapImage();
+ using (var stream = File.OpenRead(filePath))
+ {
+ bitmap.BeginInit();
+ bitmap.StreamSource = stream;
+ bitmap.CacheOption = BitmapCacheOption.OnLoad;
+ bitmap.EndInit();
+ }
+ return bitmap;
+ }
+
+ ///
+ /// 从字节数组加载图像
+ ///
+ public static BitmapImage LoadFromBytes(byte[] imageData)
+ {
+ using (var ms = new MemoryStream(imageData))
+ {
+ return StreamToBitmapImage(ms);
+ }
+ }
+
+ ///
+ /// 从任意Stream加载图像(不负责关闭流)
+ ///
+ public static BitmapImage StreamToBitmapImage(Stream stream)
+ {
+ if (stream.CanSeek) stream.Position = 0;
+
+ var bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ bitmap.StreamSource = stream;
+ bitmap.CacheOption = BitmapCacheOption.OnLoad;
+ bitmap.EndInit();
+ return bitmap;
+ }
+
+ public static BitmapImage StreamToBitmapImageFull(Stream stream)
+ {
+ if (stream == null) return null;
+ try
+ {
+ if (stream.CanSeek) stream.Position = 0;
+ using var memoryStream = new MemoryStream();
+ stream.CopyTo(memoryStream);
+ memoryStream.Position = 0;
+ var bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ bitmap.StreamSource = stream;
+ bitmap.CacheOption = BitmapCacheOption.OnLoad;
+ bitmap.EndInit();
+ bitmap.Freeze();
+
+ return bitmap;
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+
+ }
+ }
+}
diff --git a/AIK.Common/Interface/IFileDialogService.cs b/AIK.Common/Interface/IFileDialogService.cs
new file mode 100644
index 0000000..81064d6
--- /dev/null
+++ b/AIK.Common/Interface/IFileDialogService.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Interface
+{
+ public interface IFileDialogService
+ {
+ Task OpenFileAsync(string title = "选择文件");
+ Task SelectFolderAsync(string description = "请选择文件夹");
+ }
+}
diff --git a/AIK.Common/Interface/IModalDialogService.cs b/AIK.Common/Interface/IModalDialogService.cs
new file mode 100644
index 0000000..7bb1900
--- /dev/null
+++ b/AIK.Common/Interface/IModalDialogService.cs
@@ -0,0 +1,38 @@
+using AIK.Common.Enum;
+using AIK.Common.IconString;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Interface
+{
+ public interface IModalDialogService
+ {
+ Task ShowProgressAsync(
+ Func, CancellationToken, Task<(bool, string)>> work,
+ string title = "请稍候",
+ string message = "正在烧录...",
+ bool canCancel = true);
+
+ Task ShowDialogAsync(
+ string title = "请稍候",
+ string message = "正在处理...",
+ MessageTypeEnum typeEnum = MessageTypeEnum.Info,
+ bool canCancel = true, bool isAutoClose = true, int closeTime = 3000);
+
+ Task ShowTipsDialogAsync(
+ string message = "已完成",
+ MessageTypeEnum typeEnum = MessageTypeEnum.Info,
+ bool canCancel = true, bool isAutoClose = true, int closeTime = 3000);
+
+ Task ShowQRCodeDialogAsync(
+ IServiceProvider serviceProvider,
+ string title = "请稍候",
+ string message = "正在处理...",
+ MessageTypeEnum typeEnum = MessageTypeEnum.Info,
+ bool canCancel = true, bool isAutoClose = true, int closeTime = 3000);
+ }
+}
diff --git a/AIK.Common/Interface/IQRCodeService.cs b/AIK.Common/Interface/IQRCodeService.cs
new file mode 100644
index 0000000..e39536d
--- /dev/null
+++ b/AIK.Common/Interface/IQRCodeService.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Interface
+{
+ public interface IQRCodeService
+ {
+ byte[] GenerateQRCodeWithLogo(string text, string logoPath, int pixelsPerModule = 10);
+ }
+}
diff --git a/AIK.Common/Interface/ISettingsService.cs b/AIK.Common/Interface/ISettingsService.cs
new file mode 100644
index 0000000..ad8d560
--- /dev/null
+++ b/AIK.Common/Interface/ISettingsService.cs
@@ -0,0 +1,15 @@
+using AIK.Common.Language;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Interface
+{
+ public interface ISettingsService
+ {
+ UserPreferences Load();
+ void Save(UserPreferences settings);
+ }
+}
diff --git a/AIK.Common/Interface/IUpdateService.cs b/AIK.Common/Interface/IUpdateService.cs
new file mode 100644
index 0000000..8e80335
--- /dev/null
+++ b/AIK.Common/Interface/IUpdateService.cs
@@ -0,0 +1,38 @@
+using AIK.Common.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Interface
+{
+ public interface IUpdateService
+ {
+ #region 原生更新-界面无自定义
+ ///
+ /// 手动检查更新
+ ///
+ /// 更新结果
+ Task CheckForUpdateAsync();
+
+ ///
+ /// 原版更新(无自定义界面)
+ ///
+ ///
+ public Task StartUpdateProcess();
+ #endregion
+ #region 新自定义更新-界面可自定义
+ ///
+ /// 新自定义更新(检查更新)
+ ///
+ ///
+ public Task GetUpdateInfoAsync();
+ ///
+ /// 自定义更新
+ ///
+ ///
+ public Task CheckForUpdate();
+ #endregion
+ }
+}
diff --git a/AIK.Common/IsExternalInit.cs b/AIK.Common/IsExternalInit.cs
new file mode 100644
index 0000000..a869ed6
--- /dev/null
+++ b/AIK.Common/IsExternalInit.cs
@@ -0,0 +1,6 @@
+//
+// Polyfill for record types with init-only setters (required by .NET Framework 4.8)
+namespace System.Runtime.CompilerServices
+{
+ internal static class IsExternalInit { }
+}
\ No newline at end of file
diff --git a/AIK.Common/Language/AiKLanguage.cs b/AIK.Common/Language/AiKLanguage.cs
new file mode 100644
index 0000000..603da2d
--- /dev/null
+++ b/AIK.Common/Language/AiKLanguage.cs
@@ -0,0 +1,1951 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Input;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace AIK.Common.Language
+{
+ ///
+ /// 多语言
+ ///
+ public class AiKLanguage
+ {
+ public static Dictionary LanguageKey = null;
+ public static void GetLanguage(string language)
+ {
+ switch (language)
+ {
+ case "zh": // 中文
+ LanguageKey = zhlanguage();
+ break;
+ case "en": // 英文
+ LanguageKey = enlanguage();
+ break;
+ case "pt": // 葡萄牙(葡萄牙)
+ LanguageKey = ptlanguage();
+ break;
+ case "pt-BR": // 葡萄牙语(巴西)
+ LanguageKey = ptBRlanguage();
+ break;
+ case "es": // 西班牙语
+ LanguageKey = eslanguage();
+ break;
+ case "id": // 印尼语
+ LanguageKey = idlanguage();
+ break;
+ case "in": // 印度
+ LanguageKey = inlanguage();
+ break;
+ case "hi": // 印地语
+ LanguageKey = hilanguage();
+ break;
+ case "fr": // 法语
+ LanguageKey = frlanguage();
+ break;
+ case "fa": // 波斯语
+ LanguageKey = falanguage();
+ break;
+ case "he": // 希伯来语
+ LanguageKey = helanguage();
+ break;
+ case "it": // 意大利语
+ LanguageKey = itlanguage();
+ break;
+ case "ko": // 朝鲜语(韩语)
+ LanguageKey = kolanguage();
+ break;
+ case "pl": // 波兰语
+ LanguageKey = pllanguage();
+ break;
+ case "ru": // 俄语
+ LanguageKey = rulanguage();
+ break;
+ case "th": // 泰语
+ LanguageKey = thlanguage();
+ break;
+ case "tr": // 土耳其语
+ LanguageKey = trlanguage();
+ break;
+ case "vi": // 越南语
+ LanguageKey = vilanguage();
+ break;
+ case "de": // 德语
+ LanguageKey = delanguage();
+ break;
+ case "uk": // 乌克兰语
+ LanguageKey = uklanguage();
+ break;
+ case "ms": // 马来语
+ LanguageKey = mslanguage();
+ break;
+ default: // 默认中文
+ LanguageKey = zhlanguage();
+ break;
+ }
+ }
+ private static Dictionary zhlanguage()
+ {
+ #region 中文
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "主页");
+ dictionary.Add("Settings", "系统配置");
+ dictionary.Add("RemoteGeneration", "遥控生成");
+ dictionary.Add("RemoteCopy", "遥控拷贝");
+ dictionary.Add("RemoteControlDetector", "遥控检测");
+ dictionary.Add("ChipIdentificationCopy", "芯片识别拷贝");
+ dictionary.Add("ChipGeneration", "芯片生成");
+ dictionary.Add("AccessCardCopy", "门禁卡拷贝");
+ dictionary.Add("KeyUnlock", "钥匙解锁");
+ dictionary.Add("TirePressure", "胎压功能");
+ dictionary.Add("MatchingFunction", "匹配功能");
+ dictionary.Add("ChipWriteStart", "芯片写启动");
+ dictionary.Add("Programmer", "编程器");
+ dictionary.Add("AntiTheftData", "防盗资料");
+ dictionary.Add("UpdateCenter", "更新中心");
+
+ dictionary.Add("ContactWechatCopy", "微信号已复制");
+ dictionary.Add("ContactEmailCopy", "邮箱号已复制");
+
+ dictionary.Add("Tips", "提示");
+ dictionary.Add("Connected", "已连接");
+ dictionary.Add("Disconnected", "未连接");
+ dictionary.Add("DeviceDisconnected", "设备未连接");
+ dictionary.Add("K3ToolConnectTips", "请先连接K3Tool设备再进行更新");
+ dictionary.Add("FileNotFound", "文件不存在");
+
+ dictionary.Add("UpToDate", "已是最新版本");
+ dictionary.Add("PleaseNote", "请知悉");
+
+ dictionary.Add("PleasePress", "请按");
+ dictionary.Add("Button", "键");
+
+ dictionary.Add("NoKeyData", "暂无钥匙数据");
+ dictionary.Add("Lock", "锁车");
+ dictionary.Add("Unlock", "开锁");
+ dictionary.Add("Trunk", "后备箱");
+ dictionary.Add("Panic", "寻车");
+
+ dictionary.Add("BurnTips", "烧录文件不存在,请选择需要烧录的钥匙型号");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "请使用移动端App烧录C子机");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "请使用移动端App烧录CF子机");
+ dictionary.Add("BurnSuccess", "烧录成功");
+ dictionary.Add("BurnError", "烧录失败");
+ dictionary.Add("NotMoreTips", "没有更多数据了~");
+ dictionary.Add("CloudData", "云数据");
+ dictionary.Add("CloudDataSyncCompleted", "同步完成");
+ dictionary.Add("CloudDataSyncFailed", "同步失败");
+ dictionary.Add("CloudDataDownloadFailed", "下载失败");
+ dictionary.Add("CloudDataDeviceNotFound", "未读取到K3Tool存储设备");
+ dictionary.Add("CloudDataInitCompleted", "初始化K3Tool完成");
+ dictionary.Add("HidSendPacketError", "发送数据包发生错误");
+ dictionary.Add("DialogPleaseWait", "请稍候");
+ dictionary.Add("DialogProcessing", "正在处理...");
+ dictionary.Add("DialogCancelled", "已取消");
+ dictionary.Add("DialogErrorPrefix", "错误");
+ dictionary.Add("DialogElapsedPrefix", "耗时");
+ dictionary.Add("DialogBurningTitle", "正在烧录");
+ dictionary.Add("DialogBurningMessage", "正在烧录...");
+ dictionary.Add("MembershipLoginRequired", "请先登录后再开通会员功能");
+ dictionary.Add("MembershipOpening", "正在开通会员功能...");
+ dictionary.Add("MembershipOpenSuccess", "开通成功");
+ dictionary.Add("MembershipOpenFailed", "开通失败,请稍后重试");
+ dictionary.Add("MembershipLoadFailedFallback", "加载会员功能失败,已显示默认功能");
+ dictionary.Add("MembershipOpenWindowTitle", "会员开通");
+ dictionary.Add("MembershipFeeStandard", "收费标准:");
+ dictionary.Add("MembershipIntegralPerYear", "积分/年");
+ dictionary.Add("MembershipOpenButton", "开通");
+ dictionary.Add("MembershipModuleDataWriteStart", "数据写启动");
+ dictionary.Add("MembershipModuleK3GeniePlus", "K3精灵+");
+ dictionary.Add("MembershipModuleAiIntelligent", "AI智能功能");
+ dictionary.Add("RechargeMinAmountInvalid", "充值金额不能小于0.01");
+ dictionary.Add("RechargeLoginRequired", "请先登录后再充值");
+ dictionary.Add("RechargeCreatingOrder", "正在创建支付订单...");
+ dictionary.Add("RechargePcQrCodeMissing", "后端未返回PC扫码支付二维码");
+ dictionary.Add("RechargeWechatScanToPay", "请使用微信扫码支付");
+ dictionary.Add("RechargePaypalParametersMissing", "后端未返回PayPal支付参数");
+ dictionary.Add("RechargeOpeningPaypal", "正在打开PayPal支付页面...");
+ dictionary.Add("RechargeCreateOrderFailed", "创建支付订单失败,请稍后重试");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary enlanguage()
+ {
+ #region 英文
+ Dictionary dictionary = new Dictionary();
+ dictionary.Add("HomePage", "HomePage");
+ dictionary.Add("Settings", "AppSettings");
+ dictionary.Add("RemoteGeneration", "Remote");
+ dictionary.Add("RemoteCopy", "RemoteCopy");
+ dictionary.Add("RemoteControlDetector", "RemoteControlDetector");
+ dictionary.Add("ChipIdentificationCopy", "ChipIdentificationCopy");
+ dictionary.Add("ChipGeneration", "ChipGeneration");
+ dictionary.Add("AccessCardCopy", "AccessCardCopy");
+ dictionary.Add("KeyUnlock", "KeyUnlock");
+ dictionary.Add("TirePressure", "TirePressure");
+ dictionary.Add("MatchingFunction", "MatchingFunction");
+ dictionary.Add("ChipWriteStart", "ChipWriteStart");
+ dictionary.Add("Programmer", "Programmer");
+ dictionary.Add("AntiTheftData", "AntiTheftData");
+ dictionary.Add("UpdateCenter", "UpdateCenter");
+
+ dictionary.Add("ContactWechatCopy", "Contact us by wechat Copy Success");
+ dictionary.Add("ContactEmailCopy", "Contact us by email Copy Success");
+
+ dictionary.Add("Connected", "Connected");
+ dictionary.Add("Disconnected", "Disconnected");
+ dictionary.Add("DeviceDisconnected", "Device Disconnected");
+ dictionary.Add("K3ToolConnectTips", "Please connect the K3Tool device first before performing the update");
+ dictionary.Add("FileNotFound", "File not found");
+
+ dictionary.Add("UpToDate", "Up to date");
+ dictionary.Add("PleaseNote", "Please Note");
+ dictionary.Add("PleasePress", "Please press");
+ dictionary.Add("Button", "button");
+ dictionary.Add("NoKeyData", "No key data available");
+ dictionary.Add("Lock", "Lock");
+ dictionary.Add("Unlock", "Unlock");
+ dictionary.Add("Trunk", "Trunk");
+ dictionary.Add("Panic", "Panic");
+ dictionary.Add("BurnTips", "Burning file does not exist. Please select the key model to burn.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Please use the mobile app to program the C sub-key.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Please use the mobile app to program the CF sub-key.");
+ dictionary.Add("BurnSuccess", "Burning successful");
+ dictionary.Add("BurnError", "Burning failed");
+ dictionary.Add("NotMoreTips", "No more data~");
+ dictionary.Add("CloudData", "CloudData");
+ dictionary.Add("CloudDataSyncCompleted", "Sync completed");
+ dictionary.Add("CloudDataSyncFailed", "Sync failed");
+ dictionary.Add("CloudDataDownloadFailed", "Download failed");
+ dictionary.Add("CloudDataDeviceNotFound", "K3Tool storage device not detected");
+ dictionary.Add("CloudDataInitCompleted", "K3Tool initialization completed");
+ dictionary.Add("HidSendPacketError", "Error sending data packet");
+ dictionary.Add("DialogPleaseWait", "Please wait");
+ dictionary.Add("DialogProcessing", "Processing...");
+ dictionary.Add("DialogCancelled", "Cancelled");
+ dictionary.Add("DialogErrorPrefix", "Error");
+ dictionary.Add("DialogElapsedPrefix", "Elapsed");
+ dictionary.Add("DialogBurningTitle", "Burning");
+ dictionary.Add("DialogBurningMessage", "Burning...");
+ dictionary.Add("MembershipLoginRequired", "Please log in before opening membership features");
+ dictionary.Add("MembershipOpening", "Opening membership feature...");
+ dictionary.Add("MembershipOpenSuccess", " opened successfully");
+ dictionary.Add("MembershipOpenFailed", "Opening failed, please try again later");
+ dictionary.Add("MembershipLoadFailedFallback", "Failed to load membership features, showing default items");
+ dictionary.Add("MembershipOpenWindowTitle", "Membership");
+ dictionary.Add("MembershipFeeStandard", "Price:");
+ dictionary.Add("MembershipIntegralPerYear", " points/year");
+ dictionary.Add("MembershipOpenButton", "Open");
+ dictionary.Add("MembershipModuleDataWriteStart", "Data Write Start");
+ dictionary.Add("MembershipModuleK3GeniePlus", "K3 Genie+");
+ dictionary.Add("MembershipModuleAiIntelligent", "AI Intelligent Feature");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary ptlanguage()
+ {
+ #region 葡萄牙
+
+ Dictionary dictionary = new Dictionary();
+ dictionary.Add("HomePage", "Página Inicial");
+ dictionary.Add("Settings", "Configurações do Sistema");
+ dictionary.Add("RemoteGeneration", "Geração de Controle Remoto");
+ dictionary.Add("RemoteCopy", "Cópia de Controle Remoto");
+ dictionary.Add("RemoteControlDetector", "Detector de Controle Remoto");
+ dictionary.Add("ChipIdentificationCopy", "Identificação e Cópia de Chip");
+ dictionary.Add("ChipGeneration", "Geração de Chip");
+ dictionary.Add("AccessCardCopy", "Cópia de Cartão de Acesso");
+ dictionary.Add("KeyUnlock", "Desbloqueio de Chave");
+ dictionary.Add("TirePressure", "Função de Pressão dos Pneus");
+ dictionary.Add("MatchingFunction", "Função de Combinação");
+ dictionary.Add("ChipWriteStart", "Iniciar Gravação de Chip");
+ dictionary.Add("Programmer", "Programador");
+ dictionary.Add("AntiTheftData", "Dados de Antifurto");
+ dictionary.Add("UpdateCenter", "Centro de Atualização");
+
+ dictionary.Add("ContactWechatCopy", "Número do WeChat copiado");
+ dictionary.Add("ContactEmailCopy", "Endereço de e-mail copiado");
+
+ dictionary.Add("Tips", "Dicas");
+ dictionary.Add("Connected", "Conectado");
+ dictionary.Add("Disconnected", "Desconectado");
+ dictionary.Add("DeviceDisconnected", "Dispositivo não conectado");
+ dictionary.Add("K3ToolConnectTips", "Conecte o dispositivo K3Tool antes de realizar a atualização");
+ dictionary.Add("FileNotFound", "Arquivo não encontrado");
+
+ dictionary.Add("UpToDate", "Já é a versão mais recente");
+ dictionary.Add("PleaseNote", "Atenção");
+ dictionary.Add("PleasePress", "Por favor, prima");
+ dictionary.Add("Button", "botão");
+ dictionary.Add("NoKeyData", "Sem dados da chave disponíveis");
+ dictionary.Add("Lock", "Trancar");
+ dictionary.Add("Unlock", "Destrancar");
+ dictionary.Add("Trunk", "Mala");
+ dictionary.Add("Panic", "Panic");
+ dictionary.Add("BurnTips", "O ficheiro de gravação não existe. Por favor, selecione o modelo de chave a gravar.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Utilize a app móvel para gravar a subchave C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Utilize a app móvel para gravar a subchave CF.");
+ dictionary.Add("BurnSuccess", "Gravação concluída com sucesso");
+ dictionary.Add("BurnError", "Gravação falhou");
+ dictionary.Add("NotMoreTips", "Não há mais dados~");
+ dictionary.Add("CloudData", "Dados na Nuvem");
+ dictionary.Add("CloudDataSyncCompleted", "Sincronização concluída");
+ dictionary.Add("CloudDataSyncFailed", "Falha na sincronização");
+ dictionary.Add("CloudDataDownloadFailed", "Falha no download");
+ dictionary.Add("CloudDataDeviceNotFound", "Dispositivo de armazenamento K3Tool não detectado");
+ dictionary.Add("CloudDataInitCompleted", "Inicialização do K3Tool concluída");
+ dictionary.Add("HidSendPacketError", "Erro ao enviar pacote de dados");
+ dictionary.Add("DialogPleaseWait", "Aguarde");
+ dictionary.Add("DialogProcessing", "Processando...");
+ dictionary.Add("DialogCancelled", "Cancelado");
+ dictionary.Add("DialogErrorPrefix", "Erro");
+ dictionary.Add("DialogElapsedPrefix", "Tempo");
+ dictionary.Add("DialogBurningTitle", "Gravação");
+ dictionary.Add("DialogBurningMessage", "Gravando...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+
+ }
+ private static Dictionary ptBRlanguage()
+ {
+ #region 葡萄牙语(巴西)
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Início");
+ dictionary.Add("Settings", "Configurações do sistema");
+ dictionary.Add("RemoteGeneration", "Geração de controle remoto");
+ dictionary.Add("RemoteCopy", "Cópia de controle remoto");
+ dictionary.Add("RemoteControlDetector", "Detector de controles");
+ dictionary.Add("ChipIdentificationCopy", "Cópia de identificação do chip");
+ dictionary.Add("ChipGeneration", "Geração de chip");
+ dictionary.Add("AccessCardCopy", "Cópia de cartão de acesso");
+ dictionary.Add("KeyUnlock", "Destravamento de chave");
+ dictionary.Add("TirePressure", "Funções de pressão dos pneus");
+ dictionary.Add("MatchingFunction", "Funções de emparelhamento");
+ dictionary.Add("ChipWriteStart", "Início da gravação do chip");
+ dictionary.Add("Programmer", "Programador");
+ dictionary.Add("AntiTheftData", "Dados antifurto");
+ dictionary.Add("UpdateCenter", "Central de atualizações");
+
+ dictionary.Add("ContactWechatCopy", "ID do WeChat copiado");
+ dictionary.Add("ContactEmailCopy", "Endereço de e-mail copiado");
+
+ dictionary.Add("Tips", "Aviso");
+ dictionary.Add("Connected", "Conectado");
+ dictionary.Add("Disconnected", "Desconectado");
+ dictionary.Add("DeviceDisconnected", "Dispositivo não conectado");
+ dictionary.Add("K3ToolConnectTips", "Conecte o dispositivo K3Tool antes de atualizar");
+ dictionary.Add("FileNotFound", "Arquivo não encontrado");
+
+ dictionary.Add("UpToDate", "Já está atualizado");
+ dictionary.Add("PleaseNote", "Por favor, observe");
+ dictionary.Add("PleasePress", "Por favor, pressione");
+ dictionary.Add("Button", "botão");
+ dictionary.Add("NoKeyData", "Sem dados da chave disponíveis");
+ dictionary.Add("Lock", "Travar");
+ dictionary.Add("Unlock", "Destravar");
+ dictionary.Add("Trunk", "Porta-malas");
+ dictionary.Add("Panic", "Pânico");
+ dictionary.Add("BurnTips", "O arquivo de gravação não existe. Por favor, selecione o modelo de chave para gravar.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Use o app móvel para gravar a subchave C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Use o app móvel para gravar a subchave CF.");
+ dictionary.Add("BurnSuccess", "Gravação bem-sucedida");
+ dictionary.Add("BurnError", "Gravação falhou");
+ dictionary.Add("NotMoreTips", "Não há mais dados~");
+ dictionary.Add("CloudData", "Dados na Nuvem");
+ dictionary.Add("CloudDataSyncCompleted", "Sincronização concluída");
+ dictionary.Add("CloudDataSyncFailed", "Falha na sincronização");
+ dictionary.Add("CloudDataDownloadFailed", "Falha no download");
+ dictionary.Add("CloudDataDeviceNotFound", "Dispositivo de armazenamento K3Tool não detectado");
+ dictionary.Add("CloudDataInitCompleted", "Inicialização do K3Tool concluída");
+ dictionary.Add("HidSendPacketError", "Erro ao enviar pacote de dados");
+ dictionary.Add("DialogPleaseWait", "Aguarde");
+ dictionary.Add("DialogProcessing", "Processando...");
+ dictionary.Add("DialogCancelled", "Cancelado");
+ dictionary.Add("DialogErrorPrefix", "Erro");
+ dictionary.Add("DialogElapsedPrefix", "Tempo");
+ dictionary.Add("DialogBurningTitle", "Gravação");
+ dictionary.Add("DialogBurningMessage", "Gravando...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary eslanguage()
+ {
+ #region 西班牙
+ Dictionary dictionary = new Dictionary();
+ dictionary.Add("HomePage", "Página Principal");
+ dictionary.Add("Settings", "Configuración del Sistema");
+ dictionary.Add("RemoteGeneration", "Generación de Mando a Distancia");
+ dictionary.Add("RemoteCopy", "Copia de Mando a Distancia");
+ dictionary.Add("RemoteControlDetector", "Detector de Mando a Distancia");
+ dictionary.Add("ChipIdentificationCopy", "Identificación y Copia de Chip");
+ dictionary.Add("ChipGeneration", "Generación de Chip");
+ dictionary.Add("AccessCardCopy", "Copia de Tarjeta de Acceso");
+ dictionary.Add("KeyUnlock", "Desbloqueo de Llave");
+ dictionary.Add("TirePressure", "Función de Presión de Neumáticos");
+ dictionary.Add("MatchingFunction", "Función de Coincidencia");
+ dictionary.Add("ChipWriteStart", "Iniciar Escritura de Chip");
+ dictionary.Add("Programmer", "Programador");
+ dictionary.Add("AntiTheftData", "Datos Antirrobo");
+ dictionary.Add("UpdateCenter", "Centro de Actualización");
+
+ dictionary.Add("ContactWechatCopy", "Número de WeChat copiado");
+ dictionary.Add("ContactEmailCopy", "Dirección de correo electrónico copiada");
+
+ dictionary.Add("Tips", "Consejos");
+ dictionary.Add("Connected", "Conectado");
+ dictionary.Add("Disconnected", "Desconectado");
+ dictionary.Add("DeviceDisconnected", "Dispositivo no conectado");
+ dictionary.Add("K3ToolConnectTips", "Conecte el dispositivo K3Tool antes de realizar la actualización");
+ dictionary.Add("FileNotFound", "Archivo no encontrado");
+
+ dictionary.Add("UpToDate", "Ya es la última versión");
+ dictionary.Add("PleaseNote", "Nota Importante");
+ dictionary.Add("PleasePress", "Por favor, presione");
+ dictionary.Add("Button", "botón");
+ dictionary.Add("NoKeyData", "Sin datos de la llave disponibles");
+ dictionary.Add("Lock", "Bloquear");
+ dictionary.Add("Unlock", "Desbloquear");
+ dictionary.Add("Trunk", "Maletero");
+ dictionary.Add("Panic", "Pánico");
+ dictionary.Add("BurnTips", "El archivo de grabación no existe. Por favor, seleccione el modelo de llave a grabar.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Use la app móvil para grabar la subllave C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Use la app móvil para grabar la subllave CF.");
+ dictionary.Add("BurnSuccess", "Grabación exitosa");
+ dictionary.Add("BurnError", "Grabación fallida");
+ dictionary.Add("NotMoreTips", "No hay más datos~");
+ dictionary.Add("CloudData", "Datos en la Nube");
+ dictionary.Add("CloudDataSyncCompleted", "Sincronización completada");
+ dictionary.Add("CloudDataSyncFailed", "Sincronización fallida");
+ dictionary.Add("CloudDataDownloadFailed", "Descarga fallida");
+ dictionary.Add("CloudDataDeviceNotFound", "No se detectó el dispositivo de almacenamiento K3Tool");
+ dictionary.Add("CloudDataInitCompleted", "Inicialización de K3Tool completada");
+ dictionary.Add("HidSendPacketError", "Error al enviar el paquete de datos");
+ dictionary.Add("DialogPleaseWait", "Espere por favor");
+ dictionary.Add("DialogProcessing", "Procesando...");
+ dictionary.Add("DialogCancelled", "Cancelado");
+ dictionary.Add("DialogErrorPrefix", "Error");
+ dictionary.Add("DialogElapsedPrefix", "Tiempo");
+ dictionary.Add("DialogBurningTitle", "Grabando");
+ dictionary.Add("DialogBurningMessage", "Grabando...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary inlanguage()
+ {
+ #region 印度
+ Dictionary dictionary = new Dictionary();
+ dictionary.Add("HomePage", "होमपेज");
+ dictionary.Add("Settings", "सिस्टम कॉन्फ़िगरेशन");
+ dictionary.Add("RemoteGeneration", "रिमोट जनरेशन");
+ dictionary.Add("RemoteCopy", "रिमोट कॉपी");
+ dictionary.Add("RemoteControlDetector", "रिमोट डिटेक्टर");
+ dictionary.Add("ChipIdentificationCopy", "चिप पहचान कॉपी");
+ dictionary.Add("ChipGeneration", "चिप जनरेशन");
+ dictionary.Add("AccessCardCopy", "एक्सेस कार्ड कॉपी");
+ dictionary.Add("KeyUnlock", "कुंजी अनलॉक");
+ dictionary.Add("TirePressure", "टायर प्रेशर फ़ंक्शन");
+ dictionary.Add("MatchingFunction", "मैचिंग फ़ंक्शन");
+ dictionary.Add("ChipWriteStart", "चिप लेखन प्रारंभ");
+ dictionary.Add("Programmer", "प्रोग्रामर");
+ dictionary.Add("AntiTheftData", "चोरी रोधी डेटा");
+ dictionary.Add("UpdateCenter", "अपडेट सेंटर");
+
+ dictionary.Add("ContactWechatCopy", "वीचैट आईडी कॉपी की गई");
+ dictionary.Add("ContactEmailCopy", "ईमेल पता कॉपी किया गया");
+
+ dictionary.Add("Tips", "सुझाव");
+ dictionary.Add("Connected", "जुड़ा हुआ");
+ dictionary.Add("Disconnected", "डिस्कनेक्टेड");
+ dictionary.Add("DeviceDisconnected", "उपकरण डिस्कनेक्टेड है");
+ dictionary.Add("K3ToolConnectTips", "अपडेट करने से पहले कृपया K3Tool उपकरण कनेक्ट करें");
+ dictionary.Add("FileNotFound", "फ़ाइल नहीं मिली");
+
+ dictionary.Add("UpToDate", "यह पहले से ही नवीनतम संस्करण है");
+ dictionary.Add("PleaseNote", "कृपया ध्यान दें");
+ dictionary.Add("PleasePress", "कृपया दबाएं");
+ dictionary.Add("Button", "बटन");
+ dictionary.Add("NoKeyData", "कुंजी डेटा उपलब्ध नहीं है");
+ dictionary.Add("Lock", "ताला लगाएं");
+ dictionary.Add("Unlock", "ताला खोलें");
+ dictionary.Add("Trunk", "ट्रंक");
+ dictionary.Add("Panic", "पैनिक");
+ dictionary.Add("BurnTips", "बर्निंग फ़ाइल मौजूद नहीं है। कृपया बर्न करने के लिए कुंजी मॉडल चुनें।");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "C सब-की को बर्न करने के लिए मोबाइल ऐप का उपयोग करें।");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "CF सब-की को बर्न करने के लिए मोबाइल ऐप का उपयोग करें।");
+ dictionary.Add("BurnSuccess", "बर्निंग सफल");
+ dictionary.Add("BurnError", "बर्निंग विफल");
+ dictionary.Add("NotMoreTips", "कोई अन्य डेटा नहीं~");
+ dictionary.Add("CloudData", "क्लाउड डेटा");
+ dictionary.Add("CloudDataSyncCompleted", "सिंक पूर्ण");
+ dictionary.Add("CloudDataSyncFailed", "सिंक विफल");
+ dictionary.Add("CloudDataDownloadFailed", "डाउनलोड विफल");
+ dictionary.Add("CloudDataDeviceNotFound", "K3Tool स्टोरेज डिवाइस नहीं मिला");
+ dictionary.Add("CloudDataInitCompleted", "K3Tool प्रारंभिककरण पूर्ण");
+ dictionary.Add("HidSendPacketError", "डेटा पैकेट भेजने में त्रुटि");
+ dictionary.Add("DialogPleaseWait", "कृपया प्रतीक्षा करें");
+ dictionary.Add("DialogProcessing", "प्रसंस्करण हो रहा है...");
+ dictionary.Add("DialogCancelled", "रद्द किया गया");
+ dictionary.Add("DialogErrorPrefix", "त्रुटि");
+ dictionary.Add("DialogElapsedPrefix", "समय");
+ dictionary.Add("DialogBurningTitle", "बर्निंग");
+ dictionary.Add("DialogBurningMessage", "बर्निंग...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary hilanguage()
+ {
+ #region 印地语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "होम पेज");
+ dictionary.Add("Settings", "सिस्टम सेटिंग्स");
+ dictionary.Add("RemoteGeneration", "रिमोट जनरेशन");
+ dictionary.Add("RemoteCopy", "रिमोट कॉपी");
+ dictionary.Add("RemoteControlDetector", "रिमोट कंट्रोल डिटेक्टर");
+ dictionary.Add("ChipIdentificationCopy", "चिप पहचान कॉपी");
+ dictionary.Add("ChipGeneration", "चिप जनरेशन");
+ dictionary.Add("AccessCardCopy", "एक्सेस कार्ड कॉपी");
+ dictionary.Add("KeyUnlock", "कुंजी अनलॉक");
+ dictionary.Add("TirePressure", "टायर प्रेशर फ़ंक्शन");
+ dictionary.Add("MatchingFunction", "मैचिंग फ़ंक्शन");
+ dictionary.Add("ChipWriteStart", "चिप लेखन प्रारंभ करें");
+ dictionary.Add("Programmer", "प्रोग्रामर");
+ dictionary.Add("AntiTheftData", "चोरी रोधी डेटा");
+ dictionary.Add("UpdateCenter", "अपडेट सेंटर");
+
+ dictionary.Add("ContactWechatCopy", "वीचैट आईडी कॉपी किया गया");
+ dictionary.Add("ContactEmailCopy", "ईमेल पता कॉपी किया गया");
+
+ dictionary.Add("Tips", "सुझाव");
+ dictionary.Add("Connected", "जुड़ा हुआ");
+ dictionary.Add("Disconnected", "डिस्कनेक्ट हो गया");
+ dictionary.Add("DeviceDisconnected", "डिवाइस कनेक्ट नहीं है");
+ dictionary.Add("K3ToolConnectTips", "कृपया अपडेट करने से पहले K3Tool डिवाइस कनेक्ट करें");
+ dictionary.Add("FileNotFound", "फ़ाइल नहीं मिली");
+
+ dictionary.Add("UpToDate", "पहले से ही अप-टू-डेट");
+ dictionary.Add("PleaseNote", "कृपया ध्यान दें");
+ dictionary.Add("PleasePress", "कृपया दबाएं");
+ dictionary.Add("Button", "बटन");
+ dictionary.Add("NoKeyData", "कुंजी डेटा उपलब्ध नहीं है");
+ dictionary.Add("Lock", "ताला लगाएं");
+ dictionary.Add("Unlock", "ताला खोलें");
+ dictionary.Add("Trunk", "ट्रंक");
+ dictionary.Add("Panic", "पैनिक");
+ dictionary.Add("BurnTips", "बर्निंग फ़ाइल मौजूद नहीं है। कृपया बर्न करने के लिए कुंजी मॉडल चुनें।");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "C सब-की को बर्न करने के लिए मोबाइल ऐप का उपयोग करें।");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "CF सब-की को बर्न करने के लिए मोबाइल ऐप का उपयोग करें।");
+ dictionary.Add("BurnSuccess", "बर्निंग सफल");
+ dictionary.Add("BurnError", "बर्निंग विफल");
+ dictionary.Add("NotMoreTips", "कोई अन्य डेटा नहीं~");
+ dictionary.Add("CloudData", "क्लाउड डेटा");
+ dictionary.Add("CloudDataSyncCompleted", "सिंक पूर्ण");
+ dictionary.Add("CloudDataSyncFailed", "सिंक विफल");
+ dictionary.Add("CloudDataDownloadFailed", "डाउनलोड विफल");
+ dictionary.Add("CloudDataDeviceNotFound", "K3Tool स्टोरेज डिवाइस नहीं मिला");
+ dictionary.Add("CloudDataInitCompleted", "K3Tool प्रारंभिककरण पूर्ण");
+ dictionary.Add("HidSendPacketError", "डेटा पैकेट भेजने में त्रुटि");
+ dictionary.Add("DialogPleaseWait", "कृपया प्रतीक्षा करें");
+ dictionary.Add("DialogProcessing", "प्रसंस्करण हो रहा है...");
+ dictionary.Add("DialogCancelled", "रद्द किया गया");
+ dictionary.Add("DialogErrorPrefix", "त्रुटि");
+ dictionary.Add("DialogElapsedPrefix", "समय");
+ dictionary.Add("DialogBurningTitle", "बर्निंग");
+ dictionary.Add("DialogBurningMessage", "बर्निंग...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary frlanguage()
+ {
+ #region 法语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Accueil");
+ dictionary.Add("Settings", "Paramètres système");
+ dictionary.Add("RemoteGeneration", "Génération de télécommande");
+ dictionary.Add("RemoteCopy", "Copie de télécommande");
+ dictionary.Add("RemoteControlDetector", "Détecteur de télécommandes");
+ dictionary.Add("ChipIdentificationCopy", "Copie d'identification de puce");
+ dictionary.Add("ChipGeneration", "Génération de puce");
+ dictionary.Add("AccessCardCopy", "Copie de carte d'accès");
+ dictionary.Add("KeyUnlock", "Déverrouillage de clé");
+ dictionary.Add("TirePressure", "Fonctions pression pneus");
+ dictionary.Add("MatchingFunction", "Fonctions d'appairage");
+ dictionary.Add("ChipWriteStart", "Démarrer l'écriture puce");
+ dictionary.Add("Programmer", "Programmeur");
+ dictionary.Add("AntiTheftData", "Données antivol");
+ dictionary.Add("UpdateCenter", "Centre de mise à jour");
+
+ dictionary.Add("ContactWechatCopy", "ID WeChat copié");
+ dictionary.Add("ContactEmailCopy", "Adresse e-mail copiée");
+
+ dictionary.Add("Tips", "Astuce");
+ dictionary.Add("Connected", "Connecté");
+ dictionary.Add("Disconnected", "Déconnecté");
+ dictionary.Add("DeviceDisconnected", "Périphérique non connecté");
+ dictionary.Add("K3ToolConnectTips", "Veuillez connecter le périphérique K3Tool avant la mise à jour");
+ dictionary.Add("FileNotFound", "Fichier introuvable");
+
+ dictionary.Add("UpToDate", "Déjà à jour");
+ dictionary.Add("PleaseNote", "Veuillez noter");
+ dictionary.Add("PleasePress", "Veuillez appuyer sur");
+ dictionary.Add("Button", "le bouton");
+ dictionary.Add("NoKeyData", "Aucune donnée de clé disponible");
+ dictionary.Add("Lock", "Verrouiller");
+ dictionary.Add("Unlock", "Déverrouiller");
+ dictionary.Add("Trunk", "Coffre");
+ dictionary.Add("Panic", "Panic");
+ dictionary.Add("BurnTips", "Le fichier de programmation n'existe pas. Veuillez sélectionner le modèle de clé à programmer.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Veuillez utiliser l'application mobile pour programmer la sous-clé C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Veuillez utiliser l'application mobile pour programmer la sous-clé CF.");
+ dictionary.Add("BurnSuccess", "Programmation réussie");
+ dictionary.Add("BurnError", "Échec de la programmation");
+ dictionary.Add("NotMoreTips", "Plus de données~");
+ dictionary.Add("CloudData", "Données Cloud");
+ dictionary.Add("CloudDataSyncCompleted", "Synchronisation terminée");
+ dictionary.Add("CloudDataSyncFailed", "Échec de la synchronisation");
+ dictionary.Add("CloudDataDownloadFailed", "Échec du téléchargement");
+ dictionary.Add("CloudDataDeviceNotFound", "Périphérique de stockage K3Tool non détecté");
+ dictionary.Add("CloudDataInitCompleted", "Initialisation de K3Tool terminée");
+ dictionary.Add("HidSendPacketError", "Erreur lors de l'envoi du paquet de données");
+ dictionary.Add("DialogPleaseWait", "Veuillez patienter");
+ dictionary.Add("DialogProcessing", "Traitement en cours...");
+ dictionary.Add("DialogCancelled", "Annulé");
+ dictionary.Add("DialogErrorPrefix", "Erreur");
+ dictionary.Add("DialogElapsedPrefix", "Temps");
+ dictionary.Add("DialogBurningTitle", "Gravure");
+ dictionary.Add("DialogBurningMessage", "Gravure en cours...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary falanguage()
+ {
+ #region 波斯语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "صفحه اصلی");
+ dictionary.Add("Settings", "تنظیمات سیستم");
+ dictionary.Add("RemoteGeneration", "تولید ریموت");
+ dictionary.Add("RemoteCopy", "کپی ریموت");
+ dictionary.Add("RemoteControlDetector", "تشخیصدهنده ریموت");
+ dictionary.Add("ChipIdentificationCopy", "کپی شناسه تراشه");
+ dictionary.Add("ChipGeneration", "تولید تراشه");
+ dictionary.Add("AccessCardCopy", "کپی کارت دسترسی");
+ dictionary.Add("KeyUnlock", "باز کردن قفل کلید");
+ dictionary.Add("TirePressure", "عملکردهای فشار لاستیک");
+ dictionary.Add("MatchingFunction", "عملکردهای هماهنگسازی");
+ dictionary.Add("ChipWriteStart", "شروع نوشتن تراشه");
+ dictionary.Add("Programmer", "برنامهریز");
+ dictionary.Add("AntiTheftData", "دادههای ضد دزدی");
+ dictionary.Add("UpdateCenter", "مرکز بهروزرسانی");
+
+ dictionary.Add("ContactWechatCopy", "شناسه ویچت کپی شد");
+ dictionary.Add("ContactEmailCopy", "آدرس ایمیل کپی شد");
+
+ dictionary.Add("Tips", "نکته");
+ dictionary.Add("Connected", "متصل شد");
+ dictionary.Add("Disconnected", "قطع شد");
+ dictionary.Add("DeviceDisconnected", "دستگاه متصل نیست");
+ dictionary.Add("K3ToolConnectTips", "لطفاً قبل از بهروزرسانی دستگاه K3Tool را متصل کنید");
+ dictionary.Add("FileNotFound", "فایل یافت نشد");
+
+ dictionary.Add("UpToDate", "هماکنون بهروز است");
+ dictionary.Add("PleaseNote", "لطفاً توجه کنید");
+ dictionary.Add("NoKeyData", "دادههای کلید در دسترس نیست");
+ dictionary.Add("Lock", "قفل کردن");
+ dictionary.Add("Unlock", "باز کردن قفل");
+ dictionary.Add("Trunk", "صندوق عقب");
+ dictionary.Add("Panic", "پنیک");
+ dictionary.Add("BurnTips", "فایل برنامهریزی وجود ندارد. لطفاً مدل کلید مورد نظر برای برنامهریزی را انتخاب کنید.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "لطفاً برای برنامهریزی زیرکلید C از برنامه موبایل استفاده کنید.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "لطفاً برای برنامهریزی زیرکلید CF از برنامه موبایل استفاده کنید.");
+ dictionary.Add("BurnSuccess", "برنامهریزی با موفقیت انجام شد");
+ dictionary.Add("BurnError", "برنامهریزی با شکست مواجه شد");
+ dictionary.Add("NotMoreTips", "دادهای دیگر وجود ندارد~");
+ dictionary.Add("CloudData", "دادههای ابری");
+ dictionary.Add("CloudDataSyncCompleted", "همگامسازی کامل شد");
+ dictionary.Add("CloudDataSyncFailed", "همگامسازی ناموفق بود");
+ dictionary.Add("CloudDataDownloadFailed", "دانلود ناموفق بود");
+ dictionary.Add("CloudDataDeviceNotFound", "دستگاه ذخیرهسازی K3Tool شناسایی نشد");
+ dictionary.Add("CloudDataInitCompleted", "راهاندازی K3Tool کامل شد");
+ dictionary.Add("HidSendPacketError", "خطا در ارسال بسته داده");
+ dictionary.Add("DialogPleaseWait", "لطفا صبر کنید");
+ dictionary.Add("DialogProcessing", "در حال پردازش...");
+ dictionary.Add("DialogCancelled", "لغو شد");
+ dictionary.Add("DialogErrorPrefix", "خطا");
+ dictionary.Add("DialogElapsedPrefix", "زمان");
+ dictionary.Add("DialogBurningTitle", "در حال رایت");
+ dictionary.Add("DialogBurningMessage", "در حال رایت...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary helanguage()
+ {
+ #region 希伯来语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "דף הבית");
+ dictionary.Add("Settings", "הגדרות מערכת");
+ dictionary.Add("RemoteGeneration", "יצירת שלט רחוק");
+ dictionary.Add("RemoteCopy", "העתקת שלט רחוק");
+ dictionary.Add("RemoteControlDetector", "גלאי שלטים רחוקים");
+ dictionary.Add("ChipIdentificationCopy", "העתקת מזהה שבב");
+ dictionary.Add("ChipGeneration", "יצירת שבב");
+ dictionary.Add("AccessCardCopy", "העתקת כרטיס גישה");
+ dictionary.Add("KeyUnlock", "ביטול נעילת מפתח");
+ dictionary.Add("TirePressure", "פונקציות לחץ צמיגים");
+ dictionary.Add("MatchingFunction", "פונקציות התאמה");
+ dictionary.Add("ChipWriteStart", "התחל כתיבת שבב");
+ dictionary.Add("Programmer", "מתכנת");
+ dictionary.Add("AntiTheftData", "נתוני הגנה מפני גניבה");
+ dictionary.Add("UpdateCenter", "מרכז עדכונים");
+
+ dictionary.Add("ContactWechatCopy", "מזהה וייצ'אט הועתק");
+ dictionary.Add("ContactEmailCopy", "כתובת הדוא\"ל הועתקה");
+
+ dictionary.Add("Tips", "עצה");
+ dictionary.Add("Connected", "מחובר");
+ dictionary.Add("Disconnected", "מנותק");
+ dictionary.Add("DeviceDisconnected", "המכשיר אינו מחובר");
+ dictionary.Add("K3ToolConnectTips", "אנא חבר את מכשיר K3Tool לפני העדכון");
+ dictionary.Add("FileNotFound", "הקובץ לא נמצא");
+
+ dictionary.Add("UpToDate", "כבר מעודכן");
+ dictionary.Add("PleaseNote", "שים לב");
+ dictionary.Add("NoKeyData", "אין נתוני מפתח זמינים");
+ dictionary.Add("Lock", "נעל");
+ dictionary.Add("Unlock", "פתח");
+ dictionary.Add("Trunk", "מכולה");
+ dictionary.Add("Panic", "פאניקה");
+ dictionary.Add("BurnTips", "קובץ התכנות לא קיים. בחר את דגם המפתח לכתיבה.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "יש להשתמש באפליקציה לנייד כדי לתכנת את תת-המפתח C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "יש להשתמש באפליקציה לנייד כדי לתכנת את תת-המפתח CF.");
+ dictionary.Add("BurnSuccess", "התכנות הושלם בהצלחה");
+ dictionary.Add("BurnError", "התכנות נכשל");
+ dictionary.Add("NotMoreTips", "אין עוד נתונים~");
+ dictionary.Add("CloudData", "נתונים בענן");
+ dictionary.Add("CloudDataSyncCompleted", "הסנכרון הושלם");
+ dictionary.Add("CloudDataSyncFailed", "הסנכרון נכשל");
+ dictionary.Add("CloudDataDownloadFailed", "ההורדה נכשלה");
+ dictionary.Add("CloudDataDeviceNotFound", "התקן האחסון של K3Tool לא זוהה");
+ dictionary.Add("CloudDataInitCompleted", "אתחול K3Tool הושלם");
+ dictionary.Add("HidSendPacketError", "אירעה שגיאה בשליחת חבילת הנתונים");
+ dictionary.Add("DialogPleaseWait", "אנא המתן");
+ dictionary.Add("DialogProcessing", "מעבד...");
+ dictionary.Add("DialogCancelled", "בוטל");
+ dictionary.Add("DialogErrorPrefix", "שגיאה");
+ dictionary.Add("DialogElapsedPrefix", "זמן");
+ dictionary.Add("DialogBurningTitle", "צריבה");
+ dictionary.Add("DialogBurningMessage", "צורב...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary idlanguage()
+ {
+ #region 印尼语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Beranda");
+ dictionary.Add("Settings", "Pengaturan Sistem");
+ dictionary.Add("RemoteGeneration", "Pembuatan Remote");
+ dictionary.Add("RemoteCopy", "Salin Remote");
+ dictionary.Add("RemoteControlDetector", "Detektor Remote");
+ dictionary.Add("ChipIdentificationCopy", "Salin ID Chip");
+ dictionary.Add("ChipGeneration", "Pembuatan Chip");
+ dictionary.Add("AccessCardCopy", "Salin Kartu Akses");
+ dictionary.Add("KeyUnlock", "Buka Kunci Key");
+ dictionary.Add("TirePressure", "Fungsi Tekanan Ban");
+ dictionary.Add("MatchingFunction", "Fungsi Pencocokan");
+ dictionary.Add("ChipWriteStart", "Mulai Menulis Chip");
+ dictionary.Add("Programmer", "Programmer");
+ dictionary.Add("AntiTheftData", "Data Anti-Pencurian");
+ dictionary.Add("UpdateCenter", "Pusat Pembaruan");
+
+ dictionary.Add("ContactWechatCopy", "ID WeChat disalin");
+ dictionary.Add("ContactEmailCopy", "Alamat email disalin");
+
+ dictionary.Add("Tips", "Tips");
+ dictionary.Add("Connected", "Tersambung");
+ dictionary.Add("Disconnected", "Terputus");
+ dictionary.Add("DeviceDisconnected", "Perangkat tidak tersambung");
+ dictionary.Add("K3ToolConnectTips", "Harap sambungkan perangkat K3Tool sebelum memperbarui");
+ dictionary.Add("FileNotFound", "File tidak ditemukan");
+
+ dictionary.Add("UpToDate", "Sudah mutakhir");
+ dictionary.Add("PleaseNote", "Harap diperhatikan");
+ dictionary.Add("PleasePress", "Silakan tekan");
+ dictionary.Add("Button", "tombol");
+ dictionary.Add("NoKeyData", "Tidak ada data kunci tersedia");
+ dictionary.Add("Lock", "Kunci");
+ dictionary.Add("Unlock", "Buka Kunci");
+ dictionary.Add("Trunk", "Bagasi");
+ dictionary.Add("Panic", "Panic");
+ dictionary.Add("BurnTips", "File pemrograman tidak ada. Silakan pilih model kunci yang akan diprogram.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Gunakan aplikasi seluler untuk memprogram sub-kunci C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Gunakan aplikasi seluler untuk memprogram sub-kunci CF.");
+ dictionary.Add("BurnSuccess", "Pemrograman berhasil");
+ dictionary.Add("BurnError", "Pemrograman gagal");
+ dictionary.Add("NotMoreTips", "Tidak ada data lagi~");
+ dictionary.Add("CloudData", "Data Cloud");
+ dictionary.Add("CloudDataSyncCompleted", "Sinkronisasi selesai");
+ dictionary.Add("CloudDataSyncFailed", "Sinkronisasi gagal");
+ dictionary.Add("CloudDataDownloadFailed", "Unduhan gagal");
+ dictionary.Add("CloudDataDeviceNotFound", "Perangkat penyimpanan K3Tool tidak terdeteksi");
+ dictionary.Add("CloudDataInitCompleted", "Inisialisasi K3Tool selesai");
+ dictionary.Add("HidSendPacketError", "Terjadi kesalahan saat mengirim paket data");
+ dictionary.Add("DialogPleaseWait", "Harap tunggu");
+ dictionary.Add("DialogProcessing", "Memproses...");
+ dictionary.Add("DialogCancelled", "Dibatalkan");
+ dictionary.Add("DialogErrorPrefix", "Kesalahan");
+ dictionary.Add("DialogElapsedPrefix", "Waktu");
+ dictionary.Add("DialogBurningTitle", "Pemrograman");
+ dictionary.Add("DialogBurningMessage", "Sedang memprogram...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary itlanguage()
+ {
+ #region 意大利语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Home");
+ dictionary.Add("Settings", "Impostazioni di sistema");
+ dictionary.Add("RemoteGeneration", "Generazione telecomando");
+ dictionary.Add("RemoteCopy", "Copia telecomando");
+ dictionary.Add("RemoteControlDetector", "Rilevatore telecomandi");
+ dictionary.Add("ChipIdentificationCopy", "Copia identificativo chip");
+ dictionary.Add("ChipGeneration", "Generazione chip");
+ dictionary.Add("AccessCardCopy", "Copia carta d'accesso");
+ dictionary.Add("KeyUnlock", "Sblocco chiave");
+ dictionary.Add("TirePressure", "Funzioni pressione pneumatici");
+ dictionary.Add("MatchingFunction", "Funzioni di abbinamento");
+ dictionary.Add("ChipWriteStart", "Avvia scrittura chip");
+ dictionary.Add("Programmer", "Programmatore");
+ dictionary.Add("AntiTheftData", "Dati antifurto");
+ dictionary.Add("UpdateCenter", "Centro aggiornamenti");
+
+ dictionary.Add("ContactWechatCopy", "ID WeChat copiato");
+ dictionary.Add("ContactEmailCopy", "Indirizzo email copiato");
+
+ dictionary.Add("Tips", "Suggerimento");
+ dictionary.Add("Connected", "Connesso");
+ dictionary.Add("Disconnected", "Disconnesso");
+ dictionary.Add("DeviceDisconnected", "Dispositivo non connesso");
+ dictionary.Add("K3ToolConnectTips", "Collegare il dispositivo K3Tool prima dell'aggiornamento");
+ dictionary.Add("FileNotFound", "File non trovato");
+
+ dictionary.Add("UpToDate", "Già aggiornato");
+ dictionary.Add("PleaseNote", "Si prega di notare");
+ dictionary.Add("PleasePress", "Premere");
+ dictionary.Add("Button", "il pulsante");
+ dictionary.Add("NoKeyData", "Nessun dato chiave disponibile");
+ dictionary.Add("Lock", "Blocca");
+ dictionary.Add("Unlock", "Sblocca");
+ dictionary.Add("Trunk", "Bagagliaio");
+ dictionary.Add("Panic", "Panico");
+ dictionary.Add("BurnTips", "Il file di programmazione non esiste. Seleziona il modello di chiave da programmare.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Utilizza l'app mobile per programmare la sottochiave C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Utilizza l'app mobile per programmare la sottochiave CF.");
+ dictionary.Add("BurnSuccess", "Programmazione completata con successo");
+ dictionary.Add("BurnError", "Programmazione fallita");
+ dictionary.Add("NotMoreTips", "Non ci sono più dati~");
+ dictionary.Add("CloudData", "Dati Cloud");
+ dictionary.Add("CloudDataSyncCompleted", "Sincronizzazione completata");
+ dictionary.Add("CloudDataSyncFailed", "Sincronizzazione non riuscita");
+ dictionary.Add("CloudDataDownloadFailed", "Download non riuscito");
+ dictionary.Add("CloudDataDeviceNotFound", "Dispositivo di archiviazione K3Tool non rilevato");
+ dictionary.Add("CloudDataInitCompleted", "Inizializzazione K3Tool completata");
+ dictionary.Add("HidSendPacketError", "Errore durante l'invio del pacchetto dati");
+ dictionary.Add("DialogPleaseWait", "Attendere prego");
+ dictionary.Add("DialogProcessing", "Elaborazione in corso...");
+ dictionary.Add("DialogCancelled", "Annullato");
+ dictionary.Add("DialogErrorPrefix", "Errore");
+ dictionary.Add("DialogElapsedPrefix", "Tempo");
+ dictionary.Add("DialogBurningTitle", "Programmazione");
+ dictionary.Add("DialogBurningMessage", "Programmazione in corso...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary kolanguage()
+ {
+ #region 韩语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "홈");
+ dictionary.Add("Settings", "시스템 설정");
+ dictionary.Add("RemoteGeneration", "리모컨 생성");
+ dictionary.Add("RemoteCopy", "리모컨 복사");
+ dictionary.Add("RemoteControlDetector", "리모컨 탐지기");
+ dictionary.Add("ChipIdentificationCopy", "칩 ID 복사");
+ dictionary.Add("ChipGeneration", "칩 생성");
+ dictionary.Add("AccessCardCopy", "출입 카드 복사");
+ dictionary.Add("KeyUnlock", "키 잠금 해제");
+ dictionary.Add("TirePressure", "타이어 공기압 기능");
+ dictionary.Add("MatchingFunction", "매칭 기능");
+ dictionary.Add("ChipWriteStart", "칩 쓰기 시작");
+ dictionary.Add("Programmer", "프로그래머");
+ dictionary.Add("AntiTheftData", "도난 방지 데이터");
+ dictionary.Add("UpdateCenter", "업데이트 센터");
+
+ dictionary.Add("ContactWechatCopy", "WeChat ID가 복사되었습니다");
+ dictionary.Add("ContactEmailCopy", "이메일 주소가 복사되었습니다");
+
+ dictionary.Add("Tips", "팁");
+ dictionary.Add("Connected", "연결됨");
+ dictionary.Add("Disconnected", "연결 끊김");
+ dictionary.Add("DeviceDisconnected", "장치가 연결되지 않음");
+ dictionary.Add("K3ToolConnectTips", "업데이트 전에 K3Tool 장치를 연결하세요");
+ dictionary.Add("FileNotFound", "파일을 찾을 수 없습니다");
+
+ dictionary.Add("UpToDate", "이미 최신 상태입니다");
+ dictionary.Add("PleaseNote", "참고해 주세요");
+ dictionary.Add("PleasePress", "눌러 주세요");
+ dictionary.Add("Button", "버튼");
+ dictionary.Add("NoKeyData", "키 데이터 없음");
+ dictionary.Add("Lock", "잠금");
+ dictionary.Add("Unlock", "잠금 해제");
+ dictionary.Add("Trunk", "트렁크");
+ dictionary.Add("Panic", "패닉");
+ dictionary.Add("BurnTips", "프로그래밍 파일이 없습니다. 프로그래밍할 키 모델을 선택하세요.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "모바일 앱을 사용하여 C 하위 키를 프로그래밍하세요.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "모바일 앱을 사용하여 CF 하위 키를 프로그래밍하세요.");
+ dictionary.Add("BurnSuccess", "프로그래밍 성공");
+ dictionary.Add("BurnError", "프로그래밍 실패");
+ dictionary.Add("NotMoreTips", "더 이상 데이터가 없습니다~");
+ dictionary.Add("CloudData", "클라우드 데이터");
+ dictionary.Add("CloudDataSyncCompleted", "동기화 완료");
+ dictionary.Add("CloudDataSyncFailed", "동기화 실패");
+ dictionary.Add("CloudDataDownloadFailed", "다운로드 실패");
+ dictionary.Add("CloudDataDeviceNotFound", "K3Tool 저장 장치를 찾지 못했습니다");
+ dictionary.Add("CloudDataInitCompleted", "K3Tool 초기화 완료");
+ dictionary.Add("HidSendPacketError", "데이터 패킷 전송 중 오류가 발생했습니다");
+ dictionary.Add("DialogPleaseWait", "잠시 기다려 주세요");
+ dictionary.Add("DialogProcessing", "처리 중...");
+ dictionary.Add("DialogCancelled", "취소됨");
+ dictionary.Add("DialogErrorPrefix", "오류");
+ dictionary.Add("DialogElapsedPrefix", "시간");
+ dictionary.Add("DialogBurningTitle", "프로그래밍");
+ dictionary.Add("DialogBurningMessage", "프로그래밍 중...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary pllanguage()
+ {
+ #region 波兰语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Strona główna");
+ dictionary.Add("Settings", "Ustawienia systemowe");
+ dictionary.Add("RemoteGeneration", "Generowanie pilota");
+ dictionary.Add("RemoteCopy", "Kopiowanie pilota");
+ dictionary.Add("RemoteControlDetector", "Wykrywacz pilotów");
+ dictionary.Add("ChipIdentificationCopy", "Kopiowanie identyfikatora chipu");
+ dictionary.Add("ChipGeneration", "Generowanie chipu");
+ dictionary.Add("AccessCardCopy", "Kopiowanie karty dostępu");
+ dictionary.Add("KeyUnlock", "Odblokowanie klucza");
+ dictionary.Add("TirePressure", "Funkcje ciśnienia w oponach");
+ dictionary.Add("MatchingFunction", "Funkcje dopasowania");
+ dictionary.Add("ChipWriteStart", "Rozpocznij zapis chipu");
+ dictionary.Add("Programmer", "Programator");
+ dictionary.Add("AntiTheftData", "Dane antywłamaniowe");
+ dictionary.Add("UpdateCenter", "Centrum aktualizacji");
+
+ dictionary.Add("ContactWechatCopy", "Skopiowano ID WeChat");
+ dictionary.Add("ContactEmailCopy", "Skopiowano adres e-mail");
+
+ dictionary.Add("Tips", "Wskazówka");
+ dictionary.Add("Connected", "Połączono");
+ dictionary.Add("Disconnected", "Rozłączono");
+ dictionary.Add("DeviceDisconnected", "Urządzenie nie jest podłączone");
+ dictionary.Add("K3ToolConnectTips", "Podłącz urządzenie K3Tool przed aktualizacją");
+ dictionary.Add("FileNotFound", "Nie znaleziono pliku");
+
+ dictionary.Add("UpToDate", "Już aktualne");
+ dictionary.Add("PleaseNote", "Proszę zauważyć");
+ dictionary.Add("PleasePress", "Proszę nacisnąć");
+ dictionary.Add("Button", "przycisk");
+ dictionary.Add("NoKeyData", "Brak danych klucza");
+ dictionary.Add("Lock", "Zablokuj");
+ dictionary.Add("Unlock", "Odblokuj");
+ dictionary.Add("Trunk", "Bagażnik");
+ dictionary.Add("Panic", "Panika");
+ dictionary.Add("BurnTips", "Plik programowania nie istnieje. Proszę wybrać model klucza do zaprogramowania.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Użyj aplikacji mobilnej, aby zaprogramować podklucz C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Użyj aplikacji mobilnej, aby zaprogramować podklucz CF.");
+ dictionary.Add("BurnSuccess", "Programowanie zakończone pomyślnie");
+ dictionary.Add("BurnError", "Programowanie nie powiodło się");
+ dictionary.Add("NotMoreTips", "Brak więcej danych~");
+ dictionary.Add("CloudData", "Dane Chmurowe");
+ dictionary.Add("CloudDataSyncCompleted", "Synchronizacja zakończona");
+ dictionary.Add("CloudDataSyncFailed", "Synchronizacja nie powiodła się");
+ dictionary.Add("CloudDataDownloadFailed", "Pobieranie nie powiodło się");
+ dictionary.Add("CloudDataDeviceNotFound", "Nie wykryto urządzenia pamięci K3Tool");
+ dictionary.Add("CloudDataInitCompleted", "Inicjalizacja K3Tool zakończona");
+ dictionary.Add("HidSendPacketError", "Wystąpił błąd podczas wysyłania pakietu danych");
+ dictionary.Add("DialogPleaseWait", "Proszę czekać");
+ dictionary.Add("DialogProcessing", "Przetwarzanie...");
+ dictionary.Add("DialogCancelled", "Anulowano");
+ dictionary.Add("DialogErrorPrefix", "Błąd");
+ dictionary.Add("DialogElapsedPrefix", "Czas");
+ dictionary.Add("DialogBurningTitle", "Programowanie");
+ dictionary.Add("DialogBurningMessage", "Trwa programowanie...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary rulanguage()
+ {
+ #region 俄语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Главная");
+ dictionary.Add("Settings", "Системные настройки");
+ dictionary.Add("RemoteGeneration", "Генерация брелока");
+ dictionary.Add("RemoteCopy", "Копирование брелока");
+ dictionary.Add("RemoteControlDetector", "Диагностика брелока");
+ dictionary.Add("ChipIdentificationCopy", "Копирование чипа (идентификация)");
+ dictionary.Add("ChipGeneration", "Генерация чипа");
+ dictionary.Add("AccessCardCopy", "Копирование карты доступа");
+ dictionary.Add("KeyUnlock", "Разблокировка ключа");
+ dictionary.Add("TirePressure", "Функция давления в шинах");
+ dictionary.Add("MatchingFunction", "Функция привязки");
+ dictionary.Add("ChipWriteStart", "Запись стартового чипа");
+ dictionary.Add("Programmer", "Программатор");
+ dictionary.Add("AntiTheftData", "Данные иммобилайзера");
+ dictionary.Add("UpdateCenter", "Центр обновлений");
+
+ dictionary.Add("ContactWechatCopy", "Номер WeChat скопирован");
+ dictionary.Add("ContactEmailCopy", "Адрес электронной почты скопирован");
+
+ dictionary.Add("Tips", "Подсказка");
+ dictionary.Add("Connected", "Подключено");
+ dictionary.Add("Disconnected", "Отключено");
+ dictionary.Add("DeviceDisconnected", "Устройство не подключено");
+ dictionary.Add("K3ToolConnectTips", "Подключите устройство K3Tool перед началом обновления");
+ dictionary.Add("FileNotFound", "Файл не найден");
+
+ dictionary.Add("UpToDate", "Установлена последняя версия");
+ dictionary.Add("PleaseNote", "Обратите внимание");
+ dictionary.Add("PleasePress", "Нажмите");
+ dictionary.Add("Button", "кнопку");
+ dictionary.Add("NoKeyData", "Данные ключа недоступны");
+ dictionary.Add("Lock", "Заблокировать");
+ dictionary.Add("Unlock", "Разблокировать");
+ dictionary.Add("Trunk", "Багажник");
+ dictionary.Add("Panic", "Паника");
+ dictionary.Add("BurnTips", "Файл прошивки не существует. Пожалуйста, выберите модель ключа для прошивки.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Используйте мобильное приложение для прошивки C-подключа.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Используйте мобильное приложение для прошивки CF-подключа.");
+ dictionary.Add("BurnSuccess", "Прошивка успешно завершена");
+ dictionary.Add("BurnError", "Прошивка не удалась");
+ dictionary.Add("NotMoreTips", "Больше нет данных~");
+ dictionary.Add("CloudData", "Облачные Данные");
+ dictionary.Add("CloudDataSyncCompleted", "Синхронизация завершена");
+ dictionary.Add("CloudDataSyncFailed", "Синхронизация не удалась");
+ dictionary.Add("CloudDataDownloadFailed", "Не удалось загрузить");
+ dictionary.Add("CloudDataDeviceNotFound", "Накопитель K3Tool не обнаружен");
+ dictionary.Add("CloudDataInitCompleted", "Инициализация K3Tool завершена");
+ dictionary.Add("HidSendPacketError", "Ошибка при отправке пакета данных");
+ dictionary.Add("DialogPleaseWait", "Пожалуйста, подождите");
+ dictionary.Add("DialogProcessing", "Обработка...");
+ dictionary.Add("DialogCancelled", "Отменено");
+ dictionary.Add("DialogErrorPrefix", "Ошибка");
+ dictionary.Add("DialogElapsedPrefix", "Время");
+ dictionary.Add("DialogBurningTitle", "Программирование");
+ dictionary.Add("DialogBurningMessage", "Идет программирование...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary thlanguage()
+ {
+ #region 泰语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "หน้าหลัก");
+ dictionary.Add("Settings", "การตั้งค่าระบบ");
+ dictionary.Add("RemoteGeneration", "สร้างรีโมท");
+ dictionary.Add("RemoteCopy", "คัดลอกข้อมูลรีโมท");
+ dictionary.Add("RemoteControlDetector", "เครื่องตรวจจับรีโมท");
+ dictionary.Add("ChipIdentificationCopy", "คัดลอกไอดีชิป");
+ dictionary.Add("ChipGeneration", "สร้างชิป");
+ dictionary.Add("AccessCardCopy", "คัดลอกบัตรเข้าออก");
+ dictionary.Add("KeyUnlock", "ปลดล็อกกุญแจ");
+ dictionary.Add("TirePressure", "ฟังก์ชันวัดแรงดันยาง");
+ dictionary.Add("MatchingFunction", "ฟังก์ชันจับคู่");
+ dictionary.Add("ChipWriteStart", "เริ่มเขียนข้อมูลชิป");
+ dictionary.Add("Programmer", "โปรแกรมเมอร์");
+ dictionary.Add("AntiTheftData", "ข้อมูลป้องกันการโจรกรรม");
+ dictionary.Add("UpdateCenter", "ศูนย์อัปเดต");
+
+ dictionary.Add("ContactWechatCopy", "คัดลอก ID WeChat แล้ว");
+ dictionary.Add("ContactEmailCopy", "คัดลอกที่อยู่อีเมลแล้ว");
+
+ dictionary.Add("Tips", "คำแนะนำ");
+ dictionary.Add("Connected", "เชื่อมต่อแล้ว");
+ dictionary.Add("Disconnected", "ตัดการเชื่อมต่อ");
+ dictionary.Add("DeviceDisconnected", "ไม่ได้เชื่อมต่ออุปกรณ์");
+ dictionary.Add("K3ToolConnectTips", "กรุณาเชื่อมต่ออุปกรณ์ K3Tool ก่อนอัปเดต");
+ dictionary.Add("FileNotFound", "ไม่พบไฟล์");
+
+ dictionary.Add("UpToDate", "อัปเดตแล้ว");
+ dictionary.Add("PleaseNote", "โปรดทราบ");
+ dictionary.Add("PleasePress", "กรุณากด");
+ dictionary.Add("Button", "ปุ่ม");
+ dictionary.Add("NoKeyData", "ไม่มีข้อมูลกุญแจ");
+ dictionary.Add("Lock", "ล็อก");
+ dictionary.Add("Unlock", "ปลดล็อก");
+ dictionary.Add("Trunk", "ห้องเก็บของ");
+ dictionary.Add("Panic", "แพนิก");
+ dictionary.Add("BurnTips", "ไม่มีไฟล์โปรแกรม กรุณาเลือกรุ่นกุญแจที่ต้องการโปรแกรม");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "โปรดใช้แอปมือถือเพื่อโปรแกรมกุญแจย่อย C");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "โปรดใช้แอปมือถือเพื่อโปรแกรมกุญแจย่อย CF");
+ dictionary.Add("BurnSuccess", "โปรแกรมสำเร็จ");
+ dictionary.Add("BurnError", "โปรแกรมล้มเหลว");
+ dictionary.Add("NotMoreTips", "ไม่มีข้อมูลอีกแล้ว~");
+ dictionary.Add("CloudData", "ข้อมูลคลาวด์");
+ dictionary.Add("CloudDataSyncCompleted", "ซิงค์เสร็จสมบูรณ์");
+ dictionary.Add("CloudDataSyncFailed", "ซิงค์ล้มเหลว");
+ dictionary.Add("CloudDataDownloadFailed", "ดาวน์โหลดล้มเหลว");
+ dictionary.Add("CloudDataDeviceNotFound", "ไม่พบอุปกรณ์จัดเก็บข้อมูล K3Tool");
+ dictionary.Add("CloudDataInitCompleted", "เริ่มต้น K3Tool เสร็จสมบูรณ์");
+ dictionary.Add("HidSendPacketError", "เกิดข้อผิดพลาดในการส่งแพ็กเก็ตข้อมูล");
+ dictionary.Add("DialogPleaseWait", "กรุณารอสักครู่");
+ dictionary.Add("DialogProcessing", "กำลังประมวลผล...");
+ dictionary.Add("DialogCancelled", "ยกเลิกแล้ว");
+ dictionary.Add("DialogErrorPrefix", "ข้อผิดพลาด");
+ dictionary.Add("DialogElapsedPrefix", "เวลา");
+ dictionary.Add("DialogBurningTitle", "กำลังโปรแกรม");
+ dictionary.Add("DialogBurningMessage", "กำลังโปรแกรม...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary trlanguage()
+ {
+ #region 土耳其语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Ana Sayfa");
+ dictionary.Add("Settings", "Sistem Ayarları");
+ dictionary.Add("RemoteGeneration", "Uzaktan Kumanda Oluşturma");
+ dictionary.Add("RemoteCopy", "Uzaktan Kumanda Kopyalama");
+ dictionary.Add("RemoteControlDetector", "Uzaktan Kumanda Dedektörü");
+ dictionary.Add("ChipIdentificationCopy", "Çip Kimlik Kopyalama");
+ dictionary.Add("ChipGeneration", "Çip Oluşturma");
+ dictionary.Add("AccessCardCopy", "Erişim Kartı Kopyalama");
+ dictionary.Add("KeyUnlock", "Anahtar Kilidini Açma");
+ dictionary.Add("TirePressure", "Lastik Basıncı İşlevleri");
+ dictionary.Add("MatchingFunction", "Eşleştirme İşlevleri");
+ dictionary.Add("ChipWriteStart", "Çip Yazmaya Başla");
+ dictionary.Add("Programmer", "Programlayıcı");
+ dictionary.Add("AntiTheftData", "Hırsızlık Önleme Verileri");
+ dictionary.Add("UpdateCenter", "Güncelleme Merkezi");
+
+ dictionary.Add("ContactWechatCopy", "WeChat ID'si kopyalandı");
+ dictionary.Add("ContactEmailCopy", "E-posta adresi kopyalandı");
+
+ dictionary.Add("Tips", "İpucu");
+ dictionary.Add("Connected", "Bağlı");
+ dictionary.Add("Disconnected", "Bağlantı Kesildi");
+ dictionary.Add("DeviceDisconnected", "Cihaz bağlı değil");
+ dictionary.Add("K3ToolConnectTips", "Güncellemeden önce lütfen K3Tool cihazını bağlayın");
+ dictionary.Add("FileNotFound", "Dosya bulunamadı");
+
+ dictionary.Add("UpToDate", "Zaten güncel");
+ dictionary.Add("PleaseNote", "Lütfen dikkat edin");
+ dictionary.Add("PleasePress", "Lütfen basın");
+ dictionary.Add("Button", "düğme");
+ dictionary.Add("NoKeyData", "Anahtar verisi yok");
+ dictionary.Add("Lock", "Kilitle");
+ dictionary.Add("Unlock", "Kilidi Aç");
+ dictionary.Add("Trunk", "Bagaj");
+ dictionary.Add("Panic", "Panik");
+ dictionary.Add("BurnTips", "Yazma dosyası mevcut değil. Lütfen yazılacak anahtar modelini seçin.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "C alt anahtarını programlamak için mobil uygulamayı kullanın.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "CF alt anahtarını programlamak için mobil uygulamayı kullanın.");
+ dictionary.Add("BurnSuccess", "Yazma işlemi başarılı");
+ dictionary.Add("BurnError", "Yazma işlemi başarısız");
+ dictionary.Add("NotMoreTips", "Daha fazla veri yok~");
+ dictionary.Add("CloudData", "Bulut Verileri");
+ dictionary.Add("CloudDataSyncCompleted", "Senkronizasyon tamamlandı");
+ dictionary.Add("CloudDataSyncFailed", "Senkronizasyon başarısız");
+ dictionary.Add("CloudDataDownloadFailed", "İndirme başarısız");
+ dictionary.Add("CloudDataDeviceNotFound", "K3Tool depolama aygıtı algılanmadı");
+ dictionary.Add("CloudDataInitCompleted", "K3Tool başlatma tamamlandı");
+ dictionary.Add("HidSendPacketError", "Veri paketi gönderilirken hata oluştu");
+ dictionary.Add("DialogPleaseWait", "Lütfen bekleyin");
+ dictionary.Add("DialogProcessing", "İşleniyor...");
+ dictionary.Add("DialogCancelled", "İptal edildi");
+ dictionary.Add("DialogErrorPrefix", "Hata");
+ dictionary.Add("DialogElapsedPrefix", "Süre");
+ dictionary.Add("DialogBurningTitle", "Programlama");
+ dictionary.Add("DialogBurningMessage", "Programlanıyor...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary vilanguage()
+ {
+ #region 越南语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Trang chủ");
+ dictionary.Add("Settings", "Cài đặt hệ thống");
+ dictionary.Add("RemoteGeneration", "Tạo điều khiển từ xa");
+ dictionary.Add("RemoteCopy", "Sao chép điều khiển từ xa");
+ dictionary.Add("RemoteControlDetector", "Máy dò điều khiển từ xa");
+ dictionary.Add("ChipIdentificationCopy", "Sao chép ID chip");
+ dictionary.Add("ChipGeneration", "Tạo chip");
+ dictionary.Add("AccessCardCopy", "Sao chép thẻ truy cập");
+ dictionary.Add("KeyUnlock", "Mở khóa chìa");
+ dictionary.Add("TirePressure", "Chức năng áp suất lốp");
+ dictionary.Add("MatchingFunction", "Chức năng ghép nối");
+ dictionary.Add("ChipWriteStart", "Bắt đầu ghi chip");
+ dictionary.Add("Programmer", "Thiết bị lập trình");
+ dictionary.Add("AntiTheftData", "Dữ liệu chống trộm");
+ dictionary.Add("UpdateCenter", "Trung tâm cập nhật");
+
+ dictionary.Add("ContactWechatCopy", "Đã sao chép ID WeChat");
+ dictionary.Add("ContactEmailCopy", "Đã sao chép địa chỉ email");
+
+ dictionary.Add("Tips", "Mẹo");
+ dictionary.Add("Connected", "Đã kết nối");
+ dictionary.Add("Disconnected", "Ngắt kết nối");
+ dictionary.Add("DeviceDisconnected", "Thiết bị chưa kết nối");
+ dictionary.Add("K3ToolConnectTips", "Vui lòng kết nối thiết bị K3Tool trước khi cập nhật");
+ dictionary.Add("FileNotFound", "Không tìm thấy tệp");
+
+ dictionary.Add("UpToDate", "Đã là phiên bản mới nhất");
+ dictionary.Add("PleaseNote", "Vui lòng lưu ý");
+ dictionary.Add("PleasePress", "Vui lòng nhấn");
+ dictionary.Add("Button", "nút");
+ dictionary.Add("NoKeyData", "Không có dữ liệu chìa khóa");
+ dictionary.Add("Lock", "Khóa");
+ dictionary.Add("Unlock", "Mở khóa");
+ dictionary.Add("Trunk", "Cốp xe");
+ dictionary.Add("Panic", "Hoảng loạn");
+ dictionary.Add("BurnTips", "Tệp lập trình không tồn tại. Vui lòng chọn mẫu chìa khóa cần lập trình.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Vui lòng sử dụng ứng dụng di động để lập trình chìa khóa phụ C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Vui lòng sử dụng ứng dụng di động để lập trình chìa khóa phụ CF.");
+ dictionary.Add("BurnSuccess", "Lập trình thành công");
+ dictionary.Add("BurnError", "Lập trình thất bại");
+ dictionary.Add("NotMoreTips", "Không còn dữ liệu nào nữa~");
+ dictionary.Add("CloudData", "Dữ liệu Cloud");
+ dictionary.Add("CloudDataSyncCompleted", "Đồng bộ hoàn tất");
+ dictionary.Add("CloudDataSyncFailed", "Đồng bộ thất bại");
+ dictionary.Add("CloudDataDownloadFailed", "Tải xuống thất bại");
+ dictionary.Add("CloudDataDeviceNotFound", "Không phát hiện thiết bị lưu trữ K3Tool");
+ dictionary.Add("CloudDataInitCompleted", "Khởi tạo K3Tool hoàn tất");
+ dictionary.Add("HidSendPacketError", "Đã xảy ra lỗi khi gửi gói dữ liệu");
+ dictionary.Add("DialogPleaseWait", "Vui lòng chờ");
+ dictionary.Add("DialogProcessing", "Đang xử lý...");
+ dictionary.Add("DialogCancelled", "Đã hủy");
+ dictionary.Add("DialogErrorPrefix", "Lỗi");
+ dictionary.Add("DialogElapsedPrefix", "Thời gian");
+ dictionary.Add("DialogBurningTitle", "Lập trình");
+ dictionary.Add("DialogBurningMessage", "Đang lập trình...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary delanguage()
+ {
+ #region 德语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Startseite");
+ dictionary.Add("Settings", "Systemeinstellungen");
+ dictionary.Add("RemoteGeneration", "Fernbedienung generieren");
+ dictionary.Add("RemoteCopy", "Fernbedienung kopieren");
+ dictionary.Add("RemoteControlDetector", "Fernbedienungs-Detektor");
+ dictionary.Add("ChipIdentificationCopy", "Chip-ID kopieren");
+ dictionary.Add("ChipGeneration", "Chip generieren");
+ dictionary.Add("AccessCardCopy", "Zugangskarte kopieren");
+ dictionary.Add("KeyUnlock", "Schlüssel entsperren");
+ dictionary.Add("TirePressure", "Reifendruckfunktionen");
+ dictionary.Add("MatchingFunction", "Anlernfunktionen");
+ dictionary.Add("ChipWriteStart", "Chipbeschreibung starten");
+ dictionary.Add("Programmer", "Programmiergerät");
+ dictionary.Add("AntiTheftData", "Diebstahlschutzdaten");
+ dictionary.Add("UpdateCenter", "Update-Center");
+
+ dictionary.Add("ContactWechatCopy", "WeChat-ID kopiert");
+ dictionary.Add("ContactEmailCopy", "E-Mail-Adresse kopiert");
+
+ dictionary.Add("Tips", "Hinweis");
+ dictionary.Add("Connected", "Verbunden");
+ dictionary.Add("Disconnected", "Getrennt");
+ dictionary.Add("DeviceDisconnected", "Gerät nicht verbunden");
+ dictionary.Add("K3ToolConnectTips", "Bitte verbinden Sie das K3Tool-Gerät vor dem Update");
+ dictionary.Add("FileNotFound", "Datei nicht gefunden");
+
+ dictionary.Add("UpToDate", "Bereits aktuell");
+ dictionary.Add("PleaseNote", "Bitte beachten Sie");
+ dictionary.Add("PleasePress", "Bitte drücken Sie");
+ dictionary.Add("Button", "die Taste");
+ dictionary.Add("NoKeyData", "Keine Schlüsseldaten verfügbar");
+ dictionary.Add("Lock", "Verriegeln");
+ dictionary.Add("Unlock", "Entriegeln");
+ dictionary.Add("Trunk", "Kofferraum");
+ dictionary.Add("Panic", "Panik");
+ dictionary.Add("BurnTips", "Die Programmierdatei existiert nicht. Bitte wählen Sie das zu programmierende Schlüsselmodell aus.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Bitte verwenden Sie die mobile App, um den C-Unterschlüssel zu programmieren.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Bitte verwenden Sie die mobile App, um den CF-Unterschlüssel zu programmieren.");
+ dictionary.Add("BurnSuccess", "Programmierung erfolgreich abgeschlossen");
+ dictionary.Add("BurnError", "Programmierung fehlgeschlagen");
+ dictionary.Add("NotMoreTips", "Keine weiteren Daten~");
+ dictionary.Add("CloudData", "Cloud-Daten");
+ dictionary.Add("CloudDataSyncCompleted", "Synchronisierung abgeschlossen");
+ dictionary.Add("CloudDataSyncFailed", "Synchronisierung fehlgeschlagen");
+ dictionary.Add("CloudDataDownloadFailed", "Download fehlgeschlagen");
+ dictionary.Add("CloudDataDeviceNotFound", "K3Tool-Speichergerät nicht erkannt");
+ dictionary.Add("CloudDataInitCompleted", "K3Tool-Initialisierung abgeschlossen");
+ dictionary.Add("HidSendPacketError", "Fehler beim Senden des Datenpakets");
+ dictionary.Add("DialogPleaseWait", "Bitte warten");
+ dictionary.Add("DialogProcessing", "Wird verarbeitet...");
+ dictionary.Add("DialogCancelled", "Abgebrochen");
+ dictionary.Add("DialogErrorPrefix", "Fehler");
+ dictionary.Add("DialogElapsedPrefix", "Zeit");
+ dictionary.Add("DialogBurningTitle", "Programmierung");
+ dictionary.Add("DialogBurningMessage", "Wird programmiert...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary uklanguage()
+ {
+ #region 乌克兰语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Головна сторінка");
+ dictionary.Add("Settings", "Налаштування системи");
+ dictionary.Add("RemoteGeneration", "Генерація брелока");
+ dictionary.Add("RemoteCopy", "Копіювання брелока");
+ dictionary.Add("RemoteControlDetector", "Детектор брелоків");
+ dictionary.Add("ChipIdentificationCopy", "Копіювання ID чіпа");
+ dictionary.Add("ChipGeneration", "Генерація чіпа");
+ dictionary.Add("AccessCardCopy", "Копіювання картки доступу");
+ dictionary.Add("KeyUnlock", "Розблокування ключа");
+ dictionary.Add("TirePressure", "Функції тиску в шинах");
+ dictionary.Add("MatchingFunction", "Функції прив’язки");
+ dictionary.Add("ChipWriteStart", "Почати запис чіпа");
+ dictionary.Add("Programmer", "Програматор");
+ dictionary.Add("AntiTheftData", "Дані проти викрадення");
+ dictionary.Add("UpdateCenter", "Центр оновлень");
+
+ dictionary.Add("ContactWechatCopy", "ID WeChat скопійовано");
+ dictionary.Add("ContactEmailCopy", "Адресу електронної пошти скопійовано");
+
+ dictionary.Add("Tips", "Порада");
+ dictionary.Add("Connected", "Підключено");
+ dictionary.Add("Disconnected", "Відключено");
+ dictionary.Add("DeviceDisconnected", "Пристрій не підключено");
+ dictionary.Add("K3ToolConnectTips", "Будь ласка, підключіть пристрій K3Tool перед оновленням");
+ dictionary.Add("FileNotFound", "Файл не знайдено");
+
+ dictionary.Add("UpToDate", "Вже оновлено");
+ dictionary.Add("PleaseNote", "Зверніть увагу");
+ dictionary.Add("PleasePress", "Натисніть");
+ dictionary.Add("Button", "кнопку");
+ dictionary.Add("NoKeyData", "Дані ключа недоступні");
+ dictionary.Add("Lock", "Заблокувати");
+ dictionary.Add("Unlock", "Розблокувати");
+ dictionary.Add("Trunk", "Багажник");
+ dictionary.Add("Panic", "Паніка");
+ dictionary.Add("BurnTips", "Файл прошивки не існує. Будь ласка, виберіть модель ключа для прошивки.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Використовуйте мобільний застосунок для прошивки C-підключа.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Використовуйте мобільний застосунок для прошивки CF-підключа.");
+ dictionary.Add("BurnSuccess", "Прошивку успішно завершено");
+ dictionary.Add("BurnError", "Помилка прошивки");
+ dictionary.Add("NotMoreTips", "Немає більше даних~");
+ dictionary.Add("CloudData", "Хмарні Дані");
+ dictionary.Add("CloudDataSyncCompleted", "Синхронізацію завершено");
+ dictionary.Add("CloudDataSyncFailed", "Синхронізація не вдалася");
+ dictionary.Add("CloudDataDownloadFailed", "Не вдалося завантажити");
+ dictionary.Add("CloudDataDeviceNotFound", "Не виявлено пристрій зберігання K3Tool");
+ dictionary.Add("CloudDataInitCompleted", "Ініціалізацію K3Tool завершено");
+ dictionary.Add("HidSendPacketError", "Сталася помилка під час надсилання пакета даних");
+ dictionary.Add("DialogPleaseWait", "Будь ласка, зачекайте");
+ dictionary.Add("DialogProcessing", "Обробка...");
+ dictionary.Add("DialogCancelled", "Скасовано");
+ dictionary.Add("DialogErrorPrefix", "Помилка");
+ dictionary.Add("DialogElapsedPrefix", "Час");
+ dictionary.Add("DialogBurningTitle", "Програмування");
+ dictionary.Add("DialogBurningMessage", "Триває програмування...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary mslanguage()
+ {
+ #region 马来语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Halaman Utama");
+ dictionary.Add("Settings", "Tetapan Sistem");
+ dictionary.Add("RemoteGeneration", "Penjanaan Remote");
+ dictionary.Add("RemoteCopy", "Salinan Remote");
+ dictionary.Add("RemoteControlDetector", "Pengesan Remote");
+ dictionary.Add("ChipIdentificationCopy", "Salinan ID Cip");
+ dictionary.Add("ChipGeneration", "Penjanaan Cip");
+ dictionary.Add("AccessCardCopy", "Salinan Kad Akses");
+ dictionary.Add("KeyUnlock", "Nyahkunci Kunci");
+ dictionary.Add("TirePressure", "Fungsi Tekanan Tayar");
+ dictionary.Add("MatchingFunction", "Fungsi Pemadanan");
+ dictionary.Add("ChipWriteStart", "Mula Menulis Cip");
+ dictionary.Add("Programmer", "Pemprogram");
+ dictionary.Add("AntiTheftData", "Data Anti-Kecurian");
+ dictionary.Add("UpdateCenter", "Pusat Kemas Kini");
+
+ dictionary.Add("ContactWechatCopy", "ID WeChat disalin");
+ dictionary.Add("ContactEmailCopy", "Alamat e-mel disalin");
+
+ dictionary.Add("Tips", "Petua");
+ dictionary.Add("Connected", "Bersambung");
+ dictionary.Add("Disconnected", "Terputus");
+ dictionary.Add("DeviceDisconnected", "Peranti tidak bersambung");
+ dictionary.Add("K3ToolConnectTips", "Sila sambungkan peranti K3Tool sebelum mengemas kini");
+ dictionary.Add("FileNotFound", "Fail tidak dijumpai");
+
+ dictionary.Add("UpToDate", "Sudah terkini");
+ dictionary.Add("PleaseNote", "Sila ambil perhatian");
+ dictionary.Add("PleasePress", "Sila tekan");
+ dictionary.Add("Button", "butang");
+ dictionary.Add("NoKeyData", "Tiada data kunci tersedia");
+ dictionary.Add("Lock", "Kunci");
+ dictionary.Add("Unlock", "Buka Kunci");
+ dictionary.Add("Trunk", "But");
+ dictionary.Add("Panic", "Panic");
+ dictionary.Add("BurnTips", "Fail pengaturcaraan tidak wujud. Sila pilih model kunci yang perlu diprogram.");
+ dictionary.Add("BurnCSubKeyMobileAppTips", "Sila gunakan aplikasi mudah alih untuk memprogram subkunci C.");
+ dictionary.Add("BurnCFSubKeyMobileAppTips", "Sila gunakan aplikasi mudah alih untuk memprogram subkunci CF.");
+ dictionary.Add("BurnSuccess", "Pengaturcaraan berjaya");
+ dictionary.Add("BurnError", "Pengaturcaraan gagal");
+ dictionary.Add("NotMoreTips", "Tiada lagi data~");
+ dictionary.Add("CloudData", "Data Awan");
+ dictionary.Add("CloudDataSyncCompleted", "Penyegerakan selesai");
+ dictionary.Add("CloudDataSyncFailed", "Penyegerakan gagal");
+ dictionary.Add("CloudDataDownloadFailed", "Muat turun gagal");
+ dictionary.Add("CloudDataDeviceNotFound", "Peranti storan K3Tool tidak dikesan");
+ dictionary.Add("CloudDataInitCompleted", "Penyediaan K3Tool selesai");
+ dictionary.Add("HidSendPacketError", "Ralat semasa menghantar paket data");
+ dictionary.Add("DialogPleaseWait", "Sila tunggu");
+ dictionary.Add("DialogProcessing", "Sedang diproses...");
+ dictionary.Add("DialogCancelled", "Dibatalkan");
+ dictionary.Add("DialogErrorPrefix", "Ralat");
+ dictionary.Add("DialogElapsedPrefix", "Masa");
+ dictionary.Add("DialogBurningTitle", "Pengaturcaraan");
+ dictionary.Add("DialogBurningMessage", "Sedang memprogram...");
+ dictionary.Add("RechargeMinAmountInvalid", "Recharge amount cannot be less than 0.01");
+ dictionary.Add("RechargeLoginRequired", "Please log in before recharging");
+ dictionary.Add("RechargeCreatingOrder", "Creating payment order...");
+ dictionary.Add("RechargePcQrCodeMissing", "The backend did not return a PC QR payment code");
+ dictionary.Add("RechargeWechatScanToPay", "Please scan with WeChat to pay");
+ dictionary.Add("RechargePaypalParametersMissing", "The backend did not return PayPal payment parameters");
+ dictionary.Add("RechargeOpeningPaypal", "Opening PayPal payment page...");
+ dictionary.Add("RechargeCreateOrderFailed", "Failed to create payment order, please try again later");
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+
+
+
+ private static Dictionary ellanguage()
+ {
+ #region 希腊语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Αρχική σελίδα");
+ dictionary.Add("Settings", "Ρυθμίσεις συστήματος");
+ dictionary.Add("RemoteGeneration", "Δημιουργία τηλεχειριστηρίου");
+ dictionary.Add("RemoteCopy", "Αντιγραφή τηλεχειριστηρίου");
+ dictionary.Add("RemoteControlDetector", "Ανιχνευτής τηλεχειριστηρίων");
+ dictionary.Add("ChipIdentificationCopy", "Αντιγραφή αναγνωριστικού τσιπ");
+ dictionary.Add("ChipGeneration", "Δημιουργία τσιπ");
+ dictionary.Add("AccessCardCopy", "Αντιγραφή κάρτας πρόσβασης");
+ dictionary.Add("KeyUnlock", "Ξεκλείδωμα κλειδιού");
+ dictionary.Add("TirePressure", "Λειτουργίες πίεσης ελαστικών");
+ dictionary.Add("MatchingFunction", "Λειτουργίες ταύτισης");
+ dictionary.Add("ChipWriteStart", "Έναρξη εγγραφής τσιπ");
+ dictionary.Add("Programmer", "Προγραμματιστής");
+ dictionary.Add("AntiTheftData", "Δεδομένα αντικλεπτικού");
+ dictionary.Add("UpdateCenter", "Κέντρο ενημερώσεων");
+
+ dictionary.Add("ContactWechatCopy", "Το ID WeChat αντιγράφηκε");
+ dictionary.Add("ContactEmailCopy", "Η διεύθυνση email αντιγράφηκε");
+
+ dictionary.Add("Tips", "Συμβουλή");
+ dictionary.Add("Connected", "Συνδέθηκε");
+ dictionary.Add("Disconnected", "Αποσυνδέθηκε");
+ dictionary.Add("DeviceDisconnected", "Η συσκευή δεν είναι συνδεδεμένη");
+ dictionary.Add("K3ToolConnectTips", "Συνδέστε τη συσκευή K3Tool πριν την ενημέρωση");
+ dictionary.Add("FileNotFound", "Το αρχείο δεν βρέθηκε");
+
+ dictionary.Add("UpToDate", "Ήδη ενημερωμένο");
+ dictionary.Add("PleaseNote", "Παρακαλούμε σημειώστε");
+ dictionary.Add("CloudDataSyncCompleted", "Ο συγχρονισμός ολοκληρώθηκε");
+ dictionary.Add("CloudDataSyncFailed", "Ο συγχρονισμός απέτυχε");
+ dictionary.Add("CloudDataDownloadFailed", "Η λήψη απέτυχε");
+ dictionary.Add("CloudDataDeviceNotFound", "Η συσκευή αποθήκευσης K3Tool δεν εντοπίστηκε");
+ dictionary.Add("CloudDataInitCompleted", "Η αρχικοποίηση του K3Tool ολοκληρώθηκε");
+ dictionary.Add("HidSendPacketError", "Παρουσιάστηκε σφάλμα κατά την αποστολή πακέτου δεδομένων");
+ dictionary.Add("DialogPleaseWait", "Παρακαλώ περιμένετε");
+ dictionary.Add("DialogProcessing", "Σε επεξεργασία...");
+ dictionary.Add("DialogCancelled", "Ακυρώθηκε");
+ dictionary.Add("DialogErrorPrefix", "Σφάλμα");
+ dictionary.Add("DialogElapsedPrefix", "Χρόνος");
+ dictionary.Add("DialogBurningTitle", "Προγραμματισμός");
+ dictionary.Add("DialogBurningMessage", "Γίνεται προγραμματισμός...");
+
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary hulanguage()
+ {
+ #region 匈牙利语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "Kezdőlap");
+ dictionary.Add("Settings", "Rendszerbeállítások");
+ dictionary.Add("RemoteGeneration", "Távirányító generálása");
+ dictionary.Add("RemoteCopy", "Távirányító másolása");
+ dictionary.Add("RemoteControlDetector", "Távirányító érzékelő");
+ dictionary.Add("ChipIdentificationCopy", "Chip azonosító másolása");
+ dictionary.Add("ChipGeneration", "Chip generálása");
+ dictionary.Add("AccessCardCopy", "Hozzáférési kártya másolása");
+ dictionary.Add("KeyUnlock", "Kulcs feloldása");
+ dictionary.Add("TirePressure", "Gumiabroncs-nyomás funkciók");
+ dictionary.Add("MatchingFunction", "Párosítási funkciók");
+ dictionary.Add("ChipWriteStart", "Chip írásának indítása");
+ dictionary.Add("Programmer", "Programozó");
+ dictionary.Add("AntiTheftData", "Lopásgátló adatok");
+ dictionary.Add("UpdateCenter", "Frissítési központ");
+
+ dictionary.Add("ContactWechatCopy", "WeChat-azonosító másolva");
+ dictionary.Add("ContactEmailCopy", "E-mail cím másolva");
+
+ dictionary.Add("Tips", "Tipp");
+ dictionary.Add("Connected", "Csatlakozva");
+ dictionary.Add("Disconnected", "Leválasztva");
+ dictionary.Add("DeviceDisconnected", "Az eszköz nincs csatlakoztatva");
+ dictionary.Add("K3ToolConnectTips", "Kérjük, csatlakoztassa a K3Tool eszközt a frissítés előtt");
+ dictionary.Add("FileNotFound", "Fájl nem található");
+
+ dictionary.Add("UpToDate", "Már naprakész");
+ dictionary.Add("PleaseNote", "Kérjük, vegye figyelembe");
+ dictionary.Add("CloudDataSyncCompleted", "Szinkronizálás befejeződött");
+ dictionary.Add("CloudDataSyncFailed", "Szinkronizálás sikertelen");
+ dictionary.Add("CloudDataDownloadFailed", "A letöltés sikertelen");
+ dictionary.Add("CloudDataDeviceNotFound", "A K3Tool tárolóeszköz nem található");
+ dictionary.Add("CloudDataInitCompleted", "A K3Tool inicializálása befejeződött");
+ dictionary.Add("HidSendPacketError", "Hiba történt az adatcsomag elküldésekor");
+ dictionary.Add("DialogPleaseWait", "Kérjük, várjon");
+ dictionary.Add("DialogProcessing", "Feldolgozás...");
+ dictionary.Add("DialogCancelled", "Megszakítva");
+ dictionary.Add("DialogErrorPrefix", "Hiba");
+ dictionary.Add("DialogElapsedPrefix", "Idő");
+ dictionary.Add("DialogBurningTitle", "Programozás");
+ dictionary.Add("DialogBurningMessage", "Programozás folyamatban...");
+
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary arlanguage()
+ {
+ #region 阿拉伯语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "الصفحة الرئيسية");
+ dictionary.Add("Settings", "إعدادات النظام");
+ dictionary.Add("RemoteGeneration", "إنشاء جهاز تحكم عن بعد");
+ dictionary.Add("RemoteCopy", "نسخ جهاز التحكم عن بعد");
+ dictionary.Add("RemoteControlDetector", "كاشف أجهزة التحكم");
+ dictionary.Add("ChipIdentificationCopy", "نسخ معرف الشريحة");
+ dictionary.Add("ChipGeneration", "إنشاء شريحة");
+ dictionary.Add("AccessCardCopy", "نسخ بطاقة الوصول");
+ dictionary.Add("KeyUnlock", "فتح قفل المفتاح");
+ dictionary.Add("TirePressure", "وظائف ضغط الإطارات");
+ dictionary.Add("MatchingFunction", "وظائف المطابقة");
+ dictionary.Add("ChipWriteStart", "بدء كتابة الشريحة");
+ dictionary.Add("Programmer", "المبرمج");
+ dictionary.Add("AntiTheftData", "بيانات منع السرقة");
+ dictionary.Add("UpdateCenter", "مركز التحديث");
+
+ dictionary.Add("ContactWechatCopy", "تم نسخ معرف وي تشات");
+ dictionary.Add("ContactEmailCopy", "تم نسخ عنوان البريد الإلكتروني");
+
+ dictionary.Add("Tips", "تلميح");
+ dictionary.Add("Connected", "متصل");
+ dictionary.Add("Disconnected", "غير متصل");
+ dictionary.Add("DeviceDisconnected", "الجهاز غير متصل");
+ dictionary.Add("K3ToolConnectTips", "يرجى توصيل جهاز K3Tool قبل التحديث");
+ dictionary.Add("FileNotFound", "الملف غير موجود");
+
+ dictionary.Add("UpToDate", "محدث بالفعل");
+ dictionary.Add("PleaseNote", "يرجى الملاحظة");
+ dictionary.Add("CloudDataSyncCompleted", "اكتملت المزامنة");
+ dictionary.Add("CloudDataSyncFailed", "فشلت المزامنة");
+ dictionary.Add("CloudDataDownloadFailed", "فشل التنزيل");
+ dictionary.Add("CloudDataDeviceNotFound", "لم يتم اكتشاف جهاز تخزين K3Tool");
+ dictionary.Add("CloudDataInitCompleted", "اكتمل تهيئة K3Tool");
+ dictionary.Add("HidSendPacketError", "حدث خطأ أثناء إرسال حزمة البيانات");
+ dictionary.Add("DialogPleaseWait", "يرجى الانتظار");
+ dictionary.Add("DialogProcessing", "جارٍ المعالجة...");
+ dictionary.Add("DialogCancelled", "تم الإلغاء");
+ dictionary.Add("DialogErrorPrefix", "خطأ");
+ dictionary.Add("DialogElapsedPrefix", "الوقت");
+ dictionary.Add("DialogBurningTitle", "البرمجة");
+ dictionary.Add("DialogBurningMessage", "جارٍ البرمجة...");
+
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ private static Dictionary jalanguage()
+ {
+ #region 日语
+
+ Dictionary dictionary = new Dictionary();
+
+ dictionary.Add("HomePage", "ホーム");
+ dictionary.Add("Settings", "システム設定");
+ dictionary.Add("RemoteGeneration", "リモコン生成");
+ dictionary.Add("RemoteCopy", "リモコンコピー");
+ dictionary.Add("RemoteControlDetector", "リモコン検出器");
+ dictionary.Add("ChipIdentificationCopy", "チップIDコピー");
+ dictionary.Add("ChipGeneration", "チップ生成");
+ dictionary.Add("AccessCardCopy", "アクセスカードコピー");
+ dictionary.Add("KeyUnlock", "キーアンロック");
+ dictionary.Add("TirePressure", "タイヤ空気圧機能");
+ dictionary.Add("MatchingFunction", "マッチング機能");
+ dictionary.Add("ChipWriteStart", "チップ書き込み開始");
+ dictionary.Add("Programmer", "プログラマー");
+ dictionary.Add("AntiTheftData", "盗難防止データ");
+ dictionary.Add("UpdateCenter", "アップデートセンター");
+
+ dictionary.Add("ContactWechatCopy", "WeChat IDをコピーしました");
+ dictionary.Add("ContactEmailCopy", "メールアドレスをコピーしました");
+
+ dictionary.Add("Tips", "ヒント");
+ dictionary.Add("Connected", "接続済み");
+ dictionary.Add("Disconnected", "未接続");
+ dictionary.Add("DeviceDisconnected", "デバイスが接続されていません");
+ dictionary.Add("K3ToolConnectTips", "アップデート前にK3Toolデバイスを接続してください");
+ dictionary.Add("FileNotFound", "ファイルが見つかりません");
+
+ dictionary.Add("UpToDate", "最新バージョンです");
+ dictionary.Add("PleaseNote", "ご注意ください");
+ dictionary.Add("CloudDataSyncCompleted", "同期完了");
+ dictionary.Add("CloudDataSyncFailed", "同期失敗");
+ dictionary.Add("CloudDataDownloadFailed", "ダウンロード失敗");
+ dictionary.Add("CloudDataDeviceNotFound", "K3Tool ストレージデバイスが検出されませんでした");
+ dictionary.Add("CloudDataInitCompleted", "K3Tool の初期化が完了しました");
+ dictionary.Add("HidSendPacketError", "データパケットの送信中にエラーが発生しました");
+ dictionary.Add("DialogPleaseWait", "しばらくお待ちください");
+ dictionary.Add("DialogProcessing", "処理中...");
+ dictionary.Add("DialogCancelled", "キャンセルされました");
+ dictionary.Add("DialogErrorPrefix", "エラー");
+ dictionary.Add("DialogElapsedPrefix", "時間");
+ dictionary.Add("DialogBurningTitle", "書き込み");
+ dictionary.Add("DialogBurningMessage", "書き込み中...");
+
+
+
+
+
+ return dictionary;
+
+ #endregion
+ }
+ }
+}
diff --git a/AIK.Common/Language/UserPreferences.cs b/AIK.Common/Language/UserPreferences.cs
new file mode 100644
index 0000000..713d6fe
--- /dev/null
+++ b/AIK.Common/Language/UserPreferences.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Language
+{
+ public class UserPreferences
+ {
+ public string Language { get; set; } = "zh";
+
+ ///
+ /// 设备唯一标识(UUID V4,卸载重装保持不变)。
+ /// 用于 AI 客服 JSBridge 的 sid 参数。
+ ///
+ public string DeviceId { get; set; } = string.Empty;
+
+ // 可扩展其他设置:Theme, WindowSize 等
+ }
+}
diff --git a/AIK.Common/Models/UpdateInfoResult.cs b/AIK.Common/Models/UpdateInfoResult.cs
new file mode 100644
index 0000000..4ced678
--- /dev/null
+++ b/AIK.Common/Models/UpdateInfoResult.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Models
+{
+ ///
+ /// 自定义更新界面使用类
+ ///
+ public class UpdateInfoResult
+ {
+ public bool IsUpdateAvailable { get; set; }
+ public string LatestVersion { get; set; }
+ public string CurrentVersion { get; set; }
+ public string DownloadUrl { get; set; }
+ public string ChangeLog { get; set; }
+ public bool IsMandatory { get; set; }
+
+ public string VersionEnContent { get; set; }
+
+ public string VersionContent { get; set; }
+
+ }
+}
diff --git a/AIK.Common/Models/UpdateProgressDto.cs b/AIK.Common/Models/UpdateProgressDto.cs
new file mode 100644
index 0000000..b1054f8
--- /dev/null
+++ b/AIK.Common/Models/UpdateProgressDto.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.Models
+{
+ ///
+ /// 更新进度传输对象(跨程序集传递,无第三方依赖)(AutoUpdater.Net 不暴露下载进度,暂无进度条)
+ ///
+ public class UpdateProgressDto
+ {
+ public bool IsAvailable { get; set; }
+ public string? CurrentVersion { get; set; }
+ public string? LatestVersion { get; set; }
+ public string? Status { get; set; }
+ public bool HasError { get; set; }
+ public string? ErrorMessage { get; set; }
+
+ public string? DownloadUrl { get; set; }
+ }
+}
diff --git a/AIK.Common/Properties/Settings.Designer.cs b/AIK.Common/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..5eaa644
--- /dev/null
+++ b/AIK.Common/Properties/Settings.Designer.cs
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本:4.0.30319.42000
+//
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace AIK.Common.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")]
+ public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("zh")]
+ public string Language {
+ get {
+ return ((string)(this["Language"]));
+ }
+ set {
+ this["Language"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string DeviceId {
+ get {
+ return ((string)(this["DeviceId"]));
+ }
+ set {
+ this["DeviceId"] = value;
+ }
+ }
+ }
+}
diff --git a/AIK.Common/Properties/Settings.settings b/AIK.Common/Properties/Settings.settings
new file mode 100644
index 0000000..aa7c499
--- /dev/null
+++ b/AIK.Common/Properties/Settings.settings
@@ -0,0 +1,12 @@
+
+
+
+
+
+ zh
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Common/Resources/Close the U disk.bin b/AIK.Common/Resources/Close the U disk.bin
new file mode 100644
index 0000000..581fee0
Binary files /dev/null and b/AIK.Common/Resources/Close the U disk.bin differ
diff --git a/AIK.Common/Resources/Open the U disk.bin b/AIK.Common/Resources/Open the U disk.bin
new file mode 100644
index 0000000..268d354
Binary files /dev/null and b/AIK.Common/Resources/Open the U disk.bin differ
diff --git a/AIK.Common/Resources/eot.bin b/AIK.Common/Resources/eot.bin
new file mode 100644
index 0000000..599c7cc
Binary files /dev/null and b/AIK.Common/Resources/eot.bin differ
diff --git a/AIK.Common/Resources/usb connect.bin b/AIK.Common/Resources/usb connect.bin
new file mode 100644
index 0000000..5a2ecc3
Binary files /dev/null and b/AIK.Common/Resources/usb connect.bin differ
diff --git a/AIK.Common/Resources/usb create remote.bin b/AIK.Common/Resources/usb create remote.bin
new file mode 100644
index 0000000..a6e7db8
Binary files /dev/null and b/AIK.Common/Resources/usb create remote.bin differ
diff --git a/AIK.Common/StompNet/StompFrameHelper.cs b/AIK.Common/StompNet/StompFrameHelper.cs
new file mode 100644
index 0000000..95d1198
--- /dev/null
+++ b/AIK.Common/StompNet/StompFrameHelper.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.StompNet
+{
+ ///
+ /// STOMP帧结构
+ ///
+ public static class StompFrameHelper
+ {
+ private static readonly byte[] NullByte = { 0 };
+
+ public static byte[] BuildFrame(string command, Dictionary? headers = null, string? body = null)
+ {
+ var sb = new StringBuilder();
+ sb.Append(command).Append('\n');
+
+ if (headers != null)
+ {
+ foreach (var header in headers)
+ {
+ sb.Append($"{header.Key}:{header.Value}").Append("\n");
+ }
+ }
+
+ sb.Append("\n"); // 空行
+ sb.Append("\u0000"); // 结束符
+ var headerBytes = Encoding.UTF8.GetBytes(sb.ToString());
+
+ return headerBytes;
+ }
+
+ public static (string command, Dictionary headers, string body)? ParseFrame(byte[] data)
+ {
+ if (data.Length == 0 || data[data.Length - 1] != 0) return null;
+
+ var text = Encoding.UTF8.GetString(data, 0, data.Length - 1); // 去掉
+ var parts = text.Split(new[] { "\r\n\r\n", "\n\n" }, 2, StringSplitOptions.None);
+
+ if (parts.Length < 1) return null;
+
+ var headerSection = parts[0];
+ var body = parts.Length > 1 ? parts[1] : "";
+
+ var lines = headerSection.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
+ if (lines.Length == 0) return null;
+
+ var command = lines[0].Trim();
+ var headers = new Dictionary();
+
+ for (int i = 1; i < lines.Length; i++)
+ {
+ var line = lines[i];
+ var idx = line.IndexOf(':');
+ if (idx > 0)
+ {
+ var key = line.Substring(0, idx).Trim();
+ var value = line.Substring(idx + 1).Trim();
+ headers[key] = value;
+ }
+ }
+
+ return (command, headers, body);
+ }
+ }
+}
diff --git a/AIK.Common/SysCommon/ComStringHelper.cs b/AIK.Common/SysCommon/ComStringHelper.cs
new file mode 100644
index 0000000..ca0fd82
--- /dev/null
+++ b/AIK.Common/SysCommon/ComStringHelper.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.SysCommon
+{
+ public class ComStringHelper
+ {
+ public static string K3ToolDirectory = "received_data";
+ }
+}
diff --git a/AIK.Common/SysCommon/MacAddressHelper.cs b/AIK.Common/SysCommon/MacAddressHelper.cs
new file mode 100644
index 0000000..c21159b
--- /dev/null
+++ b/AIK.Common/SysCommon/MacAddressHelper.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.SysCommon
+{
+ public static class MacAddressHelper
+ {
+ ///
+ /// 获取主物理网卡的 MAC 地址(格式:00-1A-2B-3C-4D-5E)
+ ///
+ public static string GetPrimaryMacAddress()
+ {
+ try
+ {
+ var activeAdapters = NetworkInterface
+ .GetAllNetworkInterfaces()
+ .Where(nic =>
+ nic.OperationalStatus == OperationalStatus.Up &&
+ nic.NetworkInterfaceType is NetworkInterfaceType.Ethernet or NetworkInterfaceType.Wireless80211 &&
+ !IsVirtualOrLoopback(nic))
+ .OrderByDescending(nic => nic.Speed) // 优先有线 > 无线
+ .ToList();
+
+ var primary = activeAdapters.FirstOrDefault()
+ ?? NetworkInterface.GetAllNetworkInterfaces()
+ .FirstOrDefault(nic => !IsVirtualOrLoopback(nic));
+
+ if (primary?.GetPhysicalAddress().GetAddressBytes().Length > 0 is true)
+ {
+ return FormatMacAddress(primary.GetPhysicalAddress().GetAddressBytes());
+ }
+
+ return "未检测到有效物理网卡";
+ }
+ catch (Exception ex)
+ {
+ return $"获取失败: {ex.Message}";
+ }
+ }
+
+ private static bool IsVirtualOrLoopback(NetworkInterface nic)
+ {
+ if (nic.NetworkInterfaceType == NetworkInterfaceType.Loopback)
+ return true;
+
+ string desc = nic.Description.ToLowerInvariant();
+ return desc.Contains("virtual") ||
+ desc.Contains("vmware") ||
+ desc.Contains("vbox") ||
+ desc.Contains("hyper-v") ||
+ desc.Contains("bluetooth") ||
+ desc.Contains("tunnel") ||
+ desc.Contains("isatap") ||
+ desc.Contains("6to4") ||
+ desc.Contains("teredo");
+ }
+
+ private static string FormatMacAddress(ReadOnlySpan macBytes)
+ {
+ // 使用 Span 高效构建格式化字符串(.NET 8 推荐)
+ var result = new StringBuilder(macBytes.Length * 3 - 1);
+ for (int i = 0; i < macBytes.Length; i++)
+ {
+ if (i > 0) result.Append('-');
+ result.Append($"{macBytes[i]:X2}");
+ }
+ return result.ToString();
+ }
+ }
+}
diff --git a/AIK.Common/SysCommon/UserCommon/UserTokenHelper.cs b/AIK.Common/SysCommon/UserCommon/UserTokenHelper.cs
new file mode 100644
index 0000000..6e316f6
--- /dev/null
+++ b/AIK.Common/SysCommon/UserCommon/UserTokenHelper.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace AIK.Common.SysCommon.UserCommon
+{
+ public static class UserTokenHelper
+ {
+ public static (bool Success, long? UserId, long? Exp) ParseJwtPayload(string jwt)
+ {
+ try
+ {
+ var parts = jwt.Split('.');
+ if (parts.Length != 3) return (false, null, null);
+
+ var payloadJson = Base64UrlDecode(parts[1]);
+ using var doc = JsonDocument.Parse(payloadJson);
+ var root = doc.RootElement;
+
+ long? userId = root.TryGetProperty("userId", out var uid) ? uid.GetInt64() : null;
+ long? exp = root.TryGetProperty("exp", out var e) ? e.GetInt64() : null;
+
+ return (true, userId, exp);
+ }
+ catch
+ {
+ return (false, null, null);
+ }
+ }
+
+ private static string Base64UrlDecode(string input)
+ {
+ // 补齐 padding
+ string padded = input.Replace('-', '+').Replace('_', '/');
+ switch (padded.Length % 4)
+ {
+ case 2: padded += "=="; break;
+ case 3: padded += "="; break;
+ }
+ byte[] data = Convert.FromBase64String(padded);
+ return System.Text.Encoding.UTF8.GetString(data);
+ }
+ }
+}
diff --git a/AIK.Common/SysCommon/WebApiAddress.cs b/AIK.Common/SysCommon/WebApiAddress.cs
new file mode 100644
index 0000000..da85f2f
--- /dev/null
+++ b/AIK.Common/SysCommon/WebApiAddress.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.SysCommon
+{
+ ///
+ /// 自带/前缀的WebApi地址
+ ///
+ public static class WebApiAddress
+ {
+ public static string Vehicle_keyBrand_List = "/prod-api/work_key/vehicle_key/brand_list"; //获取品牌列表
+ public static string Vehicle_keyBrand_Detail = "/prod-api/work_key/vehicle_key/brand_detail"; //获取品牌详情
+ public static string CommonProfile = "/prod-api/work_main/common/profile"; //获取用户信息
+ public static string AccountLogin = "/prod-api/work_main/login";//账密登录
+ public static string PhoneRegister = "/prod-api/work_main/user/phone_register";//手机号注册
+ public static string EmailRegister = "/prod-api/work_main/user/user/email_register";//邮箱注册(路径按接口文档原样,含双 user)
+
+ #region 短信/邮箱服务(work_sms)
+ public static string SendCode = "/prod-api/work_sms/sms/send_code";//发送注册验证码(GET,参数 phone)
+ public static string SendLoginCode = "/prod-api/work_sms/sms/send_login";//发送登录验证码(GET,参数 phone)
+ public static string CheckCode = "/prod-api/work_sms/sms/check_code";//验证验证码(GET,参数 code/phone/type)
+
+ // 邮箱服务(GET,成功码 code=1)
+ public static string EmailSendCode = "/prod-api/work_sms/email/send_code";//发送邮箱验证码(参数 address/type)
+ public static string EmailCheckCode = "/prod-api/work_sms/email/check_code";//验证邮箱验证码(参数 address/code)
+ #endregion
+ public static string BannerAll = "/prod-api/work_key/banner/all"; //获取首页轮播图
+ public static string AppNew = "/prod-api/work_key/app/new"; //获取最新版本信息
+ public static string LogList = "/prod-api/work_key/d_info/log_list";//烧录记录
+ public static string Integral = "/prod-api/work_key/integral/get";//用户积分
+ public static string IntegralHistroy = "/prod-api/work_key/integral/get_history";//积分记录
+ public static string KeyAddInfo = "/prod-api/work_key/d_info/add_info";//用户添加烧录记录
+ public static string BurnAdd = "/prod-api/work_key/burn/add";//用户添加烧录次数
+
+ #region 会员功能与支付积分
+ public static string MembershipModuleList = "/prod-api/work_key/func/module_list";
+ public static string MembershipFind = "/prod-api/work_key/func/find";
+ public static string MembershipOpen = "/prod-api/work_key/func/open";
+ public static string MembershipBind = "/prod-api/work_key/func/bind";
+ public static string MembershipCheck = "/prod-api/work_key/func/check";
+ public static string MembershipActivate = "/prod-api/work_key/func/act";
+ public static string MembershipFindCount = "/prod-api/work_key/func/find_count";
+ public static string MembershipAddCount = "/prod-api/work_key/func/add_count";
+ public static string PayIntegralOrder = "/prod-api/work_app_mall/info/pay_integral_order";
+ public static string OrderPayStatus = "/prod-api/work_app_mall/info/order_pay_status";
+ public static string OrderPaypal = "/prod-api/work_key/info/order_paypal";
+ #endregion
+
+ public static string OssDataCache = "/prod-api/work_main/oss_data/cache/type";//K3tool云数据缓存地址
+
+ public static string TpmsType = "/prod-api/work_key/tpms_type/type";//获取胎压类型
+
+ #region 工具类型(用于版本更新)
+ public static string K3ToolType = "i2";
+ public static string PCType = "pcwin7";
+ public static string PCZipType = "pcwin7_zip";
+ #endregion
+
+ #region oss数据缓存类型
+ public static string K3ToolBin = "K3tool_bin";
+ #endregion
+ }
+}
diff --git a/AIK.Common/WebHelper/UrlHelper.cs b/AIK.Common/WebHelper/UrlHelper.cs
new file mode 100644
index 0000000..bde2159
--- /dev/null
+++ b/AIK.Common/WebHelper/UrlHelper.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Common.WebHelper
+{
+ public static class UrlHelper
+ {
+ ///
+ /// 从完整URL中提取文件名(保留URL编码,如 %28 不会转成 ()
+ ///
+ /// 完整的下载链接
+ /// URL编码的文件名,如 "20251126055829_721_%28K3_TOOL%291.2.9.bin"
+ public static string GetEncodedFileNameFromUrl(string url)
+ {
+ if (string.IsNullOrWhiteSpace(url))
+ return string.Empty;
+ try
+ {
+ var uri = new Uri(url);
+ // Segments 是路径按 '/' 分割的数组,最后一个元素即为文件名(含原始编码)
+ string[] segments = uri.Segments;
+ if (segments.Length == 0)
+ return string.Empty;
+
+ string fileName = segments[segments.Length - 1];
+ // 移除末尾可能的斜杠(虽然文件名通常不会有)
+ return fileName.TrimEnd('/');
+ }
+ catch (UriFormatException)
+ {
+ // URL 格式无效时返回空或抛异常,根据需求调整
+ return string.Empty;
+ }
+ }
+ }
+}
diff --git a/AIK.Common/WebHelper/WebHelper.cs b/AIK.Common/WebHelper/WebHelper.cs
new file mode 100644
index 0000000..2625755
--- /dev/null
+++ b/AIK.Common/WebHelper/WebHelper.cs
@@ -0,0 +1,180 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace AIK.Common.WebHelper
+{
+ public class WebHelper
+ {
+
+ //private static string weburlTest = "https://keytest.aik518.com";
+ ////public static string fileurl = "https://keytest.aik518.com/prod-api/work_file/file/file_download?objectName=";
+ ////接口地址
+ //private static string weburl = " https://key.aik518.com";
+ ////文件下载地址
+ //public static string fileurl = " https://key.aik518.com/prod-api/work_file/file/file_download?objectName=";
+ ////当前平台语言
+ //public static string language = "zh";
+ ////当前平台升级地址
+ //private static string updateurl = "http://124.221.137.201:8168/update.zip";
+
+ //public static System.Collections.Hashtable ImgListKey = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable());
+
+
+
+ #region HttpWebRequest(请求网络资源)
+
+ ///
+ /// 请求网络资源,返回响应的文本
+ ///
+ /// 网络资源地址
+ public static string HttpWebRequest(string url, string parameters, int timeout, bool isPost)
+ {
+ return HttpWebRequest(url, parameters, Encoding.GetEncoding("utf-8"), timeout, isPost);
+ }
+
+ ///
+ /// 请求网络资源,返回响应的文本
+ ///
+ /// 网络资源地址
+ /// 提交的参数,格式:参数1=参数值1&参数2=参数值2
+ /// 字符编码
+ /// 是否Post提交
+ /// 内容类型
+ /// Cookie容器
+ /// 超时时间
+ public static string HttpWebRequest(string url, string parameters, Encoding encoding, int timeout, bool isPost = false,
+ string contentType = "application/x-www-form-urlencoded", CookieContainer cookie = null)
+ {
+ var request = (HttpWebRequest)WebRequest.Create(url);
+ request.Timeout = timeout;
+ request.CookieContainer = cookie;
+ if (isPost)
+ {
+ byte[] postData = encoding.GetBytes(parameters);
+ request.Method = "POST";
+ request.ContentType = contentType;
+ request.ContentLength = postData.Length;
+ using (Stream stream = request.GetRequestStream())
+ {
+ stream.Write(postData, 0, postData.Length);
+ }
+ }
+ var response = (HttpWebResponse)request.GetResponse();
+ string result;
+ using (Stream stream = response.GetResponseStream())
+ {
+ if (stream == null)
+ return string.Empty;
+ using (var reader = new StreamReader(stream, encoding))
+ {
+ result = reader.ReadToEnd();
+ }
+ }
+ return result;
+ }
+
+ #endregion
+
+ #region Post json请求
+ public static string PostJson(string Url, string jsonParas)
+ {
+ string strURL = Url;
+ //创建一个HTTP请求
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);
+ //Post请求方式
+ request.Method = "POST";
+ //内容类型
+ request.ContentType = "application/json";
+ //设置参数,并进行URL编码
+ string paraUrlCoded = jsonParas;//System.Web.HttpUtility.UrlEncode(jsonParas);
+ byte[] payload;
+ //将Json字符串转化为字节
+ payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
+ //设置请求的ContentLength
+ request.ContentLength = payload.Length;
+ //发送请求,获得请求流
+ Stream writer;
+ try
+ {
+ using (writer = request.GetRequestStream())
+ {
+ //将请求参数写入流
+ writer.Write(payload, 0, payload.Length);
+ writer.Close();//关闭请求流
+ }
+ ;//获取用于写入请求数据的Stream对象
+ }
+ catch (Exception ex)
+ {
+ writer = null;
+ }
+
+ HttpWebResponse response;
+ string postContent = "";
+ try
+ {
+ //获得响应流
+ using (response = (HttpWebResponse)request.GetResponse())
+ {
+ Stream s = response.GetResponseStream();
+ // Stream postData = Request.InputStream;
+ StreamReader sRead = new StreamReader(s);
+ postContent = sRead.ReadToEnd();
+ sRead.Close();
+ }
+ ;
+ }
+ catch (WebException ex)
+ {
+ response = ex.Response as HttpWebResponse;
+ }
+ return postContent;//返回Json数据
+ }
+ #endregion
+
+ #region 异步请求
+ ///
+ /// 异步POST请求
+ ///
+ public static async Task PostJsonAsync(string url, string jsonData, CancellationToken cancellationToken = default)
+ {
+ using var client = new HttpClient();
+ using var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
+ using var response = await client.PostAsync(url, content, cancellationToken);
+ response.EnsureSuccessStatusCode();
+ return await response.Content.ReadAsStringAsync();
+ }
+
+ ///
+ /// 异步HTTP请求
+ ///
+ public static async Task HttpWebRequestAsync(string url, string data, int timeoutMs, bool isPost, CancellationToken cancellationToken = default)
+ {
+ using var client = new HttpClient();
+ client.Timeout = TimeSpan.FromMilliseconds(timeoutMs);
+
+ if (isPost && !string.IsNullOrEmpty(data))
+ {
+ using var content = new StringContent(data, Encoding.UTF8, "application/json");
+ using var response = await client.PostAsync(url, content, cancellationToken);
+ response.EnsureSuccessStatusCode();
+ return await response.Content.ReadAsStringAsync();
+ }
+ else
+ {
+ using var response = await client.GetAsync(url, cancellationToken);
+ response.EnsureSuccessStatusCode();
+ return await response.Content.ReadAsStringAsync();
+ }
+ }
+ #endregion
+
+ }
+}
diff --git a/AIK.DataAccess/AIK.DataAccess.csproj b/AIK.DataAccess/AIK.DataAccess.csproj
new file mode 100644
index 0000000..a796bd4
--- /dev/null
+++ b/AIK.DataAccess/AIK.DataAccess.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net48
+ enable
+ true
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.DataAccess/DbCore.cs b/AIK.DataAccess/DbCore.cs
new file mode 100644
index 0000000..63d719e
--- /dev/null
+++ b/AIK.DataAccess/DbCore.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.DataAccess
+{
+ public static class DbCore
+ {
+ public const string CacheKey = "veh_car_data";
+ public const string CacheModelKey = "veh_carmodel_data";
+ public const string CacheVehModelKey = $"vehModel";
+ }
+}
diff --git a/AIK.DataAccess/SQLiteCore.cs b/AIK.DataAccess/SQLiteCore.cs
new file mode 100644
index 0000000..da084c3
--- /dev/null
+++ b/AIK.DataAccess/SQLiteCore.cs
@@ -0,0 +1,194 @@
+using System.Data.SQLite;
+using System;
+using System.Threading;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.DataAccess
+{
+ public static class SQLiteCore
+ {
+ private static string _databasePath;
+ private static bool _isInitialized = false;
+ private static readonly object _initLock = new object();
+ // 连接池(线程安全队列),最大连接数控制为 5(SQLite 推荐)
+ private static readonly ConcurrentQueue _connectionPool = new ConcurrentQueue();
+ private const int MaxConnections = 5;
+ private static int _activeConnections = 0;
+ ///
+ /// 初始化 SQLitePCL 和数据库路径
+ ///
+ private static void Initialize()
+ {
+ lock (_initLock)
+ {
+ if (!_isInitialized)
+ {
+ InitializeDatabasePath();
+ _isInitialized = true;
+ }
+ }
+ }
+
+ ///
+ /// 获取池化连接(返回包装类,支持 using 自动归还)
+ ///
+ public static SqlitePooledConnection GetConnection()
+ {
+ Initialize();
+
+ // 尝试从池子里取空闲连接
+ if (_connectionPool.TryDequeue(out var connection) && connection.State == System.Data.ConnectionState.Open)
+ {
+ Interlocked.Decrement(ref _activeConnections);
+ return new SqlitePooledConnection(connection); // 用包装类包裹
+ }
+
+ // 池子里没有空闲连接,创建新连接
+ if (Interlocked.Increment(ref _activeConnections) > MaxConnections)
+ {
+ Interlocked.Decrement(ref _activeConnections);
+ throw new InvalidOperationException("SQLite 连接池已达最大连接数,建议优化事务执行速度或调整 MaxConnections");
+ }
+
+ var newConn = new SQLiteConnection($"Data Source={_databasePath}");
+ newConn.Open();
+ using (var cmd = newConn.CreateCommand())
+ {
+ cmd.CommandText = @"
+ PRAGMA journal_mode = WAL;
+ PRAGMA synchronous = NORMAL;
+ PRAGMA foreign_keys = ON;
+ PRAGMA busy_timeout = 3000;
+ ";
+ cmd.ExecuteNonQuery();
+ }
+
+ return new SqlitePooledConnection(newConn); // 用包装类包裹
+ }
+
+
+ ///
+ /// 将连接归还到连接池(避免重复创建)
+ ///
+ public static void ReturnConnection(SQLiteConnection connection)
+ {
+ try
+ {
+ if (connection == null || connection.State != System.Data.ConnectionState.Open)
+ {
+ connection?.Dispose();
+ Interlocked.Decrement(ref _activeConnections);
+ return;
+ }
+
+ // 归还到池子里(供下次复用)
+ _connectionPool.Enqueue(connection);
+ Interlocked.Decrement(ref _activeConnections);
+ }
+ catch (Exception)
+ {
+
+ }
+
+ }
+
+ ///
+ /// 释放所有连接(程序退出时调用)
+ ///
+ public static void DisposePool()
+ {
+ while (_connectionPool.TryDequeue(out var connection))
+ {
+ connection.Dispose();
+ }
+ _activeConnections = 0;
+ }
+ #region 单例模式
+ ///
+ /// 创建配置好的数据库连接
+ ///
+ //public static SQLiteConnection CreateConnection()
+ //{
+ // InitializeSQLitePCL();
+ // // 数据库文件路径
+ // _databasePath = DatabasePath;
+
+ // // 确保目录存在
+ // Directory.CreateDirectory(Path.GetDirectoryName(_databasePath));
+ // var connection = new SQLiteConnection($"Data Source={_databasePath}");
+ // connection.Open();
+
+ // // 基本优化设置
+ // using (var cmd = connection.CreateCommand())
+ // {
+ // cmd.CommandText = @"
+ // PRAGMA journal_mode = WAL;
+ // PRAGMA synchronous = NORMAL;
+ // PRAGMA foreign_keys = ON;
+ // ";
+ // cmd.ExecuteNonQuery();
+ // }
+
+ // return connection;
+ //}
+ //private static void InitializeSQLitePCL()
+ //{
+ // lock (_initLock)
+ // {
+ // if (!_isInitialized)
+ // {
+ // try
+ // {
+ // _isInitialized = true;
+ // Console.WriteLine("SQLitePCL initialized successfully.");
+ // }
+ // catch (Exception ex)
+ // {
+ // Console.WriteLine($"SQLitePCL initialization failed: {ex.Message}");
+ // throw;
+ // }
+ // }
+ // }
+ //}
+ #endregion
+ private static void InitializeDatabasePath()
+ {
+ #region(旧版本路径,未区分国内外版本)
+ //_databasePath = Path.Combine(
+ // Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
+ // "AIKKey", "Cache", "aikcache.db");
+ #endregion
+ // 1. 获取 AppData 基础路径
+ string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+
+ // 2. 定义公司和应用的基础目录名
+ string companyName = "AIKKey";
+ string baseFolderName = "Cache";
+ string databaseFileName = "aikcache.db";
+ string versionFolderName;
+#if CN
+ versionFolderName = "CN"; // 国内版使用 "CN" 子目录
+#elif TEST
+ versionFolderName = "TEST";
+#else
+ versionFolderName = "Global"; // 国外版使用 "Global" 子目录
+#endif
+ _databasePath = Path.Combine(appDataPath, companyName, baseFolderName, versionFolderName, databaseFileName);
+ // 确保目录存在
+ Directory.CreateDirectory(Path.GetDirectoryName(_databasePath));
+ }
+ public static string DatabasePath
+ {
+ get
+ {
+ InitializeDatabasePath();
+ return _databasePath;
+ }
+ }
+ }
+}
diff --git a/AIK.DataAccess/SqlitePooledConnection.cs b/AIK.DataAccess/SqlitePooledConnection.cs
new file mode 100644
index 0000000..93a68f3
--- /dev/null
+++ b/AIK.DataAccess/SqlitePooledConnection.cs
@@ -0,0 +1,50 @@
+using System.Data.SQLite;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.DataAccess
+{
+ public class SqlitePooledConnection : IDisposable
+ {
+ // 内部持有真实的 SQLite 连接
+ private readonly SQLiteConnection _innerConnection;
+ // 标记是否已释放
+ private bool _disposed = false;
+
+ ///
+ /// 暴露内部连接供 Dapper 调用(核心)
+ ///
+ public SQLiteConnection InnerConnection => _innerConnection;
+
+ ///
+ /// 构造函数(仅由 SQLiteCore 内部创建,外部不直接实例化)
+ ///
+ internal SqlitePooledConnection(SQLiteConnection innerConnection)
+ {
+ _innerConnection = innerConnection ?? throw new ArgumentNullException(nameof(innerConnection));
+ }
+
+ ///
+ /// using 结束时自动执行,归还连接到池
+ ///
+ public void Dispose()
+ {
+ if (!_disposed)
+ {
+ // 关键:归还连接到连接池,而非销毁
+ SQLiteCore.ReturnConnection(_innerConnection);
+ _disposed = true;
+ }
+ }
+
+ // 可选:暴露常用方法,简化调用(如创建命令)
+ public SQLiteCommand CreateCommand()
+ {
+ if (_disposed) throw new ObjectDisposedException(nameof(SqlitePooledConnection));
+ return _innerConnection.CreateCommand();
+ }
+ }
+}
diff --git a/AIK.Models/AIK.Models.csproj b/AIK.Models/AIK.Models.csproj
new file mode 100644
index 0000000..f3ec584
--- /dev/null
+++ b/AIK.Models/AIK.Models.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net48
+ enable
+ true
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Models/AlphabetGroup.cs b/AIK.Models/AlphabetGroup.cs
new file mode 100644
index 0000000..1cbc8e2
--- /dev/null
+++ b/AIK.Models/AlphabetGroup.cs
@@ -0,0 +1,32 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models
+{
+ public partial class AlphabetGroup : ObservableObject
+ {
+ [ObservableProperty]
+ private string letter;
+
+ [ObservableProperty]
+ private ObservableCollection items;
+
+ public void AddRange(string[] names)
+ {
+ foreach (var name in names)
+ {
+ Items.Add(new AlphabetItem(name, Letter));
+ }
+ }
+ public AlphabetGroup(string letter)
+ {
+ this.letter = letter;
+ Items = new ObservableCollection();
+ }
+ }
+}
diff --git a/AIK.Models/AlphabetItem.cs b/AIK.Models/AlphabetItem.cs
new file mode 100644
index 0000000..923e93a
--- /dev/null
+++ b/AIK.Models/AlphabetItem.cs
@@ -0,0 +1,25 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace AIK.Models
+{
+ public partial class AlphabetItem : ObservableObject
+ {
+ public AlphabetItem(string name, string letter)
+ {
+ Name = name;
+ Letter = letter;
+ }
+
+ [ObservableProperty]
+ private string name;
+
+ [ObservableProperty]
+ private string letter;
+ }
+}
diff --git a/AIK.Models/ApiModels/ApiPageResult.cs b/AIK.Models/ApiModels/ApiPageResult.cs
new file mode 100644
index 0000000..f1cd9c2
--- /dev/null
+++ b/AIK.Models/ApiModels/ApiPageResult.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+
+namespace AIK.Models.ApiModels
+{
+ public class ApiPageResult
+ {
+ public List Records { get; set; } = new();
+ public long Total { get; set; }
+ public long Current { get; set; }
+ public long Size { get; set; }
+ public long Pages { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/ApiResponse.cs b/AIK.Models/ApiModels/ApiResponse.cs
new file mode 100644
index 0000000..e3c9198
--- /dev/null
+++ b/AIK.Models/ApiModels/ApiResponse.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels
+{
+ public partial class ApiResponse
+ {
+ public int Code { get; set; }
+ public string? Msg { get; set; }
+ public string? I18nMsg { get; set; }
+ public object? Data { get; set; }
+ public Dictionary? Dict { get; set; }
+ }
+
+ public class ApiResponse
+ {
+ public int Code { get; set; }
+ public string? Msg { get; set; }
+ public string? I18nMsg { get; set; }
+ public T? Data { get; set; }
+ public Dictionary? Dict { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Banner/BannerModel.cs b/AIK.Models/ApiModels/Banner/BannerModel.cs
new file mode 100644
index 0000000..763d745
--- /dev/null
+++ b/AIK.Models/ApiModels/Banner/BannerModel.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Banner
+{
+ public class BannerModel
+ {
+ ///
+ /// 唯一标识
+ ///
+ [JsonPropertyName("id")]
+ public int? Id { get; set; }
+
+ ///
+ /// 图片路径
+ ///
+ [JsonPropertyName("imgUrl")]
+ public string? ImgUrl { get; set; }
+
+ ///
+ /// 支持的语言(如 "zh-CN", "en-US")
+ ///
+ [JsonPropertyName("language")]
+ public string? Language { get; set; }
+
+ ///
+ /// 排序序号(值越小越靠前)
+ ///
+ [JsonPropertyName("orderNo")]
+ public int OrderNo { get; set; }
+
+ ///
+ /// 跳转目标内容(URL 或内部路由)
+ ///
+ [JsonPropertyName("targetUrl")]
+ public string? TargetUrl { get; set; }
+
+ ///
+ /// 跳转类型:
+ /// 0 - 无跳转
+ /// 1 - 外部链接
+ /// 2 - 内部链接
+ ///
+ [JsonPropertyName("type")]
+ public int? Type { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Brand/KzInfo.cs b/AIK.Models/ApiModels/Brand/KzInfo.cs
new file mode 100644
index 0000000..731cf8a
--- /dev/null
+++ b/AIK.Models/ApiModels/Brand/KzInfo.cs
@@ -0,0 +1,112 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Brand
+{
+ public partial class KzInfo : ObservableObject
+ {
+ ///
+ /// bin文件地址
+ ///
+ public string binAddress { get; set; }
+
+ ///
+ /// 修改bin文件位置数组
+ ///
+ public List binAddressArray { get; set; }
+
+ ///
+ /// 芯片类型
+ ///
+ public string chipType { get; set; }
+
+ ///
+ /// 是否云遥控
+ ///
+ public bool cloudRemote { get; set; }
+
+ ///
+ /// 是否为电子芯片
+ ///
+ public bool dzxp { get; set; }
+
+ ///
+ /// 固件编号
+ ///
+ public string firmwareNo { get; set; }
+
+ ///
+ /// 是否特殊C子机bin文件
+ ///
+ public bool fixedByte { get; set; }
+
+ ///
+ /// 特殊C子机bin文件修改位置数组
+ ///
+ public List fixedByteArray { get; set; }
+
+ ///
+ /// 特殊C子机bin文件修改固定数据
+ ///
+ public string fixedByteArrays { get; set; }
+
+ ///
+ /// 固件信息包下载地址
+ ///
+ public string sourceUrl { get; set; }
+
+ ///
+ /// 是否特殊子机
+ ///
+ public bool sp { get; set; }
+
+ ///
+ /// 子机code
+ ///
+ public string spCode { get; set; }
+
+ ///
+ /// 是否使用特殊随机数
+ ///
+ public bool tsRand { get; set; }
+
+ ///
+ /// 特殊随机数字符
+ ///
+ public string tsRandStr { get; set; }
+
+ ///
+ /// 所属子机类型
+ ///
+ public string type { get; set; }
+
+ ///
+ /// 是否修改bin文件
+ ///
+ public bool updateByte { get; set; }
+
+ ///
+ /// 可用子机(可对应多个子机)
+ ///
+ public string usable { get; set; }
+
+ ///
+ /// 未知用途字段(保留)
+ ///
+ public string ysSource { get; set; }
+
+ ///
+ /// 未知用途字段(保留)
+ ///
+ public string ysSourceNo { get; set; }
+
+ ///
+ /// 遥控再生类型ID
+ ///
+ public string zsId { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Burn/BurnItem.cs b/AIK.Models/ApiModels/Burn/BurnItem.cs
new file mode 100644
index 0000000..5f2fe18
--- /dev/null
+++ b/AIK.Models/ApiModels/Burn/BurnItem.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Burn
+{
+ public class BurnItem
+ {
+ public string DeviceId { get; set; } = string.Empty;
+ public int KeyId { get; set; }
+ public string MacAddress { get; set; } = string.Empty;
+ public string ToolName { get; set; } = string.Empty;
+ }
+}
diff --git a/AIK.Models/ApiModels/Burn/BurnKeyItem.cs b/AIK.Models/ApiModels/Burn/BurnKeyItem.cs
new file mode 100644
index 0000000..8f0214f
--- /dev/null
+++ b/AIK.Models/ApiModels/Burn/BurnKeyItem.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Burn
+{
+ public class BurnKeyItem
+ {
+ public int KeyId { get; set; }
+ public string[]? KeyNoList { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/CloudData/ApiResponseOssData.cs b/AIK.Models/ApiModels/CloudData/ApiResponseOssData.cs
new file mode 100644
index 0000000..291ce45
--- /dev/null
+++ b/AIK.Models/ApiModels/CloudData/ApiResponseOssData.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.CloudData
+{
+ public class ApiResponseOssData : ApiResponse
+ {
+ public new List? Data { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/CloudData/CloudPackageInfo.cs b/AIK.Models/ApiModels/CloudData/CloudPackageInfo.cs
new file mode 100644
index 0000000..45458b6
--- /dev/null
+++ b/AIK.Models/ApiModels/CloudData/CloudPackageInfo.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.CloudData
+{
+ public class CloudPackageInfo
+ {
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ [JsonPropertyName("type")]
+ public string Type { get; set; } = string.Empty;
+
+ [JsonPropertyName("url")]
+ public string Url { get; set; } = string.Empty;
+
+ [JsonPropertyName("esaUrl")]
+ public string EsaUrl { get; set; } = string.Empty;
+
+ [JsonPropertyName("code")]
+ public string Code { get; set; } = string.Empty;
+
+ [JsonPropertyName("name")]
+ public string Name { get; set; } = string.Empty;
+
+ [JsonPropertyName("updateTime")]
+ public string UpdateTime { get; set; } = string.Empty;
+ }
+}
diff --git a/AIK.Models/ApiModels/Integral/ApiResponseIntegralRecord.cs b/AIK.Models/ApiModels/Integral/ApiResponseIntegralRecord.cs
new file mode 100644
index 0000000..fcc83db
--- /dev/null
+++ b/AIK.Models/ApiModels/Integral/ApiResponseIntegralRecord.cs
@@ -0,0 +1,20 @@
+using AIK.Models.ApiModels.Integral;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Record
+{
+ public class ApiResponseIntegralRecord : ApiResponse
+ {
+ public List Records { get; set; }
+ public int Total { get; set; }
+ public int Size { get; set; }
+ public int Current { get; set; }
+ public List Orders { get; set; }
+ public bool SearchCount { get; set; }
+ public int Pages { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Integral/IntegralModel.cs b/AIK.Models/ApiModels/Integral/IntegralModel.cs
new file mode 100644
index 0000000..c81dfae
--- /dev/null
+++ b/AIK.Models/ApiModels/Integral/IntegralModel.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Integral
+{
+ public class IntegralModel
+ {
+ public int? Id { get; set; }
+
+ public int Integral { get; set; }
+
+ public int? UsedIntegral { get; set; }
+
+ public int? UserId { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Integral/IntegralRecord.cs b/AIK.Models/ApiModels/Integral/IntegralRecord.cs
new file mode 100644
index 0000000..43cf4f3
--- /dev/null
+++ b/AIK.Models/ApiModels/Integral/IntegralRecord.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Integral
+{
+ public class IntegralRecord
+ {
+ [JsonPropertyName("craeteTime")] // 注意:JSON 中拼写为 "craeteTime"(应为 createTime)
+ public string CraeteTime { get; set; } = string.Empty;
+
+ [JsonPropertyName("createUser")]
+ public string CreateUser { get; set; } = string.Empty;
+
+ [JsonPropertyName("fh")]
+ public string Fh { get; set; } = string.Empty;
+
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ [JsonPropertyName("remark")]
+ public string Remark { get; set; } = string.Empty;
+
+ [JsonPropertyName("score")]
+ public int Score { get; set; }
+
+ [JsonPropertyName("userId")]
+ public int UserId { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Membership/MembershipModels.cs b/AIK.Models/ApiModels/Membership/MembershipModels.cs
new file mode 100644
index 0000000..2f3caca
--- /dev/null
+++ b/AIK.Models/ApiModels/Membership/MembershipModels.cs
@@ -0,0 +1,74 @@
+using System;
+
+namespace AIK.Models.ApiModels.Membership
+{
+ public class MembershipModule
+ {
+ public int Id { get; set; }
+ public string? Model { get; set; }
+ public string? Code { get; set; }
+ public string? Name { get; set; }
+ public int Num { get; set; }
+ public int NumType { get; set; }
+ public DateTime? CreateTime { get; set; }
+ }
+
+ public class MembershipFindRequest
+ {
+ public string? Model { get; set; } = "key";
+ public string? FuncCode { get; set; }
+ public int? FuncId { get; set; }
+ public string? SerNo { get; set; }
+ public string? Language { get; set; }
+ public int Page { get; set; } = 1;
+ public int Size { get; set; } = 10;
+ }
+
+ public class MembershipRecord
+ {
+ public int Id { get; set; }
+ public int FuncId { get; set; }
+ public string? FuncCode { get; set; }
+ public string? FuncName { get; set; }
+ public string? SerNo { get; set; }
+ public DateTime? StartTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ public bool Expire { get; set; }
+ }
+
+ public class OpenMembershipRequest
+ {
+ public string? FuncCode { get; set; }
+ public string? SerNo { get; set; }
+ public string? Language { get; set; }
+ }
+
+ public class BindMembershipDeviceRequest
+ {
+ public int Id { get; set; }
+ public string? SerNo { get; set; }
+ public string? Language { get; set; }
+ }
+
+ public class CheckMembershipPermissionRequest
+ {
+ public string? Code { get; set; }
+ public string? SerNo { get; set; }
+ public int Type { get; set; }
+ public string? Language { get; set; }
+ }
+
+ public class ActivateDeviceRequest
+ {
+ public string? MacAddress { get; set; }
+ public string? Language { get; set; }
+ }
+
+ public class BurnCountInfo
+ {
+ public int Count { get; set; }
+ public int DefCount { get; set; }
+ public bool Vip { get; set; }
+ public bool CanWrite { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Payment/PaymentModels.cs b/AIK.Models/ApiModels/Payment/PaymentModels.cs
new file mode 100644
index 0000000..8c788bf
--- /dev/null
+++ b/AIK.Models/ApiModels/Payment/PaymentModels.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace AIK.Models.ApiModels.Payment
+{
+ public class CreateIntegralOrderRequest
+ {
+ public decimal Amount { get; set; }
+ public int PayType { get; set; } = 2;
+ public string? Channel { get; set; }
+ public int? QrCode { get; set; }
+ }
+
+ public class PaymentParameters
+ {
+ public long Id { get; set; }
+ public string? AppId { get; set; }
+ public string? PartnerId { get; set; }
+ public string? PrepayId { get; set; }
+ public string? Package { get; set; }
+ public string? NonceStr { get; set; }
+ public string? TimeStamp { get; set; }
+ public string? Sign { get; set; }
+ public string? Body { get; set; }
+ public string? Token { get; set; }
+ public string? CodeUrl { get; set; }
+ public string? QrCode { get; set; }
+ public string? PayUrl { get; set; }
+ public object? PaymentData { get; set; }
+ }
+
+
+ public class PaymentParametersPC
+ {
+ public long id { get; set; }
+ public string? code_url { get; set; }
+ public string? status { get; set; }
+ public List? links { get; set; }
+
+ public string? PaypalApproveUrl => links?
+ .FirstOrDefault(link => string.Equals(link.rel, "approve", StringComparison.OrdinalIgnoreCase))
+ ?.href;
+ }
+
+ public class PaypalPaymentLink
+ {
+ public string? href { get; set; }
+ public string? rel { get; set; }
+ public string? method { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Record/ApiResponseRecord.cs b/AIK.Models/ApiModels/Record/ApiResponseRecord.cs
new file mode 100644
index 0000000..c79201d
--- /dev/null
+++ b/AIK.Models/ApiModels/Record/ApiResponseRecord.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Record
+{
+ public class ApiResponseRecord : ApiResponse
+ {
+ public List Records { get; set; }
+ public int Total { get; set; }
+ public int Size { get; set; }
+ public int Current { get; set; }
+ public List Orders { get; set; }
+ public bool SearchCount { get; set; }
+ public int Pages { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Record/OrderItem.cs b/AIK.Models/ApiModels/Record/OrderItem.cs
new file mode 100644
index 0000000..1ae185e
--- /dev/null
+++ b/AIK.Models/ApiModels/Record/OrderItem.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Record
+{
+ public class OrderItem
+ {
+ public string Column { get; set; }
+ public bool Asc { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Record/RecordModel.cs b/AIK.Models/ApiModels/Record/RecordModel.cs
new file mode 100644
index 0000000..4536b88
--- /dev/null
+++ b/AIK.Models/ApiModels/Record/RecordModel.cs
@@ -0,0 +1,26 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Record
+{
+ public partial class RecordModel : ObservableObject
+ {
+ public int Id { get; set; }
+ public string DeviceId { get; set; }
+ public int KeyId { get; set; }
+ public string Brand { get; set; }
+ public string Type { get; set; }
+ public string Name { get; set; }
+ public string Img { get; set; }
+ public DateTime CreatedTime { get; set; }
+ public string Zj { get; set; }
+ public string MacAddress { get; set; }
+ public string ToolName { get; set; }
+ [ObservableProperty]
+ private string _localImagePath;
+ }
+}
diff --git a/AIK.Models/ApiModels/TpmsModels/TpmsType.cs b/AIK.Models/ApiModels/TpmsModels/TpmsType.cs
new file mode 100644
index 0000000..a617f3f
--- /dev/null
+++ b/AIK.Models/ApiModels/TpmsModels/TpmsType.cs
@@ -0,0 +1,38 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.TpmsModels
+{
+ public partial class TpmsType : ObservableObject
+ {
+ public int id { get; set; }
+ public string name { get; set; }
+ public string? type { get; set; }
+ public List children { get; set; }=new List();
+ public bool haveChildren { get; set; }
+ public string? py { get; set; }
+ public string? fzm { get; set; }
+ public string? area { get; set; }
+
+ [ObservableProperty]
+ private bool _isSelected;
+ }
+ public partial class TpmsTypeChildren : ObservableObject
+ {
+ public int id { get; set; }
+ public string name { get; set; }
+ public string? type { get; set; }
+ public TpmsTypeChildren children { get; set; }
+ public bool haveChildren { get; set; }
+ public string? py { get; set; }
+ public string? fzm { get; set; }
+ public string? area { get; set; }
+
+ [ObservableProperty]
+ private bool _isSelected;
+ }
+}
diff --git a/AIK.Models/ApiModels/TpmsModels/TpmsTypeDetail.cs b/AIK.Models/ApiModels/TpmsModels/TpmsTypeDetail.cs
new file mode 100644
index 0000000..eadffe2
--- /dev/null
+++ b/AIK.Models/ApiModels/TpmsModels/TpmsTypeDetail.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.TpmsModels
+{
+ [Obsolete]
+ public class TpmsTypeDetail
+ {
+ public string area { get; set; }
+ public string blueName { get; set; }
+ public string createTime { get; set; }
+ public string fwType { get; set; }
+ public string fzm { get; set; }
+ public int id { get; set; }
+ public string name { get; set; }
+ public string nameEn { get; set; }
+ public string nameIn { get; set; }
+ public string namePu { get; set; }
+ public string nameXi { get; set; }
+ public int parentId { get; set; }
+ public string py { get; set; }
+ public string type { get; set; }
+ public string updateTime { get; set; }
+ }
+}
diff --git a/AIK.Models/ApiModels/UserModel.cs b/AIK.Models/ApiModels/UserModel.cs
new file mode 100644
index 0000000..b2d7ec0
--- /dev/null
+++ b/AIK.Models/ApiModels/UserModel.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels
+{
+ public class UserModel
+ {
+ [JsonPropertyName("createTime")]
+ public string CreateTime { get; init; } = string.Empty;
+
+ [JsonPropertyName("deptId")]
+ public int DeptId { get; init; }
+
+ [JsonPropertyName("email")]
+ public string Email { get; init; } = string.Empty;
+
+ [JsonPropertyName("id")]
+ public int Id { get; init; }
+
+ [JsonPropertyName("image")]
+ public string Image { get; init; } = string.Empty;
+
+ [JsonPropertyName("local")]
+ public string Local { get; init; } = string.Empty;
+
+ [JsonPropertyName("nickName")]
+ public string NickName { get; init; } = string.Empty;
+
+ [JsonPropertyName("phone")]
+ public string Phone { get; init; } = string.Empty;
+
+ [JsonPropertyName("remark")]
+ public string Remark { get; init; } = string.Empty;
+
+ [JsonPropertyName("sex")]
+ public string Sex { get; init; } = string.Empty;
+
+ [JsonPropertyName("updateTime")]
+ public string UpdateTime { get; init; } = string.Empty;
+
+ [JsonPropertyName("userName")]
+ public string UserName { get; init; } = string.Empty;
+
+ [JsonPropertyName("userStatus")]
+ public string UserStatus { get; init; } = string.Empty;
+
+ [JsonPropertyName("userType")]
+ public string UserType { get; init; } = string.Empty;
+
+ [JsonPropertyName("uuid")]
+ public string Uuid { get; init; } = string.Empty;
+
+ [JsonPropertyName("workerAccount")]
+ public string WorkerAccount { get; init; } = string.Empty;
+
+ [JsonPropertyName("workerId")]
+ public int WorkerId { get; init; }
+ }
+}
diff --git a/AIK.Models/ApiModels/Version/AppVersionInfo.cs b/AIK.Models/ApiModels/Version/AppVersionInfo.cs
new file mode 100644
index 0000000..9bc8746
--- /dev/null
+++ b/AIK.Models/ApiModels/Version/AppVersionInfo.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace AIK.Models.ApiModels.Version
+{
+ public class AppVersionInfo
+ {
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ [JsonPropertyName("versionName")]
+ public string VersionName { get; set; } = string.Empty;
+
+ [JsonPropertyName("fileUrl")]
+ public string FileUrl { get; set; } = string.Empty;
+
+ [JsonPropertyName("createUser")]
+ public string CreateUser { get; set; } = string.Empty;
+
+ [JsonPropertyName("createTime")]
+ public string CreateTime { get; set; } = string.Empty; // 也可转为 DateTime,见下方说明
+
+ [JsonPropertyName("force")]
+ public bool Force { get; set; }
+
+ [JsonPropertyName("versionCode")]
+ public string VersionCode { get; set; } = string.Empty; // 注意:虽然是数字字符串,但字段名为 "code",常用于比对
+
+ [JsonPropertyName("versionContent")]
+ public string VersionContent { get; set; } = string.Empty;
+
+ [JsonPropertyName("versionEnContent")]
+ public string VersionEnContent { get; set; } = string.Empty;
+
+ [JsonPropertyName("type")]
+ public string Type { get; set; } = string.Empty;
+
+ [JsonPropertyName("fileUrlB")]
+ public string? FileUrlB { get; set; } // 允许 null
+ }
+}
diff --git a/AIK.Models/BannerModels/BannerItem.cs b/AIK.Models/BannerModels/BannerItem.cs
new file mode 100644
index 0000000..15d451e
--- /dev/null
+++ b/AIK.Models/BannerModels/BannerItem.cs
@@ -0,0 +1,18 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Models.BannerModels
+{
+ public partial class BannerItem : ObservableObject
+ {
+ [ObservableProperty] private bool _isSelected;
+ [ObservableProperty] private string? _imagePath;
+ [ObservableProperty] private BitmapImage? _bitmapImage;
+ public int Index { get; set; } // 仅用于命令参数,不参与 UI 触发
+ }
+}
diff --git a/AIK.Models/CarTaiYa/CarfactoryTaiYa.cs b/AIK.Models/CarTaiYa/CarfactoryTaiYa.cs
new file mode 100644
index 0000000..b574fb0
--- /dev/null
+++ b/AIK.Models/CarTaiYa/CarfactoryTaiYa.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.CarTaiYa
+{
+ ///
+ /// 胎压类型
+ ///
+ public class CarfactoryTaiYa
+ {
+ public int id { get; set; }
+ ///
+ /// 车厂名称
+ ///
+ public string name { get; set; }
+ ///
+ /// 拼音
+ ///
+ public string py { get; set; }
+
+ ///
+ /// 子集节点
+ ///
+
+ public List children { get; set; }
+ ///
+ /// 所属区域
+ ///
+ public string area { get; set; }
+ }
+
+ public class Carchildren
+ {
+ public int id { get; set; }
+ ///
+ /// 车辆类型名称
+ ///
+ public string name { get; set; }
+ public List children { get; set; }
+ }
+
+ public class CarTypechildren
+ {
+ public int id { get; set; }
+ ///
+ /// 车辆类型名称
+ ///
+ public string name { get; set; }
+ }
+}
diff --git a/AIK.Models/CarfactoryClass.cs b/AIK.Models/CarfactoryClass.cs
new file mode 100644
index 0000000..ba77fa2
--- /dev/null
+++ b/AIK.Models/CarfactoryClass.cs
@@ -0,0 +1,46 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models
+{
+ ///
+ /// 车牌品牌类
+ ///
+ public partial class CarfactoryClass : ObservableObject
+ {
+ public string id { get; set; }
+ ///
+ /// 中文名称
+ ///
+ public string brandName { get; set; }
+ ///
+ /// 英文
+ ///
+ public string engName { get; set; }
+ ///
+ /// 葡萄牙
+ ///
+ public string puName { get; set; }
+ ///
+ /// 西班牙
+ ///
+ public string xiName { get; set; }
+
+ ///
+ /// 印度
+ ///
+ public string inName { get; set; }
+
+ ///
+ /// 名称拼音
+ ///
+ public string py { get; set; }
+
+ [ObservableProperty]
+ private bool _isSelected;
+ }
+}
diff --git a/AIK.Models/FileModels/FileCacheStats.cs b/AIK.Models/FileModels/FileCacheStats.cs
new file mode 100644
index 0000000..59b7262
--- /dev/null
+++ b/AIK.Models/FileModels/FileCacheStats.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.FileModels
+{
+ public class FileCacheStats
+ {
+ public int TotalCachedFiles { get; set; }
+ public long TotalCacheSizeBytes { get; set; }
+ public string TotalCacheSizeFormatted => FormatFileSize(TotalCacheSizeBytes);
+ public int ExpiredFilesCount { get; set; }
+ public string CacheDirectory { get; set; }
+ public DateTime LastCleanupTime { get; set; }
+ public long AvailableDiskSpaceBytes { get; set; }
+ public string AvailableDiskSpaceFormatted => FormatFileSize(AvailableDiskSpaceBytes);
+ public Dictionary FileTypeCounts { get; set; } = new Dictionary();
+
+ private static string FormatFileSize(long bytes)
+ {
+ string[] sizes = { "B", "KB", "MB", "GB" };
+ int order = 0;
+ double len = bytes;
+ while (len >= 1024 && order < sizes.Length - 1)
+ {
+ order++;
+ len /= 1024;
+ }
+ return $"{len:0.##} {sizes[order]}";
+ }
+ }
+ public class CachedFileInfo
+ {
+ public string FileUrl { get; set; }
+ public string CacheKey { get; set; }
+ public string LocalFilePath { get; set; }
+ public string FileName { get; set; }
+ public string FileExtension { get; set; }
+ public string MimeType { get; set; }
+ public long FileSizeBytes { get; set; }
+ public string FileSizeFormatted => FormatFileSize(FileSizeBytes);
+ public DateTime CreatedTime { get; set; }
+ public DateTime LastAccessTime { get; set; }
+ public int AccessCount { get; set; }
+ public DateTime ExpiryTime { get; set; }
+ public bool IsExpired => ExpiryTime < DateTime.Now;
+ public string FileHash { get; set; }
+ public TimeSpan DownloadTime { get; set; }
+ public bool IsValid { get; set; } = true;
+
+ private static string FormatFileSize(long bytes)
+ {
+ string[] sizes = { "B", "KB", "MB", "GB" };
+ int order = 0;
+ double len = bytes;
+ while (len >= 1024 && order < sizes.Length - 1)
+ {
+ order++;
+ len /= 1024;
+ }
+ return $"{len:0.##} {sizes[order]}";
+ }
+ }
+ public class FileCacheConfig
+ {
+ public TimeSpan DefaultCacheExpiry { get; set; } = TimeSpan.FromDays(30);
+ public long MaxCacheSizeBytes { get; set; } = 2L * 1024 * 1024 * 1024; // 2GB
+ public long MinFreeDiskSpaceBytes { get; set; } = 500L * 1024 * 1024; // 500MB
+ public int MaxRetryCount { get; set; } = 3;
+ public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(2);
+ public TimeSpan HttpClientTimeout { get; set; } = TimeSpan.FromSeconds(60);
+ public string CacheDirectory { get; set; }
+ public bool EnableAutoCleanup { get; set; } = true;
+ public TimeSpan CleanupInterval { get; set; } = TimeSpan.FromHours(1);
+ }
+}
diff --git a/AIK.Models/GuageModels/GaugeModel.cs b/AIK.Models/GuageModels/GaugeModel.cs
new file mode 100644
index 0000000..29083e5
--- /dev/null
+++ b/AIK.Models/GuageModels/GaugeModel.cs
@@ -0,0 +1,27 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.GuageModels
+{
+ public partial class GaugeModel : ObservableObject
+ {
+ [ObservableProperty]
+ private double value;
+
+ [ObservableProperty]
+ private double minValue = 0;
+
+ [ObservableProperty]
+ private double maxValue = 1000;
+
+ [ObservableProperty]
+ private string unit = "HZ";
+
+ [ObservableProperty]
+ private string title = "频率";
+ }
+}
diff --git a/AIK.Models/HidModels/BigPhaseTask.cs b/AIK.Models/HidModels/BigPhaseTask.cs
new file mode 100644
index 0000000..0beed47
--- /dev/null
+++ b/AIK.Models/HidModels/BigPhaseTask.cs
@@ -0,0 +1,19 @@
+using AIK.Common.Enum;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.HidModels
+{
+ ///
+ /// 大阶段任务模型(存储每个大阶段的执行参数)
+ ///
+ public class BigPhaseTask
+ {
+ public BigTransferPhase Phase { get; set; }
+ public bool IsCompleted { get; set; }
+ public string ErrorMessage { get; set; } = string.Empty;
+ }
+}
diff --git a/AIK.Models/HidModels/HidDeviceStatus.cs b/AIK.Models/HidModels/HidDeviceStatus.cs
new file mode 100644
index 0000000..f89b91f
--- /dev/null
+++ b/AIK.Models/HidModels/HidDeviceStatus.cs
@@ -0,0 +1,29 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.HidModels
+{
+ public partial class HidDeviceStatus : ObservableObject
+ {
+ [ObservableProperty]
+ private string _deviceStatusText;
+ [ObservableProperty]
+ private string _deviceStatusColor; // 默认灰色
+ [ObservableProperty]
+ private string _deviceStatusIcon; // 默认未连接图标
+ [ObservableProperty]
+ private bool _deviceStatus; // 默认未连接(连接状态)
+
+ public HidDeviceStatus()
+ {
+ DeviceStatus = false;
+ DeviceStatusText = "未连接";
+ DeviceStatusColor = "#FFF44336";
+ DeviceStatusIcon = "\uE6f9";
+ }
+ }
+}
diff --git a/AIK.Models/HidModels/ReconnectStatus.cs b/AIK.Models/HidModels/ReconnectStatus.cs
new file mode 100644
index 0000000..e1842cb
--- /dev/null
+++ b/AIK.Models/HidModels/ReconnectStatus.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.HidModels
+{
+ ///
+ /// 重连状态信息
+ ///
+ public class ReconnectStatus
+ {
+ public bool IsAutoReconnectEnabled { get; set; }
+ public int ReconnectAttempts { get; set; }
+ public int MaxReconnectAttempts { get; set; }
+ public bool IsMonitoring { get; set; }
+ }
+}
diff --git a/AIK.Models/HidModels/TransferState.cs b/AIK.Models/HidModels/TransferState.cs
new file mode 100644
index 0000000..69768df
--- /dev/null
+++ b/AIK.Models/HidModels/TransferState.cs
@@ -0,0 +1,51 @@
+using AIK.Common.Enum;
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.HidModels
+{
+ public partial class TransferState : ObservableObject
+ {
+ [ObservableProperty]
+ private TransferPhase _currentPhase = TransferPhase.Idle;
+
+ [ObservableProperty]
+ private int _totalPackets;
+
+ [ObservableProperty]
+ private int _currentPacketIndex;
+
+ [ObservableProperty]
+ private int _receivedAckCount;
+
+ [ObservableProperty]
+ private bool _isLastDataFrameSent;
+
+ [ObservableProperty]
+ private string _statusMessage = "空闲";
+
+ [ObservableProperty]
+ private bool _isConnected;
+
+ [ObservableProperty]
+ private bool _isTransferring;
+
+ [ObservableProperty]
+ private bool _isDataConnected;
+
+ public void Reset()
+ {
+ CurrentPhase = TransferPhase.Idle;
+ TotalPackets = 0;
+ CurrentPacketIndex = 0;
+ ReceivedAckCount = 0;
+ IsLastDataFrameSent = false;
+ StatusMessage = "空闲";
+ IsTransferring = false;
+ }
+ }
+}
diff --git a/AIK.Models/HttpPolicy/RetryPolicyConfig.cs b/AIK.Models/HttpPolicy/RetryPolicyConfig.cs
new file mode 100644
index 0000000..0aa09f2
--- /dev/null
+++ b/AIK.Models/HttpPolicy/RetryPolicyConfig.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.HttpPolicy
+{
+ public class RetryPolicyConfig
+ {
+ public int MaxRetryCount { get; set; } = 3;
+ public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(1);
+ public TimeSpan DefaultTimeout { get; set; } = TimeSpan.FromSeconds(30);
+ }
+}
diff --git a/AIK.Models/IsExternalInit.cs b/AIK.Models/IsExternalInit.cs
new file mode 100644
index 0000000..a869ed6
--- /dev/null
+++ b/AIK.Models/IsExternalInit.cs
@@ -0,0 +1,6 @@
+//
+// Polyfill for record types with init-only setters (required by .NET Framework 4.8)
+namespace System.Runtime.CompilerServices
+{
+ internal static class IsExternalInit { }
+}
\ No newline at end of file
diff --git a/AIK.Models/Menus/MenuModel.cs b/AIK.Models/Menus/MenuModel.cs
new file mode 100644
index 0000000..efae1c4
--- /dev/null
+++ b/AIK.Models/Menus/MenuModel.cs
@@ -0,0 +1,39 @@
+using AIK.Common.Enum;
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+
+namespace AIK.Models.Menus
+{
+ public partial class MenuModel : ObservableObject
+ {
+ [ObservableProperty]
+ private bool _isSelected;
+ public int Key { get; set; }
+ private string _menuHeader;
+ public string MenuHeader
+ {
+ get => _menuHeader;
+ set => SetProperty(ref _menuHeader, value);
+ }
+ public string TargetView { get; set; }
+ public string MenuIcon { get; set; }
+ public string ResourceKey { get; set; }
+ [ObservableProperty]
+ private bool _isAuthorized = false;
+ [ObservableProperty]
+ private bool _isShow = true;
+
+ // 添加子菜单集合
+ public ObservableCollection SubItems { get; set; } = new ObservableCollection();
+
+ [ObservableProperty]
+ private bool _isExpanded;
+ public bool HasSubItems => SubItems.Any();
+ }
+}
diff --git a/AIK.Models/SQLiteModels/SQLiteCacheItem.cs b/AIK.Models/SQLiteModels/SQLiteCacheItem.cs
new file mode 100644
index 0000000..49eb000
--- /dev/null
+++ b/AIK.Models/SQLiteModels/SQLiteCacheItem.cs
@@ -0,0 +1,31 @@
+using Dapper.Contrib.Extensions;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.SQLiteModels
+{
+ [Dapper.Contrib.Extensions.Table("CacheItems")]
+ public class CacheItem
+ {
+ [ExplicitKey] // 因为Key是字符串,不是自增ID
+ public string CacheKey { get; set; }
+
+ public string Data { get; set; }
+
+ public string DataType { get; set; }
+
+ public DateTime CreatedAt { get; set; }
+
+ public DateTime ExpiresAt { get; set; }
+
+ public DateTime LastAccessed { get; set; }
+
+ public int AccessCount { get; set; }
+
+ public string Metadata { get; set; } // 存储额外信息,如数据大小等
+ }
+}
diff --git a/AIK.Models/SQLiteModels/SplitCacheKzInfoListItem.cs b/AIK.Models/SQLiteModels/SplitCacheKzInfoListItem.cs
new file mode 100644
index 0000000..e419806
--- /dev/null
+++ b/AIK.Models/SQLiteModels/SplitCacheKzInfoListItem.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.SQLiteModels
+{
+ public class SplitCacheKzInfoListItem
+ {
+ public int ModelListId { get; set; } // 外键:指向 SplitCache_ModelList.Id
+
+ public string binAddress { get; set; } = string.Empty;
+ public string binAddressArray { get; set; } = "[]";
+ public string chipType { get; set; } = string.Empty;
+ public bool cloudRemote { get; set; }
+ public bool dzxp { get; set; }
+ public string firmwareNo { get; set; } = string.Empty;
+ public bool fixedByte { get; set; }
+ public string fixedByteArray { get; set; } = "[]";
+ public string fixedByteArrays { get; set; } = string.Empty;
+ public string sourceUrl { get; set; } = string.Empty;
+ public bool sp { get; set; }
+ public string spCode { get; set; } = string.Empty;
+ public bool tsRand { get; set; }
+ public string tsRandStr { get; set; } = string.Empty;
+ public string type { get; set; } = string.Empty;
+ public bool updateByte { get; set; }
+ public string usable { get; set; } = string.Empty;
+ public string ysSource { get; set; } = string.Empty;
+ public string ysSourceNo { get; set; } = string.Empty;
+ public string zsId { get; set; } = string.Empty;
+ public string CreateTime { get; set; } = string.Empty;
+ }
+}
diff --git a/AIK.Models/SQLiteModels/SplitCacheModelListItem.cs b/AIK.Models/SQLiteModels/SplitCacheModelListItem.cs
new file mode 100644
index 0000000..7307a1a
--- /dev/null
+++ b/AIK.Models/SQLiteModels/SplitCacheModelListItem.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.SQLiteModels
+{
+ public class SplitCacheModelListItem
+ {
+ public int Id { get; set; } // 子表自增主键
+ public int ParentTableId { get; set; } // 关联父表 SplitCache_Parent.Id
+ public string CacheKey { get; set; } = string.Empty; // 关联父表 SplitCache_Parent.CacheKey
+ public int ParentID { get; set; } // 关联 VehModelClass.ID(原外层 ID)
+
+ // VehKeyClass 基础字段
+ public int KeyId { get; set; } // 对应 VehKeyClass.id(注意:原实体 id 对应 KeyId,避免与子表自增 Id 冲突)
+ public string KeyKeyId { get; set; } = string.Empty; // 对应 VehKeyClass.keyId(字段名加前缀避免关键字冲突)
+ public string Name { get; set; } = string.Empty;
+ public string ModelName { get; set; } = string.Empty;
+ public string ModelEngName { get; set; } = string.Empty;
+ public string ModelPuName { get; set; } = string.Empty;
+ public string ModelXiName { get; set; } = string.Empty;
+ public string ModelInName { get; set; } = string.Empty;
+ public string Rate { get; set; } = string.Empty;
+ public string Usable { get; set; } = string.Empty;
+ public string UsableEn { get; set; } = string.Empty;
+ public string UsablePu { get; set; } = string.Empty;
+ public string UsableXi { get; set; } = string.Empty;
+ public string Information { get; set; } = string.Empty;
+ public string PicUrl { get; set; } = string.Empty;
+ public string FirmwareNo { get; set; } = string.Empty;
+ public string SourceUrl { get; set; } = string.Empty;
+ public string SpCode { get; set; } = string.Empty;
+ public string Support { get; set; } = string.Empty;
+ public string ChipType { get; set; } = string.Empty;
+ public string CreateTime { get; set; } = string.Empty;
+
+ // keyMatch 嵌套类展开字段
+ public string KeyMatchContent { get; set; } = string.Empty; // keyMatch.content
+ public string KeyMatchContentEn { get; set; } = string.Empty; // keyMatch.contentEn
+ public string KeyMatchContentPu { get; set; } = string.Empty; // keyMatch.contentPu
+ public string KeyMatchContentXi { get; set; } = string.Empty; // keyMatch.contentXi
+ public string KeyMatchContentIn { get; set; } = string.Empty; // keyMatch.contentIn
+
+ // 其他字段(BitmapImage 为UI字段,不存储;LocalImagePath 存储本地路径)
+ public bool IsSelected { get; set; } = false;
+ public string LocalImagePath { get; set; } = string.Empty;
+ }
+}
diff --git a/AIK.Models/SQLiteModels/SplitCacheParent.cs b/AIK.Models/SQLiteModels/SplitCacheParent.cs
new file mode 100644
index 0000000..d1be1a6
--- /dev/null
+++ b/AIK.Models/SQLiteModels/SplitCacheParent.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.SQLiteModels
+{
+ public class SplitCacheParent
+ {
+ public string CacheKey { get; set; } = string.Empty;
+ public string ParentData { get; set; } = string.Empty;
+ public int SubItemCount { get; set; } = 0;
+ public string DataType { get; set; } = string.Empty;
+ public DateTime CreatedAt { get; set; }
+ public DateTime ExpiresAt { get; set; }
+ public DateTime LastAccessed { get; set; }
+ public int AccessCount { get; set; } = 0;
+ public string Metadata { get; set; } = string.Empty;
+ }
+}
diff --git a/AIK.Models/SystemSettings/ApiSettings.cs b/AIK.Models/SystemSettings/ApiSettings.cs
new file mode 100644
index 0000000..92920a1
--- /dev/null
+++ b/AIK.Models/SystemSettings/ApiSettings.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.SystemSettings
+{
+ public class ApiSettings
+ {
+ // [修改] 私有字段存储原始配置
+ private string _baseUrl = string.Empty;
+
+ // [修改] 公开属性
+ public string BaseUrl
+ {
+ get => _baseUrl;
+ set
+ {
+#if CN
+ //适应域名更改逻辑
+ if (value == "https://key.aik518.com")
+ {
+ _baseUrl = "https://key.aikkey.cn";
+ }
+ else
+ {
+ _baseUrl = value;
+ }
+#else
+ _baseUrl = value; // 非CN环境保持原样
+#endif
+ }
+ }
+ //public string BaseUrl { get; set; } = string.Empty;
+ //public string FileUrl { get; set; } = string.Empty;
+ //public string QRCodeUrl { get; set; } = string.Empty;
+ //public string WSUrl { get; set; } = string.Empty;
+ // --- FileUrl (新增逻辑) ---
+ private string _fileUrl = string.Empty;
+ public string FileUrl
+ {
+ get => _fileUrl;
+ set
+ {
+#if CN
+ // 假设文件服务也在同一个新域名下,如果是不同域名请修改判断条件
+ if (value.Contains("key.aik518.com"))
+ _fileUrl = value.Replace("key.aik518.com", "key.aikkey.cn");
+ else
+ _fileUrl = value;
+#else
+ _fileUrl = value;
+#endif
+ }
+ }
+
+ // --- QRCodeUrl (新增逻辑) ---
+ private string _qrCodeUrl = string.Empty;
+ public string QRCodeUrl
+ {
+ get => _qrCodeUrl;
+ set
+ {
+#if CN
+ if (value.Contains("key.aik518.com"))
+ _qrCodeUrl = value.Replace("key.aik518.com", "key.aikkey.cn");
+ else
+ _qrCodeUrl = value;
+#else
+ _qrCodeUrl = value;
+#endif
+ }
+ }
+
+ // --- WSUrl (新增逻辑) ---
+ private string _wsUrl = string.Empty;
+ public string WSUrl
+ {
+ get => _wsUrl;
+ set
+ {
+#if CN
+ if (value.Contains("key.aik518.com"))
+ _wsUrl = value.Replace("key.aik518.com", "key.aikkey.cn");
+ else
+ _wsUrl = value;
+#else
+ _wsUrl = value;
+#endif
+ }
+ }
+
+ public int Timeout { get; set; } = 30;
+ public int RetryCount { get; set; } = 3;
+ public ApiEndpoints Endpoints { get; set; } = new();
+ public string Language { get; set; } = string.Empty;
+
+ ///
+ /// AI 客服 Web 聊天页 URL(JSBridge 方式加载)
+ ///
+ public string AiWebChatUrl { get; set; } = "http://localhost:1001/chat";
+ }
+
+ public class ApiEndpoints
+ {
+ public string GetCarData { get; set; } = string.Empty;
+ public string GetCarModels { get; set; } = string.Empty;
+ public string GetCarImages { get; set; } = string.Empty;
+ public string Authentication { get; set; } = string.Empty;
+ }
+ public class CacheSettings
+ {
+ public int DataCacheExpiryHours { get; set; } = 3;
+ public int ImageCacheExpiryDays { get; set; } = 7;
+ public int MaxCacheSizeMB { get; set; } = 100;
+
+ public TimeSpan DataCacheExpiry => TimeSpan.FromHours(DataCacheExpiryHours);
+ public TimeSpan ImageCacheExpiry => TimeSpan.FromDays(ImageCacheExpiryDays);
+ public long MaxCacheSizeBytes => MaxCacheSizeMB * 1024L * 1024L;
+ }
+}
diff --git a/AIK.Models/SystemSettings/AppConfig.cs b/AIK.Models/SystemSettings/AppConfig.cs
new file mode 100644
index 0000000..b0d9983
--- /dev/null
+++ b/AIK.Models/SystemSettings/AppConfig.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.SystemSettings
+{
+ public class AppConfig
+ {
+ public string Environment { get; set; } = "Production";
+ public ApiSettings ApiSettings { get; set; } = new();
+ public CacheSettings CacheSettings { get; set; } = new();
+ }
+}
diff --git a/AIK.Models/SystemSettings/LanguageItems.cs b/AIK.Models/SystemSettings/LanguageItems.cs
new file mode 100644
index 0000000..553ccf7
--- /dev/null
+++ b/AIK.Models/SystemSettings/LanguageItems.cs
@@ -0,0 +1,23 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.SystemSettings
+{
+ public partial class LanguageItems : ObservableObject
+ {
+ [ObservableProperty]
+ private string _code;
+ [ObservableProperty]
+ private string _name;
+ [ObservableProperty]
+ private string _nativeName;
+ [ObservableProperty]
+ private string _flagEmoji;
+
+ public override string ToString() => $"{FlagEmoji} {NativeName}";
+ }
+}
diff --git a/AIK.Models/SystemSettings/UserSessionState.cs b/AIK.Models/SystemSettings/UserSessionState.cs
new file mode 100644
index 0000000..57afe51
--- /dev/null
+++ b/AIK.Models/SystemSettings/UserSessionState.cs
@@ -0,0 +1,17 @@
+using AIK.Common.Enum;
+using AIK.Models.ApiModels;
+using AIK.Models.ApiModels.Integral;
+
+namespace AIK.Models.SystemSettings;
+
+public sealed class UserSessionState
+{
+ public bool IsLoggedIn { get; init; }
+ public bool IsQrCodeExpired { get; init; }
+ public string StatusText { get; init; } = string.Empty;
+ public UserStatus UserStatus { get; init; } = UserStatus.NotLoggedIn;
+ public UserModel? UserInfo { get; init; }
+ public IntegralModel? IntegralInfo { get; init; }
+ public byte[]? QrCodeUserBytes { get; init; }
+ public bool CanShowAuthorizedMenus { get; init; }
+}
diff --git a/AIK.Models/SystemSettings/UserSessionStateChangedEventArgs.cs b/AIK.Models/SystemSettings/UserSessionStateChangedEventArgs.cs
new file mode 100644
index 0000000..c4f6336
--- /dev/null
+++ b/AIK.Models/SystemSettings/UserSessionStateChangedEventArgs.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace AIK.Models.SystemSettings;
+
+public sealed class UserSessionStateChangedEventArgs : EventArgs
+{
+ public UserSessionStateChangedEventArgs(UserSessionState state)
+ {
+ State = state;
+ }
+
+ public UserSessionState State { get; }
+}
diff --git a/AIK.Models/UtilsModels/Step/StepItem.cs b/AIK.Models/UtilsModels/Step/StepItem.cs
new file mode 100644
index 0000000..6f5a2bd
--- /dev/null
+++ b/AIK.Models/UtilsModels/Step/StepItem.cs
@@ -0,0 +1,31 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.UtilsModels.Step
+{
+ public partial class StepItem : ObservableObject
+ {
+ [ObservableProperty]
+ private string _stepName;
+
+ [ObservableProperty]
+ private string _iconCode;
+
+ [ObservableProperty]
+ private bool _isActive;
+
+ [ObservableProperty]
+ private bool _isLastStep;
+
+ public StepItem(string name, string icon, bool isLast = false)
+ {
+ StepName = name;
+ IconCode = icon;
+ IsLastStep = isLast;
+ }
+ }
+}
diff --git a/AIK.Models/VehKeyClass.cs b/AIK.Models/VehKeyClass.cs
new file mode 100644
index 0000000..9941588
--- /dev/null
+++ b/AIK.Models/VehKeyClass.cs
@@ -0,0 +1,141 @@
+using AIK.Models.ApiModels.Brand;
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Models
+{
+ ///
+ /// 车钥匙数据类
+ ///
+ public partial class VehKeyClass : ObservableObject
+ {
+ public int parentId { get; set; }
+ public int id { get; set; }
+ public string keyId { get; set; }
+ ///
+ /// 中文名称
+ ///
+ private string name;
+
+ public string Name
+ {
+ get => name;
+ set => SetProperty(ref name, value);
+ }
+ ///
+ /// 中文名称
+ ///
+ public string modelName { get; set; }
+ ///
+ /// 英文名称
+ ///
+ public string modelEngName { get; set; }
+ public string modelPuName { get; set; }
+ public string modelXiName { get; set; }
+ public string modelInName { get; set; }
+ ///
+ /// 频率
+ ///
+ public string rate { get; set; }
+ ///
+ /// 子机中文描述
+ ///
+ public string usable { get; set; }
+ ///
+ /// 子机英文描述
+ ///
+ public string usableEn { get; set; }
+ public string usablePu { get; set; }
+ public string usableXi { get; set; }
+
+ ///
+ /// 参考信息
+ ///
+ public string information { get; set; }
+
+ ///
+ /// 图片路径 分割符,号取第一张
+ ///
+
+ public string picUrl { get; set; }
+ ///
+ /// Bin文件名称 分割符,号取多个
+ ///
+ public string firmwareNo { get; set; }
+ ///
+ /// Bin文件路径 分割符,号取多个
+ ///
+ public string sourceUrl { get; set; }
+
+ ///
+ /// 烧录完成 提示内容 分割符,号 一个文件提示2个比如(1,1 , 1,1) 提示 1,1一起
+ ///
+ public string spCode { get; set; }
+ ///
+ /// (1是K3 MINI 2是 K3 TOOL)只查询包含1和2的
+ ///
+ public string support { get; set; }
+
+ ///
+ /// 芯片
+ ///
+ public string chipType { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public string createTime { get; set; }
+ ///
+ /// 匹配方法描述
+ ///
+ public keyMatch keyMatch { get; set; }
+
+ ///
+ /// 扩展子机
+ ///
+ public List kzInfoList { get; set; }
+
+ private BitmapImage _bitmapImage;
+
+ public BitmapImage BitmapImage
+ {
+ get => _bitmapImage;
+ set => SetProperty(ref _bitmapImage, value);
+ }
+ [ObservableProperty]
+ private bool _isSelected;
+
+ [ObservableProperty]
+ private string _localImagePath;
+
+ [ObservableProperty]
+ private bool _isShowLabel = false;
+
+ [ObservableProperty]
+ private bool _isShowCloudLabel = false;
+
+ [ObservableProperty]
+ private bool _isShowCFLabel = false;
+
+ [ObservableProperty]
+ private string _cloudLabel;
+ }
+
+ ///
+ /// 匹配方法描述
+ ///
+ public class keyMatch
+ {
+ public string content { get; set; }
+ public string contentEn { get; set; }
+ public string contentPu { get; set; }
+ public string contentXi { get; set; }
+ public string contentIn { get; set; }
+
+ }
+}
diff --git a/AIK.Models/VehModelClass.cs b/AIK.Models/VehModelClass.cs
new file mode 100644
index 0000000..5e87153
--- /dev/null
+++ b/AIK.Models/VehModelClass.cs
@@ -0,0 +1,34 @@
+using AIK.Models.ApiModels.Brand;
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models
+{
+ ///
+ /// 车辆品牌钥匙类型以及详情获取
+ ///
+ public partial class VehModelClass : ObservableObject
+ {
+ public int ID { get; set; }
+ ///
+ /// 中文名称
+ ///
+ public string typeName { get; set; }
+ public string typeEngName { get; set; }
+ public string typePuName { get; set; }
+ public string typeXiName { get; set; }
+ public string typeInName { get; set; }
+
+ ///
+ /// 车钥匙详情集合数据
+ ///
+ public List modelList { get; set; }
+
+ [ObservableProperty]
+ private bool _isSelected;
+ }
+}
diff --git a/AIK.Models/VersionClass.cs b/AIK.Models/VersionClass.cs
new file mode 100644
index 0000000..dea2caa
--- /dev/null
+++ b/AIK.Models/VersionClass.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models
+{
+ ///
+ /// 设备固件版本
+ ///
+ public class VersionClass
+ {
+ ///
+ /// 设备固件版本id
+ ///
+ public int id { get; set; }
+ ///
+ /// 固件版本名称
+ ///
+ public string versionName { get; set; }
+ ///
+ /// 固件版本下载地址
+ ///
+ public string fileUrl { get; set; }
+ ///
+ /// 固件版本下载地址B
+ ///
+ public string fileUrlB { get; set; }
+ }
+}
diff --git a/AIK.Models/VideoModels/ShowVideoMessage.cs b/AIK.Models/VideoModels/ShowVideoMessage.cs
new file mode 100644
index 0000000..62421d2
--- /dev/null
+++ b/AIK.Models/VideoModels/ShowVideoMessage.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.VideoModels
+{
+ public class ShowVideoMessage
+ {
+ public string VideoPath { get; set; }
+ public string Title { get; set; }
+ }
+}
diff --git a/AIK.Models/VideoModels/VideoControlMessage.cs b/AIK.Models/VideoModels/VideoControlMessage.cs
new file mode 100644
index 0000000..fcbfe34
--- /dev/null
+++ b/AIK.Models/VideoModels/VideoControlMessage.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.VideoModels
+{
+ public class VideoControlMessage
+ {
+ public enum ControlAction
+ {
+ Play,
+ Pause,
+ Stop,
+ Seek,
+ ToggleFullScreen,
+ SetVolume,
+ }
+
+ public ControlAction Action { get; set; }
+ public TimeSpan? Position { get; set; }
+ public double? Volume { get; set; } // 新增音量参数
+ }
+}
diff --git a/AIK.Models/VideoModels/VolumeChangedMessage.cs b/AIK.Models/VideoModels/VolumeChangedMessage.cs
new file mode 100644
index 0000000..7d8db74
--- /dev/null
+++ b/AIK.Models/VideoModels/VolumeChangedMessage.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Models.VideoModels
+{
+ public class VolumeChangedMessage
+ {
+ public double Volume { get; set; }
+ public bool IsMuted { get; set; }
+ }
+}
diff --git a/AIK.Service/AIK.Service.csproj b/AIK.Service/AIK.Service.csproj
new file mode 100644
index 0000000..c3a0ba9
--- /dev/null
+++ b/AIK.Service/AIK.Service.csproj
@@ -0,0 +1,40 @@
+
+
+
+ net48
+ enable
+ true
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIK.Service/Extensions/FileServiceFactory.cs b/AIK.Service/Extensions/FileServiceFactory.cs
new file mode 100644
index 0000000..7dc2b45
--- /dev/null
+++ b/AIK.Service/Extensions/FileServiceFactory.cs
@@ -0,0 +1,33 @@
+using AIK.Common.Enum;
+using AIK.Service.IService;
+using AIK.Service.Service;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.Extensions
+{
+ public class FileServiceFactory : IFileServiceFactory
+ {
+ private readonly FileOBDService _obdService;
+ private readonly FileBinService _binService;
+ private readonly FileCloudDataService _cloudDataService;
+
+ public FileServiceFactory(FileOBDService obdService, FileBinService binService, FileCloudDataService cloudDataService)
+ {
+ _obdService = obdService;
+ _binService = binService;
+ _cloudDataService = cloudDataService;
+ }
+
+ public IFileCacheService GetService(FileServiceType type) => type switch
+ {
+ FileServiceType.BIN => _binService,
+ FileServiceType.OBD => _obdService,
+ FileServiceType.CloudData => _cloudDataService,
+ _ => throw new ArgumentException("Unsupported type")
+ };
+ }
+}
diff --git a/AIK.Service/Extensions/ICloseRequestAware.cs b/AIK.Service/Extensions/ICloseRequestAware.cs
new file mode 100644
index 0000000..56bd227
--- /dev/null
+++ b/AIK.Service/Extensions/ICloseRequestAware.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.Extensions
+{
+ public interface ICloseRequestAware
+ {
+ event EventHandler RequestClose;
+ }
+}
diff --git a/AIK.Service/Extensions/IFileServiceFactory.cs b/AIK.Service/Extensions/IFileServiceFactory.cs
new file mode 100644
index 0000000..0d9df7a
--- /dev/null
+++ b/AIK.Service/Extensions/IFileServiceFactory.cs
@@ -0,0 +1,15 @@
+using AIK.Common.Enum;
+using AIK.Service.IService;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.Extensions
+{
+ public interface IFileServiceFactory
+ {
+ IFileCacheService GetService(FileServiceType type);
+ }
+}
diff --git a/AIK.Service/Extensions/IWindowFactory.cs b/AIK.Service/Extensions/IWindowFactory.cs
new file mode 100644
index 0000000..4345d04
--- /dev/null
+++ b/AIK.Service/Extensions/IWindowFactory.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace AIK.Service.Extensions
+{
+ public interface IWindowFactory
+ {
+ // 新增:基于Type的方法
+ Window CreateWindow(Type windowType);
+ Window CreateWindow(Type windowType, Type viewModelType, object viewModel = null);
+ }
+}
diff --git a/AIK.Service/Extensions/WindowFactory.cs b/AIK.Service/Extensions/WindowFactory.cs
new file mode 100644
index 0000000..b075a2f
--- /dev/null
+++ b/AIK.Service/Extensions/WindowFactory.cs
@@ -0,0 +1,39 @@
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace AIK.Service.Extensions
+{
+ public class WindowFactory : IWindowFactory
+ {
+ private readonly IServiceProvider _serviceProvider;
+
+ public WindowFactory(IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ }
+
+ public Window CreateWindow(Type windowType)
+ {
+ return (Window)_serviceProvider.GetRequiredService(windowType);
+ }
+
+ public Window CreateWindow(Type windowType, Type viewModelType, object viewModel = null)
+ {
+ var window = (Window)_serviceProvider.GetRequiredService(windowType);
+
+ //if (viewModel != null && window.DataContext == null)
+ //{
+ // window.DataContext = viewModel;
+ //}
+
+ return window;
+ }
+
+ }
+}
diff --git a/AIK.Service/IService/IAikDataService.cs b/AIK.Service/IService/IAikDataService.cs
new file mode 100644
index 0000000..1e38916
--- /dev/null
+++ b/AIK.Service/IService/IAikDataService.cs
@@ -0,0 +1,67 @@
+using AIK.Common.SysCommon;
+using AIK.Models;
+using AIK.Models.ApiModels;
+using AIK.Models.ApiModels.Banner;
+using AIK.Models.ApiModels.Burn;
+using AIK.Models.ApiModels.CloudData;
+using AIK.Models.ApiModels.Integral;
+using AIK.Models.ApiModels.Record;
+using AIK.Models.ApiModels.TpmsModels;
+using AIK.Models.ApiModels.Version;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IAikDataService
+ {
+ Task GetUserInfo(string token);
+
+ Task?> GetBanner(string languagecode = "");
+
+ Task GetUserIntegral(string token);
+
+ Task GetUserIntegralHistroy(string token);
+
+ Task GetAppVersionInfo(string type);
+
+ /// 账密登录:成功时 Message 为 JWT Token,失败时 Message 为错误信息。
+ Task<(bool Success, string Message)> LoginByAccountAsync(string account, string code, string password, string type);
+
+ /// 发送注册验证码(手机号):GET /work_sms/sms/send_code,成功(code=1)Message 为空。
+ Task<(bool Success, string Message)> SendRegisterCodeAsync(string phone);
+
+ /// 发送登录验证码(手机号):GET /work_sms/sms/send_login,成功(code=1)Message 为空。
+ Task<(bool Success, string Message)> SendLoginCodeAsync(string phone);
+
+ /// 验证验证码(手机号):GET /work_sms/sms/check_code,参数 code/phone/type(可选)。
+ Task<(bool Success, string Message)> CheckVerifyCodeAsync(string phone, string code, string type = "");
+
+ /// 发送邮箱验证码:GET /work_sms/email/send_code,参数 address/type(语言,可选),成功(code=1)。
+ Task<(bool Success, string Message)> SendEmailCodeAsync(string address, string type = "");
+
+ /// 验证邮箱验证码:GET /work_sms/email/check_code,参数 address/code,成功(code=1)。
+ Task<(bool Success, string Message)> CheckEmailCodeAsync(string address, string code);
+
+ /// 手机号注册(code 验证码 + phone + psw 必填):成功(code=1)返回 true,失败 Message 为错误信息。
+ Task<(bool Success, string Message)> RegisterByPhoneAsync(string code, string phone, string psw, string nickName = "", string sex = "", string local = "", string image = "");
+
+ /// 邮箱注册(code 验证码 + email + psw 必填):成功(code=1)返回 true,失败 Message 为错误信息。
+ Task<(bool Success, string Message)> RegisterByEmailAsync(string code, string email, string psw, string nickName = "", string sex = "", string local = "", string image = "");
+
+ Task> GetBannerCache();
+
+ Task GetKeyLogList(string token, int currentindex = 1, int pagesize = 20);
+
+ Task BurnAddInfo(string token, BurnItem burnItem);
+
+ Task AddIntegral(string token, BurnKeyItem burnKeyItem);
+
+ Task GetOssDataCache(string token, string ossType="K3tool_bin");
+
+ Task> GetTpmsType(string token,int? id);
+ }
+}
diff --git a/AIK.Service/IService/ICarfactoryService.cs b/AIK.Service/IService/ICarfactoryService.cs
new file mode 100644
index 0000000..86a9d09
--- /dev/null
+++ b/AIK.Service/IService/ICarfactoryService.cs
@@ -0,0 +1,46 @@
+using AIK.Models;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Service.IService
+{
+ public interface ICarfactoryService
+ {
+ ///
+ /// 获取车辆品牌数据
+ ///
+ ///
+ ///
+ public List GetCarfactoryClassList(string vhetype);
+
+ public Task> GetCarfactoryClassListAsync(string vhetype);
+ ///
+ /// 获取车辆钥匙数据
+ ///
+ ///
+ ///
+ public List GetVehKeyClassList(int id);
+
+ public Task> GetVehKeyClassListAsync(int id);
+
+ ///
+ /// 获取K3TOOL和K3Genie固件版本数据 copying(k3mini),i2(k3tool),k3_jingling
+ ///
+ ///
+ public List GetVersionClass(string type);
+
+ ///
+ /// 获取钥匙图片
+ ///
+ ///
+ ///
+ public Task GetVehKeyImg(string url);
+
+ }
+}
diff --git a/AIK.Service/IService/IConfigurationService.cs b/AIK.Service/IService/IConfigurationService.cs
new file mode 100644
index 0000000..d7c8e88
--- /dev/null
+++ b/AIK.Service/IService/IConfigurationService.cs
@@ -0,0 +1,25 @@
+using AIK.Models.SystemSettings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IConfigurationService
+ {
+ string Environment { get; }
+ ApiSettings ApiSettings { get; }
+ CacheSettings CacheSettings { get; }
+ T GetSection(string sectionName) where T : new();
+ string GetConnectionString(string name);
+
+ // 新增方法
+ Task UpdateLanguageAsync(string languageCode);
+ Task UpdateApiSettingsAsync(Action updateAction);
+ Task UpdateCacheSettingsAsync(Action updateAction);
+ Task SaveConfigurationAsync();
+ Task ReloadConfigurationAsync();
+ }
+}
diff --git a/AIK.Service/IService/IDataCacheService.cs b/AIK.Service/IService/IDataCacheService.cs
new file mode 100644
index 0000000..318df12
--- /dev/null
+++ b/AIK.Service/IService/IDataCacheService.cs
@@ -0,0 +1,42 @@
+using AIK.Models;
+using AIK.Models.ApiModels;
+using AIK.Models.SQLiteModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IDataCacheService
+ {
+ Task GetOrCreateAsync(string key, Func> dataFetchFunc, TimeSpan expiry) where T : class;
+ Task GetAsync(string key) where T : class;
+ Task SetAsync(string key, T data, TimeSpan expiry) where T : class;
+ Task ExistsAsync(string key);
+ Task RemoveAsync(string key);
+ Task ClearExpiredAsync();
+ Task ClearAllAsync();
+ Task> GetCacheStatsAsync();
+ Task GetCacheSizeAsync();
+
+ #region 钥匙模型缓存专用
+ Task> GetSplitVehModelDataAsync(string cacheKey);
+ Task SetSplitVehModelDataAsync(string cacheKey, VehModelClass vehModel, TimeSpan expiry);
+ Task DeleteSplitVehModelDataAsync(string cacheKey);
+ Task ClearSplitCacheExpiredAsync();
+ #endregion
+
+ #region 用户Token缓存专用
+ Task StoreUserTokenAsync(string token, TimeSpan? expiry = null);
+ Task IsUserTokenValidAsync(string token);
+ Task ClearUserTokenAsync();
+ Task ClearExpiredUserTokensAsync();
+ Task GetLatestUserTokenAsync();
+ Task StoreUserInfoAsync(UserModel user);
+ Task ClearUserInfoAsync();
+ Task GetUserInfoAsync();
+ #endregion
+ }
+}
diff --git a/AIK.Service/IService/IFileCacheService.cs b/AIK.Service/IService/IFileCacheService.cs
new file mode 100644
index 0000000..11e03d3
--- /dev/null
+++ b/AIK.Service/IService/IFileCacheService.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Service.IService
+{
+ public interface IFileCacheService
+ {
+ ///
+ /// 异步获取文件。优先从缓存中获取,若不存在或已过期则从网络下载。
+ ///
+ /// 第三方文件地址
+ /// 自定义缓存键(可选)
+ /// 缓存的文件数据
+ Task GetFileByteAsync(string fileUrl, string cacheKey = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// 带进度的文件下载方法。优先从缓存中获取,若不存在或已过期则从网络下载。
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task<(bool success, string localFilePath)> DownloadFileWithProgressAsync(string fileUrl, string cacheKey, IProgress progress = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// 清除所有过期的缓存文件。(bin文件默认无过期期限)
+ ///
+ Task ClearExpiredCacheAsync();
+
+ ///
+ /// 强制清除所有缓存(内存和磁盘)。
+ ///
+ Task ClearAllCacheAsync();
+ }
+}
diff --git a/AIK.Service/IService/IFileOperationService.cs b/AIK.Service/IService/IFileOperationService.cs
new file mode 100644
index 0000000..2ef58c0
--- /dev/null
+++ b/AIK.Service/IService/IFileOperationService.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IFileOperationService
+ {
+ Task ExtractSingleArchiveAsync(
+ string archivePath,
+ string destinationDir,
+ bool overwrite = true,
+ CancellationToken cancellationToken = default);
+
+ Task ExtractMultipleArchivesAsyncNotPoress(
+ IEnumerable archivePaths,
+ string destinationDir,
+ bool overwrite = true,
+ CancellationToken cancellationToken = default);
+
+ Task ExtractMultipleArchivesAsync(
+ IReadOnlyList archivePaths,
+ string destinationDir,
+ IProgress progress,
+ bool overwrite = true,
+ CancellationToken cancellationToken = default);
+ }
+}
diff --git a/AIK.Service/IService/IHidCommunicationService.cs b/AIK.Service/IService/IHidCommunicationService.cs
new file mode 100644
index 0000000..e9a7e89
--- /dev/null
+++ b/AIK.Service/IService/IHidCommunicationService.cs
@@ -0,0 +1,124 @@
+using AIK.Common.Enum;
+using AIK.Common.Event;
+using AIK.Models.HidModels;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IHidCommunicationService
+ {
+ bool IsConnected { get; }
+ TransferState State { get; }
+
+ event EventHandler? ResponseReceived;
+ event EventHandler? LogMessage;
+ event EventHandler? ConnectionStateChanged;
+
+ Task ConnectAsync(int vendorId = 0x28E9, int productId = 0xFFF0);
+ Task ReconnectNowAsync();
+ Task DisconnectAsync();
+ ///
+ /// 发送设备分包基础帧(头帧/数据帧/结束帧等)
+ ///
+ ///
+ ///
+ Task SendAsync(byte[] data);
+
+ ///
+ /// 根据本地路径烧录文件
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task<(bool, string)> SendFileAsync(string filePath, IProgress progress, CancellationToken ct);
+ ///
+ /// 根据文件名称和文件二进制数据烧录文件
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task<(bool, string)> SendFileAsync(string fileName, byte[] filebin, IProgress progress, CancellationToken ct);
+
+ ///
+ /// 附加烧录流程阶段(连接/生成/写入)
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task<(bool, string)> SendFileProcessAsync(string fileName, byte[] filebin, IProgress progress, CancellationToken ct);
+
+ ///
+ /// 附加烧录流程阶段-固件升级(连接/生成/写入)
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task<(bool, string)> SendFileProcessAsync(string fileName, byte[] filebin, HidOperationTypeEnum hidOperationType, IProgress progress, CancellationToken ct);
+
+ Task<(bool, string)> GetDeviceVersion(HidOperationTypeEnum hidOperationType);
+
+ ///
+ /// K3Tool盘符获取
+ ///
+ ///
+ ///
+ ///
+ Task FindAssociatedUsbDisk(int vendorId = 0x28E9, int productId = 0xFFF0);
+
+ ///
+ /// 复制文件或文件夹到U盘
+ ///
+ ///
+ ///
+ ///
+ Task<(bool, string)> CopyToUdiskAsync(string sourcePath, bool isDirectory, IProgress progress, CancellationToken cts);
+ ///
+ /// 打开U盘并检测盘符
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task OpenUDiskAndDetectDriveAsync(int maxWaitSeconds = 15, int pollIntervalMs = 500, CancellationToken cancellationToken = default);
+
+ ///
+ /// 关闭U盘
+ ///
+ ///
+ ///
+ Task CloseUDiskSafeDriveAsync(string targetDrive = "");
+
+ Task KeepDeviceAliveAsync();
+
+ public Task CopyDeltaDirectoryToUdiskAsync(
+ string localRootDir,
+ IProgress progress,
+ CancellationToken ct);
+
+ public Task> ScanUdiskFilesAsync(CancellationToken ct);
+
+ public Dictionary ScanLocalFiles(string localRootDir);
+
+ public List GetChangedFiles(
+ Dictionary localFiles,
+ Dictionary udiskFiles);
+
+ public Task<(string zipPath, int count)> CreateDeltaZipAsync(
+ string localRootDir,
+ List changedRelativePaths,
+ CancellationToken ct);
+ }
+}
diff --git a/AIK.Service/IService/IHttpClientService.cs b/AIK.Service/IService/IHttpClientService.cs
new file mode 100644
index 0000000..1afb5bb
--- /dev/null
+++ b/AIK.Service/IService/IHttpClientService.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IHttpClientService
+ {
+ Task GetWithTimeoutAsync(string url, TimeSpan? timeout = null, CancellationToken cancellationToken = default);
+ Task PostWithTimeoutAsync(string url, HttpContent content, TimeSpan? timeout = null, CancellationToken cancellationToken = default);
+ Task GetStringWithTimeoutAsync(string url, TimeSpan? timeout = null, CancellationToken cancellationToken = default);
+ Task PostJsonWithTimeoutAsync(string url, string jsonData, TimeSpan? timeout = null, CancellationToken cancellationToken = default);
+ Task GetByteArrayWithTimeoutAsync(string url, TimeSpan? timeout = null, CancellationToken cancellationToken = default);
+
+ Task GetStringWithTimeoutAndTokenAsync(string url, string token, TimeSpan? timeout = null, CancellationToken cancellationToken = default);
+ Task PostJsonWithTimeoutAndTokenAsync(string url, string jsonData, string token, TimeSpan? timeout = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// 流式下载文件到指定路径。内部通过 BouncyCastleTlsHandler 的流式通道逐段读取,
+ /// 每段读取带空闲超时、无总时长限制,适合大文件下载。失败抛出异常(由调用方决定重试)。
+ /// 支持断点续传:传入 resumeOffset(已下载字节数)时自动携带 Range 头并从文件末尾追加写入。
+ ///
+ /// 文件下载地址
+ /// 目标文件路径(不存在则创建;resumeOffset>0 时追加写入)
+ /// 下载进度 0-100
+ /// 取消令牌
+ /// 已下载字节数(断点续传偏移,0 表示从头下载)
+ Task DownloadToFileWithProgressAsync(string url, string filePath, IProgress progress = null, CancellationToken cancellationToken = default, long resumeOffset = 0);
+ }
+}
diff --git a/AIK.Service/IService/IImageCacheService.cs b/AIK.Service/IService/IImageCacheService.cs
new file mode 100644
index 0000000..0d5f34e
--- /dev/null
+++ b/AIK.Service/IService/IImageCacheService.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Service.IService
+{
+ public interface IImageCacheService
+ {
+ ///
+ /// 异步获取图片。优先从缓存中获取,若不存在或已过期则从网络下载。
+ ///
+ /// 第三方图片地址
+ /// 自定义缓存键(可选)
+ /// 缓存的图片
+ Task GetImageAsync(string imageUrl, string cacheKey = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// 异步获取图片。优先从缓存中获取,若不存在或已过期则从网络下载。
+ ///
+ /// 第三方图片地址
+ /// 自定义缓存键(可选)
+ /// 缓存的图片
+ Task GetImageByLocalPathAsync(string imageUrl, string cacheKey = null, CancellationToken cancellationToken = default);
+ ///
+ /// 返回本地存储的文件路径
+ ///
+ ///
+ ///
+ ///
+ /// 缓存的图片文件本地路径
+ Task GetImagePathAsync(string imageUrl, string cacheKey = null, CancellationToken cancellationToken = default);
+ ///
+ /// 清除所有过期的缓存文件。
+ ///
+ Task ClearExpiredCacheAsync();
+
+ ///
+ /// 强制清除所有缓存(内存和磁盘)。
+ ///
+ Task ClearAllCacheAsync();
+ }
+}
diff --git a/AIK.Service/IService/ILoadAware.cs b/AIK.Service/IService/ILoadAware.cs
new file mode 100644
index 0000000..effdc25
--- /dev/null
+++ b/AIK.Service/IService/ILoadAware.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface ILoadAware
+ {
+ ///
+ /// 页面加载完成后异步初始化
+ ///
+ Task OnLoadedAsync();
+ }
+}
diff --git a/AIK.Service/IService/ILocalizationService.cs b/AIK.Service/IService/ILocalizationService.cs
new file mode 100644
index 0000000..540c5ba
--- /dev/null
+++ b/AIK.Service/IService/ILocalizationService.cs
@@ -0,0 +1,23 @@
+using AIK.Models.SystemSettings;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface ILocalizationService
+ {
+ CultureInfo CurrentCulture { get; }
+ IEnumerable SupportedCultures { get; }
+ IEnumerable SupportedLanguages { get; }
+ event EventHandler LanguageChanged;
+ Task InitializeAsync(string language);
+ void SetLanguage(string cultureName);
+ string GetString(string key);
+ string GetString(string key, CultureInfo culture);
+ }
+
+}
diff --git a/AIK.Service/IService/ILogService.cs b/AIK.Service/IService/ILogService.cs
new file mode 100644
index 0000000..f3e5ad6
--- /dev/null
+++ b/AIK.Service/IService/ILogService.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface ILogService
+ {
+ void LogDebug(string message, params object[] args);
+ void LogInformation(string message, params object[] args);
+ void LogWarning(string message, params object[] args);
+ void LogError(Exception? exception, string message, params object[] args);
+ void LogError(string message, params object[] args);
+
+ IReadOnlyList GetRecentLogs(int maxCount = 100);
+ Task UploadLogsAsync();
+ void ClearBuffer();
+ }
+}
diff --git a/AIK.Service/IService/IMembershipService.cs b/AIK.Service/IService/IMembershipService.cs
new file mode 100644
index 0000000..49da9c0
--- /dev/null
+++ b/AIK.Service/IService/IMembershipService.cs
@@ -0,0 +1,20 @@
+using AIK.Models.ApiModels;
+using AIK.Models.ApiModels.Membership;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IMembershipService
+ {
+ Task> GetModuleListAsync(string model = "key", CancellationToken cancellationToken = default);
+ Task> FindOpenedFunctionsAsync(string token, MembershipFindRequest request, CancellationToken cancellationToken = default);
+ Task> OpenFunctionAsync(string token, OpenMembershipRequest request, CancellationToken cancellationToken = default);
+ Task BindDeviceAsync(string token, BindMembershipDeviceRequest request, CancellationToken cancellationToken = default);
+ Task CheckPermissionAsync(string token, CheckMembershipPermissionRequest request, CancellationToken cancellationToken = default);
+ Task ActivateDeviceAsync(string token, ActivateDeviceRequest request, CancellationToken cancellationToken = default);
+ Task GetBurnCountInfoAsync(string token, CancellationToken cancellationToken = default);
+ Task AddBurnCountAsync(string token, string type = "ysjs", CancellationToken cancellationToken = default);
+ }
+}
\ No newline at end of file
diff --git a/AIK.Service/IService/IPaymentOrderService.cs b/AIK.Service/IService/IPaymentOrderService.cs
new file mode 100644
index 0000000..3819372
--- /dev/null
+++ b/AIK.Service/IService/IPaymentOrderService.cs
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+using System.Threading;
+using AIK.Models.ApiModels.Payment;
+
+namespace AIK.Service.IService
+{
+ public interface IPaymentOrderService
+ {
+ Task CreateIntegralOrderAsync(string token, CreateIntegralOrderRequest request, CancellationToken cancellationToken = default);
+ Task GetOrderPayStatusAsync(long orderId, int type = 2, CancellationToken cancellationToken = default);
+ Task RefreshPaypalOrderAsync(long orderId, int type = 2, CancellationToken cancellationToken = default);
+ }
+}
diff --git a/AIK.Service/IService/IRetryPolicyService.cs b/AIK.Service/IService/IRetryPolicyService.cs
new file mode 100644
index 0000000..d946591
--- /dev/null
+++ b/AIK.Service/IService/IRetryPolicyService.cs
@@ -0,0 +1,16 @@
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService
+{
+ public interface IRetryPolicyService
+ {
+ Task ExecuteWithRetryAsync(Func> operation, string operationName, CancellationToken cancellationToken = default);
+ Task ExecuteWithRetryAsync(Func operation, string operationName, CancellationToken cancellationToken = default);
+ }
+}
diff --git a/AIK.Service/IService/IUserSessionCoordinator.cs b/AIK.Service/IService/IUserSessionCoordinator.cs
new file mode 100644
index 0000000..e64a971
--- /dev/null
+++ b/AIK.Service/IService/IUserSessionCoordinator.cs
@@ -0,0 +1,18 @@
+using AIK.Models.SystemSettings;
+using System;
+using System.Threading.Tasks;
+
+namespace AIK.Service.IService;
+
+public interface IUserSessionCoordinator
+{
+ event EventHandler? StateChanged;
+
+ Task InitializeAsync();
+ Task LogoutAsync();
+ Task RefreshQrCodeAsync();
+ Task RefreshIntegralAsync();
+
+ /// 账密登录成功后写入会话(保存 Token、拉取用户信息与积分并发布登录状态),返回是否成功。
+ Task LoginWithTokenAsync(string token);
+}
diff --git a/AIK.Service/IService/IVehDataService.cs b/AIK.Service/IService/IVehDataService.cs
new file mode 100644
index 0000000..f3df692
--- /dev/null
+++ b/AIK.Service/IService/IVehDataService.cs
@@ -0,0 +1,36 @@
+using AIK.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace AIK.Service.IService
+{
+ public interface IVehDataService
+ {
+ Task> GetVehDataAsync(string vhetype, bool forceRefresh = false);
+ Task> GetVehDataFromApiAsync(string vhetype);
+ Task IsCacheValidAsync();
+ Task ClearCacheAsync();
+ Task GetCacheInfoAsync();
+
+ Task> GetVehKeyDataAsync(int id, bool forceRefresh = false);
+ Task> GetVehKeyDataFromApiAsync(int id);
+
+ Task GetVehKeyImgAsync(string url, bool forceRefresh = false);
+ Task GetVehKeyImgDataFromApiAsync(string url);
+
+ Task> GetVehKeyDataByIdAsync(int id);
+
+ }
+ public class CacheInfo
+ {
+ public bool IsValid { get; set; }
+ public DateTime? LastUpdateTime { get; set; }
+ public int DataCount { get; set; }
+ public long CacheSize { get; set; }
+ public TimeSpan? TimeToExpire { get; set; }
+ }
+}
diff --git a/AIK.Service/IService/IWindowService.cs b/AIK.Service/IService/IWindowService.cs
new file mode 100644
index 0000000..07f2797
--- /dev/null
+++ b/AIK.Service/IService/IWindowService.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace AIK.Service.IService
+{
+ public interface IWindowService
+ {
+
+ void Show(string windowKey);
+ void Show(string windowKey, TViewModel viewModel) where TViewModel : class;
+ void Show(string windowKey, TViewModel viewModel, Action initializeAction) where TViewModel : class;
+ bool? ShowDialog(string windowKey);
+ bool? ShowDialog(string windowKey, TViewModel viewModel) where TViewModel : class;
+
+ void RegisterWindow(string windowKey, Type windowType, Type viewModelType = null);
+ }
+
+ public static class WindowKey
+ {
+ public const string VideoPopup = "VideoPopup";
+ // 添加更多窗口键...
+ }
+}
diff --git a/AIK.Service/Interop/WindowsVolumeEjector.cs b/AIK.Service/Interop/WindowsVolumeEjector.cs
new file mode 100644
index 0000000..6e4c0c6
--- /dev/null
+++ b/AIK.Service/Interop/WindowsVolumeEjector.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.Interop
+{
+ ///
+ /// P/Invoke 方法实现 Windows 卷弹出功能
+ ///
+ internal static class WindowsVolumeEjector
+ {
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ private static extern IntPtr CreateFile(
+ string lpFileName,
+ uint dwDesiredAccess,
+ uint dwShareMode,
+ IntPtr lpSecurityAttributes,
+ uint dwCreationDisposition,
+ uint dwFlagsAndAttributes,
+ IntPtr hTemplateFile);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern bool DeviceIoControl(
+ IntPtr hDevice,
+ uint dwIoControlCode,
+ IntPtr lpInBuffer,
+ uint nInBufferSize,
+ IntPtr lpOutBuffer,
+ uint nOutBufferSize,
+ out uint lpBytesReturned,
+ IntPtr lpOverlapped);
+
+ [DllImport("kernel32.dll")]
+ private static extern bool CloseHandle(IntPtr hObject);
+
+ private const uint GENERIC_READ = 0x80000000;
+ private const uint FILE_SHARE_READ = 0x1;
+ private const uint FILE_SHARE_WRITE = 0x2;
+ private const uint OPEN_EXISTING = 3;
+ private const uint FSCTL_DISMOUNT_VOLUME = 0x00090020;
+ private const uint IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
+
+ public static async Task EjectVolumeAsync(string driveLetter)
+ {
+ return await Task.Run(() =>
+ {
+ if (string.IsNullOrEmpty(driveLetter))
+ return false;
+
+ // 标准化输入:确保是 "X:" 或 "X:\"
+ string cleanDrive = driveLetter.TrimEnd('\\');
+ if (!cleanDrive.EndsWith(":"))
+ return false;
+
+ string devicePath = @"\\.\" + cleanDrive + @"\";
+ IntPtr handle = IntPtr.Zero;
+
+ try
+ {
+ handle = CreateFile(devicePath, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
+
+ if (handle == IntPtr.Zero || handle == new IntPtr(-1))
+ {
+ var errorCode = Marshal.GetLastWin32Error();
+ // 可记录日志:$"CreateFile failed with error {errorCode}"
+ return false;
+ }
+
+ // 尝试卸载卷(可选,提高成功率)
+ DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME,
+ IntPtr.Zero, 0, IntPtr.Zero, 0, out _, IntPtr.Zero);
+
+ // 弹出介质
+ bool result = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA,
+ IntPtr.Zero, 0, IntPtr.Zero, 0, out _, IntPtr.Zero);
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ // 可记录异常
+ return false;
+ }
+ finally
+ {
+ if (handle != IntPtr.Zero && handle != new IntPtr(-1))
+ {
+ CloseHandle(handle);
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/AIK.Service/IsExternalInit.cs b/AIK.Service/IsExternalInit.cs
new file mode 100644
index 0000000..a869ed6
--- /dev/null
+++ b/AIK.Service/IsExternalInit.cs
@@ -0,0 +1,6 @@
+//
+// Polyfill for record types with init-only setters (required by .NET Framework 4.8)
+namespace System.Runtime.CompilerServices
+{
+ internal static class IsExternalInit { }
+}
\ No newline at end of file
diff --git a/AIK.Service/Service/AikDataService.cs b/AIK.Service/Service/AikDataService.cs
new file mode 100644
index 0000000..6f2c866
--- /dev/null
+++ b/AIK.Service/Service/AikDataService.cs
@@ -0,0 +1,621 @@
+using System.Threading.Tasks;
+using System.Threading;
+using AIK.Common.Interface;
+using AIK.Common.SysCommon;
+using AIK.Common.SysCommon.UserCommon;
+using AIK.Models;
+using AIK.Models.ApiModels;
+using AIK.Models.ApiModels.Banner;
+using AIK.Models.ApiModels.Burn;
+using AIK.Models.ApiModels.CloudData;
+using AIK.Models.ApiModels.Integral;
+using AIK.Models.ApiModels.Record;
+using AIK.Models.ApiModels.TpmsModels;
+using AIK.Models.ApiModels.Version;
+using AIK.Models.BannerModels;
+using AIK.Models.HttpPolicy;
+using AIK.Service.IService;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Security.AccessControl;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AIK.Service.Service
+{
+ public class AikDataService : IAikDataService
+ {
+ private readonly IDataCacheService _cacheService;
+ private readonly IHttpClientFactory _httpClientFactory;
+ private readonly IConfigurationService _configurationService;
+ private readonly ILogger _logger;
+ private readonly IRetryPolicyService _retryPolicyService;
+ private readonly RetryPolicyConfig _retryConfig;
+ private readonly IHttpClientService _httpClientService;
+ private readonly ISettingsService _settingsService;
+
+ private const string CacheKey_Banner = "banner_data";
+ private readonly TimeSpan _cacheExpiry = TimeSpan.FromHours(3);//默认3个小时有效期
+
+ // 通过构造函数注入
+ public AikDataService(IDataCacheService cacheService, IHttpClientFactory httpClientFactory, ILogger logger, IConfigurationService configurationService, IRetryPolicyService retryPolicyService, IHttpClientService httpClientService, ISettingsService settingsService)
+ {
+ _cacheService = cacheService;
+ _httpClientFactory = httpClientFactory;
+ _configurationService = configurationService;
+ _logger = logger;
+ _retryPolicyService = retryPolicyService;
+ _httpClientService = httpClientService;
+ _retryConfig = new RetryPolicyConfig
+ {
+ MaxRetryCount = 3,
+ RetryDelay = TimeSpan.FromSeconds(1),
+ DefaultTimeout = TimeSpan.FromSeconds(15)
+ };
+ _cacheExpiry = TimeSpan.FromHours(_configurationService.CacheSettings.DataCacheExpiryHours);
+ _settingsService = settingsService;
+ }
+ #region App版本相关
+ public async Task GetAppVersionInfo(string type)
+ {
+ return await _retryPolicyService.ExecuteWithRetryAsync(async () =>
+ {
+ try
+ {
+ string url = $"{_configurationService.ApiSettings.BaseUrl}{WebApiAddress.AppNew}?type={type}";
+
+ // 使用带超时的HTTP请求
+ var response = await _httpClientService.GetStringWithTimeoutAsync(
+ url,
+ TimeSpan.FromSeconds(15));
+
+ var jobj = JObject.Parse(response);
+ var status = jobj["code"]?.ToString();
+
+ if (status == "1")
+ {
+ var jsonstr = jobj["data"]?.ToString();
+ return JsonConvert.DeserializeObject(jsonstr) ?? null;
+ }
+ else
+ {
+ _logger.LogWarning("获取用户信息数据失败,状态码: {Status}, 响应: {Response}", status, jobj.ToString());
+ return null;
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "获取Banner失败");
+ throw; // 重新抛出,让重试机制处理
+ }
+ }, nameof(GetUserInfo));
+ }
+ #endregion
+ ///
+ /// 账密登录:POST {BaseUrl}/prod-api/work_main/login。
+ /// 参数 account/code/password/type 均非必填(string)。
+ /// 成功(code=1):msg 为 JWT Token;失败(code!=1):msg 为错误信息。
+ /// 登录失败不做重试(密码错误重试无意义)。
+ ///
+ public async Task<(bool Success, string Message)> LoginByAccountAsync(string account, string code, string password, string type)
+ {
+ try
+ {
+ string url = $"{_configurationService.ApiSettings.BaseUrl}{WebApiAddress.AccountLogin}";
+ var requestData = new
+ {
+ account = account,
+ code = code,
+ password = password,
+ type = type
+ };
+ string sendData = JsonConvert.SerializeObject(requestData);
+
+ var response = await _httpClientService.PostJsonWithTimeoutAsync(
+ url,
+ sendData,
+ TimeSpan.FromSeconds(15));
+
+ var jobj = JObject.Parse(response);
+ string status = jobj["code"]?.ToString() ?? string.Empty;
+ string msg = jobj["msg"]?.ToString() ?? string.Empty;
+
+ if (status == "1")
+ {
+ return (true, msg); // msg 为 JWT Token
+ }
+
+ _logger.LogWarning("账密登录失败,状态码: {Status}, 响应: {Response}", status, jobj.ToString());
+ return (false, string.IsNullOrEmpty(msg) ? "登录失败" : msg);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "账密登录请求异常");
+ return (false, $"网络请求失败: {ex.Message}");
+ }
+ }
+ ///
+ /// 发送注册验证码:GET {BaseUrl}/prod-api/work_sms/sms/send_code?phone=xxx。
+ /// 成功(code=1)返回 (true, 空);失败(code!=1)返回 (false, 错误信息)。
+ ///
+ public Task<(bool Success, string Message)> SendRegisterCodeAsync(string phone)
+ {
+ return SmsRequestAsync(WebApiAddress.SendCode, new Dictionary { ["phone"] = phone });
+ }
+
+ ///
+ /// 发送登录验证码:GET {BaseUrl}/prod-api/work_sms/sms/send_login?phone=xxx。
+ /// 成功(code=1)返回 (true, 空);失败(code!=1)返回 (false, 错误信息)。
+ ///
+ public Task<(bool Success, string Message)> SendLoginCodeAsync(string phone)
+ {
+ return SmsRequestAsync(WebApiAddress.SendLoginCode, new Dictionary { ["phone"] = phone });
+ }
+
+ ///
+ /// 验证验证码:GET {BaseUrl}/prod-api/work_sms/sms/check_code?code=xxx&phone=xxx[&type=]。
+ /// 成功(code=1)返回 (true, 空);失败(code!=1)返回 (false, 错误信息)。
+ ///
+ public Task<(bool Success, string Message)> CheckVerifyCodeAsync(string phone, string code, string type = "")
+ {
+ var query = new Dictionary
+ {
+ ["phone"] = phone,
+ ["code"] = code
+ };
+ if (!string.IsNullOrEmpty(type))
+ {
+ query["type"] = type;
+ }
+ return SmsRequestAsync(WebApiAddress.CheckCode, query);
+ }
+
+ ///
+ /// 发送邮箱验证码:GET {BaseUrl}/prod-api/work_sms/email/send_code?address=xxx[&type=]。
+ /// type 为语言(默认中文,en:英文,可选),成功(code=1)返回 (true, 空)。
+ ///
+ public Task<(bool Success, string Message)> SendEmailCodeAsync(string address, string type = "")
+ {
+ var query = new Dictionary { ["address"] = address };
+ if (!string.IsNullOrEmpty(type))
+ {
+ query["type"] = type;
+ }
+ return SmsRequestAsync(WebApiAddress.EmailSendCode, query);
+ }
+
+ ///
+ /// 验证邮箱验证码:GET {BaseUrl}/prod-api/work_sms/email/check_code?address=xxx&code=xxx。
+ /// 成功(code=1)返回 (true, 空);失败(code!=1)返回 (false, 错误信息)。
+ ///
+ public Task<(bool Success, string Message)> CheckEmailCodeAsync(string address, string code)
+ {
+ return SmsRequestAsync(WebApiAddress.EmailCheckCode, new Dictionary
+ {
+ ["address"] = address,
+ ["code"] = code
+ });
+ }
+
+ /// 短信服务接口公共实现(GET + query 参数,成功状态码为 1)。
+ private async Task<(bool Success, string Message)> SmsRequestAsync(string endpoint, Dictionary query)
+ {
+ try
+ {
+ var sb = new StringBuilder();
+ foreach (var kv in query)
+ {
+ if (sb.Length > 0)
+ {
+ sb.Append('&');
+ }
+ sb.Append(Uri.EscapeDataString(kv.Key)).Append('=').Append(Uri.EscapeDataString(kv.Value));
+ }
+
+ string url = $"{_configurationService.ApiSettings.BaseUrl}{endpoint}";
+ if (sb.Length > 0)
+ {
+ url += "?" + sb;
+ }
+
+ var response = await _httpClientService.GetStringWithTimeoutAsync(url, TimeSpan.FromSeconds(15));
+ var jobj = JObject.Parse(response);
+ string status = jobj["code"]?.ToString() ?? string.Empty;
+ string msg = jobj["msg"]?.ToString() ?? string.Empty;
+
+ if (status == "1")
+ {
+ return (true, string.Empty);
+ }
+
+ _logger.LogWarning("短信接口失败,状态码: {Status}, 响应: {Response}", status, jobj.ToString());
+ return (false, string.IsNullOrEmpty(msg) ? "请求失败" : msg);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "短信接口请求异常");
+ return (false, $"网络请求失败: {ex.Message}");
+ }
+ }
+ ///