From 91800a6bb102e9cfce4c6863e510856b49939fdb Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Tue, 31 Mar 2026 09:48:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(app):=20=E6=B7=BB=E5=8A=A0=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=88=87=E6=8D=A2=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=9F=BA=E7=A1=80URL=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在主界面标题时间区域添加点击事件,支持弹出环境切换对话框 - 新增EnvSwitchDialog类实现TEST/UAT/PROD三套环境切换功能 - 新增dialog_env_switch.xml布局文件定义环境切换弹窗UI - 重构GlobalData类,统一管理基础URL常量并添加持久化支持 - 修改MyApp初始化逻辑,优先读取用户手动设置的环境配置 - 添加SpTool.baseUrl属性用于环境配置的本地存储 - 修复MainActivity布局文件中的TextView垂直内边距问题 - 调整食物识别防抖时间从500ms到3000ms,优化计算营养逻辑执行时机 --- .../main/java/com/sw/dualscreen/GlobalData.kt | 10 +- app/src/main/java/com/sw/dualscreen/MyApp.kt | 16 ++- .../sw/dualscreen/activity/MainActivity.kt | 4 + .../sw/dualscreen/dialog/EnvSwitchDialog.kt | 69 ++++++++++++ .../presentation/MainScreenPresentation.kt | 16 +-- .../java/com/sw/dualscreen/utils/SpTool.kt | 7 ++ app/src/main/res/layout/activity_main.xml | 1 + app/src/main/res/layout/dialog_env_switch.xml | 106 ++++++++++++++++++ 8 files changed, 216 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/com/sw/dualscreen/dialog/EnvSwitchDialog.kt create mode 100644 app/src/main/res/layout/dialog_env_switch.xml diff --git a/app/src/main/java/com/sw/dualscreen/GlobalData.kt b/app/src/main/java/com/sw/dualscreen/GlobalData.kt index c916641..9bead1c 100644 --- a/app/src/main/java/com/sw/dualscreen/GlobalData.kt +++ b/app/src/main/java/com/sw/dualscreen/GlobalData.kt @@ -17,11 +17,14 @@ object GlobalData { */ var appVersion: String = "1" + var appBaseUrl: String = "" + /** - * 具体业务baseurl + * 具体业务 BaseUrl */ - var appBaseUrl2: String = "http://192.168.1.201:14801" - var appBaseUrl: String = "https://dev.yixiong-tech.com:8081" + const val TEST_BASE_URL = "http://192.168.1.201:14801" + const val UAT_BASE_URL = "https://dev.yixiong-tech.com:8081" + const val PROD_BASE_URL = "生产环境" /** * 菜品识别模型版本号,后边以接口返回为准 @@ -69,4 +72,5 @@ object GlobalKey { const val KEY_PICKUP_MODE = "pickupMode" const val KEY_CHARGE_MODE = "chargeMode" const val KEY_SETTLEMENT_MODE = "settlementMode" + const val KEY_BASE_URL = "baseUrlKey" } \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/MyApp.kt b/app/src/main/java/com/sw/dualscreen/MyApp.kt index 8420759..48e4447 100644 --- a/app/src/main/java/com/sw/dualscreen/MyApp.kt +++ b/app/src/main/java/com/sw/dualscreen/MyApp.kt @@ -6,6 +6,8 @@ import com.sw.dualscreen.objbox.ObjectBox import com.sw.dualscreen.sdk.SensorScaleUtils import com.sw.dualscreen.utils.ActivityManager import com.sw.dualscreen.utils.CrashHandler +import com.sw.dualscreen.utils.SPUtil +import com.sw.dualscreen.utils.SpTool import com.sw.plate.App import com.sw.plate.utils.AppUtil import timber.log.Timber @@ -13,7 +15,7 @@ import timber.log.Timber class MyApp : App() { companion object { const val DEBUG: Boolean = true - var instance: MyApp?=null + var instance: MyApp? = null } override fun onCreate() { @@ -24,13 +26,23 @@ class MyApp : App() { Timber.d("deviceId = $deviceId") // deviceId = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e" GlobalData.deviceId = deviceId - GlobalData.appBaseUrl = if ("2987f0c5-5754-33e9-b00a-251db5e2e55f" == deviceId) GlobalData.appBaseUrl2 else GlobalData.appBaseUrl ObjectBox.init(this) // 初始化崩溃处理器 CrashHandler.init(this) SensorScaleUtils.startScale() addActivityLifecycleListener() + + // 优先读取用户手动切换后持久化的 url + val savedUrl = SpTool.baseUrl + if (!savedUrl.isNullOrEmpty()) { + GlobalData.appBaseUrl = savedUrl + } else { + // 未保存过则使用默认逻辑:特定设备走测试环境,其余走 UAT + GlobalData.appBaseUrl = + if ("2987f0c5-5754-33e9-b00a-251db5e2e55f" == deviceId) GlobalData.TEST_BASE_URL else GlobalData.PROD_BASE_URL + + } } private fun addActivityLifecycleListener() { diff --git a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt index 41f98ec..ab761db 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt @@ -31,6 +31,7 @@ import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.adapter.FoodOrderAdapter import com.sw.dualscreen.adapter.MainFoodListAdapter import com.sw.dualscreen.databinding.ActivityMainBinding +import com.sw.dualscreen.dialog.EnvSwitchDialog import com.sw.dualscreen.dialog.RemindDialog import com.sw.dualscreen.ext.dp import com.sw.dualscreen.ext.gone @@ -203,6 +204,9 @@ class MainActivity : BaseActivity() { } } updateDateTime() + binding.tvTitleTime.setOnClickListener { + EnvSwitchDialog(this).show() + } binding.ivSetting.setOnClickListener { isRefreshPage = false startActivity(Intent(this, SettingActivity::class.java)) diff --git a/app/src/main/java/com/sw/dualscreen/dialog/EnvSwitchDialog.kt b/app/src/main/java/com/sw/dualscreen/dialog/EnvSwitchDialog.kt new file mode 100644 index 0000000..2365276 --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/dialog/EnvSwitchDialog.kt @@ -0,0 +1,69 @@ +package com.sw.dualscreen.dialog + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.WindowManager +import com.sw.dualscreen.GlobalData +import com.sw.dualscreen.databinding.DialogEnvSwitchBinding +import com.sw.dualscreen.ext.dp +import com.sw.dualscreen.utils.SpTool +import com.sw.plate.utils.ToastUtils + +/** + * 环境切换弹窗 + * + * 提供 TEST / UAT / PROD 三套环境的切换功能, + * 初始化时自动根据 [GlobalData.appBaseUrl] 选中当前环境, + * 确认后更新 [GlobalData.appBaseUrl] 并通过 [onEnvChanged] 回调通知外部。 + * + * @param context 上下文 + * @param onEnvChanged 确认切换后的回调,参数为新的 baseUrl + */ +class EnvSwitchDialog( + context: Context, + private val onEnvChanged: (newBaseUrl: String) -> Unit = {} +) : BaseDialog( + context, + defWidth = 600.dp, + defHeight = WindowManager.LayoutParams.WRAP_CONTENT +) { + + private lateinit var binding: DialogEnvSwitchBinding + + override fun getRootView(): View { + binding = DialogEnvSwitchBinding.inflate(LayoutInflater.from(context)) + return binding.root + } + + override fun initView() { + // 根据当前 appBaseUrl 预选对应 RadioButton,不匹配则不选 + when (GlobalData.appBaseUrl) { + GlobalData.TEST_BASE_URL -> binding.rbTest.isChecked = true + GlobalData.UAT_BASE_URL -> binding.rbUat.isChecked = true + GlobalData.PROD_BASE_URL -> binding.rbProd.isChecked = true + } + + // 取消按钮 + binding.btnCancel.setOnClickListener { dismiss() } + + // 确认按钮 + binding.btnConfirm.setOnClickListener { + // 未选中任何选项时提示用户 + if (binding.rgEnv.checkedRadioButtonId == -1) { + ToastUtils.showToast("请选择环境") + return@setOnClickListener + } + val newUrl = when (binding.rgEnv.checkedRadioButtonId) { + binding.rbTest.id -> GlobalData.TEST_BASE_URL + binding.rbUat.id -> GlobalData.UAT_BASE_URL + binding.rbProd.id -> GlobalData.PROD_BASE_URL + else -> return@setOnClickListener + } + GlobalData.appBaseUrl = newUrl + SpTool.baseUrl = newUrl + onEnvChanged(newUrl) + dismiss() + } + } +} diff --git a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt index 53ca2c6..f7aa10e 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt @@ -102,7 +102,7 @@ class MainScreenPresentation( // private var userNutritionData: UserNutritionData? = null private var userNutrition: UserNutrition? = null private var dinnerTypeInfo: DinnerType? = null - private val debouncer = Debouncer(500) + private val debouncer = Debouncer(3000) private var recognitionTime: Long = 0L // 人脸识别时的时间 var recognitionWeight: Int = 0 // 人脸识别时的重量 @@ -771,14 +771,14 @@ class MainScreenPresentation( if (currentFood == null || userNutrition == null) { return } - var weight = value - if (weight < 0) weight = 0 - if (activity.settlementMode == 0) { - activity.runOnUiThread { - addFoodToOrder(weight, currentFood!!) - } - } debouncer.debounce { + var weight = value + if (weight < 0) weight = 0 + if (activity.settlementMode == 0) { + activity.runOnUiThread { + addFoodToOrder(weight, currentFood!!) + } + } Timber.tag(TAG) .d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight") val dinnerType = dinnerTypeInfo?.dinnerType diff --git a/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt b/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt index 3118351..ec7edff 100644 --- a/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt +++ b/app/src/main/java/com/sw/dualscreen/utils/SpTool.kt @@ -1,5 +1,6 @@ package com.sw.dualscreen.utils +import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.MyApp import com.sw.dualscreen.utils.SPUtil.Companion.getInstance @@ -27,4 +28,10 @@ object SpTool { spUtil?.boolean(IS_FIRST_GET_FACE, value) } + var baseUrl: String? + get() = spUtil?.get(GlobalKey.KEY_BASE_URL, "") + set(value) { + spUtil?.put(GlobalKey.KEY_BASE_URL, value) + } + } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4cc2766..2f703a2 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -22,6 +22,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="28dp" + android:paddingVertical="10dp" android:textColor="#ff0a1428" android:textSize="26sp" android:textStyle="bold" diff --git a/app/src/main/res/layout/dialog_env_switch.xml b/app/src/main/res/layout/dialog_env_switch.xml new file mode 100644 index 0000000..45c6ff8 --- /dev/null +++ b/app/src/main/res/layout/dialog_env_switch.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +