refactor(network): 引入 RemoteRepository 隔离网络层,AppRepository 支持调料槽位查询
- 新增 RemoteRepository,将 NetViewModel 中直接调用 apiService 的逻辑下沉至仓库层 - NetViewModel 改为依赖注入 RemoteRepository,不再直接接触 apiService - AppRepository 构造函数增加 SeasoningSlotDao 参数,新增 hasSeasoningSlotConfig() 方法 - AppViewModel 新增 hasSeasoningSlotConfig() 方法,明确区分"调料数据"与"槽位配置"语义 - 同步更新 6 个 Activity 的 AppFactory 构造调用,传入 seasoningSlotDao Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package com.shuwei.dish.match.db
|
|||||||
|
|
||||||
import com.shuwei.dish.match.base.BaseApp
|
import com.shuwei.dish.match.base.BaseApp
|
||||||
import com.shuwei.dish.match.db.dao.AppDao
|
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.CookFoodEntity
|
||||||
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
|
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
|
||||||
import com.shuwei.dish.match.entity.SeasoningEntity
|
import com.shuwei.dish.match.entity.SeasoningEntity
|
||||||
@@ -9,7 +10,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.withContext
|
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) {
|
suspend fun insertCookFood(item: CookFoodEntity) = withContext(Dispatchers.IO) {
|
||||||
appDao.insertCookFood(item)
|
appDao.insertCookFood(item)
|
||||||
@@ -105,6 +106,15 @@ class AppRepository(val appDao: AppDao) {
|
|||||||
suspend fun insertSeasoning(item: SeasoningEntity) = withContext(Dispatchers.IO) {
|
suspend fun insertSeasoning(item: SeasoningEntity) = withContext(Dispatchers.IO) {
|
||||||
appDao.insertSeasoning(item)
|
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) {
|
//class SeasoningRepository(val seasoningDao: SeasoningDao) {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import java.net.UnknownHostException
|
|||||||
* @param onSuccess 成功回调
|
* @param onSuccess 成功回调
|
||||||
* @param onFailure 自定义错误回调(可选,不传则用默认提示)
|
* @param onFailure 自定义错误回调(可选,不传则用默认提示)
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
suspend fun <T> request(
|
suspend fun <T> request(
|
||||||
onRequest: suspend () -> ApiResponse<T>,
|
onRequest: suspend () -> ApiResponse<T>,
|
||||||
onSuccess: (T) -> Unit,
|
onSuccess: (T) -> Unit,
|
||||||
@@ -73,6 +74,7 @@ data class CodeMsg(
|
|||||||
var msg: String? = null
|
var msg: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
fun getApiException(e: Exception): ApiException {
|
fun getApiException(e: Exception): ApiException {
|
||||||
// 捕获各类网络异常并转换为自定义异常
|
// 捕获各类网络异常并转换为自定义异常
|
||||||
return when (e) {
|
return when (e) {
|
||||||
@@ -116,7 +118,7 @@ fun httpException2ApiException(e: HttpException): ApiException {
|
|||||||
val body = e.response()?.errorBody()?.string()
|
val body = e.response()?.errorBody()?.string()
|
||||||
val codeMsg: CodeMsg? = try {
|
val codeMsg: CodeMsg? = try {
|
||||||
body?.toObject<CodeMsg>()
|
body?.toObject<CodeMsg>()
|
||||||
} catch (ex: Exception) {
|
} catch (_: Exception) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
return ApiException(
|
return ApiException(
|
||||||
|
|||||||
@@ -8,104 +8,89 @@ import com.shuwei.dish.match.entity.FoodRecord
|
|||||||
import com.shuwei.dish.match.entity.SeasoningEntity
|
import com.shuwei.dish.match.entity.SeasoningEntity
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class NetViewModel : ViewModel() {
|
/**
|
||||||
|
* 网络请求 ViewModel,所有网络操作通过 RemoteRepository 发起,不直接依赖 apiService
|
||||||
|
* @param repository 网络数据仓库,默认使用单例实例
|
||||||
|
*/
|
||||||
|
class NetViewModel(
|
||||||
|
private val repository: RemoteRepository = RemoteRepository()
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交制作菜品
|
||||||
|
*/
|
||||||
fun submitCookFood(
|
fun submitCookFood(
|
||||||
entity: CookFoodEntity,
|
entity: CookFoodEntity,
|
||||||
onSuccess: (Any?) -> Unit,
|
onSuccess: (Any?) -> Unit,
|
||||||
onFailure: (String, String) -> Unit
|
onFailure: (String, String) -> Unit
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
request(
|
repository.submitCookFood(entity, onSuccess, onFailure)
|
||||||
onRequest = {
|
|
||||||
apiService.submitCookFood(param = entity)
|
|
||||||
},
|
|
||||||
onSuccess = onSuccess,
|
|
||||||
onFailure = onFailure
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询菜品详情
|
||||||
|
*/
|
||||||
fun getFoodDetail(
|
fun getFoodDetail(
|
||||||
foodId: String,
|
foodId: String,
|
||||||
onSuccess: (CookFoodEntity?) -> Unit,
|
onSuccess: (CookFoodEntity?) -> Unit,
|
||||||
onFailure: (String, String) -> Unit
|
onFailure: (String, String) -> Unit
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
request(
|
repository.getFoodDetail(foodId, onSuccess, onFailure)
|
||||||
onRequest = {
|
|
||||||
apiService.getFoodDetail(foodId = foodId)
|
|
||||||
},
|
|
||||||
onSuccess = onSuccess,
|
|
||||||
onFailure = onFailure
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索菜品列表
|
||||||
|
*/
|
||||||
fun searchFoodList(
|
fun searchFoodList(
|
||||||
param: MutableMap<String, Any>,
|
param: MutableMap<String, Any>,
|
||||||
onSuccess: (MutableList<FoodRecord>?) -> Unit,
|
onSuccess: (MutableList<FoodRecord>?) -> Unit,
|
||||||
onFailure: (String, String) -> Unit
|
onFailure: (String, String) -> Unit
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
request(
|
repository.searchFoodList(param, onSuccess, onFailure)
|
||||||
onRequest = {
|
|
||||||
apiService.searchFoodList(param = param)
|
|
||||||
},
|
|
||||||
onSuccess = onSuccess,
|
|
||||||
onFailure = onFailure
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询采样数据列表
|
||||||
|
*/
|
||||||
fun getSamplingList(
|
fun getSamplingList(
|
||||||
param: MutableMap<String, Any>,
|
param: MutableMap<String, Any>,
|
||||||
onSuccess: (MutableList<FoodRecord>?) -> Unit,
|
onSuccess: (MutableList<FoodRecord>?) -> Unit,
|
||||||
onFailure: (String, String) -> Unit
|
onFailure: (String, String) -> Unit
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
request(
|
repository.getSamplingList(param, onSuccess, onFailure)
|
||||||
onRequest = {
|
|
||||||
apiService.getSamplingList(param = param)
|
|
||||||
},
|
|
||||||
onSuccess = onSuccess,
|
|
||||||
onFailure = onFailure
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询物品信息列表
|
||||||
|
*/
|
||||||
fun queryGoodsList(
|
fun queryGoodsList(
|
||||||
param: MutableMap<String, Any>,
|
param: MutableMap<String, Any>,
|
||||||
onSuccess: (MutableList<CookFoodGoodsEntity>?) -> Unit,
|
onSuccess: (MutableList<CookFoodGoodsEntity>?) -> Unit,
|
||||||
onFailure: (String, String) -> Unit
|
onFailure: (String, String) -> Unit
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
request(
|
repository.queryGoodsList(param, onSuccess, onFailure)
|
||||||
onRequest = {
|
|
||||||
apiService.queryGoodsList(param = param)
|
|
||||||
},
|
|
||||||
onSuccess = onSuccess,
|
|
||||||
onFailure = onFailure
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询调料信息列表
|
||||||
|
*/
|
||||||
fun querySeasoningList(
|
fun querySeasoningList(
|
||||||
param: MutableMap<String, Any>,
|
param: MutableMap<String, Any>,
|
||||||
onSuccess: (MutableList<SeasoningEntity>?) -> Unit,
|
onSuccess: (MutableList<SeasoningEntity>?) -> Unit,
|
||||||
onFailure: (String, String) -> Unit
|
onFailure: (String, String) -> Unit
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
request(
|
repository.querySeasoningList(param, onSuccess, onFailure)
|
||||||
onRequest = {
|
|
||||||
apiService.querySeasoningList(param = param)
|
|
||||||
},
|
|
||||||
onSuccess = onSuccess,
|
|
||||||
onFailure = onFailure
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<String, Any>,
|
||||||
|
onSuccess: (MutableList<FoodRecord>?) -> 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<String, Any>,
|
||||||
|
onSuccess: (MutableList<FoodRecord>?) -> 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<String, Any>,
|
||||||
|
onSuccess: (MutableList<CookFoodGoodsEntity>?) -> 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<String, Any>,
|
||||||
|
onSuccess: (MutableList<SeasoningEntity>?) -> Unit,
|
||||||
|
onFailure: (String, String) -> Unit
|
||||||
|
) = request(
|
||||||
|
onRequest = { apiService.querySeasoningList(param = param) },
|
||||||
|
onSuccess = onSuccess,
|
||||||
|
onFailure = onFailure
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -102,7 +102,7 @@ class DishSamplingActivity : BaseActivity() {
|
|||||||
private fun initViewModel() {
|
private fun initViewModel() {
|
||||||
val db = BaseApp.instance!!.database
|
val db = BaseApp.instance!!.database
|
||||||
val factory =
|
val factory =
|
||||||
AppFactory(AppRepository(db.appDao()))
|
AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao()))
|
||||||
appViewModel =
|
appViewModel =
|
||||||
ViewModelProvider(this, factory)[AppViewModel::class.java]
|
ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ class HomeActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun initViewModel() {
|
private fun initViewModel() {
|
||||||
val db = BaseApp.instance!!.database
|
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]
|
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class InitActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun initViewModel() {
|
private fun initViewModel() {
|
||||||
val db = BaseApp.instance!!.database
|
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]
|
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class SamplingListActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun initViewModel() {
|
private fun initViewModel() {
|
||||||
val db = BaseApp.instance!!.database
|
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]
|
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class SelectDishActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun initViewModel() {
|
private fun initViewModel() {
|
||||||
val db = BaseApp.instance!!.database
|
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]
|
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun initViewModel() {
|
private fun initViewModel() {
|
||||||
val db = BaseApp.instance!!.database
|
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]
|
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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<SeasoningEntity>) {
|
// fun updateAll(list: MutableList<SeasoningEntity>) {
|
||||||
// viewModelScope.launch {
|
// viewModelScope.launch {
|
||||||
// list.forEach {
|
// list.forEach {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.shuwei.dish.match.viewmodel.factory
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.shuwei.dish.match.db.AppRepository
|
import com.shuwei.dish.match.db.AppRepository
|
||||||
|
import com.shuwei.dish.match.db.dao.SeasoningSlotDao
|
||||||
import com.shuwei.dish.match.viewmodel.AppViewModel
|
import com.shuwei.dish.match.viewmodel.AppViewModel
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
|||||||
Reference in New Issue
Block a user