feat(db): 支持早中晚三餐同一菜品独立保存及调料预填充优化
- 修复 getCookFoodById/deleteCookFood/markSubmittedAndDelete 查询条件缺少 dinnerType, 导致同一 foodId 跨餐次保存时误判已存在、主记录和主辅材数据丢失的问题; 查询键由三元组(canteenId+foodId+cookMode)升级为四元组(+dinnerType) - SamplingModeActivity 构建 FoodRecord 时补充 dinnerType,确保删除操作能精确定位餐次 - SubmitFoodActivity 制作中模式下从数据库加载 goodsList 时预填充调料到 adapter, isCooking=false 时同样预填充前一页面带入的调料数据 - dm_cook_food 表新增 submitState 字段(DB v13),区分手动删除与接口提交删除 - 提交成功后改用 markSubmittedAndDelete 替代 deleteCookFoodAndGoods,正确置 submitState=1 - InitActivity onDestroy 不再停止秤服务,避免进程存活期间秤数据中断 - GoodsItem.isItemClicked 统一改为 isClicked,PrepareFoodActivity 食材选中逻辑同步更新 - AndroidManifest InitActivity 增加 singleTask 及 configChanges 配置 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,8 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ui.InitActivity"
|
android:name=".ui.InitActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|keyboardHidden|keyboard|navigation|uiMode|locale|layoutDirection|fontScale|density"
|
||||||
tools:ignore="DiscouragedApi,LockedOrientationActivity">
|
tools:ignore="DiscouragedApi,LockedOrientationActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class FoodMaterialAdapter(list: MutableList<GoodsItem>) :
|
|||||||
else R.drawable.ic_dish_unselected
|
else R.drawable.ic_dish_unselected
|
||||||
)
|
)
|
||||||
clBlock.setBackgroundResource(
|
clBlock.setBackgroundResource(
|
||||||
if (data.isItemClicked) R.drawable.shape_item_cook_dish
|
if (data.isClicked) R.drawable.shape_item_cook_dish
|
||||||
else R.drawable.shape_white_fb_15_corners
|
else R.drawable.shape_white_fb_15_corners
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import com.shuwei.dish.match.entity.SeasoningSlotEntity
|
|||||||
CookFoodGoodsEntity::class,
|
CookFoodGoodsEntity::class,
|
||||||
SeasoningSlotEntity::class,
|
SeasoningSlotEntity::class,
|
||||||
],
|
],
|
||||||
version = 12,
|
version = 13,
|
||||||
exportSchema = true
|
exportSchema = true
|
||||||
)
|
)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
@@ -248,6 +248,14 @@ val MIGRATION_11_12 = MigrationImpl(11, 12) { db ->
|
|||||||
db.execSQL("ALTER TABLE dm_seasoning ADD COLUMN rawMaterialsType TEXT DEFAULT NULL")
|
db.execSQL("ALTER TABLE dm_seasoning ADD COLUMN rawMaterialsType TEXT DEFAULT NULL")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本12→13:为 dm_cook_food 表新增 submitState(接口提交状态)字段
|
||||||
|
* 0-未提交(本地草稿/手动删除),1-接口提交成功后删除
|
||||||
|
*/
|
||||||
|
val MIGRATION_12_13 = MigrationImpl(12, 13) { db ->
|
||||||
|
db.execSQL("ALTER TABLE dm_cook_food ADD COLUMN submitState INTEGER NOT NULL DEFAULT 0")
|
||||||
|
}
|
||||||
|
|
||||||
class DatabaseProvider(private val context: Context) {
|
class DatabaseProvider(private val context: Context) {
|
||||||
// 单例模式确保全局唯一实例
|
// 单例模式确保全局唯一实例
|
||||||
val instance: AppDatabase by lazy {
|
val instance: AppDatabase by lazy {
|
||||||
@@ -271,6 +279,7 @@ class DatabaseProvider(private val context: Context) {
|
|||||||
.addMigrations(MIGRATION_9_10)
|
.addMigrations(MIGRATION_9_10)
|
||||||
.addMigrations(MIGRATION_10_11)
|
.addMigrations(MIGRATION_10_11)
|
||||||
.addMigrations(MIGRATION_11_12)
|
.addMigrations(MIGRATION_11_12)
|
||||||
|
.addMigrations(MIGRATION_12_13)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ class DbRepository {
|
|||||||
db.cookFoodDao().updateCookFood(item)
|
db.cookFoodDao().updateCookFood(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getCookFoodById(foodId: String, cookMode: Int) = withContext(Dispatchers.IO) {
|
suspend fun getCookFoodById(foodId: String, cookMode: Int, dinnerType: String) = withContext(Dispatchers.IO) {
|
||||||
db.cookFoodDao().getCookFoodById(BaseApp.canteenId, foodId, cookMode)
|
db.cookFoodDao().getCookFoodById(BaseApp.canteenId, foodId, cookMode, dinnerType)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getCookFoodList(cookMode: Int, dinnerType: String) = withContext(Dispatchers.IO) {
|
suspend fun getCookFoodList(cookMode: Int, dinnerType: String) = withContext(Dispatchers.IO) {
|
||||||
@@ -33,13 +33,23 @@ class DbRepository {
|
|||||||
db.cookFoodDao().countCookFood(BaseApp.canteenId, cookMode)
|
db.cookFoodDao().countCookFood(BaseApp.canteenId, cookMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deleteCookFood(foodId: String, cookMode: Int) = withContext(Dispatchers.IO) {
|
suspend fun deleteCookFood(foodId: String, cookMode: Int, dinnerType: String) = withContext(Dispatchers.IO) {
|
||||||
db.cookFoodDao().deleteCookFood(BaseApp.canteenId, foodId, cookMode)
|
db.cookFoodDao().deleteCookFood(BaseApp.canteenId, foodId, cookMode, dinnerType)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 接口提交成功后逻辑删除菜品,同时把 submitState 置 1 */
|
||||||
|
suspend fun markSubmittedAndDelete(foodId: String, cookMode: Int, dinnerType: String) = withContext(Dispatchers.IO) {
|
||||||
|
db.cookFoodDao().markSubmittedAndDelete(BaseApp.canteenId, foodId, cookMode, dinnerType)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deleteCookFoodGoodsList(pid: Long, foodId: String) = withContext(Dispatchers.IO) {
|
suspend fun deleteCookFoodGoodsList(pid: Long, foodId: String) = withContext(Dispatchers.IO) {
|
||||||
db.cookFoodGoodsDao().deleteCookFoodGoodsList(pid, foodId)
|
db.cookFoodGoodsDao().deleteCookFoodGoodsList(pid, foodId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 仅逻辑删除调料行(materialType = 3),主辅材不动 */
|
||||||
|
suspend fun deleteSeasoningOnly(pid: Long, foodId: String) = withContext(Dispatchers.IO) {
|
||||||
|
db.cookFoodGoodsDao().deleteSeasoningOnly(pid, foodId)
|
||||||
|
}
|
||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
suspend fun insertGoodsList(items: MutableList<CookFoodGoodsEntity>) =
|
suspend fun insertGoodsList(items: MutableList<CookFoodGoodsEntity>) =
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ class DbViewModel : ViewModel() {
|
|||||||
private val _cookFoodDetailState = MutableStateFlow<CookFoodEntity?>(null)
|
private val _cookFoodDetailState = MutableStateFlow<CookFoodEntity?>(null)
|
||||||
val cookFoodDetailState: StateFlow<CookFoodEntity?> = _cookFoodDetailState.asStateFlow()
|
val cookFoodDetailState: StateFlow<CookFoodEntity?> = _cookFoodDetailState.asStateFlow()
|
||||||
|
|
||||||
fun getCookFoodById(foodId: String, cookMode: Int) {
|
fun getCookFoodById(foodId: String, cookMode: Int, dinnerType: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_cookFoodDetailState.value = rep.getCookFoodById(foodId, cookMode)
|
_cookFoodDetailState.value = rep.getCookFoodById(foodId, cookMode, dinnerType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,28 +68,49 @@ class DbViewModel : ViewModel() {
|
|||||||
entity: CookFoodEntity,
|
entity: CookFoodEntity,
|
||||||
list: MutableList<CookFoodGoodsEntity>?
|
list: MutableList<CookFoodGoodsEntity>?
|
||||||
) {
|
) {
|
||||||
val data = rep.getCookFoodById(entity.foodId, cookMode)
|
val data = rep.getCookFoodById(entity.foodId, cookMode, entity.dinnerType ?: "0")
|
||||||
if (data != null) {
|
if (data == null) {
|
||||||
// 存在数据先删除
|
// 首次保存:主表 + 主辅材 + 调料 全量 insert
|
||||||
rep.deleteCookFood(entity.foodId, cookMode)
|
rep.insertCookFood(entity)
|
||||||
rep.deleteCookFoodGoodsList(data.id, entity.foodId)
|
val newData = rep.getCookFoodById(entity.foodId, cookMode, entity.dinnerType ?: "0")
|
||||||
}
|
list?.let {
|
||||||
// 重新保存数据
|
it.forEach { goods ->
|
||||||
rep.insertCookFood(entity)
|
goods.id = 0
|
||||||
val newData = rep.getCookFoodById(entity.foodId, cookMode)
|
goods.pid = newData?.id ?: 0
|
||||||
list?.let { it ->
|
}
|
||||||
it.forEach { goods ->
|
rep.insertGoodsList(it)
|
||||||
goods.id = 0
|
}
|
||||||
goods.pid = newData?.id ?: 0
|
} else {
|
||||||
|
// 已存在:主表与主辅材保持不变,仅重建调料部分,避免主表/主辅材累积逻辑删除脏数据
|
||||||
|
rep.deleteSeasoningOnly(data.id, entity.foodId)
|
||||||
|
val seasoningList = list?.filter { it.materialType == 3 }?.toMutableList()
|
||||||
|
if (!seasoningList.isNullOrEmpty()) {
|
||||||
|
seasoningList.forEach { goods ->
|
||||||
|
goods.id = 0
|
||||||
|
goods.pid = data.id
|
||||||
|
goods.foodId = entity.foodId
|
||||||
|
}
|
||||||
|
rep.insertGoodsList(seasoningList)
|
||||||
}
|
}
|
||||||
rep.insertGoodsList(it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deleteCookFoodAndGoods(cookMode: Int, foodId: String) {
|
suspend fun deleteCookFoodAndGoods(cookMode: Int, foodId: String, dinnerType: String) {
|
||||||
val data = rep.getCookFoodById(foodId, cookMode)
|
val data = rep.getCookFoodById(foodId, cookMode, dinnerType)
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
rep.deleteCookFood(foodId = foodId, cookMode = cookMode)
|
rep.deleteCookFood(foodId = foodId, cookMode = cookMode, dinnerType = dinnerType)
|
||||||
|
rep.deleteCookFoodGoodsList(pid = data.id, foodId = foodId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口提交成功后删除本地菜品草稿
|
||||||
|
* 与 [deleteCookFoodAndGoods] 的区别:主表 submitState 会被置 1,便于审计区分手动删除与接口删除
|
||||||
|
*/
|
||||||
|
suspend fun markSubmittedAndDelete(cookMode: Int, foodId: String, dinnerType: String) {
|
||||||
|
val data = rep.getCookFoodById(foodId, cookMode, dinnerType)
|
||||||
|
if (data != null) {
|
||||||
|
rep.markSubmittedAndDelete(foodId = foodId, cookMode = cookMode, dinnerType = dinnerType)
|
||||||
rep.deleteCookFoodGoodsList(pid = data.id, foodId = foodId)
|
rep.deleteCookFoodGoodsList(pid = data.id, foodId = foodId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,9 +119,10 @@ class DbViewModel : ViewModel() {
|
|||||||
|
|
||||||
suspend fun getCookFoodGoodsList(
|
suspend fun getCookFoodGoodsList(
|
||||||
foodId: String,
|
foodId: String,
|
||||||
cookMode: Int
|
cookMode: Int,
|
||||||
|
dinnerType: String
|
||||||
): MutableList<CookFoodGoodsEntity> {
|
): MutableList<CookFoodGoodsEntity> {
|
||||||
val cookFood = rep.getCookFoodById(foodId, cookMode)
|
val cookFood = rep.getCookFoodById(foodId, cookMode, dinnerType)
|
||||||
return if (cookFood != null) rep.getCookFoodGoodsList(pid = cookFood.id, foodId = cookFood.foodId)
|
return if (cookFood != null) rep.getCookFoodGoodsList(pid = cookFood.id, foodId = cookFood.foodId)
|
||||||
else mutableListOf()
|
else mutableListOf()
|
||||||
}
|
}
|
||||||
@@ -343,7 +365,8 @@ class DbViewModel : ViewModel() {
|
|||||||
fields = listOf(
|
fields = listOf(
|
||||||
"id" to "${e.id}", "foodId" to "${e.foodId}", "foodName" to "${e.foodName}",
|
"id" to "${e.id}", "foodId" to "${e.foodId}", "foodName" to "${e.foodName}",
|
||||||
"canteenId" to "${e.canteenId}", "foodWeight" to "${e.foodWeight}", "cookMode" to "${e.cookMode}",
|
"canteenId" to "${e.canteenId}", "foodWeight" to "${e.foodWeight}", "cookMode" to "${e.cookMode}",
|
||||||
"dinnerType" to "${e.dinnerType}", "isDel" to "${e.isDel}", "createTime" to "${e.createTime}"
|
"dinnerType" to "${e.dinnerType}", "isDel" to "${e.isDel}", "submitState" to "${e.submitState}",
|
||||||
|
"createTime" to "${e.createTime}"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ interface CookFoodDao {
|
|||||||
@Update
|
@Update
|
||||||
suspend fun updateCookFood(item: CookFoodEntity)
|
suspend fun updateCookFood(item: CookFoodEntity)
|
||||||
|
|
||||||
@Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode")
|
@Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode AND dinnerType = :dinnerType")
|
||||||
suspend fun getCookFoodById(canteenId: String, foodId: String, cookMode: Int): CookFoodEntity?
|
suspend fun getCookFoodById(canteenId: String, foodId: String, cookMode: Int, dinnerType: String): CookFoodEntity?
|
||||||
|
|
||||||
@Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND canteenId = :canteenId AND cookMode = :cookMode AND dinnerType = :dinnerType ORDER BY createTime DESC")
|
@Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND canteenId = :canteenId AND cookMode = :cookMode AND dinnerType = :dinnerType ORDER BY createTime DESC")
|
||||||
suspend fun getCookFoodList(canteenId: String, cookMode: Int, dinnerType: String): MutableList<CookFoodEntity>?
|
suspend fun getCookFoodList(canteenId: String, cookMode: Int, dinnerType: String): MutableList<CookFoodEntity>?
|
||||||
@@ -26,8 +26,12 @@ interface CookFoodDao {
|
|||||||
suspend fun countCookFood(canteenId: String, cookMode: Int): Int
|
suspend fun countCookFood(canteenId: String, cookMode: Int): Int
|
||||||
|
|
||||||
// @Query("DELETE FROM dm_cook_food WHERE canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode")
|
// @Query("DELETE FROM dm_cook_food WHERE canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode")
|
||||||
@Query("UPDATE dm_cook_food SET isDel = 1 WHERE isDel = 0 AND canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode")
|
@Query("UPDATE dm_cook_food SET isDel = 1 WHERE isDel = 0 AND canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode AND dinnerType = :dinnerType")
|
||||||
suspend fun deleteCookFood(canteenId: String, foodId: String, cookMode: Int)
|
suspend fun deleteCookFood(canteenId: String, foodId: String, cookMode: Int, dinnerType: String)
|
||||||
|
|
||||||
|
/** 接口提交成功后逻辑删除菜品,同时把 submitState 置 1 以便在数据库审计中区分手动删除 */
|
||||||
|
@Query("UPDATE dm_cook_food SET isDel = 1, submitState = 1 WHERE isDel = 0 AND canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode AND dinnerType = :dinnerType")
|
||||||
|
suspend fun markSubmittedAndDelete(canteenId: String, foodId: String, cookMode: Int, dinnerType: String)
|
||||||
|
|
||||||
/** 查询全部菜品记录(含已删除),用于数据库调试查看 */
|
/** 查询全部菜品记录(含已删除),用于数据库调试查看 */
|
||||||
@Query("SELECT * FROM dm_cook_food ORDER BY createTime DESC")
|
@Query("SELECT * FROM dm_cook_food ORDER BY createTime DESC")
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ interface CookFoodGoodsDao {
|
|||||||
@Query("UPDATE dm_cook_food_goods SET isDel = 1 WHERE isDel = 0 AND pid = :pid AND foodId = :foodId")
|
@Query("UPDATE dm_cook_food_goods SET isDel = 1 WHERE isDel = 0 AND pid = :pid AND foodId = :foodId")
|
||||||
suspend fun deleteCookFoodGoodsList(pid: Long, foodId: String)
|
suspend fun deleteCookFoodGoodsList(pid: Long, foodId: String)
|
||||||
|
|
||||||
|
/** 仅逻辑删除调料行(materialType = 3),主辅材不动,用于 cook 时只重建调料部分 */
|
||||||
|
@Query("UPDATE dm_cook_food_goods SET isDel = 1 WHERE isDel = 0 AND pid = :pid AND foodId = :foodId AND materialType = 3")
|
||||||
|
suspend fun deleteSeasoningOnly(pid: Long, foodId: String)
|
||||||
|
|
||||||
/** 查询全部食材记录(含已删除),用于数据库调试查看 */
|
/** 查询全部食材记录(含已删除),用于数据库调试查看 */
|
||||||
@Query("SELECT * FROM dm_cook_food_goods ORDER BY createTime DESC")
|
@Query("SELECT * FROM dm_cook_food_goods ORDER BY createTime DESC")
|
||||||
suspend fun getAllCookFoodGoods(): MutableList<CookFoodGoodsEntity>
|
suspend fun getAllCookFoodGoods(): MutableList<CookFoodGoodsEntity>
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ data class CookFoodEntity(
|
|||||||
//0-制作模式,1-采样模式,2-品控模式
|
//0-制作模式,1-采样模式,2-品控模式
|
||||||
var cookMode:Int = 0,
|
var cookMode:Int = 0,
|
||||||
var isDel: Int = 0,
|
var isDel: Int = 0,
|
||||||
|
/** 接口提交状态:0-未提交(本地草稿或手动删除),1-接口提交成功后删除 */
|
||||||
|
var submitState: Int = 0,
|
||||||
var createTime: String = DateTimeUtil.formatDateTime(LocalDateTime.now()),
|
var createTime: String = DateTimeUtil.formatDateTime(LocalDateTime.now()),
|
||||||
var dinnerType: String? = "0",
|
var dinnerType: String? = "0",
|
||||||
) : BaseEntity {
|
) : BaseEntity {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ data class GoodsItem(
|
|||||||
|
|
||||||
// 从 CookFoodGoodsEntity @Ignore 迁移的 UI 状态字段
|
// 从 CookFoodGoodsEntity @Ignore 迁移的 UI 状态字段
|
||||||
var isSetFinished: Boolean = false,
|
var isSetFinished: Boolean = false,
|
||||||
var isItemClicked: Boolean = false,
|
// var isItemClicked: Boolean = false,
|
||||||
var isSamplingPage: Boolean = false,
|
var isSamplingPage: Boolean = false,
|
||||||
var isNewDishType: Boolean = false,
|
var isNewDishType: Boolean = false,
|
||||||
var isClicked: Boolean = false,
|
var isClicked: Boolean = false,
|
||||||
|
|||||||
@@ -140,9 +140,9 @@ class CookingModeActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) {
|
fun deleteCookFoodAndGoods(foodId: String, dinnerType: String, action: () -> Unit) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
appViewModel.deleteCookFoodAndGoods(cookMode = 0, foodId = foodId)
|
appViewModel.deleteCookFoodAndGoods(cookMode = 0, foodId = foodId, dinnerType = dinnerType)
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ class InitActivity : BaseActivity() {
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
countdownHandler.removeCallbacksAndMessages(null)
|
countdownHandler.removeCallbacksAndMessages(null)
|
||||||
WeightUtil.stopContinuousRead()
|
WeightUtil.stopContinuousRead()
|
||||||
ScaleServiceManager.stop()
|
// 秤服务伴随进程生命周期,无需在 Activity 销毁时停止;进程退出时 OS 会自动回收所有资源
|
||||||
|
// ScaleServiceManager.stop()
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,16 @@ class PrepareFoodActivity : BaseActivity() {
|
|||||||
WeightUtil.tareTwo(AddressUtil.ONE)
|
WeightUtil.tareTwo(AddressUtil.ONE)
|
||||||
delayDismissLoading()
|
delayDismissLoading()
|
||||||
}
|
}
|
||||||
|
// TODO: 测试功能-------------------------------
|
||||||
|
binding.btnTestConfirm.clickWithDebounce {
|
||||||
|
if (currentWeight <= 0.0) return@clickWithDebounce
|
||||||
|
val (index, item) = list.withIndex().find { (_, it) -> it.isOriginalData && it.isClicked && (it.useWeight?:0.0) <= 0.0 } ?: return@clickWithDebounce
|
||||||
|
item.useWeight = currentWeight
|
||||||
|
item.isSetFinished = true
|
||||||
|
list.forEachIndexed { i, it -> it.isClicked = i == index }
|
||||||
|
materialAdapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
// TODO: 测试功能-------------------------------
|
||||||
//binding.root.setOnClickListener { hideKeyboard() }
|
//binding.root.setOnClickListener { hideKeyboard() }
|
||||||
WeightUtil.addWeightListener(
|
WeightUtil.addWeightListener(
|
||||||
weightKey = TAG,
|
weightKey = TAG,
|
||||||
@@ -242,19 +252,25 @@ class PrepareFoodActivity : BaseActivity() {
|
|||||||
* - list 中不含该 goodsId:直接新增,isNewDishType = true
|
* - list 中不含该 goodsId:直接新增,isNewDishType = true
|
||||||
* - list 中已含该 goodsId:累加 useWeight
|
* - list 中已含该 goodsId:累加 useWeight
|
||||||
*/
|
*/
|
||||||
private val foodSelectCallback: (GoodsItem) -> Unit = { entity ->
|
private val foodSelectCallback: (GoodsItem) -> Unit = foodSelectCallback@{ entity ->
|
||||||
val existing = list.firstOrNull { it.goodsId == entity.goodsId }
|
val filterValue = list.withIndex().find { (_, it) -> it.goodsId == entity.goodsId }
|
||||||
if (existing != null) {
|
if (filterValue != null) {
|
||||||
existing.useWeight = (existing.useWeight ?: 0.0) + (entity.useWeight ?: 0.0)
|
val index = filterValue.index
|
||||||
existing.isSetFinished = true
|
val item = filterValue.value
|
||||||
materialAdapter.notifyItemChanged(list.indexOf(existing))
|
item.useWeight = (item.useWeight ?: 0.0) + (entity.useWeight ?: 0.0)
|
||||||
|
item.isSetFinished = true
|
||||||
|
list.forEachIndexed { i, it ->
|
||||||
|
item.isClicked = i == index
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
materialAdapter.add(entity.also {
|
list.forEach { it.isClicked = false }
|
||||||
|
list.add(entity.also {
|
||||||
it.isNewDishType = true
|
it.isNewDishType = true
|
||||||
it.isSetFinished = true
|
it.isSetFinished = true
|
||||||
// 标记为非接口数据,否则 updateMaterialTypes 不会为其计算 materialType,
|
// 标记为非接口数据,否则 updateMaterialTypes 不会为其计算 materialType,
|
||||||
// 导致列表中不显示"主辅材:主材/辅材"
|
// 导致列表中不显示"主辅材:主材/辅材"
|
||||||
it.isOriginalData = false
|
it.isOriginalData = false
|
||||||
|
it.isClicked = true
|
||||||
})
|
})
|
||||||
binding.rvMaterialList.smoothScrollToPosition(list.size - 1)
|
binding.rvMaterialList.smoothScrollToPosition(list.size - 1)
|
||||||
}
|
}
|
||||||
@@ -376,7 +392,7 @@ class PrepareFoodActivity : BaseActivity() {
|
|||||||
FoodMaterialAdapter(list).apply {
|
FoodMaterialAdapter(list).apply {
|
||||||
onItemClick = { positon ->
|
onItemClick = { positon ->
|
||||||
list.forEachIndexed { index, entity ->
|
list.forEachIndexed { index, entity ->
|
||||||
entity.isItemClicked = index == positon
|
entity.isClicked = index == positon
|
||||||
}
|
}
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ class SamplingModeActivity : BaseActivity() {
|
|||||||
foodName = entity.foodName
|
foodName = entity.foodName
|
||||||
cookMode = 1
|
cookMode = 1
|
||||||
isCooking = true
|
isCooking = true
|
||||||
|
dinnerType = entity.dinnerType ?: "0"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
list.clear()
|
list.clear()
|
||||||
@@ -146,9 +147,9 @@ class SamplingModeActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) {
|
fun deleteCookFoodAndGoods(foodId: String, dinnerType: String, action: () -> Unit) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
appViewModel.deleteCookFoodAndGoods(cookMode = 1, foodId = foodId)
|
appViewModel.deleteCookFoodAndGoods(cookMode = 1, foodId = foodId, dinnerType = dinnerType)
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,7 +211,7 @@ class SamplingModeActivity : BaseActivity() {
|
|||||||
.setContent("确定要删除「${item.foodName}」吗?")
|
.setContent("确定要删除「${item.foodName}」吗?")
|
||||||
.setNegativeButton("取消")
|
.setNegativeButton("取消")
|
||||||
.setPositiveButton("删除") {
|
.setPositiveButton("删除") {
|
||||||
deleteCookFoodAndGoods(foodId = item.foodId ?: "") {
|
deleteCookFoodAndGoods(foodId = item.foodId ?: "", dinnerType = item.dinnerType) {
|
||||||
if (list.size > 1) {
|
if (list.size > 1) {
|
||||||
dishAdapter.removeAt(position)
|
dishAdapter.removeAt(position)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -162,7 +162,8 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 Room 加载槽位配置后,开始订阅子设备秤数据
|
* 从 Room 加载槽位配置后,开始订阅子设备秤数据
|
||||||
* isCooking=true 时先从数据库查询 goodsList,筛选调料预填充 adapter,再开始观测
|
* isCooking=true 时从数据库查询 goodsList 并预填充调料 adapter;
|
||||||
|
* isCooking=false 时从前一页面带入的 goodsList 中预填充调料 adapter,再开始观测
|
||||||
*/
|
*/
|
||||||
private fun loadSlotsThenObserveScales() {
|
private fun loadSlotsThenObserveScales() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
@@ -174,24 +175,33 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
// 制作中:从数据库查询 goodsList,筛选调料数据预填充 adapter
|
// 制作中:从数据库查询 goodsList,筛选调料数据预填充 adapter
|
||||||
val foodId = food?.foodId ?: return@launch
|
val foodId = food?.foodId ?: return@launch
|
||||||
val cookMode = food?.cookMode ?: return@launch
|
val cookMode = food?.cookMode ?: return@launch
|
||||||
val list = appViewModel.getCookFoodGoodsList(foodId, cookMode)
|
val list = appViewModel.getCookFoodGoodsList(foodId, cookMode, food?.dinnerType ?: "0")
|
||||||
goodsList = list
|
goodsList = list
|
||||||
list.filter { it.materialType == 3 }.forEach { item ->
|
prefillSeasoningFromGoodsList(list)
|
||||||
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 {
|
} else {
|
||||||
observeScaleData()
|
// 非制作中:从前一页面带入的 goodsList 中筛选调料数据预填充 adapter
|
||||||
|
goodsList?.let { prefillSeasoningFromGoodsList(it) }
|
||||||
}
|
}
|
||||||
|
observeScaleData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 goodsList 中筛选 materialType==3 的调料数据,
|
||||||
|
* 写入 baseSeasoningMap 作为历史用量基准,并预填充到 adapter
|
||||||
|
*/
|
||||||
|
private fun prefillSeasoningFromGoodsList(list: List<CookFoodGoodsEntity>) {
|
||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,9 +409,10 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
appViewModel.deleteCookFoodAndGoods(
|
appViewModel.markSubmittedAndDelete(
|
||||||
cookMode = food!!.cookMode,
|
cookMode = food!!.cookMode,
|
||||||
foodId = food!!.foodId!!
|
foodId = food!!.foodId!!,
|
||||||
|
dinnerType = food!!.dinnerType
|
||||||
)
|
)
|
||||||
dismissLoading()
|
dismissLoading()
|
||||||
jumpPage(isSamplingData, false)
|
jumpPage(isSamplingData, false)
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ class FoodListFragment : BaseFragment<FragmentFoodListBinding>() {
|
|||||||
.setContent("确定要删除「${item.foodName}」吗?")
|
.setContent("确定要删除「${item.foodName}」吗?")
|
||||||
.setNegativeButton("取消")
|
.setNegativeButton("取消")
|
||||||
.setPositiveButton("删除") {
|
.setPositiveButton("删除") {
|
||||||
activity.deleteCookFoodAndGoods(foodId = item.foodId ?: "") {
|
activity.deleteCookFoodAndGoods(foodId = item.foodId ?: "", dinnerType = item.dinnerType) {
|
||||||
activity.toast("已删除")
|
activity.toast("已删除")
|
||||||
pageNo = 1
|
pageNo = 1
|
||||||
getDishList()
|
getDishList()
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/btnTestConfirm"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
|
|||||||
Reference in New Issue
Block a user