refactor(viewmodel): 封装调料槽位读写至 AppViewModel,消除页面直接调用 DAO 的情况

This commit is contained in:
2026-04-23 10:54:59 +08:00
parent 441cffe4da
commit debc7a0740
11 changed files with 220 additions and 155 deletions
@@ -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.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
import com.shuwei.dish.match.entity.SeasoningSlotEntity
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -122,6 +123,28 @@ class AppRepository(val appDao: AppDao, val seasoningSlotDao: SeasoningSlotDao)
suspend fun getAllSeasoningSlots() = withContext(Dispatchers.IO) { suspend fun getAllSeasoningSlots() = withContext(Dispatchers.IO) {
seasoningSlotDao.queryAll() 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<SeasoningSlotEntity>) = withContext(Dispatchers.IO) {
seasoningSlotDao.upsertAll(slots)
}
} }
// //
//class SeasoningRepository(val seasoningDao: SeasoningDao) { //class SeasoningRepository(val seasoningDao: SeasoningDao) {
@@ -19,16 +19,19 @@ class NetViewModel(
private val repository: RemoteRepository = RemoteRepository() private val repository: RemoteRepository = RemoteRepository()
) : ViewModel() { ) : ViewModel() {
/**
* 提交制作菜品的 UI 状态流,UI 层通过 collect 监听
*/
private val _submitCookFoodState = MutableStateFlow<UiState<Any?>>(UiState.Idle)
val submitCookFoodState: StateFlow<UiState<Any?>> = _submitCookFoodState.asStateFlow()
/** /**
* 提交制作菜品 * 提交制作菜品
*/ */
fun submitCookFood( fun submitCookFood(entity: CookFoodEntity) {
entity: CookFoodEntity,
onSuccess: (Any?) -> Unit,
onFailure: (String, String) -> Unit
) {
viewModelScope.launch { viewModelScope.launch {
repository.submitCookFood(entity, onSuccess, onFailure) _submitCookFoodState.value = UiState.Loading
_submitCookFoodState.value = repository.submitCookFood(entity)
} }
} }
@@ -14,18 +14,18 @@ class RemoteRepository {
/** /**
* 提交制作菜品 * 提交制作菜品
* @param entity 菜品实体 * @param entity 菜品实体
* @param onSuccess 成功回调 * @return UiState 包装的结果,Success 表示提交成功,Error 携带错误信息
* @param onFailure 失败回调,参数为 (errorCode, errorMsg)
*/ */
suspend fun submitCookFood( suspend fun submitCookFood(entity: CookFoodEntity): UiState<Any?> {
entity: CookFoodEntity, return try {
onSuccess: (Any?) -> Unit, val resp = apiService.submitCookFood(param = entity)
onFailure: (String, String) -> Unit if (resp.isSuccess()) UiState.Success(resp.data)
) = request( else UiState.Error(resp.code, resp.msg ?: "")
onRequest = { apiService.submitCookFood(param = entity) }, } catch (e: Exception) {
onSuccess = onSuccess, val ex = getApiException(e)
onFailure = onFailure UiState.Error("-1", ex.errorMsg)
) }
}
/** /**
* 查询菜品详情 * 查询菜品详情
@@ -26,12 +26,14 @@ import com.shuwei.dish.match.databinding.ListTypeScale18Binding
import com.shuwei.dish.match.databinding.ListTypeScale2Binding import com.shuwei.dish.match.databinding.ListTypeScale2Binding
import com.shuwei.dish.match.databinding.ListTypeScale22Binding import com.shuwei.dish.match.databinding.ListTypeScale22Binding
import com.shuwei.dish.match.base.BaseApp 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.databinding.ListItemScale22RowBinding
import com.shuwei.dish.match.scale.ScaleData import com.shuwei.dish.match.scale.ScaleData
import com.shuwei.dish.match.scale.ScaleDeviceConfig import com.shuwei.dish.match.scale.ScaleDeviceConfig
import com.shuwei.dish.match.scale.ScaleServiceManager 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.NetworkUtil
import com.shuwei.dish.match.utils.SizeTool import com.shuwei.dish.match.utils.SizeTool
import com.shuwei.dish.match.utils.WeightUtil import com.shuwei.dish.match.utils.WeightUtil
@@ -53,6 +55,8 @@ class MasterScaleActivity : BaseActivity() {
private lateinit var binding: ActivityMasterScaleBinding private lateinit var binding: ActivityMasterScaleBinding
private val size by lazy { SizeTool.getFlexLayoutSize(10.dp) } private val size by lazy { SizeTool.getFlexLayoutSize(10.dp) }
private lateinit var appViewModel: AppViewModel
private data class DeviceGroup( private data class DeviceGroup(
val deviceId: String, val deviceId: String,
val ip: String, val ip: String,
@@ -76,19 +80,19 @@ class MasterScaleActivity : BaseActivity() {
binding.rvScaleList.itemAnimator = null binding.rvScaleList.itemAnimator = null
binding.rvScaleList.adapter = adapter binding.rvScaleList.adapter = adapter
val db = BaseApp.instance!!.database
appViewModel = ViewModelProvider(this, AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())))[AppViewModel::class.java]
loadSlotNames() loadSlotNames()
} }
/** 从 Room 加载槽位配置到 slotNameMap,加载完成后启动数据观测 */ /** 从 Room 加载槽位配置到 slotNameMap,加载完成后启动数据观测 */
private fun loadSlotNames() { private fun loadSlotNames() {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch {
val slots = BaseApp.instance!!.database.seasoningSlotDao().queryAll() val slots = appViewModel.loadSeasoningSlot()
withContext(Dispatchers.Main) { slots.forEach { slot ->
slots.forEach { slot -> slotNameMap["${slot.deviceId}#${slot.address}"] = slot.goodsName
slotNameMap["${slot.deviceId}#${slot.address}"] = slot.goodsName
}
observeScaleData()
} }
observeScaleData()
} }
} }
@@ -141,7 +141,10 @@ class SamplingListActivity : BaseActivity() {
} }
fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) { 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) { override fun onNewIntent(intent: Intent) {
@@ -4,6 +4,8 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import com.shuwei.dish.match.R import com.shuwei.dish.match.R
import com.shuwei.dish.match.base.BaseActivity import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp import com.shuwei.dish.match.base.BaseApp
@@ -152,7 +154,10 @@ class SelectDishActivity : BaseActivity() {
} }
fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) { 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) { override fun onNewIntent(intent: Intent) {
@@ -4,12 +4,17 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.base.BaseActivity 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.CollectFragment
import com.shuwei.dish.match.ui.fragment.DeviceConfigFragment import com.shuwei.dish.match.ui.fragment.DeviceConfigFragment
import com.shuwei.dish.match.ui.fragment.SeasoningConfigFragment import com.shuwei.dish.match.ui.fragment.SeasoningConfigFragment
import com.shuwei.dish.match.utils.ext.gone import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.visible 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 * 通用单 Fragment 容器 Activity
@@ -58,8 +63,15 @@ class SingleFragmentActivity : BaseActivity() {
lifecycleCallback = callback lifecycleCallback = callback
} }
lateinit var appViewModel: AppViewModel
private set
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val db = BaseApp.instance!!.database
appViewModel = ViewModelProvider(this, AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())))[AppViewModel::class.java]
setHeaderBackground() setHeaderBackground()
// 解析页面类型,非法值直接关闭 // 解析页面类型,非法值直接关闭
@@ -30,9 +30,11 @@ import com.shuwei.dish.match.utils.NetworkUtil
import com.shuwei.dish.match.utils.SizeTool import com.shuwei.dish.match.utils.SizeTool
import com.shuwei.dish.match.utils.WeightUtil import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.dp import com.shuwei.dish.match.utils.ext.dp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch 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 var clearHighlightRunnable: Runnable? = null
private val size by lazy { SizeTool.getFlexLayoutSize(10.dp) } private val size by lazy { SizeTool.getFlexLayoutSize(10.dp) }
private lateinit var appViewModel: AppViewModel
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivitySlaveBinding.inflate(layoutInflater) binding = ActivitySlaveBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
setHeaderBackground() setHeaderBackground()
val db = BaseApp.instance!!.database
appViewModel = ViewModelProvider(this, AppFactory(AppRepository(db.appDao(), db.seasoningSlotDao())))[AppViewModel::class.java]
binding.tvDeviceId.text = "设备:${GlobalData.deviceId}" binding.tvDeviceId.text = "设备:${GlobalData.deviceId}"
binding.tvDeviceIp.text = "IP${getLocalIpAddress()}" binding.tvDeviceIp.text = "IP${getLocalIpAddress()}"
@@ -152,10 +159,9 @@ class SlaveActivity : BaseActivity() {
* 主设备未开机时也能正常展示上次配置 * 主设备未开机时也能正常展示上次配置
*/ */
private fun loadSlotsFromDb() { private fun loadSlotsFromDb() {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch {
val dao = BaseApp.instance!!.database.seasoningSlotDao() val slots = appViewModel.getSeasoningSlotsByDeviceId(GlobalData.deviceId)
val slots = dao.queryByDeviceId(GlobalData.deviceId) applySlots(slots)
withContext(Dispatchers.Main) { applySlots(slots) }
} }
} }
@@ -169,9 +175,9 @@ class SlaveActivity : BaseActivity() {
?.filter { it.deviceId == GlobalData.deviceId } ?.filter { it.deviceId == GlobalData.deviceId }
?.map { SeasoningSlotEntity(it.deviceId, it.address, it.goodsId, it.goodsName) } ?.map { SeasoningSlotEntity(it.deviceId, it.address, it.goodsId, it.goodsName) }
?: return@onSeasoningConfig ?: return@onSeasoningConfig
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch {
BaseApp.instance!!.database.seasoningSlotDao().upsertAll(mySlots) appViewModel.upsertAllSeasoningSlots(mySlots)
withContext(Dispatchers.Main) { applySlots(mySlots) } applySlots(mySlots)
} }
} }
} }
@@ -5,7 +5,9 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.shuwei.dish.match.R 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.CookFoodGoodsEntity
import com.shuwei.dish.match.entity.FoodRecord import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.net.NetViewModel 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.ScaleDeviceConfig
import com.shuwei.dish.match.scale.ScaleServiceManager import com.shuwei.dish.match.scale.ScaleServiceManager
import com.shuwei.dish.match.utils.AddressUtil import com.shuwei.dish.match.utils.AddressUtil
@@ -121,12 +124,33 @@ class SubmitFoodActivity : BaseActivity() {
}) })
setupRecyclerView() setupRecyclerView()
addViewListener() addViewListener()
initObserver()
loadSlotsThenObserveScales() loadSlotsThenObserveScales()
onBackPressedDispatcher.addCallback(this) { onBackPressedDispatcher.addCallback(this) {
remindSaveDataDialog() 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 -> {}
}
}
}
}
}
/** 初始化 RecyclerView2列 GridLayoutManager */ /** 初始化 RecyclerView2列 GridLayoutManager */
private fun setupRecyclerView() { private fun setupRecyclerView() {
binding.rvSeasoning.itemAnimator = null binding.rvSeasoning.itemAnimator = null
@@ -139,35 +163,32 @@ class SubmitFoodActivity : BaseActivity() {
* isCooking=true 时先从数据库查询 goodsList,筛选调料预填充 adapter,再开始观测 * isCooking=true 时先从数据库查询 goodsList,筛选调料预填充 adapter,再开始观测
*/ */
private fun loadSlotsThenObserveScales() { private fun loadSlotsThenObserveScales() {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch {
val slots = BaseApp.instance!!.database.seasoningSlotDao().queryAll() val slots = appViewModel.loadSeasoningSlot()
withContext(Dispatchers.Main) { slots.forEach { slot ->
slots.forEach { slot -> slotMap["${slot.deviceId}#${slot.address}"] = slot.goodsId to slot.goodsName
slotMap["${slot.deviceId}#${slot.address}"] = slot.goodsId to slot.goodsName }
} if (food?.isCooking == true) {
if (food?.isCooking == true) { // 制作中:从数据库查询 goodsList,筛选调料数据预填充 adapter
// 制作中:从数据库查询 goodsList,筛选调料数据预填充 adapter val foodId = food?.foodId ?: return@launch
val foodId = food?.foodId ?: return@withContext val cookMode = food?.cookMode ?: return@launch
val cookMode = food?.cookMode ?: return@withContext val list = appViewModel.getCookFoodGoodsList(foodId, cookMode)
appViewModel.getCookFoodGoodsList(foodId, cookMode) { list -> goodsList = list
goodsList = list list.filter { it.materialType == 3 }.forEach { item ->
list.filter { it.materialType == 3 }.forEach { item -> val name = item.goodsName ?: ""
val name = item.goodsName ?: "" val weight = item.useWeight ?: 0.0
val weight = item.useWeight ?: 0.0 baseSeasoningMap[name] = (item.goodsId) to weight
baseSeasoningMap[name] = (item.goodsId) to weight seasoningAdapter.updateItem(
seasoningAdapter.updateItem( SeasoningWeightAdapter.Item(
SeasoningWeightAdapter.Item( goodsId = item.goodsId,
goodsId = item.goodsId, goodsName = name,
goodsName = name, useWeight = weight
useWeight = weight )
) )
)
}
observeScaleData()
}
} else {
observeScaleData()
} }
observeScaleData()
} else {
observeScaleData()
} }
} }
} }
@@ -305,16 +326,15 @@ class SubmitFoodActivity : BaseActivity() {
} }
goodsList?.forEach { it.foodId = cookFoodEntity.foodId } goodsList?.forEach { it.foodId = cookFoodEntity.foodId }
appViewModel.saveCookFoodAndGoods( lifecycleScope.launch {
cookMode = food!!.cookMode, appViewModel.saveCookFoodAndGoods(
entity = cookFoodEntity, cookMode = food!!.cookMode,
list = goodsList, entity = cookFoodEntity,
onFinish = { list = goodsList
runOnUiThread { )
dismissLoading() dismissLoading()
jumpPage(isSamplingData, true) jumpPage(isSamplingData, true)
} }
})
} }
private fun submit() { private fun submit() {
@@ -354,13 +374,7 @@ class SubmitFoodActivity : BaseActivity() {
} }
Log.d(TAG, "submit: json=${cookFoodEntity.toJsonString()}") Log.d(TAG, "submit: json=${cookFoodEntity.toJsonString()}")
netViewModel.submitCookFood( netViewModel.submitCookFood(entity = cookFoodEntity)
entity = cookFoodEntity,
onSuccess = { submitSuccess(isSamplingData) },
onFailure = { _, msg ->
toast(msg)
dismissLoading()
})
} }
private fun submitSuccess(isSamplingData: Boolean) { private fun submitSuccess(isSamplingData: Boolean) {
@@ -369,10 +383,11 @@ class SubmitFoodActivity : BaseActivity() {
jumpPage(isSamplingData, false) jumpPage(isSamplingData, false)
return return
} }
appViewModel.deleteCookFoodAndGoods( lifecycleScope.launch {
cookMode = food!!.cookMode, appViewModel.deleteCookFoodAndGoods(
foodId = food!!.foodId!! cookMode = food!!.cookMode,
) { foodId = food!!.foodId!!
)
dismissLoading() dismissLoading()
jumpPage(isSamplingData, false) jumpPage(isSamplingData, false)
} }
@@ -13,7 +13,6 @@ import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager import com.google.android.flexbox.FlexboxLayoutManager
import com.shuwei.dish.match.adapter.Seasoning18GridAdapter import com.shuwei.dish.match.adapter.Seasoning18GridAdapter
import com.shuwei.dish.match.adapter.Seasoning22GridAdapter 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.BaseFragment
import com.shuwei.dish.match.base.DeviceRole import com.shuwei.dish.match.base.DeviceRole
import com.shuwei.dish.match.base.GlobalData 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.SizeTool
import com.shuwei.dish.match.utils.WeightUtil import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.dp import com.shuwei.dish.match.utils.ext.dp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() { class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
@@ -149,11 +146,10 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
* 仅主设备执行广播,子设备不调用此方法 * 仅主设备执行广播,子设备不调用此方法
*/ */
private fun saveSlotAndBroadcast(slot: SeasoningSlotEntity) { private fun saveSlotAndBroadcast(slot: SeasoningSlotEntity) {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch {
val dao = BaseApp.instance!!.database.seasoningSlotDao() currentActivity.appViewModel.upsertSeasoningSlot(slot)
dao.upsert(slot)
// 读取全量配置,通过 wsClient 推送给所有已连接子设备 // 读取全量配置,通过 wsClient 推送给所有已连接子设备
val allSlots = dao.queryAll().map { val allSlots = currentActivity.appViewModel.loadSeasoningSlot().map {
SlotConfig(it.deviceId, it.address, it.goodsId, it.goodsName) SlotConfig(it.deviceId, it.address, it.goodsId, it.goodsName)
} }
ScaleServiceManager.sendSeasoningConfig(allSlots) ScaleServiceManager.sendSeasoningConfig(allSlots)
@@ -205,25 +201,22 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
private fun loadData() { private fun loadData() {
adapter22.update(emptyList()) adapter22.update(emptyList())
adapter18.update(emptyList()) adapter18.update(emptyList())
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch {
val dao = BaseApp.instance!!.database.seasoningSlotDao() val slots22 = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_22)
val slots22 = dao.queryByDeviceId(ScaleDeviceConfig.DEVICE_ID_22) val slots18 = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_18)
val slots18 = dao.queryByDeviceId(ScaleDeviceConfig.DEVICE_ID_18) val slotsOil = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_1)
val slotsOil = dao.queryByDeviceId(ScaleDeviceConfig.DEVICE_ID_1) slots22.forEach { slot ->
withContext(Dispatchers.Main) { val pos = ScaleDeviceConfig.SCALE_ORDER_22.indexOf(slot.address)
slots22.forEach { slot -> if (pos >= 0) adapter22.updateItemName(pos, slot.goodsName)
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 "-"
} }
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 "-"
} }
} }
@@ -60,63 +60,46 @@ class AppViewModel(private val rep: AppRepository) : ViewModel() {
// } // }
// } // }
fun saveCookFoodAndGoods( suspend fun saveCookFoodAndGoods(
cookMode: Int, cookMode: Int,
entity: CookFoodEntity, entity: CookFoodEntity,
list: MutableList<CookFoodGoodsEntity>?, list: MutableList<CookFoodGoodsEntity>?
onFinish: () -> Unit
) { ) {
viewModelScope.launch { val data = rep.getCookFoodById(entity.foodId, cookMode)
val data = rep.getCookFoodById(entity.foodId, cookMode) if (data != null) {
if (data != null) { // 存在数据先删除
//存在数据删除 rep.deleteCookFood(entity.foodId, cookMode)
rep.deleteCookFood(entity.foodId, cookMode) rep.deleteCookFoodGoodsList(data.id, entity.foodId)
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.insertGoodsList(it)
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()
} }
} }
fun deleteCookFoodAndGoods( suspend fun deleteCookFoodAndGoods(cookMode: Int, foodId: String) {
cookMode: Int, val data = rep.getCookFoodById(foodId, cookMode)
foodId: String, if (data != null) {
onFinish: () -> Unit rep.deleteCookFood(foodId = foodId, cookMode = cookMode)
) { rep.deleteCookFoodGoodsList(pid = data.id, foodId = foodId)
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 getCookFoodGoodsList(
fun getCookFoodGoodsList(
foodId: String, foodId: String,
cookMode: Int, cookMode: Int
action: (list: MutableList<CookFoodGoodsEntity>) -> Unit ): MutableList<CookFoodGoodsEntity> {
) { val cookFood = rep.getCookFoodById(foodId, cookMode)
viewModelScope.launch { return if (cookFood != null) rep.getCookFoodGoodsList(pid = cookFood.id, foodId = cookFood.foodId)
val cookFood = rep.getCookFoodById(foodId, cookMode) else mutableListOf()
cookFood?.let {
val list = rep.getCookFoodGoodsList(pid = it.id, foodId = it.foodId)
action(list)
}
}
} }
// fun updateGoods(entity: CookFoodGoodsEntity) { // 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<SeasoningSlotEntity>) =
rep.upsertAllSeasoningSlots(slots)
// fun updateAll(list: MutableList<SeasoningEntity>) { // fun updateAll(list: MutableList<SeasoningEntity>) {
// viewModelScope.launch { // viewModelScope.launch {
// list.forEach { // list.forEach {