Browse Source

Merge branch 'master' into tuya230807

# Conflicts:
#	BusinessCommon/src/main/res/values/strings.xml
#	libThirdPart/libs/cofar-cooking-device-sdk-0.0.1-SNAPSHOT.jar
江天明 1 year ago
parent
commit
3ff2c58cea
47 changed files with 1764 additions and 195 deletions
  1. 186 0
      BusinessAirFryer/src/main/assets/lang_config_030.json
  2. 55 12
      BusinessAuth/src/main/java/com/develop/auth/ui/MemberProfileFragment.kt
  3. 14 6
      BusinessAuth/src/main/java/com/develop/auth/ui/MemberRegisterFragment.kt
  4. 43 6
      BusinessAuth/src/main/java/com/develop/auth/viewmodel/MemberViewModel.kt
  5. 69 64
      BusinessAuth/src/main/res/layout/fragment_member_profile.xml
  6. 3 0
      BusinessCommon/src/main/java/com/develop/common/data_repo/db/dao/UserInfoDao.kt
  7. 1 0
      BusinessCommon/src/main/java/com/develop/common/data_repo/net/Api.kt
  8. 1 1
      BusinessCommon/src/main/java/com/develop/common/data_repo/net/TokenInvalidateEvent.kt
  9. 2 0
      BusinessCommon/src/main/java/com/develop/common/data_repo/net/converter/SerializationConverter.kt
  10. 16 0
      BusinessCommon/src/main/java/com/develop/common/data_repo/net/model/request/CancelAccountBody.kt
  11. 51 0
      BusinessCommon/src/main/java/com/develop/common/data_repo/net/model/response/CancelAccountResult.kt
  12. 15 4
      BusinessCommon/src/main/java/com/develop/common/dialog/GenderSelectDialog.kt
  13. 13 4
      BusinessCommon/src/main/java/com/develop/common/ui/CommonBindingActivity.kt
  14. 2 0
      BusinessCommon/src/main/java/com/develop/common/utils/ConfigUtils.kt
  15. 15 2
      BusinessCommon/src/main/res/layout/dialog_gender_select.xml
  16. 213 0
      BusinessCommon/src/main/res/values-cz/strings.xml
  17. 1 0
      BusinessCommon/src/main/res/values-en/strings.xml
  18. 2 0
      BusinessCommon/src/main/res/values-fr/strings.xml
  19. 214 0
      BusinessCommon/src/main/res/values-hu/strings.xml
  20. 1 0
      BusinessCommon/src/main/res/values-ja/strings.xml
  21. 214 0
      BusinessCommon/src/main/res/values-sk/strings.xml
  22. 1 0
      BusinessCommon/src/main/res/values-zh-rCN/strings.xml
  23. 2 0
      BusinessCommon/src/main/res/values/strings.xml
  24. 9 6
      BusinessMain/src/main/java/com/develop/main/viewmodel/HomeViewModel.kt
  25. 18 14
      BusinessStep/src/main/java/com/develop/step/ui/ModesDetailActivity.kt
  26. 120 71
      BusinessStep/src/main/java/com/develop/step/ui/cook_step/CookStepActivity.kt
  27. 28 4
      BusinessStep/src/main/java/com/develop/step/ui/cook_step/model/CookStepUiData.kt
  28. 1 0
      LocalTools/.gitignore
  29. 15 0
      LocalTools/build.gradle
  30. BIN
      LocalTools/libs/gson-2.10.1.jar
  31. BIN
      LocalTools/libs/okhttp-4.9.0.jar
  32. BIN
      LocalTools/libs/okio-2.10.0.jar
  33. 23 0
      LocalTools/src/main/java/com/twm/tools/local/AndroidLanguage.kt
  34. 19 0
      LocalTools/src/main/java/com/twm/tools/local/BaiduLanguage.kt
  35. 12 0
      LocalTools/src/main/java/com/twm/tools/local/BaiduTranslateResponse.kt
  36. 49 0
      LocalTools/src/main/java/com/twm/tools/local/BaiduTranslateService.kt
  37. 239 0
      LocalTools/src/main/java/com/twm/tools/local/MainClass.kt
  38. 16 0
      LocalTools/src/main/java/com/twm/tools/local/QPSTaskWrapper.kt
  39. 7 0
      LocalTools/src/main/java/com/twm/tools/local/TranslateApi.kt
  40. 17 0
      LocalTools/src/main/java/com/twm/tools/local/TranslateCallable.kt
  41. 6 0
      LocalTools/src/main/java/com/twm/tools/local/Translation.kt
  42. 6 0
      LocalTools/src/main/java/com/twm/tools/local/ValuesData.kt
  43. 42 0
      LocalTools/src/main/java/com/twm/tools/local/ValuesStringSaxHandler.kt
  44. 1 1
      app/build.gradle
  45. BIN
      app/src/main/assets/skins/night.skin
  46. 1 0
      app/src/main/java/com/develop/foodcooking/FoodCookingApp.kt
  47. 1 0
      settings.gradle

+ 186 - 0
BusinessAirFryer/src/main/assets/lang_config_030.json

@@ -0,0 +1,186 @@
+{
+  "langs": [
+    {
+      "name": "Polish(波兰语)",
+      "value": "PL",
+      "icon": "icon_lang_pl",
+      "showName": "Polski",
+      "show": false
+    },
+    {
+      "name": "German(德语)",
+      "value": "DE",
+      "icon": "icon_lang_de",
+      "showName": "Deutsch",
+      "show": false
+    },
+    {
+      "name": "French(法语)",
+      "value": "FR",
+      "icon": "icon_lang_fr",
+      "showName": "Français",
+      "show": true
+    },
+    {
+      "name": "Dutch(荷兰语)",
+      "value": "NL",
+      "icon": "icon_lang_nl",
+      "showName": "Nederlands",
+      "show": false
+    },
+    {
+      "name": "Portuguese(葡萄牙语)",
+      "value": "PT",
+      "icon": "icon_lang_pt",
+      "showName": "Português",
+      "show": false
+    },
+    {
+      "name": "Spanish(西班牙语)",
+      "value": "ES",
+      "icon": "icon_lang_es",
+      "showName": "Español",
+      "show": false
+    },
+    {
+      "name": "Italiano(意大利语)",
+      "value": "IT",
+      "icon": "icon_lang_it",
+      "showName": "Italiano",
+      "show": false
+    },
+    {
+      "name": "English(英语)",
+      "value": "EN",
+      "icon": "icon_lang_en",
+      "showName": "English",
+      "show": false
+    },
+    {
+      "name": "Greek(希腊语)",
+      "value": "GR",
+      "icon": "icon_lang_gr",
+      "showName": "Ελληνικά",
+      "show": false
+    },
+    {
+      "name": "Russian(俄语)",
+      "value": "RU",
+      "icon": "icon_lang_ru",
+      "showName": "Русский",
+      "show": false
+    },
+    {
+      "name": "Romanian(罗马尼亚语)",
+      "value": "RO",
+      "icon": "icon_lang_ro",
+      "showName": "Română",
+      "show": false
+    },
+    {
+      "name": "Finnish(芬兰语)",
+      "value": "FI",
+      "icon": "icon_lang_fi",
+      "showName": "Suomi",
+      "show": false
+    },
+    {
+      "name": "Norsk(挪威语)",
+      "value": "NO",
+      "icon": "icon_lang_no",
+      "showName": "Norsk",
+      "show": false
+    },
+    {
+      "name": "Swedish(瑞典语)",
+      "value": "SE",
+      "icon": "icon_lang_se",
+      "showName": "Svenska",
+      "show": false
+    },
+    {
+      "name": "Danish(丹麦语)",
+      "value": "DK",
+      "icon": "icon_lang_dk",
+      "showName": "Dansk",
+      "show": false
+    },
+    {
+      "name": "Czech(捷克语)",
+      "value": "CZ",
+      "icon": "icon_lang_cz",
+      "showName": "Čeština",
+      "show": true
+    },
+    {
+      "name": "Estonki(爱沙尼亚语)",
+      "value": "EE",
+      "icon": "icon_lang_ee",
+      "showName": "Eesti keel",
+      "show": false
+    },
+    {
+      "name": "Slovak(斯洛伐克语)",
+      "value": "SK",
+      "icon": "icon_lang_sk",
+      "showName": "Slovenčina",
+      "show": true
+    },
+    {
+      "name": "Ukrainian(乌克兰语)",
+      "value": "UK",
+      "icon": "icon_lang_uk",
+      "showName": "Українська",
+      "show": false
+    },
+    {
+      "name": "Arabic(阿拉伯语)",
+      "value": "AR",
+      "icon": "icon_lang_ar",
+      "showName": "العربية",
+      "show": false
+    },
+    {
+      "name": "Lithuanian(立陶宛语)",
+      "value": "LT",
+      "icon": "icon_lang_lt",
+      "showName": "Lietuvių kalba",
+      "show": false
+    },
+    {
+      "name": "Farsi(波斯语)",
+      "value": "IR",
+      "icon": "icon_lang_ir",
+      "showName": "فارسی",
+      "show": false
+    },
+    {
+      "name": "Kazakh(哈萨克语)",
+      "value": "KZ",
+      "icon": "icon_lang_kz",
+      "showName": "Қазақша",
+      "show": false
+    },
+    {
+      "name": "Chinese(中文)",
+      "value": "ZH",
+      "icon": "icon_lang_zh",
+      "showName": "中文",
+      "show": false
+    },
+    {
+      "name": "Japanese(日语)",
+      "value": "JA",
+      "icon": "icon_lang_ja",
+      "showName": "日本語",
+      "show": false
+    },
+    {
+      "name": "Hungarian(匈牙利语)",
+      "value": "HU",
+      "icon": "icon_lang_hu",
+      "showName": "magyar nyelv",
+      "show": true
+    }
+  ]
+}

+ 55 - 12
BusinessAuth/src/main/java/com/develop/auth/ui/MemberProfileFragment.kt

@@ -8,11 +8,13 @@ import androidx.lifecycle.MutableLiveData
 import com.develop.auth.R
 import com.develop.auth.databinding.FragmentMemberProfileBinding
 import com.develop.auth.viewmodel.MemberViewModel
+import com.develop.base.ext.isNightTheme
 import com.develop.base.ext.navigateTo
 import com.develop.base.ext.resId2Dimension
 import com.develop.base.ext.setVisible
 import com.develop.base.ext.text_color
 import com.develop.base.mvvm.BaseBVMFragment
+import com.develop.base.util.GlobalToast
 import com.develop.base.util.MMkvUtils
 import com.develop.base.util.ThreadUtils
 import com.develop.common.data_repo.FoodDataProvider
@@ -22,6 +24,7 @@ import com.develop.common.dialog.AgeSelectDialog
 import com.develop.common.dialog.GenderSelectDialog
 import com.develop.common.router.Screens
 import com.develop.common.tag.API_TOKEN
+import com.develop.common.tag.CURRENT_USER_ID
 import com.develop.common.tag.CURRENT_USER_ID_TAG
 import com.develop.common.tag.LOGIN_TAG
 import com.develop.common.ui.CommonBVMFragment
@@ -29,7 +32,7 @@ import com.develop.common.ui.CommonBVMFragment
 class MemberProfileFragment : CommonBVMFragment<FragmentMemberProfileBinding, MemberViewModel>() {
 
     private var selectAge = 0
-    private var selectGender = 2
+    private var selectGender = 0
 
     override fun createViewBinding(
         inflater: LayoutInflater, container: ViewGroup?
@@ -52,11 +55,19 @@ class MemberProfileFragment : CommonBVMFragment<FragmentMemberProfileBinding, Me
         }
         binding.tvChooseSex.setOnClickListener {
             GenderSelectDialog {
-                selectGender = if (it) 2 else 1
-                if (selectGender == 2) {
-                    binding.tvChooseSex.text = "Male"
-                } else {
-                    binding.tvChooseSex.text = "Female"
+                selectGender = it
+                when (selectGender) {
+                    2 -> {
+                        binding.tvChooseSex.text = "Male"
+                    }
+
+                    1 -> {
+                        binding.tvChooseSex.text = "Female"
+                    }
+
+                    else -> {
+                        binding.tvChooseSex.text = "None"
+                    }
                 }
                 binding.tvChooseSex.setTextColor(Color.BLACK)
             }.showDialog(parentFragmentManager, "gender")
@@ -94,12 +105,21 @@ class MemberProfileFragment : CommonBVMFragment<FragmentMemberProfileBinding, Me
                     selectGender = userGender?.toInt() ?: 2
                     binding.etNickname.setText(userName ?: "")
                     viewModel.chooseAvatar.value = userAvatar?.toInt()
-                    if (selectGender == 2) {
-                        binding.tvChooseSex.text = "Male"
-                        binding.tvChooseAge.setTextColor(Color.BLACK)
-                    } else if (selectGender == 1) {
-                        binding.tvChooseSex.text = "Female"
-                        binding.tvChooseAge.setTextColor(Color.BLACK)
+                    when (selectGender) {
+                        2 -> {
+                            binding.tvChooseSex.text = "Male"
+                            binding.tvChooseAge.setTextColor(Color.BLACK)
+                        }
+
+                        1 -> {
+                            binding.tvChooseSex.text = "Female"
+                            binding.tvChooseAge.setTextColor(Color.BLACK)
+                        }
+
+                        0 -> {
+                            binding.tvChooseSex.text = "None"
+                            binding.tvChooseAge.setTextColor(Color.BLACK)
+                        }
                     }
                     if (selectAge > 0) {
                         binding.tvChooseAge.text = selectAge.toString()
@@ -129,6 +149,29 @@ class MemberProfileFragment : CommonBVMFragment<FragmentMemberProfileBinding, Me
                 val chooseIcon = icons.getOrNull(it ?: 0) ?: com.develop.common.R.drawable.ic_icon1
                 binding.ivMember.setImageResource(chooseIcon)
             }
+            cancelAccountLiveData.observe(viewLifecycleOwner){
+                dismissPlainDialog()
+                FoodDataProvider
+                    .getUserDatabase()
+                    .userInfoDao()
+                    .deleteUserInfoByUserId(CURRENT_USER_ID)
+                val saveToken: String? = null
+                MMkvUtils.save(API_TOKEN, saveToken)
+                MMkvUtils.save(LOGIN_TAG, false)
+                MMkvUtils.save(CURRENT_USER_ID_TAG, 0)
+                FoodDataProvider.getUserDatabase().userInfoDao().deleteAllUserInfo()
+                parentFragmentManager
+                    .beginTransaction()
+                    .replace(R.id.fl_container, MemberLoginFragment())
+                    .commitAllowingStateLoss()
+            }
+        }
+        binding.tvDestroyAccount.setOnClickListener {
+            showPlainDialog(true)
+            viewModel.cancelAccount()
+        }
+        if (isNightTheme()) {
+            binding.tvDestroyAccount.setVisible()
         }
     }
 

+ 14 - 6
BusinessAuth/src/main/java/com/develop/auth/ui/MemberRegisterFragment.kt

@@ -7,7 +7,6 @@ import com.develop.auth.databinding.FragmentMemberRegisterBinding
 import com.develop.auth.viewmodel.FragmentTag
 import com.develop.auth.viewmodel.MemberViewModel
 import com.develop.common.ui.CommonBVMFragment
-import java.util.regex.Pattern
 
 class MemberRegisterFragment : CommonBVMFragment<FragmentMemberRegisterBinding, MemberViewModel>() {
 
@@ -54,9 +53,11 @@ class MemberRegisterFragment : CommonBVMFragment<FragmentMemberRegisterBinding,
             return false
         }
         if (inputPsd.length < 8) {
+            showToast("input not available")
             return false
         }
-        if (!isNumeric(inputPsd)) {
+        if (!isPasswordForm(inputPsd)) {
+            showToast("input not available")
             return false
         }
         return true
@@ -71,10 +72,17 @@ class MemberRegisterFragment : CommonBVMFragment<FragmentMemberRegisterBinding,
         return getViewModelOfActivity(MemberViewModel::class.java)
     }
 
-    private fun isNumeric(str: String): Boolean {
-        val pattern: Pattern = Pattern.compile("[a-zA-Z0-9]")
-        return pattern.matcher(str).matches()
-    }
 
 
+    /**
+     * 检测输入密码是否符合规范
+     * 8~16位数字和字母组成
+     * 不能是纯数字或纯字母
+     */
+    private fun isPasswordForm(pwd: String): Boolean {
+        if (TextUtils.isEmpty(pwd)) return false
+        val regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$"
+        return pwd.matches(regex.toRegex())
+    }
+
 }

+ 43 - 6
BusinessAuth/src/main/java/com/develop/auth/viewmodel/MemberViewModel.kt

@@ -1,5 +1,6 @@
 package com.develop.auth.viewmodel
 
+import android.util.Log
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.scopeNetLife
 import com.develop.auth.R
@@ -22,7 +23,10 @@ import com.develop.common.tag.CURRENT_USER_ID_TAG
 import com.develop.common.tag.LOGIN_TAG
 import com.drake.net.Post
 import com.develop.base.util.UnPeekLiveData
+import com.develop.common.data_repo.net.TokenInvalidateEvent
+import com.develop.common.data_repo.net.model.response.CancelAccountResult
 import com.develop.common.data_repo.net.model.response.UpdatePwdResult
+import org.greenrobot.eventbus.EventBus
 
 class MemberViewModel : BaseViewModel() {
     private var mVerifyCodeKey = ""
@@ -36,7 +40,7 @@ class MemberViewModel : BaseViewModel() {
     var perfectInfoLiveData = MutableLiveData<AuthModel>()
 
     val userInfoLiveData = MutableLiveData<UserInfo>()
-
+    val cancelAccountLiveData = MutableLiveData<Boolean>()
     var fragmentChangeLiveData = MutableLiveData<FragmentTag>()
 
 
@@ -48,7 +52,12 @@ class MemberViewModel : BaseViewModel() {
         }
     }.catch {
         if (it.message == "账号已存在") {
-            registerLiveData.postValue(AuthModel(false, globalApp().getString(com.develop.common.R.string.the_email_has_been_already_registered)))
+            registerLiveData.postValue(
+                AuthModel(
+                    false,
+                    globalApp().getString(com.develop.common.R.string.the_email_has_been_already_registered)
+                )
+            )
         } else {
             registerLiveData.postValue(AuthModel(false, it.message))
         }
@@ -87,10 +96,17 @@ class MemberViewModel : BaseViewModel() {
             body = SendVerifyCodeBody.genSendVerifyCodeBody(email)
         }.await().apply {
             mVerifyCodeKey = verifyCodeKey
-            sendEmailLiveData.postValue(AuthModel(true, globalApp().getString(com.develop.common.R.string.email_send)))
+            sendEmailLiveData.postValue(
+                AuthModel(
+                    true,
+                    globalApp().getString(com.develop.common.R.string.email_send)
+                )
+            )
         }
     }.catch {
-        GlobalToast.showToast(it.message ?: globalApp().getString(com.develop.common.R.string.email_not_send))
+        GlobalToast.showToast(
+            it.message ?: globalApp().getString(com.develop.common.R.string.email_not_send)
+        )
         sendEmailLiveData.postValue(AuthModel(false))
     }
 
@@ -107,7 +123,12 @@ class MemberViewModel : BaseViewModel() {
                 captcha
             )
         }.await().apply {
-            resetPasswordLiveData.postValue(AuthModel(true, globalApp().getString(com.develop.common.R.string.reset_password_success)))
+            resetPasswordLiveData.postValue(
+                AuthModel(
+                    true,
+                    globalApp().getString(com.develop.common.R.string.reset_password_success)
+                )
+            )
         }
     }.catch {
         resetPasswordLiveData.postValue(AuthModel(false, it.message))
@@ -119,7 +140,12 @@ class MemberViewModel : BaseViewModel() {
             body = PerfectInfoBody.genPerfectInfoBody(nickName, sex, portrait, age)
         }.await().apply {
 
-            perfectInfoLiveData.postValue(AuthModel(true,   globalApp().getString(com.develop.common.R.string.save_success)))
+            perfectInfoLiveData.postValue(
+                AuthModel(
+                    true,
+                    globalApp().getString(com.develop.common.R.string.save_success)
+                )
+            )
             MMkvUtils.save(CURRENT_USER_ID_TAG, user.id.toLong())
             val userInfo = UserInfo(
                 user.id.toLong(),
@@ -142,6 +168,17 @@ class MemberViewModel : BaseViewModel() {
             .queryUserInfoByUserId(CURRENT_USER_ID)
         userInfoLiveData.postValue(result)
     }
+
+
+    fun cancelAccount() = scopeNetLife {
+        Post<String>(Api.CANCEL_ACCOUNT) {
+            body = CancelAccountBody.genCancelAccountBody()
+        }.await().apply {
+            cancelAccountLiveData.postValue(true)
+        }
+    }.catch {
+            Log.d("ddddd",it.message?:"")
+    }
 }
 
 enum class FragmentTag {

+ 69 - 64
BusinessAuth/src/main/res/layout/fragment_member_profile.xml

@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:orientation="vertical"
+    android:background="#fff"
     android:focusable="true"
     android:focusableInTouchMode="true"
-    android:background="#fff">
+    android:orientation="vertical">
 
     <ImageView
         android:id="@+id/iv_member"
@@ -14,137 +14,142 @@
         android:layout_height="@dimen/convert_146px"
         android:layout_marginTop="@dimen/convert_60px"
         android:background="@drawable/ic_icon1"
-        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"/>
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
 
     <View
         android:layout_width="@dimen/convert_40px"
         android:layout_height="@dimen/convert_40px"
         android:background="@drawable/ic_member_select"
-        app:layout_constraintEnd_toEndOf="@+id/iv_member"
-        app:layout_constraintBottom_toBottomOf="@+id/iv_member"/>
+        app:layout_constraintBottom_toBottomOf="@+id/iv_member"
+        app:layout_constraintEnd_toEndOf="@+id/iv_member" />
 
     <TextView
         android:id="@+id/tv_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/convert_80px"
+        android:layout_marginTop="@dimen/convert_213px"
         android:text="@string/nickname"
         android:textColor="#1A1A1A"
         android:textSize="@dimen/convert_36px"
-        android:layout_marginTop="@dimen/convert_213px"
-        android:layout_marginStart="@dimen/convert_80px"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintStart_toStartOf="parent"/>
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
 
     <EditText
         android:id="@+id/et_nickname"
         android:layout_width="match_parent"
         android:layout_height="@dimen/convert_88px"
-        android:hint="@string/enter_nickname"
-        android:textSize="@dimen/convert_30px"
-        android:singleLine="true"
-        android:background="@drawable/bg_edit_input"
-        android:layout_marginTop="@dimen/convert_12px"
         android:layout_gravity="center_horizontal"
-        android:paddingHorizontal="@dimen/convert_40px"
         android:layout_marginHorizontal="@dimen/convert_40px"
-        app:layout_constraintTop_toBottomOf="@+id/tv_title"
-        app:layout_constraintStart_toStartOf="parent"/>
+        android:layout_marginTop="@dimen/convert_12px"
+        android:background="@drawable/bg_edit_input"
+        android:hint="@string/enter_nickname"
+        android:paddingHorizontal="@dimen/convert_40px"
+        android:singleLine="true"
+        android:textSize="@dimen/convert_30px"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title" />
 
     <TextView
         android:id="@+id/tv_sex"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/convert_80px"
+        android:layout_marginTop="@dimen/convert_25px"
         android:text="@string/sex"
         android:textColor="#1A1A1A"
         android:textSize="@dimen/convert_36px"
-        android:layout_marginTop="@dimen/convert_25px"
-        android:layout_marginStart="@dimen/convert_80px"
-        app:layout_constraintTop_toBottomOf="@+id/et_nickname"
-        app:layout_constraintStart_toStartOf="parent"/>
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/et_nickname" />
 
     <TextView
         android:id="@+id/tv_choose_sex"
         android:layout_width="0dp"
         android:layout_height="@dimen/convert_88px"
-        android:textSize="@dimen/convert_30px"
-        android:text="@string/male"
-        android:textColor="#B1B2B2"
-        android:background="@drawable/bg_edit_input"
-        android:layout_marginTop="@dimen/convert_12px"
-        android:gravity="center_vertical"
         android:layout_gravity="center_horizontal"
-        android:paddingHorizontal="@dimen/convert_66px"
         android:layout_marginStart="@dimen/convert_40px"
+        android:layout_marginTop="@dimen/convert_12px"
         android:layout_marginEnd="@dimen/convert_53px"
+        android:background="@drawable/bg_edit_input"
+        android:gravity="center_vertical"
+        android:paddingHorizontal="@dimen/convert_66px"
+        android:text="@string/none"
+        android:textColor="#B1B2B2"
+        android:textSize="@dimen/convert_30px"
+        app:layout_constraintEnd_toStartOf="@+id/tv_choose_age"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/tv_sex"
-        app:layout_constraintEnd_toStartOf="@+id/tv_choose_age"/>
+        app:layout_constraintTop_toBottomOf="@+id/tv_sex" />
 
     <TextView
         android:id="@+id/tv_choose_age"
         android:layout_width="0dp"
         android:layout_height="@dimen/convert_88px"
-        android:textSize="@dimen/convert_30px"
-        android:text="20"
-        android:textColor="#B1B2B2"
+        android:layout_gravity="center_horizontal"
+        android:layout_marginEnd="@dimen/convert_40px"
         android:background="@drawable/bg_edit_input"
         android:gravity="center_vertical"
-        android:layout_gravity="center_horizontal"
         android:paddingHorizontal="@dimen/convert_66px"
-        android:layout_marginEnd="@dimen/convert_40px"
-        app:layout_constraintTop_toTopOf="@+id/tv_choose_sex"
+        android:text="20"
+        android:textColor="#B1B2B2"
+        android:textSize="@dimen/convert_30px"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@+id/tv_choose_sex"/>
+        app:layout_constraintStart_toEndOf="@+id/tv_choose_sex"
+        app:layout_constraintTop_toTopOf="@+id/tv_choose_sex" />
 
     <TextView
         android:id="@+id/tv_age"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/convert_40px"
         android:text="@string/age"
         android:textColor="#1a1a1a"
         android:textSize="@dimen/convert_36px"
-        android:layout_marginStart="@dimen/convert_40px"
-        app:layout_constraintTop_toTopOf="@+id/tv_sex"
-        app:layout_constraintStart_toStartOf="@+id/tv_choose_age"/>
+        app:layout_constraintStart_toStartOf="@+id/tv_choose_age"
+        app:layout_constraintTop_toTopOf="@+id/tv_sex" />
 
     <TextView
         android:id="@+id/tv_save"
         android:layout_width="match_parent"
         android:layout_height="@dimen/convert_98px"
-        android:textColor="#fff"
-        android:textSize="@dimen/convert_36px"
-        android:text="@string/save"
-        android:gravity="center"
         android:layout_gravity="center_horizontal"
-        android:background="@drawable/language_conner"
-        android:layout_marginTop="@dimen/convert_40px"
         android:layout_marginHorizontal="@dimen/convert_40px"
-        app:layout_constraintTop_toBottomOf="@+id/tv_choose_sex"/>
+        android:layout_marginTop="@dimen/convert_40px"
+        android:background="@drawable/language_conner"
+        android:gravity="center"
+        android:text="@string/save"
+        android:textColor="#fff"
+        android:textSize="@dimen/convert_36px"
+        app:layout_constraintTop_toBottomOf="@+id/tv_choose_sex" />
 
     <TextView
         android:id="@+id/tv_skip_for_now"
-        android:layout_width="match_parent"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
+        android:gravity="center"
+        android:paddingTop="@dimen/convert_40px"
+        android:paddingBottom="@dimen/convert_50px"
+        android:text="@string/skip_for_now"
         android:textColor="@color/skin_for_now"
         android:textSize="@dimen/convert_30px"
-        android:text="@string/skip_for_now"
+        app:layout_constraintEnd_toStartOf="@+id/tv_destroy_account"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_save" />
+
+    <TextView
+        android:id="@+id/tv_destroy_account"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
         android:gravity="center"
         android:paddingTop="@dimen/convert_40px"
         android:paddingBottom="@dimen/convert_50px"
-        app:layout_constraintTop_toBottomOf="@+id/tv_save"/>
-
-    <!--    <TextView-->
-    <!--        android:id="@+id/tv_destroy_account"-->
-    <!--        android:layout_width="wrap_content"-->
-    <!--        android:layout_height="wrap_content"-->
-    <!--        android:textColor="#E60012"-->
-    <!--        android:textSize="@dimen/convert_39px"-->
-    <!--        android:text="@string/cancellation_of_account"-->
-    <!--        android:gravity="center"-->
-    <!--        android:visibility="gone"-->
-    <!--        android:layout_marginTop="@dimen/convert_16px"-->
-    <!--        android:layout_gravity="center_horizontal"/>-->
+        android:text="@string/cancellation_of_account"
+        android:textColor="#E60012"
+        android:textSize="@dimen/convert_30px"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/tv_skip_for_now"
+        app:layout_constraintTop_toBottomOf="@+id/tv_save" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 3 - 0
BusinessCommon/src/main/java/com/develop/common/data_repo/db/dao/UserInfoDao.kt

@@ -21,6 +21,9 @@ interface UserInfoDao {
     @Query("select * from user_info where userId =:userId")
     fun queryUserInfoByUserId(userId: Long): UserInfo?
 
+    @Query("delete from user_info where userId =:userId")
+    fun deleteUserInfoByUserId(userId: Long)
+
     @Query("select * from user_history_recipes where userId =:userId")
     fun queryHistoryRecipes(userId: Long): List<UserHistoryRecipes>
 

+ 1 - 0
BusinessCommon/src/main/java/com/develop/common/data_repo/net/Api.kt

@@ -20,6 +20,7 @@ object Api {
     const val DEV_INFO = "devInfo"
     const val GET_NOTICES = "notices"
     const val GET_HOT_TAGS = "hotTags"
+    const val CANCEL_ACCOUNT = "cancelAccount"
 
 
 }

+ 1 - 1
BusinessCommon/src/main/java/com/develop/common/data_repo/net/TokenInvalidateEvent.kt

@@ -1,4 +1,4 @@
 package com.develop.common.data_repo.net
 
-class TokenInvalidateEvent {
+class TokenInvalidateEvent(var cancelAccount: Boolean = false) {
 }

+ 2 - 0
BusinessCommon/src/main/java/com/develop/common/data_repo/net/converter/SerializationConverter.kt

@@ -2,6 +2,7 @@
 
 package com.develop.common.data_repo.net.converter
 
+import android.util.Log
 import com.develop.common.data_repo.net.TokenInvalidateEvent
 import com.drake.net.NetConfig
 import com.drake.net.convert.NetConverter
@@ -47,6 +48,7 @@ class SerializationConverter(
             when {
                 code in 200..299 -> { // 请求成功
                     val bodyString = response.body?.string() ?: return null
+                    Log.d("ddddddd",bodyString)
                     val kType = response.request.kType
                         ?: throw ConvertException(response, "Request does not contain KType")
                     return try {

+ 16 - 0
BusinessCommon/src/main/java/com/develop/common/data_repo/net/model/request/CancelAccountBody.kt

@@ -0,0 +1,16 @@
+package com.develop.common.data_repo.net.model.request
+
+import com.develop.base.ext.genMultipartBody
+import com.develop.base.ext.getSN
+import com.develop.base.util.MMkvUtils
+import com.develop.common.tag.API_TOKEN
+import okhttp3.RequestBody
+
+object CancelAccountBody {
+    fun genCancelAccountBody(): RequestBody {
+        val map = HashMap<String, String>()
+        map["token"] = MMkvUtils.getString(API_TOKEN) ?: ""
+        map["sn"] = getSN()
+        return map.genMultipartBody()
+    }
+}

+ 51 - 0
BusinessCommon/src/main/java/com/develop/common/data_repo/net/model/response/CancelAccountResult.kt

@@ -0,0 +1,51 @@
+package com.develop.common.data_repo.net.model.response
+import kotlinx.serialization.Serializable
+
+import kotlinx.serialization.SerialName
+
+
+@Serializable
+data class CancelAccountResult(
+    @SerialName("informs")
+    var informs: List<Inform>
+) {
+    @Serializable
+    data class Inform(
+        @SerialName("brandOwnerCode")
+        var brandOwnerCode: String,
+        @SerialName("brandOwnerNumber")
+        var brandOwnerNumber: String,
+        @SerialName("code")
+        var code: String,
+        @SerialName("content")
+        var content: String,
+        @SerialName("createTime")
+        var createTime: Long,
+        @SerialName("deviceCode")
+        var deviceCode: String?,
+        @SerialName("id")
+        var id: Int,
+        @SerialName("informCode")
+        var informCode: String,
+        @SerialName("informNumber")
+        var informNumber: String,
+        @SerialName("readStatus")
+        var readStatus: Boolean,
+        @SerialName("readTime")
+        var readTime: String?,
+        @SerialName("sn")
+        var sn: String?,
+        @SerialName("title")
+        var title: String,
+        @SerialName("updateTime")
+        var updateTime: Long,
+        @SerialName("userCode")
+        var userCode: String,
+        @SerialName("userNumber")
+        var userNumber: String,
+        @SerialName("valid")
+        var valid: Int,
+        @SerialName("version")
+        var version: Int
+    )
+}

+ 15 - 4
BusinessCommon/src/main/java/com/develop/common/dialog/GenderSelectDialog.kt

@@ -9,7 +9,7 @@ import com.develop.common.databinding.DialogGenderSelectBinding
 
 
 class GenderSelectDialog(
-    private val onSelect: (male: Boolean) -> Unit
+    private val onSelect: (male: Int) -> Unit
 ) : FullScreenTransparentDialog() {
 
     private lateinit var binding: DialogGenderSelectBinding
@@ -28,19 +28,30 @@ class GenderSelectDialog(
         binding.ivCancel.setOnClickListener {
             removeSelf()
         }
+
+        binding.tvSelectNo.setOnClickListener {
+            binding.tvSelectFemale.isSelected = false
+            binding.tvSelectMale.isSelected = false
+            binding.tvSelectNo.isSelected  =true
+            onSelect(0)
+            removeSelf()
+        }
+
         binding.tvSelectMale.setOnClickListener {
             binding.tvSelectFemale.isSelected = false
             binding.tvSelectMale.isSelected = true
-            onSelect(true)
+            binding.tvSelectNo.isSelected  =false
+            onSelect(2)
             removeSelf()
         }
         binding.tvSelectFemale.setOnClickListener {
             binding.tvSelectFemale.isSelected = true
             binding.tvSelectMale.isSelected = false
-            onSelect(false)
+            binding.tvSelectNo.isSelected  =false
+            onSelect(1)
             removeSelf()
         }
-        binding.tvSelectMale.isSelected = true
+        binding.tvSelectNo.isSelected = true
         return binding.root
     }
 }

+ 13 - 4
BusinessCommon/src/main/java/com/develop/common/ui/CommonBindingActivity.kt

@@ -20,12 +20,14 @@ import com.develop.base.util.GlobalToast
 import com.develop.base.util.MMkvUtils
 import com.develop.base.util.TopResumedAtyHolder
 import com.develop.common.R
+import com.develop.common.data_repo.FoodDataProvider
 import com.develop.common.data_repo.net.TokenInvalidateEvent
 import com.develop.common.dialog.CancelConfirmDialog
 import com.develop.common.dialog.PlainDialogView
 import com.develop.common.food_sdk.FoodSdkUtils
 import com.develop.common.food_sdk.GlobalDevEvent
 import com.develop.common.router.Screens
+import com.develop.common.tag.CURRENT_USER_ID
 import com.develop.common.tag.SCREENSAVER
 import com.develop.common.utils.NoScreenEvent
 import com.develop.common.utils.TimeDownUtil
@@ -278,9 +280,9 @@ abstract class CommonBindingActivity<T : ViewBinding> : BaseBindingActivity<T>()
         if (lastMsg == "dian_zi_cheng_tong_xin_yi_chan" && !isWidget) {
             return
         }
-        if (isWidget && lastMsg != "dian_zi_cheng_tong_xin_yi_chan") {
-            return
-        }
+//        if (isWidget && lastMsg != "dian_zi_cheng_tong_xin_yi_chan") {
+//            return
+//        }
         cancelConfirmDialog.showCancel = event.isShowCancelBtn
         cancelConfirmDialog.showConfirm = event.isShowConfirmBtn
 
@@ -334,7 +336,14 @@ abstract class CommonBindingActivity<T : ViewBinding> : BaseBindingActivity<T>()
 
     @Subscribe
     fun onTokenInvalidateEvent(event: TokenInvalidateEvent) {
-        GlobalToast.showToast(getString(R.string.login_expire_tips))
+        if (event.cancelAccount) {
+            FoodDataProvider
+                .getUserDatabase()
+                .userInfoDao()
+                .deleteUserInfoByUserId(CURRENT_USER_ID)
+        } else {
+            GlobalToast.showToast(getString(R.string.login_expire_tips))
+        }
         navigateTo(Screens.Auth.MEMBER) {
             val bundle = Bundle()
             bundle.putBoolean("isTokenOut", true)

+ 2 - 0
BusinessCommon/src/main/java/com/develop/common/utils/ConfigUtils.kt

@@ -1,6 +1,8 @@
 package com.develop.common.utils
 
 import android.content.Context
+import android.util.Log
+import com.azhon.appupdate.util.LogUtil
 import com.develop.base.ext.GlobalApp
 import com.develop.base.ext.getSN
 import com.develop.common.bean.CfConfig

+ 15 - 2
BusinessCommon/src/main/res/layout/dialog_gender_select.xml

@@ -10,7 +10,7 @@
     <LinearLayout
         android:id="@+id/ll_dialog"
         android:layout_width="@dimen/convert_430px"
-        android:layout_height="@dimen/convert_361px"
+        android:layout_height="@dimen/convert_460px"
         android:orientation="vertical"
         android:gravity="center_horizontal"
         android:background="@drawable/shape_10pxffffff_stoke"
@@ -21,6 +21,19 @@
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent">
 
+        <TextView
+            android:id="@+id/tv_select_no"
+            android:layout_width="@dimen/convert_326px"
+            android:layout_height="@dimen/convert_88px"
+            android:text="@string/none"
+            android:textSize="@dimen/convert_30px"
+            android:gravity="center"
+            android:background="@drawable/bg_amount_item"
+            android:textColor="@color/color_amount_text"
+            android:layout_marginTop="@dimen/convert_69px"/>
+
+
+
         <TextView
             android:id="@+id/tv_select_male"
             android:layout_width="@dimen/convert_326px"
@@ -30,7 +43,7 @@
             android:gravity="center"
             android:background="@drawable/bg_amount_item"
             android:textColor="@color/color_amount_text"
-            android:layout_marginTop="@dimen/convert_69px"/>
+            android:layout_marginTop="@dimen/convert_24px"/>
 
         <TextView
             android:id="@+id/tv_select_female"

+ 213 - 0
BusinessCommon/src/main/res/values-cz/strings.xml

@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources><string name="not_a_member_yet">Ještě nemáte účet?</string>
+    <string name="member">Členství</string>
+    <string name="select_language">Zvolte jazyk</string>
+    <string name="next">DALŠÍ</string>
+    <string name="english">English</string>
+    <string name="chinese">简体中文</string>
+    <string name="france">Français</string>
+    <string name="japan">日本語</string>
+    <string name="czech">čeština</string>
+    <string name="slovak">日本語</string>
+    <string name="hungarian">Magyar</string>
+    <string name="polish">Polski</string>
+    <string name="skip">PŘESKOČIT</string>
+    <string name="recipes">RECEPTY</string>
+    <string name="mode">REŽIM</string>
+    <string name="sunday">Neděle</string>
+    <string name="monday">Pondělí</string>
+    <string name="tuesday">Úterý</string>
+    <string name="wednesday">Středa</string>
+    <string name="thursday">Čtvrtek</string>
+    <string name="friday">Pátek</string>
+    <string name="saturday">Sobota</string>
+    <string name="resume">OBNOVIT</string>
+    <string name="privacy_policy">Zásady ochrany osobních údajů</string>
+    <string name="privacy_policy_content"> Zásady ochrany osobních údajů:
+neshromažďujeme žádné vaše osobní údaje.</string>
+    <string name="i_agree">Souhlasím</string>
+    <string name="i_have_read_the_privacy_policy">Přečetl/a jsem si zásady ochrany osobních údajů</string>
+    <string name="second">Zadruhé</string>
+    <string name="wifi">WI-FI</string>
+    <string name="off_line">OFF-LINE</string>
+    <string name="ok">OK</string>
+    <string name="on_line">ON-LINE</string>
+    <string name="pwd_can_not_be_empty">Vyplňte prosím heslo.</string>
+    <string name="skin_for_now">Aktuální vzhled</string>
+    <string name="login">Přihlášení</string>
+    <string name="online_recipes">Online recepty</string>
+    <string name="cook_history">Historie vaření</string>
+    <string name="favourite_recipes">Oblíbené recepty</string>
+    <string name="settings">Nastavení</string>
+    <string name="grid_view">Zobrazení v mřížce</string>
+    <string name="list_view">Zobrazení seznamu</string>
+    <string name="adapted_cooking">UPRAVENÉ RECEPTY</string>
+    <string name="scales">VÁHA</string>
+    <string name="boil_water">VAŘENÍ VODY</string>
+    <string name="chop">nakrájejte</string>
+    <string name="slow_cook">POMALÉ VAŘENÍ</string>
+    <string name="knead_dough">HNĚTENÍ TĚSTA</string>
+    <string name="steam">PÁRA</string>
+    <string name="food_processor">ZPRACOVÁNÍ POTRAVIN</string>
+    <string name="turbo">TURBO</string>
+    <string name="language">JAZYK</string>
+    <string name="sound">ZVUK</string>
+    <string name="brightness">JAS</string>
+    <string name="user_account">UŽIVATELSKÝ ÚČET</string>
+    <string name="storage">ÚLOŽIŠTĚ</string>
+    <string name="reset">ÚLOŽIŠTĚ</string>
+    <string name="about">O</string>
+    <string name="weight">HMOTNOST</string>
+    <string name="local_recipes">Místní recepty</string>
+    <string name="download">Ke stažení</string>
+    <string name="downloading">Stahování</string>
+    <string name="enter_search">Vyhledejte</string>
+    <string name="search">Vyhledávání</string>
+    <string name="most_popular">Nejoblíbenější</string>
+    <string name="newest">Nejnovější</string>
+    <string name="the_most_commonly_searched">Nejčastěji vyhledávané</string>
+    <string name="notice">Oznámení</string>
+    <string name="all">VŠECHNY</string>
+    <string name="Recipes">Recepty</string>
+    <string name="ingredients">Ingredience</string>
+    <string name="Brightness">Jas</string>
+    <string name="screen_lock_time">Doba uzamčení obrazovky</string>
+    <string name="time_3min">3 minuty</string>
+    <string name="time_10min">10Min</string>
+    <string name="time_30min">30Min</string>
+    <string name="Sound">Zvuk</string>
+    <string name="text_to_speech">Převod textu na řeč</string>
+    <string name="Language">Jazyk</string>
+    <string name="Continue">POKRAČOVAT</string>
+    <string name="start_cooking">ZAČÍNÁME VAŘIT</string>
+    <string name="off">VYPNOUT</string>
+    <string name="on">ZAPNOUT</string>
+    <string name="update_the_recipes">Aktualizace receptů</string>
+    <string name="apk">APK</string>
+    <string name="mcu">MCU</string>
+    <string name="tp">TP</string>
+    <string name="serial_number">Sériové číslo</string>
+    <string name="standby_time">Doba pohotovostního režimu</string>
+    <string name="update">Aktualizace</string>
+    <string name="About">O stránkách</string>
+    <string name="are_you_sure_to_restore_factory_settings">Určitě chcete obnovit tovární nastavení?</string>
+    <string name="yes">ANO</string>
+    <string name="restore_factory_settings">Obnovení továrního nastavení</string>
+    <string name="network_wifi_status_connected_no_internet">Připojeno, ale nelze přistupovat k Internetu</string>
+    <string name="network_wifi_status_saved">Uloženo</string>
+    <string name="network_wifi_status_idle">Stav sítě</string>
+    <string name="network_wifi_status_disabled">"Zastaveno"</string>
+    <string name="network_wifi_status_network_failure">Selhání konfigurace IP adresy</string>
+    <string name="network_wifi_status_wifi_failure">"Selhání připojení k síti WLAN"</string>
+    <string name="network_wifi_status_password_failure">"Nastal problém s ověřováním"</string>
+    <string name="network_wifi_status_scanning">Skenování...</string>
+    <string name="network_wifi_status_connecting">Připojování...</string>
+    <string name="network_wifi_status_authenticating">Probíhá ověřování...</string>
+    <string name="network_wifi_status_obtaining_ip_address">Získání IP adresy...</string>
+    <string name="network_wifi_status_connected">Připojeno</string>
+    <string name="network_wifi_status_suspended">Pozastaveno</string>
+    <string name="network_wifi_status_disconnecting">Odpojování...</string>
+    <string name="network_wifi_status_disconnected">Odpojeno</string>
+    <string name="network_wifi_status_failed">Neúspěšně</string>
+    <string name="network_wifi_status_blocked">Zablokováno</string>
+    <string name="network_wifi_status_verifying_poor_link">Dočasně vypnuto (špatný stav sítě)</string>
+    <string name="start">START</string>
+    <string name="pause">PAUZA</string>
+    <string name="cancel">ZRUŠIT</string>
+    <string name="confirm">POTVRDIT</string>
+    <string name="stop">STOP</string>
+    <string name="turn_right">Otočte\ndoprava</string>
+    <string name="turn_left">Otočit\nvlevo</string>
+    <string name="temperature">TEPLOTA</string>
+    <string name="time">ČAS</string>
+    <string name="speed">RYCHLOST</string>
+    <string name="direction">SMĚR</string>
+    <string name="bad">Špatný</string>
+    <string name="imperfect">Nedokonalý</string>
+    <string name="ordinary">Obyčejný</string>
+    <string name="good">Dobrý</string>
+    <string name="perfect">Perfektní</string>
+    <string name="are_you_sure_to_delete">Určitě chcete smazat?</string>
+    <string name="no">NE</string>
+    <string name="unset_param_tips">Nastavte prosím parametry operace</string>
+    <string name="pmpt_confirm">Potvrďte</string>
+    <string name="pmpt_cancel">Zrušit</string>
+    <string name="pmpt_msg">Tipy</string>
+    <string name="dev_end_of_run_tips">Hotovo</string>
+    <string name="hight_temp_warning_tips">Aktuální teplota je vyšší než 60 °C a otáčky motoru překračují třetí rychlostní stupeň. Určitě chcete pokračovat?</string>
+    <string name="hight_temp_turbo_tips">Aktuální teplota přesahuje 60 °C, funkci turbo nelze provozovat.</string>
+    <string name="update_msg">Probíhá aktualizace systému, vyčkejte prosím</string>
+    <string name="update_title">Jedná se o nejnovější verzi?</string>
+    <string name="finish_download">Staženo</string>
+    <string name="download_fail">Stahování se nezdařilo</string>
+    <string name="start_download">Zahájit stahování</string>
+    <string name="weight_overload_tips">Váha přetížena</string>
+    <string name="forgot_password">Zapomenuté heslo</string>
+    <string name="enter_email_id">Zadejte E-mail</string>
+    <string name="enter_password">Zadejte heslo</string>
+    <string name="register">Zaregistrujte se</string>
+    <string name="launch_detail">Připojte se k nám ještě dnes a užijte si dokonalý zážitek z vaření</string>
+    <string name="login_sign_up">Přihlášení / registrace</string>
+    <string name="skip_for_now">Prozatím přeskočit</string>
+    <string name="reset_password">Obnovit heslo</string>
+    <string name="enter_captcha">Vyplňte Captcha</string>
+    <string name="send_email">Odeslat e-mail</string>
+    <string name="enter_password_again">Zadejte heslo znovu</string>
+    <string name="enter_the_captcha_obtained_from_the_mail">Zadejte Captcha kód získaný z E-mailu</string>
+    <string name="nickname">Uživatelské jméno</string>
+    <string name="enter_nickname">Zadejte jméno</string>
+    <string name="Gender">Pohlaví</string>
+    <string name="male">Muž</string>
+    <string name="age">Věk</string>
+    <string name="save">Uložit</string>
+    <string name="cancellation_of_account">Zrušení účtu</string>
+    <string name="sign_up_it_s_free">Zaregistrujte se, je to ZDARMA</string>
+    <string name="pwd_requirement">Skládá se z písmen a číslic, přičemž počet číslic nesmí být menší než 8.</string>
+    <string name="please_select_age">Vyberte prosím věk</string>
+    <string name="cancel_lower">Zrušit</string>
+    <string name="female">Žena</string>
+    <string name="tare">TARE</string>
+    <string name="keep_cooking_in_the_background">Pokračovat ve vaření na pozadí?</string>
+    <string name="reset_button">RESET</string>
+    <string name="finish">Dokončit!</string>
+    <string name="error">Chyba</string>
+    <string name="download_failed">Stažení se nezdařilo</string>
+    <string name="warning">Varování!</string>
+    <string name="lid_unlock">Odemknutí víka</string>
+    <string name="share_with_more_people">Sdílet s více lidmi</string>
+    <string name="scan_qr_code_with_camera">Naskenujte QR kód pomocí fotoaparátu</string>
+    <string name="enter_what_you_want_to_say">Zadejte svůj komentář</string>
+    <string name="note_title">NADPIS POZNÁMKY</string>
+    <string name="type_your_notes_here">Zde zadejte svou poznámku</string>
+    <string name="make_1_jar">1 sklenice</string>
+    <string name="make_n_jars">%1 sklenic</string>
+    <string name="per_serving">Na jednu porci</string>
+    <string name="preparation">Příprava:</string>
+    <string name="hours">h</string>
+    <string name="min">min</string>
+    <string name="ready_in">Hotova za:</string>
+    <string name="jar">Sklenice</string>
+    <string name="serving_sizes">Velikost porce</string>
+    <string name="score">Skóre</string>
+    <string name="share">Sdílet</string>
+    <string name="delete">Smazat</string>
+    <string name="recipe_update_tips">Bylo nalezeno celkem {{num}} receptů. Chcete si je stáhnout?</string>
+    <string name="no_recipe_update_tips">Není k dispozici žádný nový balíček receptů \n Aktuálně nejnovější verze</string>
+    <string name="recipe_update_process_tips">(({{progress}})Stahování dat receptů...</string>
+    <string name="recipe_update_finish">Aktualizace receptů dokončena</string>
+    <string name="update_recipe_title">Aktualizace receptů</string>
+    <string name="restore_confirm_tips">Určitě chcete obnovit tovární nastavení?</string>
+    <string name="change_lang_tips">Program je spuštěn, ukončete prosím program a spusťte novou operaci!</string>
+    <string name="exit_weight_align">Ukončit kalibrace</string>
+    <string name="weight_aligning">Kalibrace…</string>
+    <string name="weight_one_kg_tips">Vložte hmotnost 1 kg</string>
+    <string name="weight_two_kg_tips">Vložte hmotnost 2 kg</string>
+    <string name="weight_align_success">Kalibrace proběhla úspěšně!</string>
+    <string name="change_lang_tips2">Po přepnutí jazyka se současně změní i jazyky receptů a zařízení se znovu spustí. Určitě chcete změnit jazyk? </string>
+    <string name="pot_clover_not_clost_tips">Víko je odemčené. Prosím, neprve zamkněte víko, pak spusťte.</string>
+    <string name="screen_saver_title">Chcete přejít do "breath-holding" režimu?</string>
+    <string name="sex">Pohlaví</string>
+    <string name="wight">HMOTNOST</string>
+    <string name="running_block_tips">Zastavte běžící program a spusťte nový.</string>
+    <string name="unset_target_time">Čas nebyl nastaven.</string>
+</resources>

+ 1 - 0
BusinessCommon/src/main/res/values-en/strings.xml

@@ -233,4 +233,5 @@ Nanfang plus client is an online information platform developed and operated by
     <string name="no_login">Please enter the fields above to login</string>
     <string name="enjoy_your_meal_desc">enjoy your meal</string>
     <string name="wrong_captcha">Wrong captcha</string>
+    <string name="none">None</string>
 </resources>

+ 2 - 0
BusinessCommon/src/main/res/values-fr/strings.xml

@@ -286,4 +286,6 @@ Nanfang plus client is an online information platform developed and operated by
     <string name="enjoy_your_meal_desc">Votre recette est prête !</string>
     <string name="login_expire_tips">Veuillez saisir les champs ci-dessus pour vous connecter</string>
     <string name="wrong_captcha">Wrong captcha</string>
+    <string name="frement_010d_stage_first_finish">Ajoutez un film étirable dans le fond du panier vapeur puis disposez vos pots de yaourt. Fermez le couvercle et couvrez avec un linge ou un torchon.</string>
+    <string name="none">None</string>
 </resources>

+ 214 - 0
BusinessCommon/src/main/res/values-hu/strings.xml

@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="not_a_member_yet">Még nincs fiókod?</string>
+    <string name="member">Tagság</string>
+    <string name="select_language">Válasszon nyelvet</string>
+    <string name="next">TOVÁBB</string>
+    <string name="english">English</string>
+    <string name="chinese">简体中文</string>
+    <string name="france">Français</string>
+    <string name="japan">日本語</string>
+    <string name="czech">čeština</string>
+    <string name="slovak">日本語</string>
+    <string name="hungarian">Magyar</string>
+    <string name="polish">Polski</string>
+    <string name="skip">SKIP</string>
+    <string name="recipes">RECORDS</string>
+    <string name="mode">MODE</string>
+    <string name="sunday">Vasárnap</string>
+    <string name="monday">Hétfő</string>
+    <string name="tuesday">Kedd</string>
+    <string name="wednesday">Szerda</string>
+    <string name="thursday">Csütörtök</string>
+    <string name="friday">Péntek</string>
+    <string name="saturday">Szombat</string>
+    <string name="resume">RENEW</string>
+    <string name="privacy_policy">Adatvédelem</string>
+    <string name="privacy_policy_content"> Adatvédelmi szabályzat: nem gyűjtünk semmilyen személyes adatot.</string>
+    <string name="i_agree">Egyetértek</string>
+    <string name="i_have_read_the_privacy_policy">Elolvastam az adatvédelmi szabályzatot</string>
+    <string name="second">Második</string>
+    <string name="wifi">WI-FI</string>
+    <string name="off_line">OFF-LINE</string>
+    <string name="ok">OK</string>
+    <string name="on_line">ON-LINE</string>
+    <string name="pwd_can_not_be_empty">Kérjük, adja meg a jelszót.</string>
+    <string name="skin_for_now">Jelenlegi megjelenés</string>
+    <string name="login">Bejelentkezés</string>
+    <string name="online_recipes">Online receptek</string>
+    <string name="cook_history">Főzés története</string>
+    <string name="favourite_recipes">Kedvenc receptek</string>
+    <string name="settings">Beállítások</string>
+    <string name="grid_view">Rácsnézet</string>
+    <string name="list_view">Lista nézet</string>
+    <string name="adapted_cooking">MÓDOSÍTOTT RECEPTEK</string>
+    <string name="scales">SÚLY</string>
+    <string name="boil_water">FORRÓ VÍZ</string>
+    <string name="chop">vágott</string>
+    <string name="slow_cook">LASSÚ FŐZÉS</string>
+    <string name="knead_dough">A TÉSZTA GYÚRÁSA</string>
+    <string name="steam">GŐZ</string>
+    <string name="food_processor">ÉLELMISZER-FELDOLGOZÁS</string>
+    <string name="turbo">TURBO</string>
+    <string name="language">NYELV</string>
+    <string name="sound">HANG</string>
+    <string name="brightness">JAS</string>
+    <string name="user_account">FELHASZNÁLÓI FELSZÁLLÍTÁS</string>
+    <string name="storage">HÁTTÉR</string>
+    <string name="reset">HÁTTÉR</string>
+    <string name="about">O</string>
+    <string name="weight">MASS</string>
+    <string name="local_recipes">Helyi receptek</string>
+    <string name="download">Letöltések</string>
+    <string name="downloading">Letöltés</string>
+    <string name="enter_search">Visszakeresve a</string>
+    <string name="search">Keresés</string>
+    <string name="most_popular">Legnépszerűbb</string>
+    <string name="newest">Legújabb</string>
+    <string name="the_most_commonly_searched">Legtöbbet keresett</string>
+    <string name="notice">Közlemények</string>
+    <string name="all">ALL</string>
+    <string name="Recipes">Receptek</string>
+    <string name="ingredients">Hozzávalók</string>
+    <string name="Brightness">Jas</string>
+    <string name="screen_lock_time">Képernyőzár idő</string>
+    <string name="time_3min">3 perc</string>
+    <string name="time_10min">10 perc</string>
+    <string name="time_30min">30 perc</string>
+    <string name="Sound">Hang</string>
+    <string name="text_to_speech">Szövegről beszédre</string>
+    <string name="Language">Nyelv</string>
+    <string name="Continue">TOVÁBB</string>
+    <string name="start_cooking">A FŐZÉS MEGKEZDÉSE</string>
+    <string name="off">FORRÁS</string>
+    <string name="on">BEÁLLÍTÁS</string>
+    <string name="update_the_recipes">Receptfrissítések</string>
+    <string name="apk">APK</string>
+    <string name="mcu">MCU</string>
+    <string name="tp">TP</string>
+    <string name="serial_number">Sorozatszám</string>
+    <string name="standby_time">Készenléti idő</string>
+    <string name="update">Frissítés</string>
+    <string name="About">A webhelyről</string>
+    <string name="are_you_sure_to_restore_factory_settings">Biztos, hogy vissza szeretné állítani a gyári beállításokat?</string>
+    <string name="yes">IGEN</string>
+    <string name="restore_factory_settings">Gyári beállítások visszaállítása</string>
+    <string name="network_wifi_status_connected_no_internet">Csatlakoztatva van, de nem tud hozzáférni az internethez</string>
+    <string name="network_wifi_status_saved">Mentette</string>
+    <string name="network_wifi_status_idle">Hálózat állapota</string>
+    <string name="network_wifi_status_disabled">"Leállt"</string>
+    <string name="network_wifi_status_network_failure">IP-cím konfigurációs hiba</string>
+    <string name="network_wifi_status_wifi_failure">"WLAN-kapcsolat meghibásodása"</string>
+    <string name="network_wifi_status_password_failure">"Hitelesítési probléma lépett fel"</string>
+    <string name="network_wifi_status_scanning">Szkennelés...</string>
+    <string name="network_wifi_status_connecting">Csatlakozás</string>
+    <string name="network_wifi_status_authenticating">Hitelesítés folyamatban...</string>
+    <string name="network_wifi_status_obtaining_ip_address">IP-cím megszerzése...</string>
+    <string name="network_wifi_status_connected">Csatlakozás</string>
+    <string name="network_wifi_status_suspended">Felfüggesztve</string>
+    <string name="network_wifi_status_disconnecting">Kapcsolat megszakad...</string>
+    <string name="network_wifi_status_disconnected">Lekapcsolva</string>
+    <string name="network_wifi_status_failed">Sikertelen</string>
+    <string name="network_wifi_status_blocked">Blokkolt</string>
+    <string name="network_wifi_status_verifying_poor_link">Átmenetileg letiltva (rossz hálózati állapot)</string>
+    <string name="start">START</string>
+    <string name="pause">PAUSE</string>
+    <string name="cancel">CANCEL</string>
+    <string name="confirm">MEGERŐSÍTÉS</string>
+    <string name="stop">STOP</string>
+    <string name="turn_right">Forgassa\ésjobbra</string>
+    <string name="turn_left">Forduljon balra</string>
+    <string name="temperature">TEMPERATURE</string>
+    <string name="time">IDŐ</string>
+    <string name="speed">SPEED</string>
+    <string name="direction">IRÁNY</string>
+    <string name="bad">Bad</string>
+    <string name="imperfect">Tökéletlen</string>
+    <string name="ordinary">Normális</string>
+    <string name="good">Jó</string>
+    <string name="perfect">Tökéletes</string>
+    <string name="are_you_sure_to_delete">Biztos, hogy törölni akarja?</string>
+    <string name="no">NEM</string>
+    <string name="unset_param_tips">Kérjük, állítsa be a műveleti paramétereket</string>
+    <string name="pmpt_confirm">Megerősítés</string>
+    <string name="pmpt_cancel">Cancel</string>
+    <string name="pmpt_msg">Tippek</string>
+    <string name="dev_end_of_run_tips">Kész</string>
+    <string name="hight_temp_warning_tips">Az aktuális hőmérséklet 60 °C felett van, és a motor fordulatszáma a harmadik fokozat felett van. Biztos, hogy folytatni szeretné?</string>
+    <string name="hight_temp_turbo_tips">Az aktuális hőmérséklet meghaladja a 60 °C-ot, a turbó funkció nem működtethető.</string>
+    <string name="update_msg">Rendszerfrissítés folyamatban, kérjük, várjon</string>
+    <string name="update_title">Ez a legújabb verzió?</string>
+    <string name="finish_download">Letöltve a</string>
+    <string name="download_fail">A letöltés sikertelen</string>
+    <string name="start_download">Kezdeményezze a letöltést</string>
+    <string name="weight_overload_tips">Túlterhelt súly</string>
+    <string name="forgot_password">Elfelejtett jelszó</string>
+    <string name="enter_email_id">Adja meg az e-mail címét</string>
+    <string name="enter_password">Jelszó megadása</string>
+    <string name="register">Regisztrálj</string>
+    <string name="launch_detail">Csatlakozzon hozzánk még ma és élvezze a végső főzési élményt</string>
+    <string name="login_sign_up">Bejelentkezés / Regisztráció</string>
+    <string name="skip_for_now">Egyelőre kihagyni</string>
+    <string name="reset_password">Jelszó visszaállítása</string>
+    <string name="enter_captcha">Töltse ki a Captcha-t</string>
+    <string name="send_email">E-mail küldése</string>
+    <string name="enter_password_again">Adja meg újra a jelszót</string>
+    <string name="enter_the_captcha_obtained_from_the_mail">Írja be az e-mailben kapott Captcha kódot</string>
+    <string name="nickname">Felhasználónév</string>
+    <string name="enter_nickname">Adja meg a nevet</string>
+    <string name="Gender">Nem</string>
+    <string name="male">Férfi</string>
+    <string name="age">Életkor</string>
+    <string name="save">Mentés</string>
+    <string name="cancellation_of_account">Számla törlése</string>
+    <string name="sign_up_it_s_free">Regisztrálj, ez INGYENES</string>
+    <string name="pwd_requirement">Betűkből és számokból áll, legalább 8 számjegyből.</string>
+    <string name="please_select_age">Kérjük, válassza ki az életkorát</string>
+    <string name="cancel_lower">Törlés</string>
+    <string name="female">Női</string>
+    <string name="tare">TARE</string>
+    <string name="keep_cooking_in_the_background">Folytassa a főzést a háttérben?</string>
+    <string name="reset_button">RESET</string>
+    <string name="finish">Befejezni!</string>
+    <string name="error">Hiba</string>
+    <string name="download_failed">A letöltés sikertelen</string>
+    <string name="warning">Figyelmeztetés!</string>
+    <string name="lid_unlock">A fedél feloldása</string>
+    <string name="share_with_more_people">Megosztás több emberrel</string>
+    <string name="scan_qr_code_with_camera">Szkennelje be a QR-kódot a kamerával</string>
+    <string name="enter_what_you_want_to_say">Írja be a megjegyzését</string>
+    <string name="note_title">A MEGJEGYZÉS CÍME</string>
+    <string name="type_your_notes_here">Írja be a megjegyzést ide</string>
+    <string name="make_1_jar">1 pohár</string>
+    <string name="make_n_jars">%1 pohár</string>
+    <string name="per_serving">Adagonként</string>
+    <string name="preparation">Elkészítés</string>
+    <string name="hours">óra</string>
+    <string name="min">perc</string>
+    <string name="ready_in">Kész:</string>
+    <string name="jar">poharak</string>
+    <string name="serving_sizes">Adagolási méret</string>
+    <string name="score">Pontozás</string>
+    <string name="share">Ossza meg ezt</string>
+    <string name="delete">Törölje</string>
+    <string name="recipe_update_tips">Összesen {{num}} receptet találtunk. Szeretné letölteni őket?</string>
+    <string name="no_recipe_update_tips">Nincs új receptcsomag elérhető \n Jelenleg a legújabb verzió</string>
+    <string name="recipe_update_process_tips">({{progress}})A receptadatok letöltése...</string>
+    <string name="recipe_update_finish">A receptek frissítése befejeződött</string>
+    <string name="update_recipe_title">Recept frissítések</string>
+    <string name="restore_confirm_tips">Biztos, hogy vissza szeretné állítani a gyári beállításokat?</string>
+    <string name="change_lang_tips">A program fut, kérjük, lépjen ki a programból és indítson új műveletet!</string>
+    <string name="exit_weight_align">Kilépés a kalibrálásból</string>
+    <string name="weight_aligning">Kalibrálás...</string>
+    <string name="weight_one_kg_tips">Kérjük, adjon meg 1 kg súlyt</string>
+    <string name="weight_two_kg_tips">Kérjük, adjon meg 2 kg súlyt</string>
+    <string name="weight_align_success">A kalibrálás sikeres volt!</string>
+    <string name="change_lang_tips2">A nyelvváltás után a receptnyelvek egyszerre változnak, és a készülék újraindul. Biztos, hogy meg akarja változtatni a nyelvet?</string>
+    <string name="pot_clover_not_clost_tips">A fedél fel van oldva. Kérjük, ne zárja le a fedelet, majd indítsa el.</string>
+    <string name="screen_saver_title">Szeretne "breath-holding"  üzemmódba lépni?</string>
+    <string name="sex">Gender</string>
+    <string name="wight">SÚLY</string>
+    <string name="running_block_tips">Állítsa le a futó programot, és indítson el egy újat.</string>
+    <string name="unset_target_time">Az idő nem lett beállítva.</string>
+</resources>

+ 1 - 0
BusinessCommon/src/main/res/values-ja/strings.xml

@@ -158,4 +158,5 @@
     <string name="Min20">20Min</string>
     <string name="enjoy_your_meal">ENJOY YOUR MEAL</string>
     <string name="wrong_captcha">Wrong captcha</string>
+    <string name="none">None</string>
 </resources>

+ 214 - 0
BusinessCommon/src/main/res/values-sk/strings.xml

@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="not_a_member_yet">Ešte nemáte účet?</string>
+    <string name="member">Členstvo</string>
+    <string name="select_language">Vyberte si svoj jazyk</string>
+    <string name="next">VIAC</string>
+    <string name="english">English</string>
+    <string name="chinese">简体中文</string>
+    <string name="france">Français</string>
+    <string name="japan">日本語</string>
+    <string name="czech">čeština</string>
+    <string name="slovak">日本語</string>
+    <string name="hungarian">Magyar</string>
+    <string name="polish">Polski</string>
+    <string name="skip">SKIP</string>
+    <string name="recipes">RECORDY</string>
+    <string name="mode">REŽIM</string>
+    <string name="sunday">Nedeľa</string>
+    <string name="monday">Pondelok</string>
+    <string name="tuesday">Utorok</string>
+    <string name="wednesday">Streda</string>
+    <string name="thursday">Štvrtok</string>
+    <string name="friday">Piatok</string>
+    <string name="saturday">Sobota</string>
+    <string name="resume">RENEW</string>
+    <string name="privacy_policy">Zásady ochrany osobných údajov</string>
+    <string name="privacy_policy_content">Zásady ochrany osobných údajov: Nezhromažďujeme žiadne vaše osobné údaje.</string>
+    <string name="i_agree">Súhlasím</string>
+    <string name="i_have_read_the_privacy_policy">Prečítal som si zásady ochrany osobných údajov</string>
+    <string name="second">Druhá stránka</string>
+    <string name="wifi">WI-FI</string>
+    <string name="off_line">OFF-LINE</string>
+    <string name="ok">OK</string>
+    <string name="on_line">ON-LINE</string>
+    <string name="pwd_can_not_be_empty">Vyplňte heslo.</string>
+    <string name="skin_for_now">Aktuálny vzhľad</string>
+    <string name="login">Prihlásenie</string>
+    <string name="online_recipes">Online recepty</string>
+    <string name="cook_history">História varenia</string>
+    <string name="favourite_recipes">Obľúbené recepty</string>
+    <string name="settings">Nastavenia</string>
+    <string name="grid_view">Zobrazenie mriežky</string>
+    <string name="list_view">Zobrazenie zoznamu</string>
+    <string name="adapted_cooking">UPRAVENÉ RECEPTY</string>
+    <string name="scales">WEIGHT</string>
+    <string name="boil_water">VARNÁ VODA</string>
+    <string name="chop">nakrájané na</string>
+    <string name="slow_cook">POMALÉ VARENIE</string>
+    <string name="knead_dough">MIESENIE CESTA</string>
+    <string name="steam">PÁRA</string>
+    <string name="food_processor">SPRACOVANIE POTRAVÍN</string>
+    <string name="turbo">TURBO</string>
+    <string name="language">JAZYČNICA</string>
+    <string name="sound">ZVUK</string>
+    <string name="brightness">JAS</string>
+    <string name="user_account">UŽÍVATEĽSKÝ ÚČET</string>
+    <string name="storage">BACKGROUND</string>
+    <string name="reset">BACKGROUND</string>
+    <string name="about">O</string>
+    <string name="weight">MASS</string>
+    <string name="local_recipes">Miestne recepty</string>
+    <string name="download">Na stiahnutie</string>
+    <string name="downloading">Na stiahnutie</string>
+    <string name="enter_search">Získané z</string>
+    <string name="search">Vyhľadávanie</string>
+    <string name="most_popular">Najobľúbenejšie</string>
+    <string name="newest">Najnovšie</string>
+    <string name="the_most_commonly_searched">Najvyhľadávanejšie</string>
+    <string name="notice">Oznámenia</string>
+    <string name="all">VŠETKY</string>
+    <string name="Recipes">Recepty</string>
+    <string name="ingredients">Ingrediencie</string>
+    <string name="Brightness">Jas</string>
+    <string name="screen_lock_time">Čas uzamknutia obrazovky</string>
+    <string name="time_3min">3 minúty</string>
+    <string name="time_10min">10 minút</string>
+    <string name="time_30min">30 minút</string>
+    <string name="Sound">Zvuk</string>
+    <string name="text_to_speech">Prevod textu na reč</string>
+    <string name="Language">Jazyk</string>
+    <string name="Continue">POKRAČOVAŤ</string>
+    <string name="start_cooking">ZAČÍNAME VARIŤ</string>
+    <string name="off">ZDROJ</string>
+    <string name="on">ZAPNUTIE</string>
+    <string name="update_the_recipes">Aktualizácie receptov</string>
+    <string name="apk">APK</string>
+    <string name="mcu">MCU</string>
+    <string name="tp">TP</string>
+    <string name="serial_number">Sériové číslo</string>
+    <string name="standby_time">Čas pohotovostného režimu</string>
+    <string name="update">Aktualizácia</string>
+    <string name="About">O stránke</string>
+    <string name="are_you_sure_to_restore_factory_settings">Ste si istí, že chcete obnoviť výrobné nastavenia?</string>
+    <string name="yes">ÁNO</string>
+    <string name="restore_factory_settings">Obnovenie továrenských nastavení</string>
+    <string name="network_wifi_status_connected_no_internet">Pripojený, ale bez prístupu na internet</string>
+    <string name="network_wifi_status_saved">Uložené</string>
+    <string name="network_wifi_status_idle">Stav siete</string>
+    <string name="network_wifi_status_disabled">"Zastavené"</string>
+    <string name="network_wifi_status_network_failure">Zlyhanie konfigurácie adresy IP</string>
+    <string name="network_wifi_status_wifi_failure">"Zlyhanie pripojenia k sieti WLAN"</string>
+    <string name="network_wifi_status_password_failure">"Vyskytol sa problém s overovaním"</string>
+    <string name="network_wifi_status_scanning">Skenovanie...</string>
+    <string name="network_wifi_status_connecting">Pripojenie</string>
+    <string name="network_wifi_status_authenticating">Prebieha overovanie...</string>
+    <string name="network_wifi_status_obtaining_ip_address">Získavanie IP adresy...</string>
+    <string name="network_wifi_status_connected">Pripojené</string>
+    <string name="network_wifi_status_suspended">Pozastavené</string>
+    <string name="network_wifi_status_disconnecting">Odpojenie...</string>
+    <string name="network_wifi_status_disconnected">Odpojené</string>
+    <string name="network_wifi_status_failed">Neúspešné</string>
+    <string name="network_wifi_status_blocked">Zablokované</string>
+    <string name="network_wifi_status_verifying_poor_link">Dočasne vypnuté (zlý stav siete)</string>
+    <string name="start">START</string>
+    <string name="pause">PAUZA</string>
+    <string name="cancel">CANCEL</string>
+    <string name="confirm">CONFIRM</string>
+    <string name="stop">STOP</string>
+    <string name="turn_right">Otáčajte\a doprava</string>
+    <string name="turn_left">Otočiť doľava</string>
+    <string name="temperature">TEPLOTA</string>
+    <string name="time">ČAS</string>
+    <string name="speed">RÝCHLOSŤ</string>
+    <string name="direction">SMER</string>
+    <string name="bad">Zlé</string>
+    <string name="imperfect">Nedokonalé</string>
+    <string name="ordinary">Obyčajný</string>
+    <string name="good">Dobrý</string>
+    <string name="perfect">Perfektný</string>
+    <string name="are_you_sure_to_delete">Ste si istí, že ho chcete vymazať?</string>
+    <string name="no">NIE</string>
+    <string name="unset_param_tips">Nastavte parametre operácie</string>
+    <string name="pmpt_confirm">Potvrďte</string>
+    <string name="pmpt_cancel">Zrušiť</string>
+    <string name="pmpt_msg">Tipy</string>
+    <string name="dev_end_of_run_tips">Hotovo</string>
+    <string name="hight_temp_warning_tips">Aktuálna teplota je vyššia ako 60 °C a otáčky motora sú vyššie ako tretí prevodový stupeň. Ste si istí, že chcete pokračovať?</string>
+    <string name="hight_temp_turbo_tips">Aktuálna teplota je vyššia ako 60 °C, funkciu turbo nemožno spustiť.</string>
+    <string name="update_msg">Prebieha aktualizácia systému, počkajte, prosím</string>
+    <string name="update_title">Je toto najnovšia verzia?</string>
+    <string name="finish_download">Stiahnutá z</string>
+    <string name="download_fail">Stiahnutie sa nepodarilo</string>
+    <string name="start_download">Spustite sťahovanie</string>
+    <string name="weight_overload_tips">Hmotnosť preťažená</string>
+    <string name="forgot_password">Zabudli ste heslo</string>
+    <string name="enter_email_id">Zadajte e-mail</string>
+    <string name="enter_password">Zadajte heslo</string>
+    <string name="register">Zaregistrujte sa</string>
+    <string name="launch_detail">Pridajte sa k nám ešte dnes a užite si dokonalý zážitok z varenia</string>
+    <string name="login_sign_up">Prihlásenie / registrácia</string>
+    <string name="skip_for_now">Preskočiť pre teraz</string>
+    <string name="reset_password">Obnoviť heslo</string>
+    <string name="enter_captcha">Vyplňte Captcha</string>
+    <string name="send_email">Odoslať e-mail</string>
+    <string name="enter_password_again">Znovu zadajte heslo</string>
+    <string name="enter_the_captcha_obtained_from_the_mail">Zadajte kód Captcha získaný z e-mailu</string>
+    <string name="nickname">Používateľské meno</string>
+    <string name="enter_nickname">Zadajte meno</string>
+    <string name="Gender">Pohlavie</string>
+    <string name="male">Muž</string>
+    <string name="age">Vek</string>
+    <string name="save">Uložiť</string>
+    <string name="cancellation_of_account">Zrušenie účtu</string>
+    <string name="sign_up_it_s_free">Zaregistrujte sa, je to ZADARMO</string>
+    <string name="pwd_requirement">Pozostáva z písmen a číslic, pričom nesmie obsahovať menej ako 8 číslic.</string>
+    <string name="please_select_age">Vyberte svoj vek</string>
+    <string name="cancel_lower">Zrušiť</string>
+    <string name="female">Žena</string>
+    <string name="tare">TARE</string>
+    <string name="keep_cooking_in_the_background">Pokračovať vo varení na pozadí?</string>
+    <string name="reset_button">RESETOVAŤ</string>
+    <string name="finish">Dokončiť!</string>
+    <string name="error">Chyba</string>
+    <string name="download_failed">Stiahnutie sa nepodarilo</string>
+    <string name="warning">Upozornenie!</string>
+    <string name="lid_unlock">Odomknutie veka</string>
+    <string name="share_with_more_people">Zdieľanie s ďalšími ľuďmi</string>
+    <string name="scan_qr_code_with_camera">Naskenujte kód QR pomocou fotoaparátu</string>
+    <string name="enter_what_you_want_to_say">Zadajte svoj komentár</string>
+    <string name="note_title">NÁZOV POZNÁMKY</string>
+    <string name="type_your_notes_here">Tu zadajte svoj komentár</string>
+    <string name="make_1_jar">1 sklo</string>
+    <string name="make_n_jars">%1 pohárov</string>
+    <string name="per_serving">Na jednu porciu</string>
+    <string name="preparation">Príprava:</string>
+    <string name="hours">h</string>
+    <string name="min">min</string>
+    <string name="ready_in">Hotové za:</string>
+    <string name="jar">Skleničky</string>
+    <string name="serving_sizes">Veľkosť porcie</string>
+    <string name="score">Skóre</string>
+    <string name="share">Zdieľať</string>
+    <string name="delete">Vymazať</string>
+    <string name="recipe_update_tips">Celkovo bolo nájdených {{num}} receptov. Chcete si ich stiahnuť?</string>
+    <string name="no_recipe_update_tips">Žiadny nový balík receptov nie je k dispozícii \n V súčasnosti je k dispozícii najnovšia verzia</string>
+    <string name="recipe_update_process_tips">({{progress}})Sťahovanie údajov o receptoch...</string>
+    <string name="recipe_update_finish">Aktualizácia receptov dokončená</string>
+    <string name="update_recipe_title">Aktualizácia receptov</string>
+    <string name="restore_confirm_tips">Ste si istí, že chcete obnoviť výrobné nastavenia?</string>
+    <string name="change_lang_tips">Program je spustený, ukončite ho a spustite novú operáciu!</string>
+    <string name="exit_weight_align">Ukončenie kalibrácie</string>
+    <string name="weight_aligning">Kalibrácia...</string>
+    <string name="weight_one_kg_tips">Vložte hmotnosť 1 kg</string>
+    <string name="weight_two_kg_tips">Vložte hmotnosť 2 kg</string>
+    <string name="weight_align_success">Kalibrácia prebehla úspešne!</string>
+    <string name="change_lang_tips2">Po prepnutí jazyka sa súčasne zmenia aj jazyky receptov a zariadenie sa reštartuje. Ste si istí, že chcete zmeniť jazyk?</string>
+    <string name="pot_clover_not_clost_tips">Veko je odomknuté. Prosím, nezamykajte veko, potom spustite.</string>
+    <string name="screen_saver_title">Chcete prejsť do režimu "breath-holding"?</string>
+    <string name="sex">Pohlavie</string>
+    <string name="wight">HMOTNOSŤ</string>
+    <string name="running_block_tips">Zastavte spustený program a spustite nový program.</string>
+    <string name="unset_target_time">Čas nebol nastavený.</string>
+</resources>

+ 1 - 0
BusinessCommon/src/main/res/values-zh-rCN/strings.xml

@@ -296,4 +296,5 @@ Nanfang plus client is an online information platform developed and operated by
     <string name="no_net_error">Please connect to Wifi</string>
     <string name="no_login">Veuillez saisir les champs ci-dessus pour vous connecter</string>
     <string name="wrong_captcha">Wrong captcha</string>
+    <string name="none">None</string>
 </resources>

+ 2 - 0
BusinessCommon/src/main/res/values/strings.xml

@@ -299,5 +299,7 @@ Nanfang plus client is an online information platform developed and operated by
     <string name="wrong_captcha">Wrong captcha</string>
     <string name="sao_ma_pei_wang">Please scan the QR code for network configuration.</string>
     <string name="cancel_tuya_bind">Cancel Bind</string>
+    <string name="frement_010d_stage_first_finish">Place a sheet of plastic wrap at the bottom of the steaming basket, then arrange your yogurt pots. Close the lid and cover with a cloth or a towel.</string>
+    <string name="none">None</string>
 
 </resources>

+ 9 - 6
BusinessMain/src/main/java/com/develop/main/viewmodel/HomeViewModel.kt

@@ -109,6 +109,9 @@ class HomeViewModel : BaseViewModel() {
                     size.toString()
                 }
             }
+            result.sortBy {
+                it.name
+            }
             categorySizeList.forEach {
                 allSize += it.value.toInt()
             }
@@ -322,7 +325,7 @@ class HomeViewModel : BaseViewModel() {
                             FoodContentModel(
                                 it.photoPath ?: "",
                                 it.name ?: "",
-                                3,
+                                it.score?.toInt() ?: 0,
                                 getTime(it.makeHours ?: 0, it.makeMinutes ?: 0),
                                 it.difficultyLevel ?: "",
                                 foodId = it.number ?: "",
@@ -338,7 +341,7 @@ class HomeViewModel : BaseViewModel() {
                             FoodContentModel(
                                 it.photoPath ?: "",
                                 it.name ?: "",
-                                3,
+                                it.score?.toInt() ?: 0,
                                 getTime(it.makeHours ?: 0, it.makeMinutes ?: 0),
                                 it.difficultyLevel ?: "",
                                 foodId = it.number ?: "",
@@ -354,7 +357,7 @@ class HomeViewModel : BaseViewModel() {
                             FoodContentModel(
                                 it.photoPath ?: "",
                                 it.name ?: "",
-                                3,
+                                it.score?.toInt() ?: 0,
                                 getTime(it.makeHours ?: 0, it.makeMinutes ?: 0),
                                 it.difficultyLevel ?: "",
                                 foodId = it.number ?: "",
@@ -415,7 +418,7 @@ class HomeViewModel : BaseViewModel() {
                             FoodContentModel(
                                 it.photoPath ?: "",
                                 it.name ?: "",
-                                3,
+                                it.score?.toInt() ?: 0,
                                 getTime(it.makeHours ?: 0, it.makeMinutes ?: 0),
                                 it.difficultyLevel ?: "",
                                 foodId = it.number ?: ""
@@ -430,7 +433,7 @@ class HomeViewModel : BaseViewModel() {
                             FoodContentModel(
                                 it.photoPath ?: "",
                                 it.name ?: "",
-                                3,
+                                it.score?.toInt() ?: 0,
                                 getTime(it.makeHours ?: 0, it.makeMinutes ?: 0),
                                 it.difficultyLevel ?: "",
                                 foodId = it.number ?: ""
@@ -445,7 +448,7 @@ class HomeViewModel : BaseViewModel() {
                             FoodContentModel(
                                 it.photoPath ?: "",
                                 it.name ?: "",
-                                3,
+                                it.score?.toInt() ?: 0,
                                 getTime(it.makeHours ?: 0, it.makeMinutes ?: 0),
                                 it.difficultyLevel ?: "",
                                 foodId = it.number ?: ""

+ 18 - 14
BusinessStep/src/main/java/com/develop/step/ui/ModesDetailActivity.kt

@@ -88,6 +88,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
     private var isTempChange = false
     private var isTimeChange = false
     private var isMotorGearChange = false
+    private var isMotorDirectionGearChange = false
     private var isWaterGearChange = false
     private var initModeData = false
     private var pressStartTime = -1L
@@ -773,7 +774,8 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                             isMotorGearChange,
                             focusUpdate = true
                         )
-
+                        this@ModesDetailActivity.isMotorDirectionGearChange =
+                            isMotorDirectionGearChange
                         updateMotorDirectionUI(motorDirection.toInt(), isMotorDirectionChange)
 
                         updateWeightUI(currDevInfo.weight.toFloat())
@@ -1813,24 +1815,26 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
      * 点击电机方向事件
      */
     private fun motorGearDirectionClick(direction: DirectionView.Direction) {
-        userChanging = true
-        binding.clCookDirection.updateChangeValue(
-            viewModel.getDirectionStr(
-                direction == DirectionView.Direction.LEFT, resources
+        if (isMotorDirectionGearChange) {
+            userChanging = true
+            binding.clCookDirection.updateChangeValue(
+                viewModel.getDirectionStr(
+                    direction == DirectionView.Direction.LEFT, resources
+                )
             )
-        )
-        if (direction != DirectionView.Direction.RIGHT) {
-            CofarSDK.cfgMotorDirection(MotorDirections.REVERSE);
-            updateMotorDirectionUI(MotorDirections.REVERSE.toInt(), true);
+            if (direction != DirectionView.Direction.RIGHT) {
+                CofarSDK.cfgMotorDirection(MotorDirections.REVERSE);
+                updateMotorDirectionUI(MotorDirections.REVERSE.toInt(), true);
 
 
-        } else {
-            CofarSDK.cfgMotorDirection(MotorDirections.FORWARD);
-            updateMotorDirectionUI(MotorDirections.FORWARD.toInt(), true);
+            } else {
+                CofarSDK.cfgMotorDirection(MotorDirections.FORWARD);
+                updateMotorDirectionUI(MotorDirections.FORWARD.toInt(), true);
 
-        }
+            }
 
-        showConfirmAndCancelBtn()
+            showConfirmAndCancelBtn()
+        }
     }
 
     /**

+ 120 - 71
BusinessStep/src/main/java/com/develop/step/ui/cook_step/CookStepActivity.kt

@@ -11,6 +11,7 @@ import androidx.core.view.isInvisible
 import com.alibaba.android.arouter.facade.annotation.Autowired
 import com.develop.base.ext.load
 import com.alibaba.android.arouter.facade.annotation.Route
+import com.blankj.utilcode.util.LogUtils
 import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
 import com.develop.base.ext.background_drawable
 import com.develop.base.ext.isNightTheme
@@ -18,6 +19,7 @@ import com.develop.base.ext.navigateTo
 import com.develop.base.ext.setGone
 import com.develop.base.ext.setVisible
 import com.develop.base.ext.src
+import com.develop.base.ext.toJson
 import com.develop.base.ext.updateText
 import com.develop.base.util.MusicBackPlayerUtil
 import com.develop.base.util.ThreadUtils
@@ -48,6 +50,8 @@ import com.kuyuntech.cofarcooking.device.sdk.constant.core.*
 import com.kuyuntech.cofarcooking.device.sdk.eventbus.core.DevInfo
 import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevCommonEvent
 import com.kuyuntech.cofarcooking.device.sdk.util.core.CofarSDK
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import java.io.File
@@ -77,6 +81,11 @@ class CookStepActivity : CookStepBaseActivity() {
     private var titleName = ""
     private var currModes = ""
 
+    private var currentTemp = 0
+    private var currentMotorGer = 0
+    private var currentWaterGear = 0
+    private var currTime = 0
+
 
     private fun turnDevModeUI() {
 
@@ -133,6 +142,7 @@ class CookStepActivity : CookStepBaseActivity() {
                         val totalTime = second + (minute + hours * 60) * 60
                         viewModel.displayStep()?.uiData?.targetTime = totalTime
                         binding.controller.tvCookingTimeTarget.updateText("--${time}--")
+                        currTime = totalTime
                         CofarSDK.cfgTime(totalTime)
                     }
                 }
@@ -483,7 +493,10 @@ class CookStepActivity : CookStepBaseActivity() {
                         binding.llStepFinish.setGone()
                     }
                     it.uiData.applyRecipeSetting(it.source)
-
+                    currentTemp = it.uiData.targetTemp
+                    currentMotorGer = it.uiData.currentSpeed
+                    currentWaterGear = it.uiData.currentWaterGear
+                    currTime = it.uiData.targetTime
                     if (!it.isWeightMode() && !it.isDescription()) {
                         //设置初始参数
                         CofarSDK.cfgMotorGear(0)
@@ -609,6 +622,11 @@ class CookStepActivity : CookStepBaseActivity() {
             }
         } else if (tag == BUTTON_TAG_CANCEL) {
             CofarSDK.cancel()
+            val uiData = viewModel.displayStep()?.uiData
+            currTime = uiData?.targetTime ?: 0
+            currentMotorGer = uiData?.currentSpeed ?: 0
+            currentWaterGear = uiData?.currentWaterGear ?: 0
+            currentTemp = uiData?.targetTemp ?: 0
             binding.controller.btnStart.setGone()
             binding.controller.btnReset.setGone()
         } else if (tag == BUTTON_TAG_NEXT_STEP) {
@@ -631,8 +649,10 @@ class CookStepActivity : CookStepBaseActivity() {
     }
 
     override fun onUserChangeTemp(value: Int) {
+        currentTemp = value
         val v = FoodSdkUtils.parseTemp(value.toShort())
         viewModel.displayStep()?.uiData?.targetTemp = v.toInt()
+        LogUtils.d("保存的目标温度:${v.toInt()}")
         binding.controller.tvCookingTempTarget.updateText("--${v}°C--")
         binding.controller.tvRingTempText.updateText("${v}°C")
         CofarSDK.cfgHeat(value.toShort(), HeatModes.PU_TONG)
@@ -640,6 +660,7 @@ class CookStepActivity : CookStepBaseActivity() {
     }
 
     override fun onUserChangeSpeed(value: Int) {
+        currentMotorGer = value
         viewModel.displayStep()?.uiData?.currentSpeed = value
         binding.controller.tvSetSpeed.updateText(value.toString())
         binding.controller.tvSpeedText.updateText(value.toString())
@@ -648,6 +669,7 @@ class CookStepActivity : CookStepBaseActivity() {
     }
 
     override fun onUserWaterGear(value: Int) {
+        currentWaterGear = value
         CofarSDK.cfgWaterBear(value);
         binding.controller.waterSprayShow.updateGear(value)                               // 圆环设置-当前运行速度
         binding.controller.clCookWater.binding.waterSprayShow.updateGear(value)
@@ -686,9 +708,13 @@ class CookStepActivity : CookStepBaseActivity() {
                 it.uiData.currentTemp = FoodSdkUtils.parseTemp(devInfo.temp).toInt()
                 it.uiData.remainTime = devInfo.remainTime
                 it.uiData.targetTimeBuffer = devInfo.targetTimeBuffer
+                it.uiData.targetTempBuffer = devInfo.targetTempBuffer.toInt()
                 it.uiData.isTimeChange = devInfo.mode.isTimeChange
                 it.uiData.isTempChange = devInfo.mode.isTempChange
                 it.uiData.isMotorDirectionChange = devInfo.mode.isMotorDirectionChange
+                it.uiData.motorGearBuffer = devInfo.motorGearBuffer.toInt()
+                it.uiData.motorDirectionBuffer = devInfo.motorDirectionBuffer.toInt()
+                it.uiData.waterGearBuffer = devInfo.waterGearBuffer.toInt()
                 it.uiData.isMotorGearChange = devInfo.mode.isMotorGearChange
                 it.uiData.limitMaxSpeed = devInfo.mode.maxMotorGear
                 it.uiData.limitMinSpeed = devInfo.mode.minMotorGear
@@ -821,67 +847,77 @@ class CookStepActivity : CookStepBaseActivity() {
         if (tabType == CookSettingType.TEMP_SETTING) {
             cookStep?.uiData?.let {
                 if (!it.isTempChange) {
+                    LogUtils.d("========")
                     return
                 }
+                LogUtils.d("调节前温度:${currentTemp}")
                 if (increase) {
-                    it.targetTemp += CofarSDK.getTempInterval()
-                    if (it.targetTemp > it.limitMaxTemp) {
-                        it.targetTemp = it.limitMaxTemp
+                    currentTemp += CofarSDK.getTempInterval()
+                    if (currentTemp > it.limitMaxTemp) {
+                        currentTemp = it.limitMaxTemp
+                    }
+                    if (currentTemp < 35) {
+                        currentTemp = 35
                     }
                 } else {
-                    it.targetTemp -= CofarSDK.getTempInterval()
-                    if (it.targetTemp < it.limitMinTemp) {
-                        it.targetTemp = it.limitMinTemp
+                    currentTemp -= CofarSDK.getTempInterval()
+                    if (currentTemp < it.limitMinTemp) {
+                        currentTemp = it.limitMinTemp
                     }
 
-                    if (it.targetTemp < 35) {
-                        it.targetTemp = 0
+                    if (currentTemp < 35) {
+                        currentTemp = 0
                     }
 
                 }
                 viewModel.stepUiData.doingModify = true
-                binding.controller.tempRingView.updateProgress(it.targetTemp)
-                onUserChangeTemp(it.targetTemp)
+                binding.controller.tempRingView.updateProgress(currentTemp)
+                LogUtils.d("调节后温度:${currentTemp}")
+                onUserChangeTemp(currentTemp)
             }
         } else if (tabType == CookSettingType.SPEED_SETTING) {
             cookStep?.uiData?.let {
                 if (!it.isMotorGearChange) {
                     return
                 }
+
+                LogUtils.d("调节前转速:${currentMotorGer}")
                 if (increase) {
-                    it.currentSpeed++
-                    if (it.currentSpeed > it.limitMaxSpeed) {
-                        it.currentSpeed = it.limitMaxSpeed
+                    currentMotorGer++
+                    if (currentMotorGer > it.limitMaxSpeed) {
+                        currentMotorGer = it.limitMaxSpeed
                     }
                 } else {
-                    it.currentSpeed--
-                    if (it.currentSpeed < it.limitMinSpeed) {
-                        it.currentSpeed = it.limitMinSpeed
+                    currentMotorGer--
+                    if (currentMotorGer < it.limitMinSpeed) {
+                        currentMotorGer = it.limitMinSpeed
                     }
                 }
                 viewModel.stepUiData.doingModify = true
-                binding.controller.speedRingView.updateProgress(it.currentSpeed)
-                onUserChangeSpeed(it.currentSpeed)
+                binding.controller.speedRingView.updateProgress(currentMotorGer)
+                LogUtils.d("调节后转速:${currentMotorGer}")
+                onUserChangeSpeed(currentMotorGer)
             }
         } else if (tabType == CookSettingType.WATER_SPRY) {
             cookStep?.uiData?.let {
                 if (!it.isWaterGearChange) {
                     return
                 }
+
                 if (increase) {
-                    it.currentWaterGear++
-                    if (it.currentWaterGear > it.limitMaxWaterGear) {
-                        it.currentWaterGear = it.limitMaxWaterGear
+                    currentWaterGear++
+                    if (currentWaterGear > it.limitMaxWaterGear) {
+                        currentWaterGear = it.limitMaxWaterGear
                     }
                 } else {
-                    it.currentWaterGear--
-                    if (it.currentWaterGear < it.limitMinWaterGear) {
-                        it.currentWaterGear = it.limitMinWaterGear
+                    currentWaterGear--
+                    if (currentWaterGear < it.limitMinWaterGear) {
+                        currentWaterGear = it.limitMinWaterGear
                     }
                 }
                 viewModel.stepUiData.doingModify = true
-                binding.controller.waterRingView.updateProgress(it.currentWaterGear)
-                onUserWaterGear(it.currentWaterGear)
+                binding.controller.waterRingView.updateProgress(currentWaterGear)
+                onUserWaterGear(currentWaterGear)
             }
         } else if (tabType == CookSettingType.TIME_SETTING) {
             cookStep?.uiData?.let {
@@ -903,13 +939,13 @@ class CookStepActivity : CookStepBaseActivity() {
 
     private fun dealWithTimeByOperation(uiData: CookStepUiData, increase: Boolean) {
         //当前调节时间
-        var targetTime = if (uiData.runningStatus != DevStatus.RUNNING.toInt()) {
-            uiData.targetTime
-        } else if (uiData.targetTimeBuffer > 0) {
-            uiData.targetTimeBuffer
-        } else {
-            uiData.targetTime
-        }
+//        var targetTime = uiData.targetTime
+//        if (uiData.remainTime != 0) {
+//            targetTime = uiData.remainTime
+//        }
+//        if (uiData.targetTimeBuffer != -1) {
+//            targetTime = uiData.targetTimeBuffer
+//        }
         var step = 0
         if (whereIndex == 1) {
             step += 60
@@ -917,19 +953,19 @@ class CookStepActivity : CookStepBaseActivity() {
             step = rotateStep()
         }
         if (increase) {
-            targetTime += step
+            currTime += step
         } else {
-            targetTime -= step
+            currTime -= step
         }
-        if (targetTime > uiData.limitMaxTime) {
-            targetTime = uiData.limitMaxTime
+        if (currTime > uiData.limitMaxTime) {
+            currTime = uiData.limitMaxTime
         }
-        if (targetTime < uiData.limitMinTime) {
-            targetTime = uiData.limitMinTime
+        if (currTime < uiData.limitMinTime) {
+            currTime = uiData.limitMinTime
         }
-        val sec = targetTime % 60
-        val min = ((targetTime / 60) % 60)
-        val hour = (targetTime / 3600)
+        val sec = currTime % 60
+        val min = ((currTime / 60) % 60)
+        val hour = (currTime / 3600)
         var time = ""
         if (hour > 0) {
             time += if (hour < 10) {
@@ -957,11 +993,13 @@ class CookStepActivity : CookStepBaseActivity() {
             }
         }
         uiData.isTimeChange = true
-        Log.d("eeeeeee", "${uiData.targetTime} == ${targetTime} === $step")
-        uiData.targetTime = targetTime
+        Log.d("eeeeeee", "${uiData.targetTime} == ${currTime} === $step")
+        uiData.targetTime = currTime
+        LogUtils.d("调节时间:${currTime}")
         binding.controller.clSetTime.isTimeCanChange(true)
         // 回调到上面那个地方来设置时间
-        TimeUtil.getTimes(targetTime, timeArray)
+        TimeUtil.getTimes(currTime, timeArray)
+        CofarSDK.cfgTime(currTime)
         binding.controller.clSetTime.setTimeInternal(
             timeArray[0],
             timeArray[1],
@@ -1174,41 +1212,47 @@ class CookStepActivity : CookStepBaseActivity() {
         }
 
         // 时间设置
-        if (runningState == DevStatus.STOP.toInt()) {
-            TimeUtil.getTimes(uiData.targetTime, timeArray)
+        val time = if (uiData.targetTimeBuffer != -1) {
+            uiData.targetTimeBuffer
         } else {
-            TimeUtil.getTimes(uiData.remainTime, timeArray)
-        }
-        if (!viewModel.stepUiData.doingModify || focusUpdate) {
-            binding.controller.clSetTime.setTimeInternal(
-                timeArray[0],
-                timeArray[1],
-                timeArray[2],
-                true
-            ) // 表盘时间设置-当前剩余时间
-            TimeUtil.getTimes(uiData.targetTime, timeArray)
-            binding.controller.tvCookingTimeTarget.updateText("--${TimeUtil.formatTime(timeArray)}--") // 下面的TAB-目标运行时间
+            uiData.targetTime
         }
+        TimeUtil.getTimes(time, timeArray)
+        binding.controller.clSetTime.setTimeInternal(
+            timeArray[0],
+            timeArray[1],
+            timeArray[2],
+            true
+        ) // 表盘时间设置-当前剩余时间
+        TimeUtil.getTimes(time, timeArray)
+        binding.controller.tvCookingTimeTarget.updateText("--${TimeUtil.formatTime(timeArray)}--") // 下面的TAB-目标运行时间
+
         TimeUtil.getTimes(uiData.remainTime, timeArray)
         binding.controller.tvSetTime.updateText(TimeUtil.formatTime(timeArray))                            // 下面的TAB-当前剩余时间
 
         // 温度
-        val showTemp =
-            if (runningState == DevStatus.STOP.toInt()) uiData.targetTemp else uiData.currentTemp;
-        if (!viewModel.stepUiData.doingModify || focusUpdate) {
-            binding.controller.tvCookingTempTarget.updateText("--${uiData.targetTemp}°C--")            // 下面的TAB-目标运行温度
-            binding.controller.tempRingView.updateProgress(showTemp)                                 // 圆环设置-当前运行温度
-            binding.controller.tvRingTempText.updateText("${showTemp}°C")                     // 圆环内的数字-当前运行温度
-        }
+//        val showTemp = if (uiData.targetTempBuffer != -1) {
+//            uiData.targetTempBuffer
+//        } else {
+//            uiData.targetTemp
+//        }
+        binding.controller.tvCookingTempTarget.updateText("--${FoodSdkUtils.parseTemp(currentTemp.toShort())}°C--")            // 下面的TAB-目标运行温度
+        binding.controller.tempRingView.updateProgress(
+            FoodSdkUtils.parseTemp(currentTemp.toShort()).toInt()
+        )                                 // 圆环设置-当前运行温度
+        binding.controller.tvRingTempText.updateText("${FoodSdkUtils.parseTemp(currentTemp.toShort())}°C")                     // 圆环内的数字-当前运行温度
         binding.controller.tvTempValue.updateText("${uiData.currentTemp}°C")                       // 下面的TAB-当前运行温度
 
         // 速度设置
-        if (!viewModel.stepUiData.doingModify || focusUpdate) {
 
-            binding.controller.speedRingView.updateProgress(uiData.currentSpeed)                               // 圆环设置-当前运行速度
-            binding.controller.tvSpeedText.updateText(uiData.currentSpeed.toString())                          // 圆环内的数字-当前运行速度
-            binding.controller.tvSetSpeed.updateText(uiData.currentSpeed.toString())                           // 下面的TAB-当前运行速度
+        val speed = if (uiData.motorGearBuffer != -1) {
+            uiData.motorGearBuffer
+        } else {
+            uiData.currentSpeed
         }
+        binding.controller.speedRingView.updateProgress(currentMotorGer)                               // 圆环设置-当前运行速度
+        binding.controller.tvSpeedText.updateText(currentMotorGer.toString())                          // 圆环内的数字-当前运行速度
+        binding.controller.tvSetSpeed.updateText(currentMotorGer.toString())                           // 下面的TAB-当前运行速度
 
         // 喷水设置
         if (!viewModel.stepUiData.doingModify || focusUpdate) {
@@ -1224,8 +1268,13 @@ class CookStepActivity : CookStepBaseActivity() {
         }
 
         // 方向设置
+        val direction = if (uiData.motorDirectionBuffer != -1) {
+            uiData.motorDirectionBuffer
+        } else {
+            uiData.direction
+        }
         if (!viewModel.stepUiData.doingModify || focusUpdate) {
-            updateDirection(uiData.direction)
+            updateDirection(direction)
         }
     }
 

+ 28 - 4
BusinessStep/src/main/java/com/develop/step/ui/cook_step/model/CookStepUiData.kt

@@ -3,6 +3,7 @@ package com.develop.step.ui.cook_step.model
 import com.develop.common.data_repo.db.entity.DevRecipeCookingStep
 import com.kuyuntech.cofarcooking.device.sdk.constant.core.DevStatus
 import com.kuyuntech.cofarcooking.device.sdk.util.core.CofarSDK
+import kotlinx.serialization.Serializable
 
 class CookStepUiData {
     var doingModify = false
@@ -10,26 +11,40 @@ class CookStepUiData {
 
     // 设置目标温度
     var targetTemp = 0
+
     // 设置目标时间
     var targetTime = 0
 
+    var targetTempBuffer = -1
+
     // 当前温度
     var currentTemp = 0
+
     // 当前时间
     var currentTime = 0
+
     // 当前剩余时间
     var remainTime = 0
+
     // targetTimeBuffer
-    var targetTimeBuffer = 0
+    var targetTimeBuffer = -1
+
     // 称重数
     var weightNum = 0
+
     // 当前方向
     var direction = 0
+
     // 当前转速
     var currentSpeed = 0
 
-    var currentWaterGear = 0
+    var currentWaterGear = -1
+
+    var motorGearBuffer = -1
 
+    var waterGearBuffer = -1
+
+    var motorDirectionBuffer = -1
 
     // 限制时间调整范围
     var limitMinTime = 0
@@ -83,7 +98,6 @@ class CookStepUiData {
         currentSpeed = getFixedValue(currentSpeed, limitMinSpeed, limitMaxSpeed)
 
 
-
     }
 
     private fun getFixedValue(source: Int, min: Int, max: Int): Int {
@@ -116,11 +130,16 @@ class CookStepUiData {
             it.isTempChange = isTempChange
             it.isTimeChange = isTimeChange
             it.isMotorGearChange = isMotorGearChange
+            it.targetTimeBuffer = targetTimeBuffer
+            it.targetTempBuffer = targetTempBuffer
+            it.motorDirectionBuffer = motorDirectionBuffer
+            it.motorGearBuffer = motorGearBuffer
+            it.waterGearBuffer = waterGearBuffer
             it.isMotorDirectionChange = isMotorDirectionChange
         }
         return uiData
     }
-    
+
     fun copyFrom(uiData: CookStepUiData): CookStepUiData {
         uiData.let {
             targetTemp = it.targetTemp
@@ -141,6 +160,11 @@ class CookStepUiData {
             isTimeChange = it.isTimeChange
             isMotorGearChange = it.isMotorGearChange
             isMotorDirectionChange = it.isMotorDirectionChange
+            targetTimeBuffer = it.targetTimeBuffer
+            targetTempBuffer = it.targetTempBuffer
+            waterGearBuffer = it.waterGearBuffer
+            motorDirectionBuffer = it.motorDirectionBuffer
+            motorGearBuffer = it.waterGearBuffer
         }
         return uiData
     }

+ 1 - 0
LocalTools/.gitignore

@@ -0,0 +1 @@
+/build

+ 15 - 0
LocalTools/build.gradle

@@ -0,0 +1,15 @@
+plugins {
+    id 'java-library'
+    id 'org.jetbrains.kotlin.jvm'
+}
+
+java {
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
+}
+
+dependencies {
+    implementation files('libs/okhttp-4.9.0.jar')
+    implementation files('libs/okio-2.10.0.jar')
+    implementation files('libs/gson-2.10.1.jar')
+}

BIN
LocalTools/libs/gson-2.10.1.jar


BIN
LocalTools/libs/okhttp-4.9.0.jar


BIN
LocalTools/libs/okio-2.10.0.jar


+ 23 - 0
LocalTools/src/main/java/com/twm/tools/local/AndroidLanguage.kt

@@ -0,0 +1,23 @@
+package com.twm.tools.local
+
+enum class AndroidLanguage(
+    val valuesLang: String,
+    val baiduLang: String
+) {
+    TW("zh-rTW", BaiduLanguage.TW),
+    HK("zh-rHK", BaiduLanguage.TW),
+    EN("en", BaiduLanguage.EN),
+    JP("ja", BaiduLanguage.JP),
+    KO("ko", BaiduLanguage.KO),
+    FR("fr", BaiduLanguage.FR),
+    SP("es", BaiduLanguage.SP),
+    RU("ru", BaiduLanguage.RU),
+    PT("pt", BaiduLanguage.PT),
+    DE("de", BaiduLanguage.DE),
+    IT("it", BaiduLanguage.IT),
+    NL("nl", BaiduLanguage.NL),
+    PL("pl", BaiduLanguage.PL),
+    SW("sw", BaiduLanguage.SW),
+    VI("vi", BaiduLanguage.VI),
+    TH("th", BaiduLanguage.TH),
+}

+ 19 - 0
LocalTools/src/main/java/com/twm/tools/local/BaiduLanguage.kt

@@ -0,0 +1,19 @@
+package com.twm.tools.local
+
+object BaiduLanguage {
+    const val TW = "cht" // 繁中
+    const val EN = "en" // 英语
+    const val JP = "jp" // 日语
+    const val KO = "kor" // 韩语
+    const val FR = "fra" // 法语
+    const val SP = "spa" // 西班牙
+    const val RU = "ru" // 俄语
+    const val PT = "pt" // 葡萄牙语
+    const val DE = "de" // 德语
+    const val IT = "it" // 意大利语
+    const val NL = "nl" // 荷兰语
+    const val PL = "pl" // 波兰语
+    const val SW = "swe" // 瑞典语
+    const val VI = "vie" // 越南语
+    const val TH = "th" // 泰语
+}

+ 12 - 0
LocalTools/src/main/java/com/twm/tools/local/BaiduTranslateResponse.kt

@@ -0,0 +1,12 @@
+package com.twm.tools.local
+
+class BaiduTranslateResponse(
+    val from: String,
+    val to: String,
+    val trans_result: List<BaiduTranslateResult>?
+)
+
+class BaiduTranslateResult(
+    val src: String,
+    val dst: String?
+)

+ 49 - 0
LocalTools/src/main/java/com/twm/tools/local/BaiduTranslateService.kt

@@ -0,0 +1,49 @@
+package com.twm.tools.local
+
+import com.google.gson.Gson
+import okhttp3.FormBody
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import java.math.BigInteger
+import java.security.MessageDigest
+
+object BaiduTranslateService: TranslateApi {
+    private const val TRANSLATE_URL = "https://fanyi-api.baidu.com/api/trans/vip/translate"
+    private const val BAIDU_APPID = "20230809001774667"
+    private const val BAIDU_SECRET = ""
+    private val client = OkHttpClient.Builder().build()
+
+    override fun translate(source: String, lang: String): String? {
+        val salt = System.nanoTime().toString()
+        val sign = (BAIDU_APPID + source + salt + BAIDU_SECRET).getMd5()
+        val body = FormBody.Builder()
+            .add("q", source)
+            .add("from", "auto")
+            .add("to", lang)
+            .add("appid", BAIDU_APPID)
+            .add("salt", salt)
+            .add("sign", sign)
+            .build()
+        val request = Request.Builder()
+            .post(body)
+            .url(TRANSLATE_URL)
+            .header("Content-Type", "application/x-www-form-urlencoded")
+            .build()
+        val response = runCatching {
+            client.newCall(request).execute()
+        }
+        if (response.isFailure) {
+            return null
+        }
+        val result = response.getOrThrow().body?.string() ?: return null
+        val translate = Gson().fromJson(
+            result, BaiduTranslateResponse::class.java
+        )
+        return translate.trans_result?.firstOrNull()?.dst
+    }
+
+    private fun String.getMd5(): String {
+        val md = MessageDigest.getInstance("MD5")
+        return BigInteger(1, md.digest(this.toByteArray())).toString(16).padStart(32, '0')
+    }
+}

+ 239 - 0
LocalTools/src/main/java/com/twm/tools/local/MainClass.kt

@@ -0,0 +1,239 @@
+package com.twm.tools.local
+
+import java.io.File
+import java.io.RandomAccessFile
+import java.util.Scanner
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+import java.util.concurrent.Future
+import java.util.concurrent.Semaphore
+import java.util.concurrent.TimeUnit
+import javax.xml.parsers.SAXParserFactory
+import javax.xml.transform.OutputKeys
+import javax.xml.transform.sax.SAXTransformerFactory
+import javax.xml.transform.stream.StreamResult
+import kotlin.system.exitProcess
+
+
+object MainClass {
+    private const val TARGET_LIB = "BusinessCommon"
+    private const val STRING_FILE = "strings.xml"
+    private const val LIMITED_QPS = 6
+    private val translateApi = BaiduTranslateService
+    private val semaphore = Semaphore(LIMITED_QPS)
+    private lateinit var taskExecutor: ExecutorService
+
+    /**
+     * 每次新增多语言, 在默认strings.xml处新增完毕后,点此处开始即可同步所有多语言
+     */
+    @JvmStatic
+    fun main(args: Array<String>) {
+        prepareHttpExecutors()
+        syncTranslations(listOf(
+            AndroidLanguage.EN,
+            AndroidLanguage.DE,
+            AndroidLanguage.JP,
+            AndroidLanguage.KO,
+            AndroidLanguage.HK,
+            AndroidLanguage.RU,
+            AndroidLanguage.FR,
+            AndroidLanguage.TH,
+        ))
+        exitProcess(0)
+    }
+
+    private fun prepareHttpExecutors() {
+        semaphore.acquire(LIMITED_QPS)
+        val executor = Executors.newScheduledThreadPool(1)
+        val qpsRelease = {
+            semaphore.release(1)
+        }
+        executor.scheduleAtFixedRate(
+            qpsRelease, 0, (1000f / LIMITED_QPS).toLong(), TimeUnit.MILLISECONDS
+        )
+        taskExecutor = Executors.newFixedThreadPool(LIMITED_QPS)
+    }
+
+    private fun syncTranslations(languages: List<AndroidLanguage>) {
+        val parentDir = File("${TARGET_LIB}/src/main/res")
+        val templateDir = File(parentDir, "values")
+        if (!templateDir.exists()) {
+            throw IllegalStateException("没有找到${TARGET_LIB}下的values文件夹")
+        }
+        val templateFile = File(templateDir, STRING_FILE)
+        if (!templateFile.exists()) {
+            throw IllegalStateException("模板values中无strings.xml文件")
+        }
+        for (language in languages) {
+            val langDir = File(parentDir, "values-${language.valuesLang}")
+            if (!langDir.exists() && !langDir.mkdirs()) {
+                throw IllegalStateException("创建文件夹失败:${langDir}")
+            }
+            val langFile = File(langDir, STRING_FILE)
+            if (!langFile.exists() && !langFile.createNewFile()) {
+                throw IllegalStateException("创建文件失败:${langFile}")
+            }
+        }
+
+        // parse languages
+        val saxFactory = SAXParserFactory.newInstance()
+        val saxParser = saxFactory.newSAXParser()
+        val saxHandler = ValuesStringSaxHandler()
+        val saxResult = runCatching {
+            saxParser.parse(templateFile, saxHandler)
+        }
+        if (saxResult.isFailure) {
+            println("模板strings文件解析失败:${saxResult.exceptionOrNull()}")
+            return
+        }
+        val templateValues = saxHandler.getCollectValues()
+        val holdingValues = mutableMapOf<AndroidLanguage, Set<String>>()
+        for (language in languages) {
+            val stringFile = getStringValuesDir(language)
+            val valueHandler = ValuesStringSaxHandler()
+            val parseResult = runCatching {
+                saxParser.parse(stringFile, valueHandler)
+            }
+            if (parseResult.isFailure) {
+                println("${language}中的文件内容解析失败或内容为空")
+            }
+            holdingValues[language] = valueHandler
+                .getCollectValues()
+                .map { it.key }
+                .toHashSet()
+        }
+        val pendingValues = mutableMapOf<AndroidLanguage, MutableList<Translation>>()
+        for (value in templateValues) {
+            for (entry in holdingValues.entries) {
+                if (entry.value.contains(value.key)) {
+                    continue
+                }
+                val valueList = pendingValues.getOrPut(entry.key) {
+                    mutableListOf()
+                }
+                valueList.add(Translation(ValuesData(value.key), value.value))
+                println("${entry.key.valuesLang} 待翻译key => ${value.key}")
+            }
+        }
+        if (pendingValues.isEmpty()) {
+            println("所有翻译均与默认strings.xml同步, 无新增翻译")
+            return
+        }
+        println("<==========================================>")
+        for (entry in pendingValues.entries) {
+            if (entry.value.isEmpty()) {
+                println("${entry.key.valuesLang} 无新增翻译内容")
+                continue
+            }
+            inflateTranslations(entry.key, entry.value, taskExecutor)
+            writeResultToFile(entry.key, entry.value)
+            println("写入文件完成:${entry.key.valuesLang}, 翻译数量:${entry.value.size}")
+            println("<==========================================>")
+        }
+    }
+
+    private fun inflateTranslations(
+        language: AndroidLanguage,
+        translations: List<Translation>,
+        executor: ExecutorService
+    ) {
+        val records = mutableMapOf<ValuesData, Future<String?>>()
+        for (translation in translations) {
+            val callable = TranslateCallable(
+                translateApi, translation.template, language.baiduLang
+            )
+            val qpsTask = QPSTaskWrapper(semaphore, callable)
+            records[translation.valueData] = executor.submit(qpsTask)
+        }
+        for (record in records) {
+            try {
+                val translation = record.value.get()
+                if (translation == null) {
+                    println("翻译失败 => ${language.valuesLang} => ${record.key.key}")
+                } else {
+                    record.key.value = processForTranslation(language, translation)
+                    println("翻译完成 => ${language.valuesLang} => ${record.key}")
+                }
+            } catch (ex: Exception) {
+                ex.printStackTrace()
+            }
+        }
+    }
+
+    private fun writeResultToFile(
+        language: AndroidLanguage,
+        translations: List<Translation>
+    ) {
+        val targetFile = getStringValuesDir(language)
+        ensureValidXmlFile(targetFile)
+        val accessFile = RandomAccessFile(targetFile, "rw")
+        val fileLength = accessFile.length()
+        val endTag = "</resources>"
+        if (fileLength <= endTag.length * 2) {
+            throw RuntimeException("strings.xml is invalid!")
+        }
+        var seekPosition = endTag.length
+        var resourceEnd = -1
+        while (seekPosition <= fileLength) {
+            accessFile.seek(fileLength - seekPosition)
+            val currentLine = accessFile.readLine()
+            if (currentLine.contains("</resources>")) {
+                resourceEnd = seekPosition
+                break
+            }
+            seekPosition++
+        }
+        val current = resourceEnd
+        if (current < 0) {
+            throw IllegalStateException("strings.xml文件格式有误")
+        }
+        accessFile.seek(fileLength - current)
+        for (translation in translations) {
+            val insertString = "    <string name=\"${translation.valueData.key}\">${translation.valueData.value}</string>"
+            accessFile.write(insertString.toByteArray())
+            accessFile.writeBytes("\n")
+        }
+        accessFile.writeBytes(endTag)
+        accessFile.close()
+    }
+
+    private fun ensureValidXmlFile(file: File) {
+        var validFile = false
+        val scanner = Scanner(file)
+        while (scanner.hasNextLine()) {
+            val nextLine = scanner.nextLine()
+            if (nextLine.contains("<resources>")) {
+                validFile = true
+            }
+        }
+        if (validFile) {
+            return
+        }
+        val target = SAXTransformerFactory.newInstance() as SAXTransformerFactory
+        val handler = target.newTransformerHandler()
+        handler.transformer.apply {
+            setOutputProperty(OutputKeys.ENCODING, "UTF-8")
+            setOutputProperty(OutputKeys.INDENT, "yes")
+        }
+        val result = StreamResult(file)
+        handler.setResult(result)
+        handler.startDocument()
+        val indent = "\n".toCharArray()
+        handler.characters(indent, 0, indent.size)
+        handler.startElement("", "", "resources", null)
+        handler.characters(indent, 0, indent.size)
+        handler.endElement("", "", "resources")
+        handler.endDocument()
+    }
+
+    private fun processForTranslation(language: AndroidLanguage, source: String): String {
+        if (language != AndroidLanguage.FR) {
+            return source
+        }
+        return source.replace("'", "\\'")
+    }
+
+    private fun getStringValuesDir(language: AndroidLanguage): File {
+        return File("${TARGET_LIB}/src/main/res/values-${language.valuesLang}/${STRING_FILE}")
+    }
+}

+ 16 - 0
LocalTools/src/main/java/com/twm/tools/local/QPSTaskWrapper.kt

@@ -0,0 +1,16 @@
+package com.twm.tools.local
+
+import java.util.concurrent.Callable
+import java.util.concurrent.Semaphore
+
+class QPSTaskWrapper<V>(
+    private val semaphore: Semaphore,
+    private val delegate: Callable<V>
+): Callable<V> {
+
+    override fun call(): V {
+        semaphore.acquireUninterruptibly(1)
+        return delegate.call()
+    }
+
+}

+ 7 - 0
LocalTools/src/main/java/com/twm/tools/local/TranslateApi.kt

@@ -0,0 +1,7 @@
+package com.twm.tools.local
+
+interface TranslateApi {
+
+    fun translate(source: String, lang: String): String?
+
+}

+ 17 - 0
LocalTools/src/main/java/com/twm/tools/local/TranslateCallable.kt

@@ -0,0 +1,17 @@
+package com.twm.tools.local
+
+import java.util.concurrent.Callable
+
+class TranslateCallable(
+    private val translateApi: TranslateApi,
+    private val source: String,
+    private val language: String
+): Callable<String?> {
+
+    override fun call(): String? {
+        if (source.isEmpty()) {
+            return null
+        }
+        return translateApi.translate(source, language)
+    }
+}

+ 6 - 0
LocalTools/src/main/java/com/twm/tools/local/Translation.kt

@@ -0,0 +1,6 @@
+package com.twm.tools.local
+
+class Translation(
+    val valueData: ValuesData,
+    val template: String
+)

+ 6 - 0
LocalTools/src/main/java/com/twm/tools/local/ValuesData.kt

@@ -0,0 +1,6 @@
+package com.twm.tools.local
+
+data class ValuesData(
+    val key: String,
+    var value: String = ""
+)

+ 42 - 0
LocalTools/src/main/java/com/twm/tools/local/ValuesStringSaxHandler.kt

@@ -0,0 +1,42 @@
+package com.twm.tools.local
+
+import org.xml.sax.Attributes
+import org.xml.sax.helpers.DefaultHandler
+
+class ValuesStringSaxHandler: DefaultHandler() {
+
+    private val values = mutableListOf<ValuesData>()
+    private var pending: ValuesData? = null
+
+    override fun startElement(uri: String?, localName: String?, qName: String?, attrs: Attributes?) {
+        if (qName != "string") {
+            pending = null
+            return
+        }
+        val key = attrs?.getValue("name")
+        if (key == null) {
+            pending = null
+        } else {
+            pending = ValuesData(key)
+        }
+    }
+
+    override fun endElement(uri: String?, localName: String?, qName: String?) {
+        if (qName != "string") {
+            pending = null
+            return
+        }
+        if (pending != null) {
+            values.add(pending!!)
+            pending = null
+        }
+    }
+
+    override fun characters(p0: CharArray, p1: Int, p2: Int) {
+        if (pending != null) {
+            pending?.value = String(p0, p1, p2)
+        }
+    }
+
+    fun getCollectValues() = values as List<ValuesData>
+}

+ 1 - 1
app/build.gradle

@@ -12,7 +12,7 @@ ext{
 
     versionCode=Integer.parseInt(new SimpleDateFormat("yyMMddHH").format(new Date()) + 1)
 //    versionCode=230617180
-    brandCode="036I"
+    brandCode="030A"
     model="1039"
 }
 

BIN
app/src/main/assets/skins/night.skin


+ 1 - 0
app/src/main/java/com/develop/foodcooking/FoodCookingApp.kt

@@ -72,6 +72,7 @@ class FoodCookingApp : BaseApp() {
     var minute = 0
     private  var heartBeatInterval :Interval?=null
     override fun onCreate() {
+
         hookWebView()
         super.onCreate()
 

+ 1 - 0
settings.gradle

@@ -35,3 +35,4 @@ include ':BusinessMain'
 include ':BusinessStep'
 include ':BusinessAirFryer'
 include ':skin-support'
+include ':LocalTools'