From debc7a0740adb34c9166092b06162b7e0f63e9ac Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Thu, 23 Apr 2026 10:54:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor(viewmodel):=20=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E8=B0=83=E6=96=99=E6=A7=BD=E4=BD=8D=E8=AF=BB=E5=86=99=E8=87=B3?= =?UTF-8?q?=20AppViewModel=EF=BC=8C=E6=B6=88=E9=99=A4=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E8=B0=83=E7=94=A8=20DAO=20=E7=9A=84=E6=83=85?= =?UTF-8?q?=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dish/match/db/DatabaseRepository.kt | 23 ++++ .../com/shuwei/dish/match/net/NetViewModel.kt | 15 ++- .../shuwei/dish/match/net/RemoteRepository.kt | 22 ++-- .../dish/match/ui/MasterScaleActivity.kt | 22 ++-- .../dish/match/ui/SamplingListActivity.kt | 5 +- .../dish/match/ui/SelectDishActivity.kt | 7 +- .../dish/match/ui/SingleFragmentActivity.kt | 12 ++ .../com/shuwei/dish/match/ui/SlaveActivity.kt | 24 ++-- .../dish/match/ui/SubmitFoodActivity.kt | 113 ++++++++++-------- .../ui/fragment/SeasoningConfigFragment.kt | 43 +++---- .../dish/match/viewmodel/AppViewModel.kt | 89 +++++++------- 11 files changed, 220 insertions(+), 155 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 6f6e5a2..1c881df 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 @@ -6,6 +6,7 @@ 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 +import com.shuwei.dish.match.entity.SeasoningSlotEntity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -122,6 +123,28 @@ class AppRepository(val appDao: AppDao, val seasoningSlotDao: SeasoningSlotDao) suspend fun getAllSeasoningSlots() = withContext(Dispatchers.IO) { seasoningSlotDao.queryAll() } + + /** + * 查询指定设备的调料槽位配置 + * @param deviceId 目标设备 ID + */ + suspend fun getSeasoningSlotsByDeviceId(deviceId: String) = withContext(Dispatchers.IO) { + seasoningSlotDao.queryByDeviceId(deviceId) + } + + /** + * 插入或更新单个调料槽位配置 + */ + suspend fun upsertSeasoningSlot(slot: SeasoningSlotEntity) = withContext(Dispatchers.IO) { + seasoningSlotDao.upsert(slot) + } + + /** + * 批量插入或更新调料槽位配置 + */ + suspend fun upsertAllSeasoningSlots(slots: List) = withContext(Dispatchers.IO) { + seasoningSlotDao.upsertAll(slots) + } } // //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 eb35ba3..19741b0 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 @@ -19,16 +19,19 @@ class NetViewModel( private val repository: RemoteRepository = RemoteRepository() ) : ViewModel() { + /** + * 提交制作菜品的 UI 状态流,UI 层通过 collect 监听 + */ + private val _submitCookFoodState = MutableStateFlow>(UiState.Idle) + val submitCookFoodState: StateFlow> = _submitCookFoodState.asStateFlow() + /** * 提交制作菜品 */ - fun submitCookFood( - entity: CookFoodEntity, - onSuccess: (Any?) -> Unit, - onFailure: (String, String) -> Unit - ) { + fun submitCookFood(entity: CookFoodEntity) { viewModelScope.launch { - repository.submitCookFood(entity, onSuccess, onFailure) + _submitCookFoodState.value = UiState.Loading + _submitCookFoodState.value = repository.submitCookFood(entity) } } 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 9a170c3..eb149b0 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 @@ -14,18 +14,18 @@ class RemoteRepository { /** * 提交制作菜品 * @param entity 菜品实体 - * @param onSuccess 成功回调 - * @param onFailure 失败回调,参数为 (errorCode, errorMsg) + * @return UiState 包装的结果,Success 表示提交成功,Error 携带错误信息 */ - suspend fun submitCookFood( - entity: CookFoodEntity, - onSuccess: (Any?) -> Unit, - onFailure: (String, String) -> Unit - ) = request( - onRequest = { apiService.submitCookFood(param = entity) }, - onSuccess = onSuccess, - onFailure = onFailure - ) + suspend fun submitCookFood(entity: CookFoodEntity): UiState { + return try { + val resp = apiService.submitCookFood(param = entity) + 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/MasterScaleActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/MasterScaleActivity.kt index 3640459..d29c7c6 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/MasterScaleActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/MasterScaleActivity.kt @@ -26,12 +26,14 @@ import com.shuwei.dish.match.databinding.ListTypeScale18Binding import com.shuwei.dish.match.databinding.ListTypeScale2Binding import com.shuwei.dish.match.databinding.ListTypeScale22Binding import com.shuwei.dish.match.base.BaseApp +import com.shuwei.dish.match.db.AppRepository +import androidx.lifecycle.ViewModelProvider +import com.shuwei.dish.match.viewmodel.AppViewModel +import com.shuwei.dish.match.viewmodel.factory.AppFactory import com.shuwei.dish.match.databinding.ListItemScale22RowBinding import com.shuwei.dish.match.scale.ScaleData import com.shuwei.dish.match.scale.ScaleDeviceConfig import com.shuwei.dish.match.scale.ScaleServiceManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import com.shuwei.dish.match.utils.NetworkUtil import com.shuwei.dish.match.utils.SizeTool import com.shuwei.dish.match.utils.WeightUtil @@ -53,6 +55,8 @@ class MasterScaleActivity : BaseActivity() { private lateinit var binding: ActivityMasterScaleBinding private val size by lazy { SizeTool.getFlexLayoutSize(10.dp) } + + private lateinit var appViewModel: AppViewModel private data class DeviceGroup( val deviceId: String, val ip: String, @@ -76,19 +80,19 @@ class MasterScaleActivity : BaseActivity() { binding.rvScaleList.itemAnimator = null binding.rvScaleList.adapter = adapter + val db = BaseApp.instance!!.database + appViewModel = ViewModelProvider(this, AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())))[AppViewModel::class.java] loadSlotNames() } /** 从 Room 加载槽位配置到 slotNameMap,加载完成后启动数据观测 */ private fun loadSlotNames() { - lifecycleScope.launch(Dispatchers.IO) { - val slots = BaseApp.instance!!.database.seasoningSlotDao().queryAll() - withContext(Dispatchers.Main) { - slots.forEach { slot -> - slotNameMap["${slot.deviceId}#${slot.address}"] = slot.goodsName - } - observeScaleData() + lifecycleScope.launch { + val slots = appViewModel.loadSeasoningSlot() + slots.forEach { slot -> + slotNameMap["${slot.deviceId}#${slot.address}"] = slot.goodsName } + observeScaleData() } } 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 c3d5dcb..8777c61 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 @@ -141,7 +141,10 @@ class SamplingListActivity : BaseActivity() { } fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) { - appViewModel.deleteCookFoodAndGoods(cookMode = 1, foodId = foodId, onFinish = action) + lifecycleScope.launch { + appViewModel.deleteCookFoodAndGoods(cookMode = 1, foodId = foodId) + action() + } } override fun onNewIntent(intent: Intent) { 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 ce8ea8a..db7840e 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 @@ -4,6 +4,8 @@ import android.content.Intent import android.os.Bundle import androidx.activity.addCallback import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch import com.shuwei.dish.match.R import com.shuwei.dish.match.base.BaseActivity import com.shuwei.dish.match.base.BaseApp @@ -152,7 +154,10 @@ class SelectDishActivity : BaseActivity() { } fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) { - appViewModel.deleteCookFoodAndGoods(cookMode = 0, foodId = foodId, onFinish = action) + lifecycleScope.launch { + appViewModel.deleteCookFoodAndGoods(cookMode = 0, foodId = foodId) + action() + } } override fun onNewIntent(intent: Intent) { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt index cc6190d..0516307 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt @@ -4,12 +4,17 @@ import android.content.Context import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.shuwei.dish.match.base.BaseActivity +import com.shuwei.dish.match.base.BaseApp +import com.shuwei.dish.match.db.AppRepository import com.shuwei.dish.match.ui.fragment.CollectFragment import com.shuwei.dish.match.ui.fragment.DeviceConfigFragment import com.shuwei.dish.match.ui.fragment.SeasoningConfigFragment import com.shuwei.dish.match.utils.ext.gone import com.shuwei.dish.match.utils.ext.visible +import com.shuwei.dish.match.viewmodel.AppViewModel +import com.shuwei.dish.match.viewmodel.factory.AppFactory /** * 通用单 Fragment 容器 Activity @@ -58,8 +63,15 @@ class SingleFragmentActivity : BaseActivity() { lifecycleCallback = callback } + lateinit var appViewModel: AppViewModel + private set + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + val db = BaseApp.instance!!.database + appViewModel = ViewModelProvider(this, AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())))[AppViewModel::class.java] + setHeaderBackground() // 解析页面类型,非法值直接关闭 diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt index 83f2a8c..149dfa8 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SlaveActivity.kt @@ -30,9 +30,11 @@ import com.shuwei.dish.match.utils.NetworkUtil import com.shuwei.dish.match.utils.SizeTool import com.shuwei.dish.match.utils.WeightUtil import com.shuwei.dish.match.utils.ext.dp -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import androidx.lifecycle.ViewModelProvider +import com.shuwei.dish.match.db.AppRepository +import com.shuwei.dish.match.viewmodel.AppViewModel +import com.shuwei.dish.match.viewmodel.factory.AppFactory /** * 子设备专属页面(小屏幕设备使用) @@ -64,12 +66,17 @@ class SlaveActivity : BaseActivity() { private var clearHighlightRunnable: Runnable? = null private val size by lazy { SizeTool.getFlexLayoutSize(10.dp) } + private lateinit var appViewModel: AppViewModel + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivitySlaveBinding.inflate(layoutInflater) setContentView(binding.root) setHeaderBackground() + val db = BaseApp.instance!!.database + appViewModel = ViewModelProvider(this, AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())))[AppViewModel::class.java] + binding.tvDeviceId.text = "设备:${GlobalData.deviceId}" binding.tvDeviceIp.text = "IP:${getLocalIpAddress()}" @@ -152,10 +159,9 @@ class SlaveActivity : BaseActivity() { * 主设备未开机时也能正常展示上次配置 */ private fun loadSlotsFromDb() { - lifecycleScope.launch(Dispatchers.IO) { - val dao = BaseApp.instance!!.database.seasoningSlotDao() - val slots = dao.queryByDeviceId(GlobalData.deviceId) - withContext(Dispatchers.Main) { applySlots(slots) } + lifecycleScope.launch { + val slots = appViewModel.getSeasoningSlotsByDeviceId(GlobalData.deviceId) + applySlots(slots) } } @@ -169,9 +175,9 @@ class SlaveActivity : BaseActivity() { ?.filter { it.deviceId == GlobalData.deviceId } ?.map { SeasoningSlotEntity(it.deviceId, it.address, it.goodsId, it.goodsName) } ?: return@onSeasoningConfig - lifecycleScope.launch(Dispatchers.IO) { - BaseApp.instance!!.database.seasoningSlotDao().upsertAll(mySlots) - withContext(Dispatchers.Main) { applySlots(mySlots) } + lifecycleScope.launch { + appViewModel.upsertAllSeasoningSlots(mySlots) + applySlots(mySlots) } } } 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 bb8886b..341840e 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 @@ -5,7 +5,9 @@ import android.os.Bundle import android.util.Log import androidx.activity.addCallback import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.GridLayoutManager import com.google.gson.reflect.TypeToken import com.shuwei.dish.match.R @@ -19,6 +21,7 @@ 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.net.NetViewModel +import com.shuwei.dish.match.net.UiState import com.shuwei.dish.match.scale.ScaleDeviceConfig import com.shuwei.dish.match.scale.ScaleServiceManager import com.shuwei.dish.match.utils.AddressUtil @@ -121,12 +124,33 @@ class SubmitFoodActivity : BaseActivity() { }) setupRecyclerView() addViewListener() + initObserver() loadSlotsThenObserveScales() onBackPressedDispatcher.addCallback(this) { remindSaveDataDialog() } } + /** + * 收集 submitCookFoodState,处理提交成功/失败 + */ + private fun initObserver() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + netViewModel.submitCookFoodState.collect { state -> + when (state) { + is UiState.Success -> submitSuccess(food?.cookMode == 1) + is UiState.Error -> { + toast(state.msg) + dismissLoading() + } + else -> {} + } + } + } + } + } + /** 初始化 RecyclerView,2列 GridLayoutManager */ private fun setupRecyclerView() { binding.rvSeasoning.itemAnimator = null @@ -139,35 +163,32 @@ class SubmitFoodActivity : BaseActivity() { * isCooking=true 时先从数据库查询 goodsList,筛选调料预填充 adapter,再开始观测 */ private fun loadSlotsThenObserveScales() { - lifecycleScope.launch(Dispatchers.IO) { - val slots = BaseApp.instance!!.database.seasoningSlotDao().queryAll() - withContext(Dispatchers.Main) { - slots.forEach { slot -> - slotMap["${slot.deviceId}#${slot.address}"] = slot.goodsId to slot.goodsName - } - if (food?.isCooking == true) { - // 制作中:从数据库查询 goodsList,筛选调料数据预填充 adapter - val foodId = food?.foodId ?: return@withContext - val cookMode = food?.cookMode ?: return@withContext - appViewModel.getCookFoodGoodsList(foodId, cookMode) { list -> - goodsList = list - list.filter { it.materialType == 3 }.forEach { item -> - val name = item.goodsName ?: "" - val weight = item.useWeight ?: 0.0 - baseSeasoningMap[name] = (item.goodsId) to weight - seasoningAdapter.updateItem( - SeasoningWeightAdapter.Item( - goodsId = item.goodsId, - goodsName = name, - useWeight = weight - ) - ) - } - observeScaleData() - } - } else { - observeScaleData() + lifecycleScope.launch { + val slots = appViewModel.loadSeasoningSlot() + slots.forEach { slot -> + slotMap["${slot.deviceId}#${slot.address}"] = slot.goodsId to slot.goodsName + } + if (food?.isCooking == true) { + // 制作中:从数据库查询 goodsList,筛选调料数据预填充 adapter + val foodId = food?.foodId ?: return@launch + val cookMode = food?.cookMode ?: return@launch + val list = appViewModel.getCookFoodGoodsList(foodId, cookMode) + goodsList = list + list.filter { it.materialType == 3 }.forEach { item -> + val name = item.goodsName ?: "" + val weight = item.useWeight ?: 0.0 + baseSeasoningMap[name] = (item.goodsId) to weight + seasoningAdapter.updateItem( + SeasoningWeightAdapter.Item( + goodsId = item.goodsId, + goodsName = name, + useWeight = weight + ) + ) } + observeScaleData() + } else { + observeScaleData() } } } @@ -305,16 +326,15 @@ class SubmitFoodActivity : BaseActivity() { } goodsList?.forEach { it.foodId = cookFoodEntity.foodId } - appViewModel.saveCookFoodAndGoods( - cookMode = food!!.cookMode, - entity = cookFoodEntity, - list = goodsList, - onFinish = { - runOnUiThread { - dismissLoading() - jumpPage(isSamplingData, true) - } - }) + lifecycleScope.launch { + appViewModel.saveCookFoodAndGoods( + cookMode = food!!.cookMode, + entity = cookFoodEntity, + list = goodsList + ) + dismissLoading() + jumpPage(isSamplingData, true) + } } private fun submit() { @@ -354,13 +374,7 @@ class SubmitFoodActivity : BaseActivity() { } Log.d(TAG, "submit: json=${cookFoodEntity.toJsonString()}") - netViewModel.submitCookFood( - entity = cookFoodEntity, - onSuccess = { submitSuccess(isSamplingData) }, - onFailure = { _, msg -> - toast(msg) - dismissLoading() - }) + netViewModel.submitCookFood(entity = cookFoodEntity) } private fun submitSuccess(isSamplingData: Boolean) { @@ -369,10 +383,11 @@ class SubmitFoodActivity : BaseActivity() { jumpPage(isSamplingData, false) return } - appViewModel.deleteCookFoodAndGoods( - cookMode = food!!.cookMode, - foodId = food!!.foodId!! - ) { + lifecycleScope.launch { + appViewModel.deleteCookFoodAndGoods( + cookMode = food!!.cookMode, + foodId = food!!.foodId!! + ) dismissLoading() jumpPage(isSamplingData, false) } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/fragment/SeasoningConfigFragment.kt b/app/src/main/java/com/shuwei/dish/match/ui/fragment/SeasoningConfigFragment.kt index 434dc4e..395e0f4 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/fragment/SeasoningConfigFragment.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/fragment/SeasoningConfigFragment.kt @@ -13,7 +13,6 @@ import com.google.android.flexbox.FlexWrap import com.google.android.flexbox.FlexboxLayoutManager import com.shuwei.dish.match.adapter.Seasoning18GridAdapter import com.shuwei.dish.match.adapter.Seasoning22GridAdapter -import com.shuwei.dish.match.base.BaseApp import com.shuwei.dish.match.base.BaseFragment import com.shuwei.dish.match.base.DeviceRole import com.shuwei.dish.match.base.GlobalData @@ -29,9 +28,7 @@ import com.shuwei.dish.match.ui.SingleFragmentActivity import com.shuwei.dish.match.utils.SizeTool import com.shuwei.dish.match.utils.WeightUtil import com.shuwei.dish.match.utils.ext.dp -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class SeasoningConfigFragment : BaseFragment() { @@ -149,11 +146,10 @@ class SeasoningConfigFragment : BaseFragment() { * 仅主设备执行广播,子设备不调用此方法 */ private fun saveSlotAndBroadcast(slot: SeasoningSlotEntity) { - lifecycleScope.launch(Dispatchers.IO) { - val dao = BaseApp.instance!!.database.seasoningSlotDao() - dao.upsert(slot) + lifecycleScope.launch { + currentActivity.appViewModel.upsertSeasoningSlot(slot) // 读取全量配置,通过 wsClient 推送给所有已连接子设备 - val allSlots = dao.queryAll().map { + val allSlots = currentActivity.appViewModel.loadSeasoningSlot().map { SlotConfig(it.deviceId, it.address, it.goodsId, it.goodsName) } ScaleServiceManager.sendSeasoningConfig(allSlots) @@ -205,25 +201,22 @@ class SeasoningConfigFragment : BaseFragment() { private fun loadData() { adapter22.update(emptyList()) adapter18.update(emptyList()) - lifecycleScope.launch(Dispatchers.IO) { - val dao = BaseApp.instance!!.database.seasoningSlotDao() - val slots22 = dao.queryByDeviceId(ScaleDeviceConfig.DEVICE_ID_22) - val slots18 = dao.queryByDeviceId(ScaleDeviceConfig.DEVICE_ID_18) - val slotsOil = dao.queryByDeviceId(ScaleDeviceConfig.DEVICE_ID_1) - withContext(Dispatchers.Main) { - slots22.forEach { slot -> - val pos = ScaleDeviceConfig.SCALE_ORDER_22.indexOf(slot.address) - if (pos >= 0) adapter22.updateItemName(pos, slot.goodsName) - } - slots18.forEach { slot -> - val pos = ScaleDeviceConfig.SCALE_ORDER_18.indexOf(slot.address) - if (pos >= 0) adapter18.updateItemName(pos, slot.goodsName) - } - // 加载油盆格子名称(address=1) - val oilSlot = slotsOil.firstOrNull { it.address == 1 } - binding.tvOilSlot.text = - if (oilSlot != null && oilSlot.goodsName.isNotEmpty()) oilSlot.goodsName else "-" + lifecycleScope.launch { + val slots22 = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_22) + val slots18 = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_18) + val slotsOil = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_1) + slots22.forEach { slot -> + val pos = ScaleDeviceConfig.SCALE_ORDER_22.indexOf(slot.address) + if (pos >= 0) adapter22.updateItemName(pos, slot.goodsName) } + slots18.forEach { slot -> + val pos = ScaleDeviceConfig.SCALE_ORDER_18.indexOf(slot.address) + if (pos >= 0) adapter18.updateItemName(pos, slot.goodsName) + } + // 加载油盆格子名称(address=1) + val oilSlot = slotsOil.firstOrNull { it.address == 1 } + binding.tvOilSlot.text = + if (oilSlot != null && oilSlot.goodsName.isNotEmpty()) oilSlot.goodsName else "-" } } 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 8220e70..2c880b4 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 @@ -60,63 +60,46 @@ class AppViewModel(private val rep: AppRepository) : ViewModel() { // } // } - fun saveCookFoodAndGoods( + suspend fun saveCookFoodAndGoods( cookMode: Int, entity: CookFoodEntity, - list: MutableList?, - onFinish: () -> Unit + list: MutableList? ) { - viewModelScope.launch { - val data = rep.getCookFoodById(entity.foodId, cookMode) - if (data != null) { - //存在数据删除 - rep.deleteCookFood(entity.foodId, cookMode) - rep.deleteCookFoodGoodsList(data.id, entity.foodId) + val data = rep.getCookFoodById(entity.foodId, cookMode) + if (data != null) { + // 存在数据先删除 + rep.deleteCookFood(entity.foodId, cookMode) + rep.deleteCookFoodGoodsList(data.id, entity.foodId) + } + // 重新保存数据 + rep.insertCookFood(entity) + val newData = rep.getCookFoodById(entity.foodId, cookMode) + list?.let { it -> + it.forEach { goods -> + goods.id = 0 + goods.pid = newData?.id ?: 0 } - //重新保存数据 - rep.insertCookFood(entity) - val newData = rep.getCookFoodById(entity.foodId, cookMode) - list?.let { it -> - it.forEach { goods -> - goods.id = 0 - goods.pid = newData?.id?:0 - } - rep.insertGoodsList(it) - } - onFinish() + rep.insertGoodsList(it) } } - fun deleteCookFoodAndGoods( - cookMode: Int, - foodId: String, - onFinish: () -> Unit - ) { - viewModelScope.launch { - val data = rep.getCookFoodById(foodId, cookMode) - if (data != null) { - rep.deleteCookFood(foodId = foodId, cookMode = cookMode) - rep.deleteCookFoodGoodsList(pid = data.id, foodId = foodId) - } - onFinish() + suspend fun deleteCookFoodAndGoods(cookMode: Int, foodId: String) { + val data = rep.getCookFoodById(foodId, cookMode) + if (data != null) { + rep.deleteCookFood(foodId = foodId, cookMode = cookMode) + rep.deleteCookFoodGoodsList(pid = data.id, foodId = foodId) } } //-------------------------------------------------------------------------------------------------------- - - fun getCookFoodGoodsList( + suspend fun getCookFoodGoodsList( foodId: String, - cookMode: Int, - action: (list: MutableList) -> Unit - ) { - viewModelScope.launch { - val cookFood = rep.getCookFoodById(foodId, cookMode) - cookFood?.let { - val list = rep.getCookFoodGoodsList(pid = it.id, foodId = it.foodId) - action(list) - } - } + cookMode: Int + ): MutableList { + val cookFood = rep.getCookFoodById(foodId, cookMode) + return if (cookFood != null) rep.getCookFoodGoodsList(pid = cookFood.id, foodId = cookFood.foodId) + else mutableListOf() } // fun updateGoods(entity: CookFoodGoodsEntity) { @@ -206,6 +189,24 @@ class AppViewModel(private val rep: AppRepository) : ViewModel() { } } + /** + * 查询指定设备的调料槽位配置 + */ + suspend fun getSeasoningSlotsByDeviceId(deviceId: String) = + rep.getSeasoningSlotsByDeviceId(deviceId) + + /** + * 插入或更新单个调料槽位配置 + */ + suspend fun upsertSeasoningSlot(slot: SeasoningSlotEntity) = + rep.upsertSeasoningSlot(slot) + + /** + * 批量插入或更新调料槽位配置 + */ + suspend fun upsertAllSeasoningSlots(slots: List) = + rep.upsertAllSeasoningSlots(slots) + // fun updateAll(list: MutableList) { // viewModelScope.launch { // list.forEach {