refactor(network): 重构网络请求配置以支持动态环境切换

- 将布局文件中的 Button 替换为 AppCompatButton 组件
- 更新环境切换对话框中的 URL 映射关系
- 添加 LOCAL_BASE_URL 和修改 TEST_BASE_URL 的常量定义
- 启用并实现环境切换功能的时间点击事件处理
- 在 API 接口定义中使用 @Url 注解实现动态 URL 设置
- 创建 DynamicBaseUrlInterceptor 拦截器实现实时域名替换
- 更新依赖注入模块以使用新的拦截器和全局基础 URL
- 修改仓库层调用以使用具名参数传递
This commit is contained in:
2026-06-03 16:48:50 +08:00
parent ee84189fdf
commit 15e1f87913
8 changed files with 64 additions and 35 deletions
@@ -56,8 +56,10 @@ object GlobalData {
* 具体业务 BaseUrl
*/
// const val TEST_BASE_URL = "http://192.168.1.201:14801"
const val TEST_BASE_URL = "http://192.168.10.118:14801"
const val UAT_BASE_URL = "https://dev.yixiong-tech.com:8083"
// const val LOCAL_BASE_URL = "http://192.168.10.118:14801"
const val LOCAL_BASE_URL = "http://192.168.10.101:24801";
// const val TEST_BASE_URL = "https://dev.yixiong-tech.com:8083"
const val TEST_BASE_URL = "https://dev.yixiong-tech.com:8081"
const val PROD_BASE_URL = "https://api.dm.yixiong-tech.com:8443"
var appBaseUrl: String = ""
@@ -81,20 +81,20 @@ class HomeActivity : BaseActivity() {
// startActivity<FoodCollectionActivity>()
// }
//
// // 时间点击:打开环境切换弹窗
// binding.tvTime.setOnClickListener { v ->
// EnvSwitchDialog(context = this, onEnvChanged = {
// Loading.show(this)
// lifecycleScope.launch {
// 时间点击:打开环境切换弹窗
binding.tvTime.setOnClickListener { v ->
EnvSwitchDialog(context = this, onEnvChanged = {
Loading.show(this)
lifecycleScope.launch {
// ObjectBox.removeAll()
// FoodModule.init(this@HomeActivity)
// v.postDelayed({
// Loading.dismiss()
// toast("服务重置完成")
// }, 500)
// }
// }).show()
// }
v.postDelayed({
Loading.dismiss()
toast("服务重置完成")
}, 500)
}
}).show()
}
// // 采购单入库入口
// binding.ivOrderPurchase.setOnClickListener {
@@ -1,7 +1,6 @@
package com.sw.inbound.activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@@ -152,7 +151,7 @@ class InitActivity : BaseActivity() {
"f0bcabbb-0d58-3b14-8bed-9863b7ec61ef"
)
if (list.contains(GlobalData.deviceId)) {
GlobalData.appBaseUrl = GlobalData.TEST_BASE_URL
GlobalData.appBaseUrl = GlobalData.LOCAL_BASE_URL
}
}
val intent = Intent(this, HomeActivity::class.java)
@@ -1,14 +1,19 @@
package com.sw.inbound.di
import com.google.gson.GsonBuilder
import com.sw.inbound.GlobalData
import com.sw.inbound.MyApp
import com.sw.inbound.network.api.InboundApiService
import com.sw.inbound.network.interceptor.InboundInterceptor
import com.sw.inbound.network.interceptor.RequestInterceptor
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
@@ -21,9 +26,23 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
object InboundNetworkModule {
private const val INBOUND_BASE_URL = "http://192.168.10.101:24801/"
// private const val INBOUND_BASE_URL = "http://192.168.10.101:24801/"
private const val TIME_OUT = 30L
/** 动态域名拦截器:将 Retrofit 请求的 baseUrl 实时替换为 [GlobalData.appBaseUrl] */
class DynamicBaseUrlInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val newUrl = GlobalData.appBaseUrl.toHttpUrlOrNull() ?: return chain.proceed(request)
val url = request.url.newBuilder()
.scheme(newUrl.scheme)
.host(newUrl.host)
.port(newUrl.port)
.build()
return chain.proceed(request.newBuilder().url(url).build())
}
}
@Provides
@Singleton
@Named("inbound")
@@ -38,7 +57,9 @@ object InboundNetworkModule {
level = if (MyApp.DEBUG) HttpLoggingInterceptor.Level.BODY
else HttpLoggingInterceptor.Level.NONE
})
.addInterceptor(InboundInterceptor())
.addInterceptor(DynamicBaseUrlInterceptor())
// .addInterceptor(InboundInterceptor())
.addInterceptor(RequestInterceptor())
.build()
}
@@ -48,7 +69,7 @@ object InboundNetworkModule {
fun provideInboundRetrofit(@Named("inbound") okHttpClient: OkHttpClient): Retrofit {
val gson = GsonBuilder().setLenient().create()
return Retrofit.Builder()
.baseUrl(INBOUND_BASE_URL)
.baseUrl(GlobalData.appBaseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
@@ -40,8 +40,8 @@ class EnvSwitchDialog(
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.LOCAL_BASE_URL -> binding.rbTest.isChecked = true
GlobalData.TEST_BASE_URL -> binding.rbUat.isChecked = true
GlobalData.PROD_BASE_URL -> binding.rbProd.isChecked = true
}
@@ -56,8 +56,8 @@ class EnvSwitchDialog(
return@setOnClickListener
}
val newUrl = when (binding.rgEnv.checkedRadioButtonId) {
binding.rbTest.id -> GlobalData.TEST_BASE_URL
binding.rbUat.id -> GlobalData.UAT_BASE_URL
binding.rbTest.id -> GlobalData.LOCAL_BASE_URL
binding.rbUat.id -> GlobalData.TEST_BASE_URL
binding.rbProd.id -> GlobalData.PROD_BASE_URL
else -> return@setOnClickListener
}
@@ -1,5 +1,6 @@
package com.sw.inbound.network.api
import com.sw.inbound.GlobalData
import com.sw.inbound.model.response.IngredientByTrace
import com.sw.inbound.model.response.InboundApiResponse
import com.sw.inbound.model.response.SupplierOption
@@ -8,6 +9,7 @@ import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
import retrofit2.http.Url
/**
* 入库秤设备端接口
@@ -17,34 +19,39 @@ import retrofit2.http.Query
interface InboundApiService {
/** 按溯源码查食材,用于毛菜/净菜入库时联动选择食材 */
@GET("nutrition/neglect/inbound/ingredient-by-trace")
@GET
suspend fun getIngredientByTrace(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/ingredient-by-trace",
@Query("traceCode") traceCode: String
): InboundApiResponse<List<IngredientByTrace>>
/** 仓库区域下拉列表 */
@GET("nutrition/neglect/inbound/zone-options")
@GET
suspend fun getZoneOptions(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/zone-options",
@Query("warehouseId") warehouseId: Long? = null,
@Query("keyword") keyword: String? = null
): InboundApiResponse<List<ZoneOption>>
/** 供应商下拉列表,type: 1-内部,2-外部,不传返回全部 */
@GET("nutrition/neglect/inbound/supplier-options")
@GET
suspend fun getSupplierOptions(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/supplier-options",
@Query("type") type: Int? = null,
@Query("keyword") keyword: String? = null
): InboundApiResponse<List<SupplierOption>>
/** 毛菜入库提交,入参为 Map 以便动态组装字段 */
@POST("nutrition/neglect/inbound/raw-inbound")
@POST
suspend fun submitRawInbound(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/raw-inbound",
@Body param: Map<String, @JvmSuppressWildcards Any>
): InboundApiResponse<Unit>
/** 净菜入库提交,入参为 Map 以便动态组装字段 */
@POST("nutrition/neglect/inbound/clean-inbound")
@POST
suspend fun submitCleanInbound(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/clean-inbound",
@Body param: Map<String, @JvmSuppressWildcards Any>
): InboundApiResponse<Unit>
}
@@ -24,7 +24,7 @@ class InboundRepository @Inject constructor(
/** 按溯源码查食材 */
suspend fun getIngredientByTrace(traceCode: String): InboundApiResponse<List<IngredientByTrace>> {
return safeCall { apiService.getIngredientByTrace(traceCode) }
return safeCall { apiService.getIngredientByTrace(traceCode = traceCode) }
}
/** 仓库区域下拉列表 */
@@ -32,7 +32,7 @@ class InboundRepository @Inject constructor(
warehouseId: Long? = null,
keyword: String? = null
): InboundApiResponse<List<ZoneOption>> {
return safeCall { apiService.getZoneOptions(warehouseId, keyword) }
return safeCall { apiService.getZoneOptions(warehouseId = warehouseId, keyword = keyword) }
}
/** 供应商下拉列表 */
@@ -40,17 +40,17 @@ class InboundRepository @Inject constructor(
type: Int? = null,
keyword: String? = null
): InboundApiResponse<List<SupplierOption>> {
return safeCall { apiService.getSupplierOptions(type, keyword) }
return safeCall { apiService.getSupplierOptions(type = type, keyword = keyword) }
}
/** 毛菜入库提交 */
suspend fun submitRawInbound(param: Map<String, Any>): InboundApiResponse<Unit> {
return safeCall { apiService.submitRawInbound(param) }
return safeCall { apiService.submitRawInbound(param = param) }
}
/** 净菜入库提交 */
suspend fun submitCleanInbound(param: Map<String, Any>): InboundApiResponse<Unit> {
return safeCall { apiService.submitCleanInbound(param) }
return safeCall { apiService.submitCleanInbound(param = param) }
}
private suspend fun <T> safeCall(call: suspend () -> InboundApiResponse<T>): InboundApiResponse<T> {
@@ -79,7 +79,7 @@
android:gravity="center"
android:orientation="horizontal">
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnCancel"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -90,7 +90,7 @@
android:textColor="#ff141428"
android:textSize="28sp" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnConfirm"
android:layout_width="0dp"
android:layout_height="match_parent"