refactor(viewmodel): 将回调方式统一改为 StateFlow + UiState,消除竞态问题
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,6 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlin.collections.forEach
|
|
||||||
|
|
||||||
class DbViewModel : ViewModel() {
|
class DbViewModel : ViewModel() {
|
||||||
|
|
||||||
@@ -24,10 +23,12 @@ class DbViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCookFoodById(foodId: String, cookMode: Int, action: (CookFoodEntity?) -> Unit) {
|
private val _cookFoodDetailState = MutableStateFlow<CookFoodEntity?>(null)
|
||||||
|
val cookFoodDetailState: StateFlow<CookFoodEntity?> = _cookFoodDetailState.asStateFlow()
|
||||||
|
|
||||||
|
fun getCookFoodById(foodId: String, cookMode: Int) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val data = rep.getCookFoodById(foodId, cookMode)
|
_cookFoodDetailState.value = rep.getCookFoodById(foodId, cookMode)
|
||||||
action(data)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,11 +44,8 @@ class DbViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun countCookFood(cookMode: Int, action: (Int) -> Unit) {
|
suspend fun countCookFood(cookMode: Int): Int {
|
||||||
viewModelScope.launch {
|
return rep.countCookFood(cookMode)
|
||||||
val count = rep.countCookFood(cookMode)
|
|
||||||
action(count)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fun saveCookFood(cookMode: Int, entity: CookFoodEntity) {
|
// fun saveCookFood(cookMode: Int, entity: CookFoodEntity) {
|
||||||
@@ -141,11 +139,18 @@ class DbViewModel : ViewModel() {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
private val loadSeasoningMutex = Mutex()
|
private val loadSeasoningMutex = Mutex()
|
||||||
fun loadSeasoning(action: (MutableList<SeasoningEntity>) -> Unit) {
|
|
||||||
|
/**
|
||||||
|
* 本地调料列表状态流
|
||||||
|
*/
|
||||||
|
private val _seasoningState = MutableStateFlow<MutableList<SeasoningEntity>>(mutableListOf())
|
||||||
|
val seasoningState: StateFlow<MutableList<SeasoningEntity>> = _seasoningState.asStateFlow()
|
||||||
|
|
||||||
|
fun loadSeasoning() {
|
||||||
if (loadSeasoningMutex.isLocked) return
|
if (loadSeasoningMutex.isLocked) return
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
loadSeasoningMutex.withLock {
|
loadSeasoningMutex.withLock {
|
||||||
action(rep.getAllStream())
|
_seasoningState.value = rep.getAllStream()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,21 +177,26 @@ class DbViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearAllSeasoning(action:()->Unit) {
|
private val _clearAllSeasoningState = MutableStateFlow(false)
|
||||||
|
val clearAllSeasoningState: StateFlow<Boolean> = _clearAllSeasoningState.asStateFlow()
|
||||||
|
|
||||||
|
fun clearAllSeasoning() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
rep.clearAllSeasoning()
|
rep.clearAllSeasoning()
|
||||||
action()
|
_clearAllSeasoningState.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val _hasSeasoningSlotConfigState = MutableStateFlow(false)
|
||||||
|
val hasSeasoningSlotConfigState: StateFlow<Boolean> = _hasSeasoningSlotConfigState.asStateFlow()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询指定设备是否已配置调料槽位
|
* 查询指定设备是否已配置调料槽位
|
||||||
* @param deviceId 目标设备 ID
|
* @param deviceId 目标设备 ID
|
||||||
* @param action 回调,true 表示已配置,false 表示未配置
|
|
||||||
*/
|
*/
|
||||||
fun hasSeasoningSlotConfig(deviceId: String, action: (Boolean) -> Unit) {
|
fun hasSeasoningSlotConfig(deviceId: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
action(rep.hasSeasoningSlotConfig(deviceId))
|
_hasSeasoningSlotConfigState.value = rep.hasSeasoningSlotConfig(deviceId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.view.isEmpty
|
import androidx.core.view.isEmpty
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
@@ -17,9 +20,12 @@ import com.shuwei.dish.match.base.BaseActivity
|
|||||||
import com.shuwei.dish.match.base.BaseApp
|
import com.shuwei.dish.match.base.BaseApp
|
||||||
import com.shuwei.dish.match.databinding.DialogFoodSearchBinding
|
import com.shuwei.dish.match.databinding.DialogFoodSearchBinding
|
||||||
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
|
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
|
||||||
|
import com.shuwei.dish.match.net.UiState
|
||||||
import com.shuwei.dish.match.utils.KeyboardUtil
|
import com.shuwei.dish.match.utils.KeyboardUtil
|
||||||
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
|
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
|
||||||
import com.shuwei.dish.match.utils.ext.toast
|
import com.shuwei.dish.match.utils.ext.toast
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 食材搜索弹窗,继承 BottomSheetDialog 确保只初始化一次
|
* 食材搜索弹窗,继承 BottomSheetDialog 确保只初始化一次
|
||||||
@@ -97,6 +103,8 @@ class FoodSearchDialog(
|
|||||||
binding.ivSearch.setOnClickListener { searchGoods(it) }
|
binding.ivSearch.setOnClickListener { searchGoods(it) }
|
||||||
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it.context, it) }
|
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it.context, it) }
|
||||||
|
|
||||||
|
initObserver()
|
||||||
|
|
||||||
// 若有默认食材名称,自动填充并触发搜索
|
// 若有默认食材名称,自动填充并触发搜索
|
||||||
if (!defGoodsName.isNullOrBlank()) {
|
if (!defGoodsName.isNullOrBlank()) {
|
||||||
binding.etSheetInput.setText(defGoodsName)
|
binding.etSheetInput.setText(defGoodsName)
|
||||||
@@ -104,6 +112,26 @@ class FoodSearchDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收集 goodsListState,统一处理 Loading / Success / Error 状态
|
||||||
|
*/
|
||||||
|
private fun initObserver() {
|
||||||
|
activity.lifecycleScope.launch {
|
||||||
|
activity.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
activity.netViewModel.goodsListState.collect { state ->
|
||||||
|
when (state) {
|
||||||
|
is UiState.Success -> loadGoodsList(state.data)
|
||||||
|
is UiState.Error -> {
|
||||||
|
activity.toast(state.msg)
|
||||||
|
finishRefresh()
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 触发搜索:校验输入、隐藏键盘、发起请求
|
* 触发搜索:校验输入、隐藏键盘、发起请求
|
||||||
*/
|
*/
|
||||||
@@ -130,12 +158,7 @@ class FoodSearchDialog(
|
|||||||
if (!goodsName.isNullOrBlank()) {
|
if (!goodsName.isNullOrBlank()) {
|
||||||
param["goodsName"] = goodsName!!
|
param["goodsName"] = goodsName!!
|
||||||
}
|
}
|
||||||
activity.netViewModel.queryGoodsList(param = param, onSuccess = {
|
activity.netViewModel.queryGoodsList(param)
|
||||||
loadGoodsList(it)
|
|
||||||
}, onFailure = { _, msg ->
|
|
||||||
activity.toast(msg)
|
|
||||||
finishRefresh()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ import android.view.WindowManager
|
|||||||
import androidx.core.graphics.toColorInt
|
import androidx.core.graphics.toColorInt
|
||||||
import androidx.core.view.isEmpty
|
import androidx.core.view.isEmpty
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
@@ -27,6 +30,7 @@ import com.shuwei.dish.match.base.BaseActivity
|
|||||||
import com.shuwei.dish.match.base.BaseApp
|
import com.shuwei.dish.match.base.BaseApp
|
||||||
import com.shuwei.dish.match.databinding.DialogSeasoningSearchBinding
|
import com.shuwei.dish.match.databinding.DialogSeasoningSearchBinding
|
||||||
import com.shuwei.dish.match.entity.SeasoningEntity
|
import com.shuwei.dish.match.entity.SeasoningEntity
|
||||||
|
import com.shuwei.dish.match.net.UiState
|
||||||
import com.shuwei.dish.match.utils.KeyboardUtil
|
import com.shuwei.dish.match.utils.KeyboardUtil
|
||||||
import com.shuwei.dish.match.utils.WeightUtil
|
import com.shuwei.dish.match.utils.WeightUtil
|
||||||
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
|
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
|
||||||
@@ -35,6 +39,8 @@ import com.shuwei.dish.match.utils.ext.buildSpannableString
|
|||||||
import com.shuwei.dish.match.utils.ext.dp
|
import com.shuwei.dish.match.utils.ext.dp
|
||||||
import com.shuwei.dish.match.utils.ext.roundedDecimalPlace
|
import com.shuwei.dish.match.utils.ext.roundedDecimalPlace
|
||||||
import com.shuwei.dish.match.utils.ext.toast
|
import com.shuwei.dish.match.utils.ext.toast
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调料搜索弹窗,继承 BottomSheetDialog 确保只初始化一次
|
* 调料搜索弹窗,继承 BottomSheetDialog 确保只初始化一次
|
||||||
@@ -106,10 +112,10 @@ class SeasoningSearchDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RecyclerView 初始化及滑动冲突处理
|
// RecyclerView 初始化及滑动冲突处理
|
||||||
binding.recyclerView.run {
|
binding.recyclerView.let {
|
||||||
layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.VERTICAL, false)
|
it.layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.VERTICAL, false)
|
||||||
adapter = this@SeasoningSearchDialog.adapter
|
it.adapter = adapter
|
||||||
addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
it.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
|
||||||
super.onScrolled(rv, dx, dy)
|
super.onScrolled(rv, dx, dy)
|
||||||
// 解决 RecyclerView 与 SmartRefreshLayout 滑动冲突
|
// 解决 RecyclerView 与 SmartRefreshLayout 滑动冲突
|
||||||
@@ -147,6 +153,8 @@ class SeasoningSearchDialog(
|
|||||||
)
|
)
|
||||||
binding.tvWeight.text = getTextSpan(0.0)
|
binding.tvWeight.text = getTextSpan(0.0)
|
||||||
|
|
||||||
|
initObserver()
|
||||||
|
|
||||||
// 若有默认调料名称,自动填充并触发搜索
|
// 若有默认调料名称,自动填充并触发搜索
|
||||||
if (!clickName.isNullOrBlank()) {
|
if (!clickName.isNullOrBlank()) {
|
||||||
binding.etSheetInput.setText(clickName.trim())
|
binding.etSheetInput.setText(clickName.trim())
|
||||||
@@ -155,6 +163,26 @@ class SeasoningSearchDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收集 seasoningListState,统一处理 Loading / Success / Error 状态
|
||||||
|
*/
|
||||||
|
private fun initObserver() {
|
||||||
|
activity.lifecycleScope.launch {
|
||||||
|
activity.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
activity.netViewModel.seasoningListState.collect { state ->
|
||||||
|
when (state) {
|
||||||
|
is UiState.Success -> loadGoodsList(state.data)
|
||||||
|
is UiState.Error -> {
|
||||||
|
activity.toast(state.msg)
|
||||||
|
finishRefresh()
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 触发搜索:校验输入、隐藏键盘、发起请求
|
* 触发搜索:校验输入、隐藏键盘、发起请求
|
||||||
*/
|
*/
|
||||||
@@ -181,12 +209,7 @@ class SeasoningSearchDialog(
|
|||||||
if (!goodsName.isNullOrBlank()) {
|
if (!goodsName.isNullOrBlank()) {
|
||||||
param["goodsName"] = goodsName!!
|
param["goodsName"] = goodsName!!
|
||||||
}
|
}
|
||||||
activity.netViewModel.querySeasoningList(param = param, onSuccess = {
|
activity.netViewModel.querySeasoningList(param)
|
||||||
loadGoodsList(it)
|
|
||||||
}, onFailure = { _, msg ->
|
|
||||||
activity.toast(msg)
|
|
||||||
finishRefresh()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -35,16 +35,19 @@ class NetViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询菜品详情的 UI 状态流,UI 层通过 collect 监听
|
||||||
|
*/
|
||||||
|
private val _foodDetailState = MutableStateFlow<UiState<CookFoodEntity?>>(UiState.Idle)
|
||||||
|
val foodDetailState: StateFlow<UiState<CookFoodEntity?>> = _foodDetailState.asStateFlow()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询菜品详情
|
* 查询菜品详情
|
||||||
*/
|
*/
|
||||||
fun getFoodDetail(
|
fun getFoodDetail(foodId: String) {
|
||||||
foodId: String,
|
|
||||||
onSuccess: (CookFoodEntity?) -> Unit,
|
|
||||||
onFailure: (String, String) -> Unit
|
|
||||||
) {
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
repository.getFoodDetail(foodId, onSuccess, onFailure)
|
_foodDetailState.value = UiState.Loading
|
||||||
|
_foodDetailState.value = repository.getFoodDetail(foodId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,29 +83,35 @@ class NetViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询物品信息列表的 UI 状态流,UI 层通过 collect 监听
|
||||||
|
*/
|
||||||
|
private val _goodsListState = MutableStateFlow<UiState<MutableList<CookFoodGoodsEntity>?>>(UiState.Idle)
|
||||||
|
val goodsListState: StateFlow<UiState<MutableList<CookFoodGoodsEntity>?>> = _goodsListState.asStateFlow()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询物品信息列表
|
* 查询物品信息列表
|
||||||
*/
|
*/
|
||||||
fun queryGoodsList(
|
fun queryGoodsList(param: MutableMap<String, Any>) {
|
||||||
param: MutableMap<String, Any>,
|
|
||||||
onSuccess: (MutableList<CookFoodGoodsEntity>?) -> Unit,
|
|
||||||
onFailure: (String, String) -> Unit
|
|
||||||
) {
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
repository.queryGoodsList(param, onSuccess, onFailure)
|
_goodsListState.value = UiState.Loading
|
||||||
|
_goodsListState.value = repository.queryGoodsList(param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询调料信息列表的 UI 状态流,UI 层通过 collect 监听
|
||||||
|
*/
|
||||||
|
private val _seasoningListState = MutableStateFlow<UiState<MutableList<SeasoningEntity>?>>(UiState.Idle)
|
||||||
|
val seasoningListState: StateFlow<UiState<MutableList<SeasoningEntity>?>> = _seasoningListState.asStateFlow()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询调料信息列表
|
* 查询调料信息列表
|
||||||
*/
|
*/
|
||||||
fun querySeasoningList(
|
fun querySeasoningList(param: MutableMap<String, Any>) {
|
||||||
param: MutableMap<String, Any>,
|
|
||||||
onSuccess: (MutableList<SeasoningEntity>?) -> Unit,
|
|
||||||
onFailure: (String, String) -> Unit
|
|
||||||
) {
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
repository.querySeasoningList(param, onSuccess, onFailure)
|
_seasoningListState.value = UiState.Loading
|
||||||
|
_seasoningListState.value = repository.querySeasoningList(param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,18 +30,18 @@ class RemoteRepository {
|
|||||||
/**
|
/**
|
||||||
* 查询菜品详情
|
* 查询菜品详情
|
||||||
* @param foodId 菜品 ID
|
* @param foodId 菜品 ID
|
||||||
* @param onSuccess 成功回调
|
* @return UiState 包装的结果,Success 携带详情数据,Error 携带错误信息
|
||||||
* @param onFailure 失败回调,参数为 (errorCode, errorMsg)
|
|
||||||
*/
|
*/
|
||||||
suspend fun getFoodDetail(
|
suspend fun getFoodDetail(foodId: String): UiState<CookFoodEntity?> {
|
||||||
foodId: String,
|
return try {
|
||||||
onSuccess: (CookFoodEntity?) -> Unit,
|
val resp = apiService.getFoodDetail(foodId = foodId)
|
||||||
onFailure: (String, String) -> Unit
|
if (resp.isSuccess()) UiState.Success(resp.data)
|
||||||
) = request(
|
else UiState.Error(resp.code, resp.msg ?: "")
|
||||||
onRequest = { apiService.getFoodDetail(foodId = foodId) },
|
} catch (e: Exception) {
|
||||||
onSuccess = onSuccess,
|
val ex = getApiException(e)
|
||||||
onFailure = onFailure
|
UiState.Error("-1", ex.errorMsg)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索菜品列表
|
* 搜索菜品列表
|
||||||
@@ -78,32 +78,34 @@ class RemoteRepository {
|
|||||||
/**
|
/**
|
||||||
* 查询物品信息列表
|
* 查询物品信息列表
|
||||||
* @param param 查询参数
|
* @param param 查询参数
|
||||||
* @param onSuccess 成功回调
|
* @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息
|
||||||
* @param onFailure 失败回调,参数为 (errorCode, errorMsg)
|
|
||||||
*/
|
*/
|
||||||
suspend fun queryGoodsList(
|
suspend fun queryGoodsList(param: MutableMap<String, Any>): UiState<MutableList<CookFoodGoodsEntity>?> {
|
||||||
param: MutableMap<String, Any>,
|
return try {
|
||||||
onSuccess: (MutableList<CookFoodGoodsEntity>?) -> Unit,
|
val resp = apiService.queryGoodsList(param = param)
|
||||||
onFailure: (String, String) -> Unit
|
if (resp.isSuccess()) UiState.Success(resp.data)
|
||||||
) = request(
|
else UiState.Error(resp.code, resp.msg ?: "")
|
||||||
onRequest = { apiService.queryGoodsList(param = param) },
|
} catch (e: Exception) {
|
||||||
onSuccess = onSuccess,
|
val ex = getApiException(e)
|
||||||
onFailure = onFailure
|
UiState.Error("-1", ex.errorMsg)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询调料信息列表
|
* 查询调料信息列表
|
||||||
* @param param 查询参数
|
* @param param 查询参数
|
||||||
* @param onSuccess 成功回调
|
* @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息
|
||||||
* @param onFailure 失败回调,参数为 (errorCode, errorMsg)
|
|
||||||
*/
|
*/
|
||||||
suspend fun querySeasoningList(
|
suspend fun querySeasoningList(param: MutableMap<String, Any>): UiState<MutableList<SeasoningEntity>?> {
|
||||||
param: MutableMap<String, Any>,
|
return try {
|
||||||
onSuccess: (MutableList<SeasoningEntity>?) -> Unit,
|
val resp = apiService.querySeasoningList(param = param)
|
||||||
onFailure: (String, String) -> Unit
|
if (resp.isSuccess()) UiState.Success(resp.data)
|
||||||
) = request(
|
else UiState.Error(resp.code, resp.msg ?: "")
|
||||||
onRequest = { apiService.querySeasoningList(param = param) },
|
} catch (e: Exception) {
|
||||||
onSuccess = onSuccess,
|
val ex = getApiException(e)
|
||||||
onFailure = onFailure
|
UiState.Error("-1", ex.errorMsg)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,12 +142,12 @@ class HomeActivity : BaseActivity() {
|
|||||||
finish()
|
finish()
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
appViewModel.countCookFood(cookMode = 1) { count ->
|
val count = appViewModel.countCookFood(cookMode = 1)
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
// 有烹饪中数据,打开采样历史列表页面
|
// 有烹饪中数据,打开采样历史列表页面
|
||||||
startActivity<SamplingListActivity>()
|
startActivity<SamplingListActivity>()
|
||||||
finish()
|
finish()
|
||||||
return@countCookFood
|
return@launch
|
||||||
}
|
}
|
||||||
// 无烹饪数据,打开新增采样页面
|
// 无烹饪数据,打开新增采样页面
|
||||||
startActivity<PrepareCookActivity> {
|
startActivity<PrepareCookActivity> {
|
||||||
@@ -156,6 +156,5 @@ class HomeActivity : BaseActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -95,11 +95,11 @@ class InitActivity : BaseActivity() {
|
|||||||
startActivity<SamplingListActivity>()
|
startActivity<SamplingListActivity>()
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
appViewModel.countCookFood(cookMode = 1) { count ->
|
val count = appViewModel.countCookFood(cookMode = 1)
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
// 有烹饪中数据,打开采样历史列表页面
|
// 有烹饪中数据,打开采样历史列表页面
|
||||||
startActivity<SamplingListActivity>()
|
startActivity<SamplingListActivity>()
|
||||||
return@countCookFood
|
return@launch
|
||||||
}
|
}
|
||||||
// 无烹饪数据,打开新增采样页面
|
// 无烹饪数据,打开新增采样页面
|
||||||
startActivity<PrepareCookActivity> {
|
startActivity<PrepareCookActivity> {
|
||||||
@@ -107,7 +107,6 @@ class InitActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
WeightUtil.stopContinuousRead()
|
WeightUtil.stopContinuousRead()
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import android.util.Log
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.activity.addCallback
|
import androidx.activity.addCallback
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.shuwei.dish.match.R
|
import com.shuwei.dish.match.R
|
||||||
@@ -20,6 +22,7 @@ import com.shuwei.dish.match.dialog.CommonDialog
|
|||||||
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.FoodRecord
|
import com.shuwei.dish.match.entity.FoodRecord
|
||||||
|
import com.shuwei.dish.match.net.UiState
|
||||||
import com.shuwei.dish.match.objbox.FoodModule
|
import com.shuwei.dish.match.objbox.FoodModule
|
||||||
import com.shuwei.dish.match.utils.AddressUtil
|
import com.shuwei.dish.match.utils.AddressUtil
|
||||||
import com.shuwei.dish.match.utils.CameraUtils
|
import com.shuwei.dish.match.utils.CameraUtils
|
||||||
@@ -36,6 +39,7 @@ import com.shuwei.dish.match.utils.ext.toJsonString
|
|||||||
import com.shuwei.dish.match.utils.ext.toast
|
import com.shuwei.dish.match.utils.ext.toast
|
||||||
import com.shuwei.dish.match.utils.ext.visible
|
import com.shuwei.dish.match.utils.ext.visible
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
@@ -110,6 +114,7 @@ class PrepareCookActivity : BaseActivity() {
|
|||||||
addBackKeyListener()
|
addBackKeyListener()
|
||||||
initCamera(binding.flCameraContainer)
|
initCamera(binding.flCameraContainer)
|
||||||
initRecyclerView()
|
initRecyclerView()
|
||||||
|
initObserver()
|
||||||
|
|
||||||
if (!isSamplingMode) {
|
if (!isSamplingMode) {
|
||||||
getDishDetail()
|
getDishDetail()
|
||||||
@@ -267,6 +272,28 @@ class PrepareCookActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun initObserver() {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
netViewModel.foodDetailState.collect { state ->
|
||||||
|
when (state) {
|
||||||
|
is UiState.Success -> {
|
||||||
|
val detail = state.data
|
||||||
|
if (detail == null) {
|
||||||
|
toast("查询菜品信息为空")
|
||||||
|
return@collect
|
||||||
|
}
|
||||||
|
loadDishDetail(detail)
|
||||||
|
}
|
||||||
|
|
||||||
|
is UiState.Error -> toast(state.msg)
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getDishDetail() {
|
private fun getDishDetail() {
|
||||||
// //649
|
// //649
|
||||||
// val url = "${UrlConfig.DISH_DETAIL}?foodId=${food?.foodId}"
|
// val url = "${UrlConfig.DISH_DETAIL}?foodId=${food?.foodId}"
|
||||||
@@ -285,17 +312,7 @@ class PrepareCookActivity : BaseActivity() {
|
|||||||
// toast(msg)
|
// toast(msg)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
netViewModel.getFoodDetail(
|
netViewModel.getFoodDetail(food?.foodId ?: "")
|
||||||
food?.foodId ?: "",
|
|
||||||
onSuccess = { detail ->
|
|
||||||
if (detail == null) {
|
|
||||||
toast("查询菜品信息为空")
|
|
||||||
return@getFoodDetail
|
|
||||||
}
|
|
||||||
loadDishDetail(detail)
|
|
||||||
}, onFailure = { code, msg ->
|
|
||||||
toast(msg)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user