feat(activity): 重构 SubmitFoodActivity 调料展示,改用子设备实时秤数据
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
package com.shuwei.dish.match.adapter
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.shuwei.dish.match.databinding.ItemSeasoningWeightBinding
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调料使用重量列表 Adapter
|
||||||
|
* 用于 SubmitFoodActivity 展示各调料槽位的实时用量
|
||||||
|
*
|
||||||
|
* @param items 调料数据列表,外部直接操作后调用 notifyDataSetChanged
|
||||||
|
*/
|
||||||
|
class SeasoningWeightAdapter : RecyclerView.Adapter<SeasoningWeightAdapter.VH>() {
|
||||||
|
|
||||||
|
/** 调料展示数据项 */
|
||||||
|
data class Item(
|
||||||
|
/** 唯一标识:deviceId#address */
|
||||||
|
val key: String,
|
||||||
|
val goodsId: String,
|
||||||
|
val goodsName: String,
|
||||||
|
/** 使用重量(克),= 初始重量 - 当前重量,≥0 */
|
||||||
|
val useWeight: Double
|
||||||
|
)
|
||||||
|
|
||||||
|
val items = mutableListOf<Item>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新单个 item 的重量,若 key 不存在则追加
|
||||||
|
*/
|
||||||
|
fun updateItem(item: Item) {
|
||||||
|
val idx = items.indexOfFirst { it.key == item.key }
|
||||||
|
if (idx >= 0) {
|
||||||
|
items[idx] = item
|
||||||
|
notifyItemChanged(idx)
|
||||||
|
} else {
|
||||||
|
items.add(item)
|
||||||
|
notifyItemInserted(items.lastIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除指定 key 的 item(用量不足阈值时调用)
|
||||||
|
*/
|
||||||
|
fun removeItem(key: String) {
|
||||||
|
val idx = items.indexOfFirst { it.key == key }
|
||||||
|
if (idx >= 0) {
|
||||||
|
items.removeAt(idx)
|
||||||
|
notifyItemRemoved(idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||||
|
val binding = ItemSeasoningWeightBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context), parent, false
|
||||||
|
)
|
||||||
|
return VH(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||||
|
holder.bind(items[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
|
||||||
|
class VH(private val b: ItemSeasoningWeightBinding) : RecyclerView.ViewHolder(b.root) {
|
||||||
|
fun bind(item: Item) {
|
||||||
|
b.tvSeasoningName.text = item.goodsName
|
||||||
|
b.tvSeasoningWeight.text = "${item.useWeight}g"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,25 +3,22 @@ package com.shuwei.dish.match.ui
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.SparseArray
|
|
||||||
import android.util.SparseIntArray
|
|
||||||
import android.widget.FrameLayout
|
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.core.util.forEach
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
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
|
||||||
import com.shuwei.dish.match.adapter.TextCellAdapter
|
import com.shuwei.dish.match.adapter.SeasoningWeightAdapter
|
||||||
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
|
||||||
import com.shuwei.dish.match.databinding.ActivitySubmitFoodBinding
|
import com.shuwei.dish.match.databinding.ActivitySubmitFoodBinding
|
||||||
import com.shuwei.dish.match.db.AppRepository
|
import com.shuwei.dish.match.db.AppRepository
|
||||||
|
|
||||||
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.entity.SeasoningEntity
|
|
||||||
import com.shuwei.dish.match.net.NetViewModel
|
import com.shuwei.dish.match.net.NetViewModel
|
||||||
|
import com.shuwei.dish.match.scale.ScaleDeviceConfig
|
||||||
|
import com.shuwei.dish.match.scale.ScaleServiceManager
|
||||||
import com.shuwei.dish.match.utils.AddressUtil
|
import com.shuwei.dish.match.utils.AddressUtil
|
||||||
import com.shuwei.dish.match.utils.WeightUtil
|
import com.shuwei.dish.match.utils.WeightUtil
|
||||||
import com.shuwei.dish.match.utils.ext.clickWithDebounce
|
import com.shuwei.dish.match.utils.ext.clickWithDebounce
|
||||||
@@ -34,7 +31,10 @@ 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 com.shuwei.dish.match.viewmodel.AppViewModel
|
import com.shuwei.dish.match.viewmodel.AppViewModel
|
||||||
import com.shuwei.dish.match.viewmodel.factory.AppFactory
|
import com.shuwei.dish.match.viewmodel.factory.AppFactory
|
||||||
import kotlin.getValue
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@SuppressLint("UseSparseArrays")
|
@SuppressLint("UseSparseArrays")
|
||||||
class SubmitFoodActivity : BaseActivity() {
|
class SubmitFoodActivity : BaseActivity() {
|
||||||
@@ -50,8 +50,6 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
private var food: FoodRecord? = null
|
private var food: FoodRecord? = null
|
||||||
private var goodsList: MutableList<CookFoodGoodsEntity>? = null
|
private var goodsList: MutableList<CookFoodGoodsEntity>? = null
|
||||||
|
|
||||||
private var isCooking = false
|
|
||||||
|
|
||||||
private val cookFoodEntity by lazy {
|
private val cookFoodEntity by lazy {
|
||||||
CookFoodEntity().apply {
|
CookFoodEntity().apply {
|
||||||
food?.let {
|
food?.let {
|
||||||
@@ -64,6 +62,21 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 调料列表 adapter */
|
||||||
|
private val seasoningAdapter = SeasoningWeightAdapter()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 各秤的初始重量快照,key = "deviceId#address"
|
||||||
|
* 首次收到稳定数据时记录,之后用于计算用量差值
|
||||||
|
*/
|
||||||
|
private val baselineMap = mutableMapOf<String, Double>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 槽位配置:key = "deviceId#address",value = goodsId to goodsName
|
||||||
|
* 从 Room dm_seasoning_slot 加载
|
||||||
|
*/
|
||||||
|
private val slotMap = mutableMapOf<String, Pair<String, String>>()
|
||||||
|
|
||||||
@Suppress("unchecked_cast", "DEPRECATION")
|
@Suppress("unchecked_cast", "DEPRECATION")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -74,15 +87,9 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
intent.extras?.apply {
|
intent.extras?.apply {
|
||||||
food = getSerializable(FOOD_ITEM) as FoodRecord?
|
food = getSerializable(FOOD_ITEM) as FoodRecord?
|
||||||
Log.d(TAG, "onCreate: cookMode=${food?.cookMode}")
|
Log.d(TAG, "onCreate: cookMode=${food?.cookMode}")
|
||||||
isCooking = food?.isCooking ?: false
|
|
||||||
if (isCooking) {
|
|
||||||
//烹饪中,从本地查询数据
|
|
||||||
loadSeasoningFromLocal()
|
|
||||||
} else {
|
|
||||||
// 非烹饪中,从菜品主辅材配置页面带入数据
|
// 非烹饪中,从菜品主辅材配置页面带入数据
|
||||||
goodsList = getSerializable(GOODS_LIST) as MutableList<CookFoodGoodsEntity>?
|
goodsList = getSerializable(GOODS_LIST) as MutableList<CookFoodGoodsEntity>?
|
||||||
}
|
}
|
||||||
}
|
|
||||||
setTitleBar(titleBarAction = {
|
setTitleBar(titleBarAction = {
|
||||||
it.visible()
|
it.visible()
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
@@ -90,80 +97,91 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
}, rightIconActon = {
|
}, rightIconActon = {
|
||||||
it.gone()
|
it.gone()
|
||||||
it.setImageResource(R.drawable.ic_setting)
|
it.setImageResource(R.drawable.ic_setting)
|
||||||
it.setOnClickListener {
|
|
||||||
//startActivity<DeviceSettingActivity>()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
setupRecyclerView()
|
||||||
addViewListener()
|
addViewListener()
|
||||||
|
loadSlotsThenObserveScales()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSeasoningFromLocal() {
|
/** 初始化 RecyclerView,2列 GridLayoutManager */
|
||||||
appViewModel.getCookFoodGoodsList(
|
private fun setupRecyclerView() {
|
||||||
foodId = food!!.foodId!!,
|
binding.rvSeasoning.itemAnimator = null
|
||||||
cookMode = food!!.cookMode
|
binding.rvSeasoning.layoutManager = GridLayoutManager(this, 2)
|
||||||
) { it ->
|
binding.rvSeasoning.adapter = seasoningAdapter
|
||||||
goodsList = mutableListOf()
|
|
||||||
val goodsIdList = mutableListOf<String>()
|
|
||||||
//设置主辅材数据
|
|
||||||
val tempList = it.filter { goods -> goods.materialType != 3 }
|
|
||||||
tempList.forEach {
|
|
||||||
if (!goodsIdList.contains(it.goodsId)) {
|
|
||||||
goodsList?.add(it)
|
|
||||||
goodsIdList.add(it.goodsId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取调料数据并展示
|
/**
|
||||||
val filterList: List<SeasoningEntity>? = it.filter { goods -> goods.materialType == 3 }
|
* 从 Room 加载槽位配置后,开始订阅子设备秤数据
|
||||||
.map { entity ->
|
* 确保 slotMap 就绪后再处理秤数据,避免名称为空
|
||||||
SeasoningEntity().also { se ->
|
*/
|
||||||
se.goodsId = entity.goodsId
|
private fun loadSlotsThenObserveScales() {
|
||||||
se.goodsName = entity.goodsName
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
se.goodsOrRelationCode = entity.goodsOrRelationCode
|
val slots = BaseApp.instance!!.database.seasoningSlotDao().queryAll()
|
||||||
se.relateionType = entity.relateionType
|
withContext(Dispatchers.Main) {
|
||||||
se.materialType = entity.materialType
|
slots.forEach { slot ->
|
||||||
se.allEdible = entity.allEdible
|
slotMap["${slot.deviceId}#${slot.address}"] = slot.goodsId to slot.goodsName
|
||||||
se.useWeight = entity.useWeight
|
|
||||||
se.popularName = entity.popularName
|
|
||||||
se.canteenId = entity.canteenId
|
|
||||||
se.relateionType_dictText = entity.relateionType_dictText
|
|
||||||
se.foodId = entity.foodId
|
|
||||||
se.sort = entity.sort
|
|
||||||
se.pageType = 0
|
|
||||||
}
|
}
|
||||||
}
|
observeScaleData()
|
||||||
filterList?.toMutableList()?.let { cellData ->
|
|
||||||
loadTextCell(cellData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订阅 ScaleServiceManager.allScales,过滤子设备数据并更新 adapter
|
||||||
|
* 排除主设备(DEVICE_ID_2),只处理 22格、18格、1格子设备
|
||||||
|
*/
|
||||||
|
private fun observeScaleData() {
|
||||||
|
val flow = ScaleServiceManager.allScales ?: return
|
||||||
|
lifecycleScope.launch {
|
||||||
|
flow.collectLatest { scaleMap ->
|
||||||
|
scaleMap.forEach { (key, data) ->
|
||||||
|
// 排除主设备 2格秤
|
||||||
|
if (data.deviceId == ScaleDeviceConfig.DEVICE_ID_2) return@forEach
|
||||||
|
|
||||||
// private lateinit var seasoningList: List<SeasoningEntity>
|
// 1格设备调料名固定为"油",其余从槽位配置读取
|
||||||
// private var isFirstSave = true
|
val (goodsId, goodsName) = if (data.deviceId == ScaleDeviceConfig.DEVICE_ID_1) {
|
||||||
// fun updateSeasoningList(list: MutableList<SeasoningEntity>) {
|
"" to "油"
|
||||||
// if (isFirstSave) {
|
} else {
|
||||||
// val json = list.toJsonString()
|
slotMap[key] ?: return@forEach
|
||||||
// val typeToken = object : TypeToken<List<SeasoningEntity>>() {}
|
|
||||||
// seasoningList = json.toType(typeToken = typeToken)
|
|
||||||
// isFirstSave = false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private val seasoningArray by lazy {
|
|
||||||
SparseArray<Double>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 首次收到稳定数据时记录基准重量
|
||||||
|
val baseline = baselineMap[key]
|
||||||
|
if (baseline == null) {
|
||||||
|
if (data.state == WeightUtil.STATE_STABLE) {
|
||||||
|
baselineMap[key] = data.weight
|
||||||
|
}
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
private val firstGoodsArray = SparseArray<Double>()
|
// 用量 = 初始重量 - 当前重量,负值归零
|
||||||
|
val useWeight = (baseline - data.weight)
|
||||||
|
.coerceAtLeast(0.0)
|
||||||
|
.roundedOneDecimalPlace()
|
||||||
|
|
||||||
|
// 用量不足 0.5g 时从列表移除(或不添加)
|
||||||
|
if (useWeight < 0.5) {
|
||||||
|
seasoningAdapter.removeItem(key)
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
seasoningAdapter.updateItem(
|
||||||
|
SeasoningWeightAdapter.Item(
|
||||||
|
key = key,
|
||||||
|
goodsId = goodsId,
|
||||||
|
goodsName = goodsName,
|
||||||
|
useWeight = useWeight
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun addViewListener() {
|
private fun addViewListener() {
|
||||||
addWeightListener()
|
|
||||||
binding.btnWeightClear.setOnClickListener { WeightUtil.tareTwo(AddressUtil.TWO) }
|
binding.btnWeightClear.setOnClickListener { WeightUtil.tareTwo(AddressUtil.TWO) }
|
||||||
|
|
||||||
binding.btnCook.clickWithDebounce {
|
binding.btnCook.clickWithDebounce { cook() }
|
||||||
cook()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.btnSubmit.clickWithDebounce {
|
binding.btnSubmit.clickWithDebounce {
|
||||||
if (cookFoodEntity.foodWeight <= 0.toDouble()) {
|
if (cookFoodEntity.foodWeight <= 0.toDouble()) {
|
||||||
@@ -172,114 +190,40 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
submit()
|
submit()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun addWeightListener() {
|
// 监听主设备 2格秤的熟重
|
||||||
WeightUtil.addWeightListener(
|
WeightUtil.addWeightListener(TAG) { address, _, weight ->
|
||||||
weightKey = TAG,
|
|
||||||
getWeight = { address, state, weight ->
|
|
||||||
if (address == AddressUtil.TWO) {
|
if (address == AddressUtil.TWO) {
|
||||||
cookFoodEntity.foodWeight = weight.toDouble()
|
cookFoodEntity.foodWeight = weight.toDouble()
|
||||||
binding.tvTotalWeight.text = "${weight / 1000f}"
|
binding.tvTotalWeight.text = "${weight / 1000f}"
|
||||||
}
|
}
|
||||||
val firstWeight = firstGoodsArray.get(address, null)
|
|
||||||
if (firstWeight == null) {
|
|
||||||
//未设置数据
|
|
||||||
if (state != WeightUtil.STATE_STABLE) {
|
|
||||||
//首次记录数据需要稳定数据
|
|
||||||
return@addWeightListener
|
|
||||||
}
|
|
||||||
firstGoodsArray.put(address, weight)
|
|
||||||
return@addWeightListener
|
|
||||||
}
|
|
||||||
var realUseWeight = firstWeight - weight
|
|
||||||
realUseWeight = if (realUseWeight > 0) realUseWeight else 0.0
|
|
||||||
seasoningArray.put(address, realUseWeight.toDouble())
|
|
||||||
|
|
||||||
// refreshSeasoningWeight()
|
|
||||||
|
|
||||||
val item = seasoningItems.firstOrNull { address == addressArray[it.sort] }
|
|
||||||
item?.let {
|
|
||||||
val lastWeight = seasoningArray.get(address) ?: 0.toDouble()
|
|
||||||
it.useWeight =
|
|
||||||
(lastWeight + getCookingSeasoning(address)).roundedOneDecimalPlace()
|
|
||||||
updateGridData(it)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// private fun refreshSeasoningWeight() {
|
|
||||||
// if (seasoningItems.isEmpty()) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// seasoningItems.let { items ->
|
|
||||||
// addressArray.forEach { key, value ->
|
|
||||||
// items[key].useWeight =
|
|
||||||
// (seasoningArray.get(value) ?: 0.toDouble()) + getCookingSeasoning(value)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// setGridData(seasoningItems)
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun updateGridData(entity: SeasoningEntity) {
|
|
||||||
val gridLayout = binding.include.root
|
|
||||||
val tag = entity.sort.toString()
|
|
||||||
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
|
||||||
TextCellAdapter.loadLayout(frameLayout, entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCookingSeasoning(address: Int): Double {
|
|
||||||
if (isCooking.not()) return 0.toDouble()
|
|
||||||
if (seasoningItems.isEmpty()) return 0.toDouble()
|
|
||||||
val weight =
|
|
||||||
seasoningCookingItems?.get(weightRelateArray2.get(address))?.useWeight ?: 0.toDouble()
|
|
||||||
return weight
|
|
||||||
}
|
|
||||||
|
|
||||||
private val weightRelateArray2 by lazy {
|
|
||||||
SparseIntArray().apply {
|
|
||||||
addressArray.forEach { key, value ->
|
|
||||||
put(value, key)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private val addressArray by lazy {
|
|
||||||
AddressUtil.getWeighAddressArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
// private fun prepareData(acton: () -> Unit) {
|
|
||||||
//
|
|
||||||
// //只有制作和采样列表页面才能进入设置页面,提交页面无法进行设置,不存在调料数据被修改的问题
|
|
||||||
// val seasoningJson = realSeasoningData.toJsonString()
|
|
||||||
// val typeToken = object : TypeToken<List<CookFoodGoodsEntity>>() {}
|
|
||||||
// val tempSeasoningList = seasoningJson.toType(typeToken = typeToken)
|
|
||||||
// goodsList?.addAll(tempSeasoningList)
|
|
||||||
// acton()
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun cook() {
|
private fun cook() {
|
||||||
if (food == null || goodsList.isNullOrEmpty()) {
|
if (food == null || goodsList.isNullOrEmpty()) {
|
||||||
toast("未获取到菜品或构成信息")
|
toast("未获取到菜品或构成信息")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val realSeasoningData = seasoningItems
|
val seasoningData = seasoningAdapter.items
|
||||||
//(binding.rvSeasoning.adapter as TextCellAdapter).list
|
if (seasoningData.isEmpty()) {
|
||||||
if (realSeasoningData.isEmpty() && !isCooking) {
|
|
||||||
toast("未获取到调料信息")
|
toast("未获取到调料信息")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (realSeasoningData.isNotEmpty() && realSeasoningData[0].goodsId.isNullOrBlank()) {
|
|
||||||
toast("还未设置调料信息,请去设置页面操作")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
showLoading()
|
showLoading()
|
||||||
//只有制作和采样列表页面才能进入设置页面,提交页面无法进行设置,不存在调料数据被修改的问题
|
|
||||||
val seasoningJson = realSeasoningData.toJsonString()
|
// 将调料数据转为 CookFoodGoodsEntity 追加到 goodsList
|
||||||
val typeToken = object : TypeToken<List<CookFoodGoodsEntity>>() {}
|
val typeToken = object : TypeToken<List<CookFoodGoodsEntity>>() {}
|
||||||
val tempSeasoningList = seasoningJson.toType(typeToken = typeToken)
|
val tempSeasoningList = seasoningData.map { item ->
|
||||||
|
CookFoodGoodsEntity().also { entity ->
|
||||||
|
entity.goodsId = item.goodsId
|
||||||
|
entity.goodsName = item.goodsName
|
||||||
|
entity.useWeight = item.useWeight
|
||||||
|
entity.materialType = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
goodsList?.addAll(tempSeasoningList)
|
goodsList?.addAll(tempSeasoningList)
|
||||||
|
|
||||||
cookFoodEntity.let {
|
cookFoodEntity.let {
|
||||||
it.dinnerType = when (it.dinnerType) {
|
it.dinnerType = when (it.dinnerType) {
|
||||||
"早餐" -> "1"
|
"早餐" -> "1"
|
||||||
@@ -288,17 +232,14 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
else -> it.dinnerType
|
else -> it.dinnerType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val isSamplingData = food!!.cookMode == 1
|
val isSamplingData = food!!.cookMode == 1
|
||||||
if (isSamplingData) {
|
if (isSamplingData) {
|
||||||
//生成临时foodId,解决采样模式没有foodId,无法关联数据的问题
|
|
||||||
val tempFoodId = cookFoodEntity.foodId.ifBlank { "${System.currentTimeMillis()}" }
|
val tempFoodId = cookFoodEntity.foodId.ifBlank { "${System.currentTimeMillis()}" }
|
||||||
cookFoodEntity.foodId = tempFoodId
|
cookFoodEntity.foodId = tempFoodId
|
||||||
}
|
}
|
||||||
//全部设置同一foodId
|
goodsList?.forEach { it.foodId = cookFoodEntity.foodId }
|
||||||
goodsList?.forEach {
|
|
||||||
it.foodId = cookFoodEntity.foodId
|
|
||||||
}
|
|
||||||
//保存菜品-保存主辅料调料
|
|
||||||
appViewModel.saveCookFoodAndGoods(
|
appViewModel.saveCookFoodAndGoods(
|
||||||
cookMode = food!!.cookMode,
|
cookMode = food!!.cookMode,
|
||||||
entity = cookFoodEntity,
|
entity = cookFoodEntity,
|
||||||
@@ -316,31 +257,22 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
toast("未获取到菜品或构成信息")
|
toast("未获取到菜品或构成信息")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val realSeasoningData = seasoningItems
|
val seasoningData = seasoningAdapter.items
|
||||||
if (realSeasoningData.isEmpty() && !isCooking) {
|
|
||||||
toast("未获取到调料信息")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (realSeasoningData.isNotEmpty() && realSeasoningData[0].goodsId.isNullOrBlank()) {
|
|
||||||
toast("还未设置调料信息,请去设置页面操作")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
showLoading()
|
showLoading()
|
||||||
//只有制作和采样列表页面才能进入设置页面,提交页面无法进行设置,不存在调料数据被修改的问题
|
|
||||||
val seasoningJson = realSeasoningData.toJsonString()
|
// 将重量大于0且不重复的调料追加到 goodsList
|
||||||
val typeToken = object : TypeToken<List<CookFoodGoodsEntity>>() {}
|
seasoningData.forEach { item ->
|
||||||
val tempSeasoningList = seasoningJson.toType(typeToken = typeToken)
|
if (item.useWeight > 0.0 && goodsList?.none { it.goodsId == item.goodsId } == true) {
|
||||||
tempSeasoningList.forEach { entity ->
|
goodsList?.add(CookFoodGoodsEntity().also { entity ->
|
||||||
val realWeight = entity.useWeight ?: 0.toDouble()
|
entity.goodsId = item.goodsId
|
||||||
val filterData = goodsList?.firstOrNull { it.goodsId == entity.goodsId }
|
entity.goodsName = item.goodsName
|
||||||
//确保重量大于0,且无重复数据
|
entity.useWeight = item.useWeight
|
||||||
if (realWeight > 0.toDouble() && filterData == null) {
|
entity.materialType = 3
|
||||||
goodsList?.add(entity)
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cookFoodEntity.let {
|
cookFoodEntity.let {
|
||||||
// it.stFoodInfoConstituteList = this@SubmitFoodActivity.goodsList
|
|
||||||
it.matchingConstituteInfoList = this@SubmitFoodActivity.goodsList
|
it.matchingConstituteInfoList = this@SubmitFoodActivity.goodsList
|
||||||
it.dinnerType = when (it.dinnerType) {
|
it.dinnerType = when (it.dinnerType) {
|
||||||
"1" -> "早餐"
|
"1" -> "早餐"
|
||||||
@@ -352,30 +284,15 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
|
|
||||||
val isSamplingData = food!!.cookMode == 1
|
val isSamplingData = food!!.cookMode == 1
|
||||||
if (isSamplingData) {
|
if (isSamplingData) {
|
||||||
//采样模式没有foodId
|
|
||||||
cookFoodEntity.foodId = ""
|
cookFoodEntity.foodId = ""
|
||||||
goodsList?.forEach { it.foodId = "" }
|
goodsList?.forEach { it.foodId = "" }
|
||||||
}
|
}
|
||||||
val json = cookFoodEntity.toJsonString()
|
|
||||||
Log.d(TAG, "submit: json=$json")
|
|
||||||
// HttpUtil.postJson(
|
|
||||||
// url = UrlConfig.SUBMIT_DISH,
|
|
||||||
// json = json,
|
|
||||||
// doSuccess = {
|
|
||||||
// Log.d(TAG, "submit: postJson=$it")
|
|
||||||
// submitSuccess(isSamplingData)
|
|
||||||
// }, doFailure = { code, msg ->
|
|
||||||
// Log.d(TAG, "submit: postJson:code=$code,msg=$msg")
|
|
||||||
// toast(msg)
|
|
||||||
// dismissLoading()
|
|
||||||
// })
|
|
||||||
|
|
||||||
|
Log.d(TAG, "submit: json=${cookFoodEntity.toJsonString()}")
|
||||||
netViewModel.submitCookFood(
|
netViewModel.submitCookFood(
|
||||||
entity = cookFoodEntity,
|
entity = cookFoodEntity,
|
||||||
onSuccess = {
|
onSuccess = { submitSuccess(isSamplingData) },
|
||||||
submitSuccess(isSamplingData)
|
onFailure = { _, msg ->
|
||||||
},
|
|
||||||
onFailure = { code, msg ->
|
|
||||||
toast(msg)
|
toast(msg)
|
||||||
dismissLoading()
|
dismissLoading()
|
||||||
})
|
})
|
||||||
@@ -383,12 +300,10 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun submitSuccess(isSamplingData: Boolean) {
|
private fun submitSuccess(isSamplingData: Boolean) {
|
||||||
if (food?.foodId.isNullOrBlank()) {
|
if (food?.foodId.isNullOrBlank()) {
|
||||||
//本地无删除数据直接跳转页面
|
|
||||||
dismissLoading()
|
dismissLoading()
|
||||||
jumpPage(isSamplingData, false)
|
jumpPage(isSamplingData, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//删除本地数据
|
|
||||||
appViewModel.deleteCookFoodAndGoods(
|
appViewModel.deleteCookFoodAndGoods(
|
||||||
cookMode = food!!.cookMode,
|
cookMode = food!!.cookMode,
|
||||||
foodId = food!!.foodId!!
|
foodId = food!!.foodId!!
|
||||||
@@ -415,57 +330,12 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun initViewModel() {
|
private fun initViewModel() {
|
||||||
val db = BaseApp.instance!!.database
|
val db = BaseApp.instance!!.database
|
||||||
val factory =
|
val factory = AppFactory(AppRepository(db.appDao()))
|
||||||
AppFactory(AppRepository(db.appDao()))
|
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
appViewModel =
|
|
||||||
ViewModelProvider(this, factory)[AppViewModel::class.java]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onDestroy() {
|
||||||
super.onResume()
|
WeightUtil.removeWeightListener(TAG)
|
||||||
if (isCooking.not()) {
|
super.onDestroy()
|
||||||
//烹饪中使用本地数据,未烹饪则使用默认的调料配置数据
|
|
||||||
appViewModel.loadSeasoning {
|
|
||||||
Log.d(TAG, "onResume: loadSeasoning:${it.toJsonString()}")
|
|
||||||
loadTextCell(it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private var seasoningItems = mutableListOf<SeasoningEntity>()
|
|
||||||
private var seasoningCookingItems: List<SeasoningEntity>? = null
|
|
||||||
private fun loadTextCell(list: MutableList<SeasoningEntity>) {
|
|
||||||
seasoningItems.clear()
|
|
||||||
seasoningItems.addAll(list)
|
|
||||||
initConfigData()
|
|
||||||
// setGridData(list)
|
|
||||||
list.forEach { entity ->
|
|
||||||
//烹饪中重量数据从本地获取,否则显示0
|
|
||||||
if (isCooking.not()) {
|
|
||||||
entity.useWeight = 0.0
|
|
||||||
}
|
|
||||||
updateGridData(entity)
|
|
||||||
}
|
|
||||||
seasoningCookingItems = seasoningItems.map { it.copy() }.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initConfigData() {
|
|
||||||
repeat(12) { num ->
|
|
||||||
val firstOne = seasoningItems.firstOrNull { it.sort == num }
|
|
||||||
if (firstOne == null) {
|
|
||||||
seasoningItems.add(SeasoningEntity().also { it.sort = num })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setGridData(list: MutableList<SeasoningEntity>) {
|
|
||||||
val gridLayout = binding.include.root
|
|
||||||
list.forEach { entity ->
|
|
||||||
val tag = entity.sort.toString()
|
|
||||||
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
|
||||||
TextCellAdapter.loadLayout(frameLayout, entity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,12 @@
|
|||||||
android:textColor="@color/black666"
|
android:textColor="@color/black666"
|
||||||
android:textSize="28sp" />
|
android:textSize="28sp" />
|
||||||
|
|
||||||
<include
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/include"
|
android:id="@+id/rvSeasoning"
|
||||||
layout="@layout/layout_grid"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="660dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:overScrollMode="never" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvSeasoningName"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/black666"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvSeasoningWeight"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user