refactor(viewmodel): 新增 seasoningSlotState 替代 loadSeasoning,将 getSamplingList 迁移至 StateFlow

This commit is contained in:
2026-04-23 10:29:17 +08:00
parent 9e99e6ef6d
commit 3581975ab0
7 changed files with 84 additions and 74 deletions
@@ -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) {
@@ -61,16 +61,19 @@ class NetViewModel(
}
}
/**
* 查询采样数据列表的 UI 状态流,UI 层通过 collect 监听
*/
private val _samplingListState = MutableStateFlow<UiState<MutableList<FoodRecord>?>>(UiState.Idle)
val samplingListState: StateFlow<UiState<MutableList<FoodRecord>?>> = _samplingListState.asStateFlow()
/**
* 查询采样数据列表
*/
fun getSamplingList(
param: MutableMap<String, Any>,
onSuccess: (MutableList<FoodRecord>?) -> Unit,
onFailure: (String, String) -> Unit
) {
fun getSamplingList(param: MutableMap<String, Any>) {
viewModelScope.launch {
repository.getSamplingList(param, onSuccess, onFailure)
_samplingListState.value = UiState.Loading
_samplingListState.value = repository.getSamplingList(param)
}
}
@@ -62,18 +62,18 @@ class RemoteRepository {
/**
* 查询采样数据列表
* @param param 查询参数
* @param onSuccess 成功回调
* @param onFailure 失败回调,参数为 (errorCode, errorMsg)
* @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息
*/
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
)
suspend fun getSamplingList(param: MutableMap<String, Any>): UiState<MutableList<FoodRecord>?> {
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)
}
}
/**
* 查询物品信息列表
@@ -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<SamplingListActivity>()
finish()
return@loadSeasoning
return@launch
}
appViewModel.countCookFood(cookMode = 1) { count ->
if (count > 0) {
//有烹饪中数据打开采样历史列表页面
// 有烹饪中数据打开采样历史列表页面
startActivity<SamplingListActivity>()
finish()
return@countCookFood
}
//无烹饪数据打开新增采样页面
// 无烹饪数据打开新增采样页面
startActivity<PrepareCookActivity> {
putExtra(PrepareCookActivity.PAGE_FROM, PrepareCookActivity.HOME)
}
@@ -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<SamplingListActivity>()
return@loadSeasoning
return@launch
}
appViewModel.countCookFood(cookMode = 1) { count ->
if (count > 0) {
//有烹饪中数据打开采样历史列表页面
// 有烹饪中数据打开采样历史列表页面
startActivity<SamplingListActivity>()
return@countCookFood
}
//无烹饪数据打开新增采样页面
// 无烹饪数据打开新增采样页面
startActivity<PrepareCookActivity> {
putExtra(PrepareCookActivity.PAGE_FROM, PrepareCookActivity.HOME)
}
@@ -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()
@@ -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<List<SeasoningSlotEntity>>(emptyList())
val seasoningSlotState: StateFlow<List<SeasoningSlotEntity>> = _seasoningSlotState.asStateFlow()
/**
* 查询所有调料槽位配置,更新 seasoningSlotState 并返回结果
* 声明为 suspend,调用方可在同一协程中直接使用返回值,无需等待 StateFlow 更新
*/
suspend fun loadSeasoningSlot(): List<SeasoningSlotEntity> {
val slots = rep.getAllSeasoningSlots()
_seasoningSlotState.value = slots
return slots
}
fun deleteSeasoningBySort(sort: Int) {
viewModelScope.launch {
rep.deleteSeasoningBySort(sort)