From 3581975ab04dcfa12b6cdd52baa8039406df4b30 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Thu, 23 Apr 2026 10:29:17 +0800 Subject: [PATCH] =?UTF-8?q?refactor(viewmodel):=20=E6=96=B0=E5=A2=9E=20sea?= =?UTF-8?q?soningSlotState=20=E6=9B=BF=E4=BB=A3=20loadSeasoning=EF=BC=8C?= =?UTF-8?q?=E5=B0=86=20getSamplingList=20=E8=BF=81=E7=A7=BB=E8=87=B3=20Sta?= =?UTF-8?q?teFlow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dish/match/db/DatabaseRepository.kt | 7 ++ .../com/shuwei/dish/match/net/NetViewModel.kt | 15 ++-- .../shuwei/dish/match/net/RemoteRepository.kt | 22 +++--- .../com/shuwei/dish/match/ui/HomeActivity.kt | 15 ++-- .../com/shuwei/dish/match/ui/InitActivity.kt | 13 ++-- .../dish/match/ui/SamplingListActivity.kt | 69 +++++++------------ .../dish/match/viewmodel/AppViewModel.kt | 17 +++++ 7 files changed, 84 insertions(+), 74 deletions(-) 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 bb47541..6f6e5a2 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 @@ -115,6 +115,13 @@ class AppRepository(val appDao: AppDao, val seasoningSlotDao: SeasoningSlotDao) suspend fun hasSeasoningSlotConfig(deviceId: String) = withContext(Dispatchers.IO) { seasoningSlotDao.queryByDeviceId(deviceId).isNotEmpty() } + + /** + * 查询所有设备的调料槽位配置 + */ + suspend fun getAllSeasoningSlots() = withContext(Dispatchers.IO) { + seasoningSlotDao.queryAll() + } } // //class SeasoningRepository(val seasoningDao: SeasoningDao) { 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 caa5240..eb35ba3 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 @@ -61,16 +61,19 @@ class NetViewModel( } } + /** + * 查询采样数据列表的 UI 状态流,UI 层通过 collect 监听 + */ + private val _samplingListState = MutableStateFlow?>>(UiState.Idle) + val samplingListState: StateFlow?>> = _samplingListState.asStateFlow() + /** * 查询采样数据列表 */ - fun getSamplingList( - param: MutableMap, - onSuccess: (MutableList?) -> Unit, - onFailure: (String, String) -> Unit - ) { + fun getSamplingList(param: MutableMap) { viewModelScope.launch { - repository.getSamplingList(param, onSuccess, onFailure) + _samplingListState.value = UiState.Loading + _samplingListState.value = repository.getSamplingList(param) } } 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 index 5fb598c..9a170c3 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt @@ -62,18 +62,18 @@ class RemoteRepository { /** * 查询采样数据列表 * @param param 查询参数 - * @param onSuccess 成功回调 - * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + * @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息 */ - suspend fun getSamplingList( - param: MutableMap, - onSuccess: (MutableList?) -> Unit, - onFailure: (String, String) -> Unit - ) = request( - onRequest = { apiService.getSamplingList(param = param) }, - onSuccess = onSuccess, - onFailure = onFailure - ) + suspend fun getSamplingList(param: MutableMap): UiState?> { + return try { + val resp = apiService.getSamplingList(param = param) + if (resp.isSuccess()) UiState.Success(resp.data) + else UiState.Error(resp.code, resp.msg ?: "") + } catch (e: Exception) { + val ex = getApiException(e) + UiState.Error("-1", ex.errorMsg) + } + } /** * 查询物品信息列表 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 7a81893..7c998fc 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 @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.os.Bundle import androidx.activity.addCallback import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.shuwei.dish.match.R import com.shuwei.dish.match.adapter.HomeModeAdapter @@ -17,6 +18,7 @@ import com.shuwei.dish.match.utils.ext.startActivity import com.shuwei.dish.match.utils.ext.toast import com.shuwei.dish.match.viewmodel.AppViewModel import com.shuwei.dish.match.viewmodel.factory.AppFactory +import kotlinx.coroutines.launch class HomeActivity : BaseActivity() { @@ -143,21 +145,22 @@ class HomeActivity : BaseActivity() { } private fun goSampling() { - appViewModel.loadSeasoning { - if (it.isEmpty()) { - //无调料信息打开采样历史列表页面,点击设置配置调料信息 + lifecycleScope.launch { + val slots = appViewModel.loadSeasoningSlot() + if (slots.isEmpty()) { + // 无调料信息,打开采样历史列表页面,点击设置配置调料信息 startActivity() finish() - return@loadSeasoning + return@launch } appViewModel.countCookFood(cookMode = 1) { count -> if (count > 0) { - //有烹饪中数据打开采样历史列表页面 + // 有烹饪中数据,打开采样历史列表页面 startActivity() finish() return@countCookFood } - //无烹饪数据打开新增采样页面 + // 无烹饪数据,打开新增采样页面 startActivity { putExtra(PrepareCookActivity.PAGE_FROM, PrepareCookActivity.HOME) } 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 5e2ebd5..cb683f0 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 @@ -100,19 +100,20 @@ class InitActivity : BaseActivity() { } private fun goSampling() { - appViewModel.loadSeasoning { - if (it.isEmpty()) { - //无调料信息打开采样历史列表页面,点击设置配置调料信息 + lifecycleScope.launch { + val slots = appViewModel.loadSeasoningSlot() + if (slots.isEmpty()) { + // 无调料信息,打开采样历史列表页面,点击设置配置调料信息 startActivity() - return@loadSeasoning + return@launch } appViewModel.countCookFood(cookMode = 1) { count -> if (count > 0) { - //有烹饪中数据打开采样历史列表页面 + // 有烹饪中数据,打开采样历史列表页面 startActivity() return@countCookFood } - //无烹饪数据打开新增采样页面 + // 无烹饪数据,打开新增采样页面 startActivity { putExtra(PrepareCookActivity.PAGE_FROM, PrepareCookActivity.HOME) } 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 a3130ea..c3d5dcb 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 @@ -31,6 +31,7 @@ import com.shuwei.dish.match.viewmodel.AppViewModel import com.shuwei.dish.match.viewmodel.factory.AppFactory import java.io.Serializable import kotlinx.coroutines.launch +import com.shuwei.dish.match.net.UiState class SamplingListActivity : BaseActivity() { @@ -88,6 +89,24 @@ class SamplingListActivity : BaseActivity() { } } } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + netViewModel.samplingListState.collect { state -> + when (state) { + is UiState.Loading -> showLoading() + is UiState.Success -> loadDishList(state.data) + is UiState.Error -> { + binding.refreshLayout.setEnableRefresh(true) + toast(state.msg) + finishRefresh() + delayDismissLoading() + if (pageNo == 1) loadEmptyView() + } + is UiState.Idle -> {} + } + } + } + } } @@ -229,53 +248,12 @@ class SamplingListActivity : BaseActivity() { @SuppressLint("NotifyDataSetChanged") fun getSamplingList() { - showLoading() -// val map = mapOf( -//// "foodName" to input, -// "pageNo" to "$pageNo", -// "pageSize" to "$pageSize", -// "canteenId" to BaseApp.canteenId -// ) -// val sb = StringBuilder(UrlConfig.SAMPLING_LIST).apply { -// append("?") -// map.forEach { (key, value) -> append("$key=$value&") } -// } -// sb.deleteCharAt(sb.length - 1) -// HttpUtil.get( -// url = sb.toString(), -// doSuccess = { -// loadDishList(it) -// }, doFailure = { code, msg -> -// binding.refreshLayout.run { -// setEnableRefresh(true) -// } -// toast(msg) -// finishRefresh() -// binding.refreshLayout.setEnableRefresh(true) -// delayDismissLoading() -// if (pageNo == 1) { -// loadEmptyView() -// } -// }) - netViewModel.getSamplingList( param = mutableMapOf( "pageNum" to pageNo, "pageSize" to pageSize, "placeId" to BaseApp.canteenId - ), - onSuccess = { - loadDishList(it) - }, - onFailure = { code, msg -> - binding.refreshLayout.setEnableRefresh(true) - toast(msg) - finishRefresh() - delayDismissLoading() - if (pageNo == 1) { - loadEmptyView() - } - } + ) ) } @@ -381,10 +359,11 @@ class SamplingListActivity : BaseActivity() { block() return } - appViewModel.loadSeasoning { - if (it.isEmpty()) { + lifecycleScope.launch { + val slots = appViewModel.loadSeasoningSlot() + if (slots.isEmpty()) { showDeviceConfigDialog() - return@loadSeasoning + return@launch } configFinished = true block() 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 30368b5..8220e70 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 @@ -6,6 +6,7 @@ import com.shuwei.dish.match.db.AppRepository import com.shuwei.dish.match.entity.CookFoodEntity import com.shuwei.dish.match.entity.CookFoodGoodsEntity import com.shuwei.dish.match.entity.SeasoningEntity +import com.shuwei.dish.match.entity.SeasoningSlotEntity import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -165,6 +166,22 @@ class AppViewModel(private val rep: AppRepository) : ViewModel() { } } + /** + * 所有设备调料槽位配置的 UI 状态流 + */ + private val _seasoningSlotState = MutableStateFlow>(emptyList()) + val seasoningSlotState: StateFlow> = _seasoningSlotState.asStateFlow() + + /** + * 查询所有调料槽位配置,更新 seasoningSlotState 并返回结果 + * 声明为 suspend,调用方可在同一协程中直接使用返回值,无需等待 StateFlow 更新 + */ + suspend fun loadSeasoningSlot(): List { + val slots = rep.getAllSeasoningSlots() + _seasoningSlotState.value = slots + return slots + } + fun deleteSeasoningBySort(sort: Int) { viewModelScope.launch { rep.deleteSeasoningBySort(sort)