feat(pack): 优化菜品净菜包装界面和功能
- 调整布局间距,移除商品名称和材料类型显示 - 修改开始组配按钮文本为完成组配并设为可见 - 更新API服务接口支持可空参数类型 - 添加餐品净菜包装数据模型字段 - 实现包装数据收集和提交功能 - 添加时间工具类导入和设备码字段 - 优化适配器中材料分类显示逻辑
This commit is contained in:
@@ -48,7 +48,7 @@ class TaskDetailAdapter(list: MutableList<NutComboTaskItemDetail>) :
|
||||
1 -> "主材"
|
||||
2 -> "辅材"
|
||||
3 -> "调料"
|
||||
else -> "未知"
|
||||
else -> "-"
|
||||
}
|
||||
tvIngredientClass.text = classText
|
||||
|
||||
|
||||
@@ -72,9 +72,11 @@ data class NutFoodOptionVO(
|
||||
*/
|
||||
@Parcelize
|
||||
data class NutFoodComposition(
|
||||
val materId: Long?,
|
||||
val ingredientName: String?,
|
||||
val isMain: Int?
|
||||
var materId: Long?,
|
||||
var ingredientName: String?,
|
||||
var traceCode: String?,
|
||||
var amount: Double?,
|
||||
var isMain: Int?
|
||||
) : Parcelable
|
||||
|
||||
/**
|
||||
@@ -218,6 +220,7 @@ data class NutComboTaskDetailVO(
|
||||
var portions: Int? = null,
|
||||
var comboStatus: Int? = null,
|
||||
var ownerName: String? = null,
|
||||
var deviceCode: String? = null,
|
||||
var items: List<NutComboTaskItemDetail>? = null,
|
||||
) : Parcelable
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ interface ApiServiceV2 {
|
||||
@POST
|
||||
suspend fun addCleanPackage(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/clean-package/add",
|
||||
@Body param: Map<String, @JvmSuppressWildcards Any>
|
||||
@Body param: Map<String, @JvmSuppressWildcards Any?>
|
||||
): ApiResponse<Unit>
|
||||
|
||||
// ========== 四、餐品净菜包装接口 ==========
|
||||
@@ -144,7 +144,7 @@ interface ApiServiceV2 {
|
||||
@POST
|
||||
suspend fun addMealPackage(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/meal-package/add",
|
||||
@Body param: Map<String, @JvmSuppressWildcards Any>
|
||||
@Body param: Map<String, @JvmSuppressWildcards Any?>
|
||||
): ApiResponse<Unit>
|
||||
|
||||
// ========== 五、组配任务接口 ==========
|
||||
|
||||
@@ -157,13 +157,11 @@ class NetViewModelV2(
|
||||
is UiState.Success -> {
|
||||
block(true, "")
|
||||
}
|
||||
|
||||
is UiState.Error -> {
|
||||
block(false, uiState.msg)
|
||||
}
|
||||
|
||||
is UiState.Loading -> {}
|
||||
UiState.Idle -> {}
|
||||
is UiState.Idle -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +211,7 @@ class NetViewModelV2(
|
||||
private val _addCleanPackageState = MutableStateFlow<UiState<Unit?>>(UiState.Idle)
|
||||
val addCleanPackageState: StateFlow<UiState<Unit?>> = _addCleanPackageState.asStateFlow()
|
||||
|
||||
fun addCleanPackage(param: Map<String, Any>) {
|
||||
fun addCleanPackage(param: Map<String, Any?>) {
|
||||
viewModelScope.launch {
|
||||
_addCleanPackageState.value = UiState.Loading
|
||||
_addCleanPackageState.value = repository.addCleanPackage(param)
|
||||
@@ -225,6 +223,24 @@ class NetViewModelV2(
|
||||
private val _addMealPackageState = MutableStateFlow<UiState<Unit?>>(UiState.Idle)
|
||||
val addMealPackageState: StateFlow<UiState<Unit?>> = _addMealPackageState.asStateFlow()
|
||||
|
||||
fun addMealPackage(param: Map<String, Any?>, callback: (Boolean, String) -> Unit) {
|
||||
viewModelScope.launch {
|
||||
val uiState = repository.addMealPackage(param)
|
||||
when (uiState) {
|
||||
is UiState.Success -> {
|
||||
callback(true, "")
|
||||
}
|
||||
|
||||
is UiState.Error -> {
|
||||
callback(false, uiState.msg)
|
||||
}
|
||||
|
||||
is UiState.Loading -> {}
|
||||
is UiState.Idle -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addMealPackage(param: Map<String, Any>) {
|
||||
viewModelScope.launch {
|
||||
_addMealPackageState.value = UiState.Loading
|
||||
|
||||
@@ -85,12 +85,12 @@ class RemoteRepositoryV2 {
|
||||
|
||||
// ========== 单品净菜包装接口 ==========
|
||||
|
||||
suspend fun addCleanPackage(param: Map<String, Any>): UiState<Unit?> =
|
||||
suspend fun addCleanPackage(param: Map<String, Any?>): UiState<Unit?> =
|
||||
safeApiCall { apiService.addCleanPackage(param = param) }
|
||||
|
||||
// ========== 餐品净菜包装接口 ==========
|
||||
|
||||
suspend fun addMealPackage(param: Map<String, Any>): UiState<Unit?> =
|
||||
suspend fun addMealPackage(param: Map<String, Any?>): UiState<Unit?> =
|
||||
safeApiCall { apiService.addMealPackage(param = param) }
|
||||
|
||||
// ========== 组配任务接口 ==========
|
||||
|
||||
@@ -53,7 +53,9 @@ import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.math.abs
|
||||
import com.shuwei.dish.match.model.NutFoodComposition
|
||||
import com.shuwei.dish.match.net.NetViewModelV2
|
||||
import com.shuwei.dish.match.utils.DateTimeUtil
|
||||
import com.shuwei.dish.match.utils.ext.roundedOneDecimalPlace
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
class PackActivity : BaseActivity() {
|
||||
@@ -96,8 +98,7 @@ class PackActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
val isSamplingMode = SpTool.cookMode == 1
|
||||
val titleText = if (isSamplingMode) "菜品信息采集" else "菜品净菜包装"
|
||||
val titleText = "菜品净菜包"
|
||||
setTitleBar(titleBarAction = {
|
||||
it.visible()
|
||||
}, titleAction = {
|
||||
@@ -115,7 +116,7 @@ class PackActivity : BaseActivity() {
|
||||
binding.etInputDish.isFocusableInTouchMode = false
|
||||
binding.ivDishSearch.gone()
|
||||
|
||||
binding.tvGoodsName.text = "食材名称"
|
||||
// binding.tvGoodsName.text = "食材名称"
|
||||
|
||||
addViewClickListener()
|
||||
addBackKeyListener()
|
||||
@@ -229,7 +230,72 @@ class PackActivity : BaseActivity() {
|
||||
}.show()
|
||||
}
|
||||
binding.btnSubmit.clickWithDebounce {
|
||||
submit()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集字段提交值,根据 apiKey / extraApiKeys 规则汇总
|
||||
* @return 提交参数 Map,key 为接口参数名,value 为提交值
|
||||
*/
|
||||
private fun collectSubmitValues(): MutableMap<String, String> {
|
||||
val params = mutableMapOf<String, String>()
|
||||
for (field in fields) {
|
||||
if (field.hidden) continue
|
||||
// 跳过 CHILDREN 类型,暂不处理
|
||||
if (field.type == FieldType.CHILDREN) continue
|
||||
|
||||
if (field.extraApiKeys.isNotEmpty()) {
|
||||
// 下拉字段:直接读取 bindDropdown 已解析好的 extraValues
|
||||
field.extraValues.forEach { (apiKey, value) ->
|
||||
params[apiKey] = value
|
||||
}
|
||||
} else if (field.apiKey.isNotBlank()) {
|
||||
// 普通字段
|
||||
params[field.apiKey] = field.value
|
||||
}
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交餐品净菜包装
|
||||
*/
|
||||
private fun submit() {
|
||||
val food = mealItem ?: return
|
||||
//包装方式、包装份数、保质期至、包装人、存放温度、终端设备
|
||||
val values = collectSubmitValues()
|
||||
val params = mutableMapOf<String, Any?>()
|
||||
values.forEach { (key, value) ->
|
||||
params[key] = value
|
||||
}
|
||||
//关联餐品id
|
||||
params["foodId"] = food.foodId
|
||||
//包装餐品名称
|
||||
params["mealName"] = food.foodName
|
||||
//包装日期
|
||||
params["packageDate"] = DateTimeUtil.formatDateTime(LocalDateTime.now())
|
||||
//操作类型
|
||||
params["opType"] = "设备自动"
|
||||
|
||||
//食材明细列表
|
||||
params["ingredients"] = list.map {
|
||||
NutFoodComposition(
|
||||
materId = it.goodsId.toLongOrNull(),
|
||||
ingredientName = it.goodsName,
|
||||
traceCode = it.materCode,
|
||||
amount = it.useWeight,
|
||||
isMain = if (it.materialType == 1) 1 else 0
|
||||
)
|
||||
}.toMutableList()
|
||||
|
||||
viewModelV2.addMealPackage(params) { state, msg ->
|
||||
if (state.not()) {
|
||||
toast("提交失败:$msg")
|
||||
return@addMealPackage
|
||||
}
|
||||
toast("提交成功")
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,12 +466,12 @@ class PackActivity : BaseActivity() {
|
||||
entity.isClicked = index == positon
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
binding.tvGoodsName.text = item.goodsName
|
||||
binding.tvMaterialType.text = when (item.materialType) {
|
||||
1 -> "主材"
|
||||
2 -> "辅材"
|
||||
else -> "未知"
|
||||
}
|
||||
// binding.tvGoodsName.text = item.goodsName
|
||||
// binding.tvMaterialType.text = when (item.materialType) {
|
||||
// 1 -> "主材"
|
||||
// 2 -> "辅材"
|
||||
// else -> "未知"
|
||||
// }
|
||||
}
|
||||
addOnItemChildClickListener(R.id.ivClearIcon) { _, _, position ->
|
||||
val item = list.getOrNull(position) ?: return@addOnItemChildClickListener
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.shuwei.dish.match.R
|
||||
import com.shuwei.dish.match.adapter.TaskDetailAdapter
|
||||
import com.shuwei.dish.match.base.BaseActivity
|
||||
import com.shuwei.dish.match.base.GlobalData
|
||||
import com.shuwei.dish.match.databinding.ActivityTaskDetailBinding
|
||||
import com.shuwei.dish.match.dialog.CommonDialog
|
||||
import com.shuwei.dish.match.dialog.InboundIngredientSearchDialog
|
||||
@@ -152,14 +153,15 @@ class TaskDetailActivity : BaseActivity() {
|
||||
binding.tvStatus.text = getStatusText(it.comboStatus)
|
||||
|
||||
// 仅待组配状态显示"开始组配"按钮
|
||||
if (it.comboStatus == 0) {
|
||||
binding.btnStart.visible()
|
||||
// if (it.comboStatus == 0) {
|
||||
// binding.btnStart.visible()
|
||||
binding.btnStart.clickWithDebounce {
|
||||
startComboTask(it.id ?: return@clickWithDebounce)
|
||||
//val taskId = it.id ?: return@clickWithDebounce
|
||||
startComboTask()
|
||||
}
|
||||
} else {
|
||||
binding.btnStart.gone()
|
||||
}
|
||||
// } else {
|
||||
// binding.btnStart.gone()
|
||||
// }
|
||||
}
|
||||
binding.btnGetTraceCode.clickWithDebounce {
|
||||
val item = itemAdapter.getItem(clickIndex) ?: return@clickWithDebounce
|
||||
@@ -271,13 +273,14 @@ class TaskDetailActivity : BaseActivity() {
|
||||
/**
|
||||
* 开始组配
|
||||
*/
|
||||
private fun startComboTask(taskId: Long) {
|
||||
private fun startComboTask() {
|
||||
val task = taskDetailVO ?: return
|
||||
val count = comboTaskList.count { it.traceCode.isNullOrBlank() }
|
||||
if (count > 0) {
|
||||
toast("存在未设置的溯源码")
|
||||
return
|
||||
}
|
||||
task.deviceCode = GlobalData.deviceId
|
||||
showLoading("正在开始组配……")
|
||||
lifecycleScope.launch {
|
||||
//viewModelV2.startComboTask(taskId)
|
||||
|
||||
@@ -54,58 +54,26 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:background="@drawable/shape_white_30_corners"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="90dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="30dp"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="30sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLength="12"
|
||||
android:textStyle="bold"
|
||||
tools:text="豆腐" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMaterialType"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="26sp"
|
||||
tools:text="主材" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.divider.MaterialDivider
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
app:dividerColor="@color/gray_eb" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvFormList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:overScrollMode="never"/>
|
||||
android:layout_marginVertical="10dp"
|
||||
android:overScrollMode="never" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.divider.MaterialDivider
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
app:dividerColor="@color/gray_eb" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/shape_white_30_corners"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -165,7 +133,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/shape_white_30_corners"
|
||||
android:orientation="vertical">
|
||||
@@ -204,14 +172,14 @@
|
||||
android:id="@+id/btnGetTraceCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:text="获取溯源码"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:background="@drawable/ripple_effect_light"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:text="获取溯源码"
|
||||
android:textColor="@color/dish_green"
|
||||
android:background="@drawable/ripple_effect_light"/>
|
||||
android:textSize="18sp" />
|
||||
|
||||
|
||||
<FrameLayout
|
||||
|
||||
@@ -265,10 +265,10 @@
|
||||
android:background="@drawable/shape_green_bg"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:text="开始组配"
|
||||
android:text="完成组配"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
android:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
Reference in New Issue
Block a user