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 * 具体业务 BaseUrl
*/ */
// const val TEST_BASE_URL = "http://192.168.1.201:14801" // const val TEST_BASE_URL = "http://192.168.1.201:14801"
const val TEST_BASE_URL = "http://192.168.10.118:14801" // const val LOCAL_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.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" const val PROD_BASE_URL = "https://api.dm.yixiong-tech.com:8443"
var appBaseUrl: String = "" var appBaseUrl: String = ""
@@ -81,20 +81,20 @@ class HomeActivity : BaseActivity() {
// startActivity<FoodCollectionActivity>() // startActivity<FoodCollectionActivity>()
// } // }
// //
// // 时间点击:打开环境切换弹窗 // 时间点击:打开环境切换弹窗
// binding.tvTime.setOnClickListener { v -> binding.tvTime.setOnClickListener { v ->
// EnvSwitchDialog(context = this, onEnvChanged = { EnvSwitchDialog(context = this, onEnvChanged = {
// Loading.show(this) Loading.show(this)
// lifecycleScope.launch { lifecycleScope.launch {
// ObjectBox.removeAll() // ObjectBox.removeAll()
// FoodModule.init(this@HomeActivity) // FoodModule.init(this@HomeActivity)
// v.postDelayed({ v.postDelayed({
// Loading.dismiss() Loading.dismiss()
// toast("服务重置完成") toast("服务重置完成")
// }, 500) }, 500)
// } }
// }).show() }).show()
// } }
// // 采购单入库入口 // // 采购单入库入口
// binding.ivOrderPurchase.setOnClickListener { // binding.ivOrderPurchase.setOnClickListener {
@@ -1,7 +1,6 @@
package com.sw.inbound.activity package com.sw.inbound.activity
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@@ -152,7 +151,7 @@ class InitActivity : BaseActivity() {
"f0bcabbb-0d58-3b14-8bed-9863b7ec61ef" "f0bcabbb-0d58-3b14-8bed-9863b7ec61ef"
) )
if (list.contains(GlobalData.deviceId)) { if (list.contains(GlobalData.deviceId)) {
GlobalData.appBaseUrl = GlobalData.TEST_BASE_URL GlobalData.appBaseUrl = GlobalData.LOCAL_BASE_URL
} }
} }
val intent = Intent(this, HomeActivity::class.java) val intent = Intent(this, HomeActivity::class.java)
@@ -1,14 +1,19 @@
package com.sw.inbound.di package com.sw.inbound.di
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.sw.inbound.GlobalData
import com.sw.inbound.MyApp import com.sw.inbound.MyApp
import com.sw.inbound.network.api.InboundApiService import com.sw.inbound.network.api.InboundApiService
import com.sw.inbound.network.interceptor.InboundInterceptor import com.sw.inbound.network.interceptor.InboundInterceptor
import com.sw.inbound.network.interceptor.RequestInterceptor
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
@@ -21,9 +26,23 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
object InboundNetworkModule { 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 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 @Provides
@Singleton @Singleton
@Named("inbound") @Named("inbound")
@@ -38,7 +57,9 @@ object InboundNetworkModule {
level = if (MyApp.DEBUG) HttpLoggingInterceptor.Level.BODY level = if (MyApp.DEBUG) HttpLoggingInterceptor.Level.BODY
else HttpLoggingInterceptor.Level.NONE else HttpLoggingInterceptor.Level.NONE
}) })
.addInterceptor(InboundInterceptor()) .addInterceptor(DynamicBaseUrlInterceptor())
// .addInterceptor(InboundInterceptor())
.addInterceptor(RequestInterceptor())
.build() .build()
} }
@@ -48,7 +69,7 @@ object InboundNetworkModule {
fun provideInboundRetrofit(@Named("inbound") okHttpClient: OkHttpClient): Retrofit { fun provideInboundRetrofit(@Named("inbound") okHttpClient: OkHttpClient): Retrofit {
val gson = GsonBuilder().setLenient().create() val gson = GsonBuilder().setLenient().create()
return Retrofit.Builder() return Retrofit.Builder()
.baseUrl(INBOUND_BASE_URL) .baseUrl(GlobalData.appBaseUrl)
.client(okHttpClient) .client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson)) .addConverterFactory(GsonConverterFactory.create(gson))
.build() .build()
@@ -40,8 +40,8 @@ class EnvSwitchDialog(
override fun initView() { override fun initView() {
// 根据当前 appBaseUrl 预选对应 RadioButton,不匹配则不选 // 根据当前 appBaseUrl 预选对应 RadioButton,不匹配则不选
when (GlobalData.appBaseUrl) { when (GlobalData.appBaseUrl) {
GlobalData.TEST_BASE_URL -> binding.rbTest.isChecked = true GlobalData.LOCAL_BASE_URL -> binding.rbTest.isChecked = true
GlobalData.UAT_BASE_URL -> binding.rbUat.isChecked = true GlobalData.TEST_BASE_URL -> binding.rbUat.isChecked = true
GlobalData.PROD_BASE_URL -> binding.rbProd.isChecked = true GlobalData.PROD_BASE_URL -> binding.rbProd.isChecked = true
} }
@@ -56,8 +56,8 @@ class EnvSwitchDialog(
return@setOnClickListener return@setOnClickListener
} }
val newUrl = when (binding.rgEnv.checkedRadioButtonId) { val newUrl = when (binding.rgEnv.checkedRadioButtonId) {
binding.rbTest.id -> GlobalData.TEST_BASE_URL binding.rbTest.id -> GlobalData.LOCAL_BASE_URL
binding.rbUat.id -> GlobalData.UAT_BASE_URL binding.rbUat.id -> GlobalData.TEST_BASE_URL
binding.rbProd.id -> GlobalData.PROD_BASE_URL binding.rbProd.id -> GlobalData.PROD_BASE_URL
else -> return@setOnClickListener else -> return@setOnClickListener
} }
@@ -1,5 +1,6 @@
package com.sw.inbound.network.api package com.sw.inbound.network.api
import com.sw.inbound.GlobalData
import com.sw.inbound.model.response.IngredientByTrace import com.sw.inbound.model.response.IngredientByTrace
import com.sw.inbound.model.response.InboundApiResponse import com.sw.inbound.model.response.InboundApiResponse
import com.sw.inbound.model.response.SupplierOption import com.sw.inbound.model.response.SupplierOption
@@ -8,6 +9,7 @@ import retrofit2.http.Body
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.POST import retrofit2.http.POST
import retrofit2.http.Query import retrofit2.http.Query
import retrofit2.http.Url
/** /**
* 入库秤设备端接口 * 入库秤设备端接口
@@ -17,34 +19,39 @@ import retrofit2.http.Query
interface InboundApiService { interface InboundApiService {
/** 按溯源码查食材,用于毛菜/净菜入库时联动选择食材 */ /** 按溯源码查食材,用于毛菜/净菜入库时联动选择食材 */
@GET("nutrition/neglect/inbound/ingredient-by-trace") @GET
suspend fun getIngredientByTrace( suspend fun getIngredientByTrace(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/ingredient-by-trace",
@Query("traceCode") traceCode: String @Query("traceCode") traceCode: String
): InboundApiResponse<List<IngredientByTrace>> ): InboundApiResponse<List<IngredientByTrace>>
/** 仓库区域下拉列表 */ /** 仓库区域下拉列表 */
@GET("nutrition/neglect/inbound/zone-options") @GET
suspend fun getZoneOptions( suspend fun getZoneOptions(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/zone-options",
@Query("warehouseId") warehouseId: Long? = null, @Query("warehouseId") warehouseId: Long? = null,
@Query("keyword") keyword: String? = null @Query("keyword") keyword: String? = null
): InboundApiResponse<List<ZoneOption>> ): InboundApiResponse<List<ZoneOption>>
/** 供应商下拉列表,type: 1-内部,2-外部,不传返回全部 */ /** 供应商下拉列表,type: 1-内部,2-外部,不传返回全部 */
@GET("nutrition/neglect/inbound/supplier-options") @GET
suspend fun getSupplierOptions( suspend fun getSupplierOptions(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/supplier-options",
@Query("type") type: Int? = null, @Query("type") type: Int? = null,
@Query("keyword") keyword: String? = null @Query("keyword") keyword: String? = null
): InboundApiResponse<List<SupplierOption>> ): InboundApiResponse<List<SupplierOption>>
/** 毛菜入库提交,入参为 Map 以便动态组装字段 */ /** 毛菜入库提交,入参为 Map 以便动态组装字段 */
@POST("nutrition/neglect/inbound/raw-inbound") @POST
suspend fun submitRawInbound( suspend fun submitRawInbound(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/raw-inbound",
@Body param: Map<String, @JvmSuppressWildcards Any> @Body param: Map<String, @JvmSuppressWildcards Any>
): InboundApiResponse<Unit> ): InboundApiResponse<Unit>
/** 净菜入库提交,入参为 Map 以便动态组装字段 */ /** 净菜入库提交,入参为 Map 以便动态组装字段 */
@POST("nutrition/neglect/inbound/clean-inbound") @POST
suspend fun submitCleanInbound( suspend fun submitCleanInbound(
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/inbound/clean-inbound",
@Body param: Map<String, @JvmSuppressWildcards Any> @Body param: Map<String, @JvmSuppressWildcards Any>
): InboundApiResponse<Unit> ): InboundApiResponse<Unit>
} }
@@ -24,7 +24,7 @@ class InboundRepository @Inject constructor(
/** 按溯源码查食材 */ /** 按溯源码查食材 */
suspend fun getIngredientByTrace(traceCode: String): InboundApiResponse<List<IngredientByTrace>> { 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, warehouseId: Long? = null,
keyword: String? = null keyword: String? = null
): InboundApiResponse<List<ZoneOption>> { ): 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, type: Int? = null,
keyword: String? = null keyword: String? = null
): InboundApiResponse<List<SupplierOption>> { ): 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> { 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> { 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> { private suspend fun <T> safeCall(call: suspend () -> InboundApiResponse<T>): InboundApiResponse<T> {
@@ -79,7 +79,7 @@
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal">
<Button <androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnCancel" android:id="@+id/btnCancel"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
@@ -90,7 +90,7 @@
android:textColor="#ff141428" android:textColor="#ff141428"
android:textSize="28sp" /> android:textSize="28sp" />
<Button <androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnConfirm" android:id="@+id/btnConfirm"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"