From 75830b9204c42bfe0a51ead608ae51701385ae75 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Wed, 22 Apr 2026 18:31:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor(network):=20=E5=BC=95=E5=85=A5=20Remot?= =?UTF-8?q?eRepository=20=E9=9A=94=E7=A6=BB=E7=BD=91=E7=BB=9C=E5=B1=82?= =?UTF-8?q?=EF=BC=8CAppRepository=20=E6=94=AF=E6=8C=81=E8=B0=83=E6=96=99?= =?UTF-8?q?=E6=A7=BD=E4=BD=8D=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 RemoteRepository,将 NetViewModel 中直接调用 apiService 的逻辑下沉至仓库层 - NetViewModel 改为依赖注入 RemoteRepository,不再直接接触 apiService - AppRepository 构造函数增加 SeasoningSlotDao 参数,新增 hasSeasoningSlotConfig() 方法 - AppViewModel 新增 hasSeasoningSlotConfig() 方法,明确区分"调料数据"与"槽位配置"语义 - 同步更新 6 个 Activity 的 AppFactory 构造调用,传入 seasoningSlotDao Co-Authored-By: Claude Sonnet 4.6 --- .../dish/match/db/DatabaseRepository.kt | 12 +- .../com/shuwei/dish/match/net/ApiRequest.kt | 4 +- .../com/shuwei/dish/match/net/NetViewModel.kt | 77 +++++-------- .../shuwei/dish/match/net/RemoteRepository.kt | 109 ++++++++++++++++++ .../dish/match/ui/DishSamplingActivity.kt | 2 +- .../com/shuwei/dish/match/ui/HomeActivity.kt | 2 +- .../com/shuwei/dish/match/ui/InitActivity.kt | 2 +- .../dish/match/ui/SamplingListActivity.kt | 2 +- .../dish/match/ui/SelectDishActivity.kt | 2 +- .../dish/match/ui/SubmitFoodActivity.kt | 2 +- .../dish/match/viewmodel/AppViewModel.kt | 11 ++ .../dish/match/viewmodel/factory/VMFactory.kt | 1 + 12 files changed, 172 insertions(+), 54 deletions(-) create mode 100644 app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt diff --git a/app/src/main/java/com/shuwei/dish/match/db/DatabaseRepository.kt b/app/src/main/java/com/shuwei/dish/match/db/DatabaseRepository.kt index 7c293d2..bb47541 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/DatabaseRepository.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/DatabaseRepository.kt @@ -2,6 +2,7 @@ package com.shuwei.dish.match.db import com.shuwei.dish.match.base.BaseApp import com.shuwei.dish.match.db.dao.AppDao +import com.shuwei.dish.match.db.dao.SeasoningSlotDao import com.shuwei.dish.match.entity.CookFoodEntity import com.shuwei.dish.match.entity.CookFoodGoodsEntity import com.shuwei.dish.match.entity.SeasoningEntity @@ -9,7 +10,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -class AppRepository(val appDao: AppDao) { +class AppRepository(val appDao: AppDao, val seasoningSlotDao: SeasoningSlotDao) { suspend fun insertCookFood(item: CookFoodEntity) = withContext(Dispatchers.IO) { appDao.insertCookFood(item) @@ -105,6 +106,15 @@ class AppRepository(val appDao: AppDao) { suspend fun insertSeasoning(item: SeasoningEntity) = withContext(Dispatchers.IO) { appDao.insertSeasoning(item) } + + /** + * 查询指定设备是否已配置调料槽位 + * @param deviceId 目标设备 ID + * @return true 表示已有配置,false 表示未配置 + */ + suspend fun hasSeasoningSlotConfig(deviceId: String) = withContext(Dispatchers.IO) { + seasoningSlotDao.queryByDeviceId(deviceId).isNotEmpty() + } } // //class SeasoningRepository(val seasoningDao: SeasoningDao) { diff --git a/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt b/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt index 09bf890..7b73ff5 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt @@ -47,6 +47,7 @@ import java.net.UnknownHostException * @param onSuccess 成功回调 * @param onFailure 自定义错误回调(可选,不传则用默认提示) */ +@Suppress("UNCHECKED_CAST") suspend fun request( onRequest: suspend () -> ApiResponse, onSuccess: (T) -> Unit, @@ -73,6 +74,7 @@ data class CodeMsg( var msg: String? = null ) +@Suppress("DEPRECATION") fun getApiException(e: Exception): ApiException { // 捕获各类网络异常并转换为自定义异常 return when (e) { @@ -116,7 +118,7 @@ fun httpException2ApiException(e: HttpException): ApiException { val body = e.response()?.errorBody()?.string() val codeMsg: CodeMsg? = try { body?.toObject() - } catch (ex: Exception) { + } catch (_: Exception) { null } return ApiException( diff --git a/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt b/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt index 2adbb24..31220c6 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt @@ -8,104 +8,89 @@ import com.shuwei.dish.match.entity.FoodRecord import com.shuwei.dish.match.entity.SeasoningEntity import kotlinx.coroutines.launch -class NetViewModel : ViewModel() { +/** + * 网络请求 ViewModel,所有网络操作通过 RemoteRepository 发起,不直接依赖 apiService + * @param repository 网络数据仓库,默认使用单例实例 + */ +class NetViewModel( + private val repository: RemoteRepository = RemoteRepository() +) : ViewModel() { + /** + * 提交制作菜品 + */ fun submitCookFood( entity: CookFoodEntity, onSuccess: (Any?) -> Unit, onFailure: (String, String) -> Unit ) { viewModelScope.launch { - request( - onRequest = { - apiService.submitCookFood(param = entity) - }, - onSuccess = onSuccess, - onFailure = onFailure - ) + repository.submitCookFood(entity, onSuccess, onFailure) } } + /** + * 查询菜品详情 + */ fun getFoodDetail( foodId: String, onSuccess: (CookFoodEntity?) -> Unit, onFailure: (String, String) -> Unit ) { viewModelScope.launch { - request( - onRequest = { - apiService.getFoodDetail(foodId = foodId) - }, - onSuccess = onSuccess, - onFailure = onFailure - ) + repository.getFoodDetail(foodId, onSuccess, onFailure) } } - + /** + * 搜索菜品列表 + */ fun searchFoodList( param: MutableMap, onSuccess: (MutableList?) -> Unit, onFailure: (String, String) -> Unit ) { viewModelScope.launch { - request( - onRequest = { - apiService.searchFoodList(param = param) - }, - onSuccess = onSuccess, - onFailure = onFailure - ) + repository.searchFoodList(param, onSuccess, onFailure) } } + /** + * 查询采样数据列表 + */ fun getSamplingList( param: MutableMap, onSuccess: (MutableList?) -> Unit, onFailure: (String, String) -> Unit ) { viewModelScope.launch { - request( - onRequest = { - apiService.getSamplingList(param = param) - }, - onSuccess = onSuccess, - onFailure = onFailure - ) + repository.getSamplingList(param, onSuccess, onFailure) } } + /** + * 查询物品信息列表 + */ fun queryGoodsList( param: MutableMap, onSuccess: (MutableList?) -> Unit, onFailure: (String, String) -> Unit ) { viewModelScope.launch { - request( - onRequest = { - apiService.queryGoodsList(param = param) - }, - onSuccess = onSuccess, - onFailure = onFailure - ) + repository.queryGoodsList(param, onSuccess, onFailure) } } + /** + * 查询调料信息列表 + */ fun querySeasoningList( param: MutableMap, onSuccess: (MutableList?) -> Unit, onFailure: (String, String) -> Unit ) { viewModelScope.launch { - request( - onRequest = { - apiService.querySeasoningList(param = param) - }, - onSuccess = onSuccess, - onFailure = onFailure - ) + repository.querySeasoningList(param, onSuccess, onFailure) } } - - } diff --git a/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt b/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt new file mode 100644 index 0000000..3b24236 --- /dev/null +++ b/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt @@ -0,0 +1,109 @@ +package com.shuwei.dish.match.net + +import com.shuwei.dish.match.entity.CookFoodEntity +import com.shuwei.dish.match.entity.CookFoodGoodsEntity +import com.shuwei.dish.match.entity.FoodRecord +import com.shuwei.dish.match.entity.SeasoningEntity + +/** + * 网络数据仓库,封装所有 ApiService 调用 + * ViewModel 不直接接触 apiService,统一通过此类发起网络请求 + */ +class RemoteRepository { + + /** + * 提交制作菜品 + * @param entity 菜品实体 + * @param onSuccess 成功回调 + * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + */ + suspend fun submitCookFood( + entity: CookFoodEntity, + onSuccess: (Any?) -> Unit, + onFailure: (String, String) -> Unit + ) = request( + onRequest = { apiService.submitCookFood(param = entity) }, + onSuccess = onSuccess, + onFailure = onFailure + ) + + /** + * 查询菜品详情 + * @param foodId 菜品 ID + * @param onSuccess 成功回调 + * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + */ + suspend fun getFoodDetail( + foodId: String, + onSuccess: (CookFoodEntity?) -> Unit, + onFailure: (String, String) -> Unit + ) = request( + onRequest = { apiService.getFoodDetail(foodId = foodId) }, + onSuccess = onSuccess, + onFailure = onFailure + ) + + /** + * 搜索菜品列表 + * @param param 查询参数 + * @param onSuccess 成功回调 + * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + */ + suspend fun searchFoodList( + param: MutableMap, + onSuccess: (MutableList?) -> Unit, + onFailure: (String, String) -> Unit + ) = request( + onRequest = { apiService.searchFoodList(param = param) }, + onSuccess = onSuccess, + onFailure = onFailure + ) + + /** + * 查询采样数据列表 + * @param param 查询参数 + * @param onSuccess 成功回调 + * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + */ + suspend fun getSamplingList( + param: MutableMap, + onSuccess: (MutableList?) -> Unit, + onFailure: (String, String) -> Unit + ) = request( + onRequest = { apiService.getSamplingList(param = param) }, + onSuccess = onSuccess, + onFailure = onFailure + ) + + /** + * 查询物品信息列表 + * @param param 查询参数 + * @param onSuccess 成功回调 + * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + */ + suspend fun queryGoodsList( + param: MutableMap, + onSuccess: (MutableList?) -> Unit, + onFailure: (String, String) -> Unit + ) = request( + onRequest = { apiService.queryGoodsList(param = param) }, + onSuccess = onSuccess, + onFailure = onFailure + ) + + /** + * 查询调料信息列表 + * @param param 查询参数 + * @param onSuccess 成功回调 + * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + */ + suspend fun querySeasoningList( + param: MutableMap, + onSuccess: (MutableList?) -> Unit, + onFailure: (String, String) -> Unit + ) = request( + onRequest = { apiService.querySeasoningList(param = param) }, + onSuccess = onSuccess, + onFailure = onFailure + ) +} diff --git a/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt index d796640..42f2df8 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt @@ -102,7 +102,7 @@ class DishSamplingActivity : BaseActivity() { private fun initViewModel() { val db = BaseApp.instance!!.database val factory = - AppFactory(AppRepository(db.appDao())) + AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())) appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java] } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt index 6df75e4..7a81893 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/HomeActivity.kt @@ -138,7 +138,7 @@ class HomeActivity : BaseActivity() { private fun initViewModel() { val db = BaseApp.instance!!.database - val factory = AppFactory(AppRepository(db.appDao())) + val factory = AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())) appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java] } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/InitActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/InitActivity.kt index 9dda7f8..5e2ebd5 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/InitActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/InitActivity.kt @@ -70,7 +70,7 @@ class InitActivity : BaseActivity() { private fun initViewModel() { val db = BaseApp.instance!!.database - val factory = AppFactory(AppRepository(db.appDao())) + val factory = AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())) appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java] } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt index 4eab86a..0577cd6 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SamplingListActivity.kt @@ -74,7 +74,7 @@ class SamplingListActivity : BaseActivity() { private fun initViewModel() { val db = BaseApp.instance!!.database - val factory = AppFactory(AppRepository(db.appDao())) + val factory = AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())) appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java] } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt index 8699187..bb986e8 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SelectDishActivity.kt @@ -68,7 +68,7 @@ class SelectDishActivity : BaseActivity() { private fun initViewModel() { val db = BaseApp.instance!!.database - val factory = AppFactory(AppRepository(db.appDao())) + val factory = AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())) appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java] } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt index 7e5e190..8f5d233 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt @@ -395,7 +395,7 @@ class SubmitFoodActivity : BaseActivity() { private fun initViewModel() { val db = BaseApp.instance!!.database - val factory = AppFactory(AppRepository(db.appDao())) + val factory = AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())) appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java] } diff --git a/app/src/main/java/com/shuwei/dish/match/viewmodel/AppViewModel.kt b/app/src/main/java/com/shuwei/dish/match/viewmodel/AppViewModel.kt index 7d4d5fb..166ec14 100644 --- a/app/src/main/java/com/shuwei/dish/match/viewmodel/AppViewModel.kt +++ b/app/src/main/java/com/shuwei/dish/match/viewmodel/AppViewModel.kt @@ -173,6 +173,17 @@ class AppViewModel(private val rep: AppRepository) : ViewModel() { } } + /** + * 查询指定设备是否已配置调料槽位 + * @param deviceId 目标设备 ID + * @param action 回调,true 表示已配置,false 表示未配置 + */ + fun hasSeasoningSlotConfig(deviceId: String, action: (Boolean) -> Unit) { + viewModelScope.launch { + action(rep.hasSeasoningSlotConfig(deviceId)) + } + } + // fun updateAll(list: MutableList) { // viewModelScope.launch { // list.forEach { diff --git a/app/src/main/java/com/shuwei/dish/match/viewmodel/factory/VMFactory.kt b/app/src/main/java/com/shuwei/dish/match/viewmodel/factory/VMFactory.kt index 1ca32fc..0d1dd19 100644 --- a/app/src/main/java/com/shuwei/dish/match/viewmodel/factory/VMFactory.kt +++ b/app/src/main/java/com/shuwei/dish/match/viewmodel/factory/VMFactory.kt @@ -3,6 +3,7 @@ package com.shuwei.dish.match.viewmodel.factory import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.shuwei.dish.match.db.AppRepository +import com.shuwei.dish.match.db.dao.SeasoningSlotDao import com.shuwei.dish.match.viewmodel.AppViewModel @Suppress("UNCHECKED_CAST")