feat(clean-pack): 实现净菜包装页面功能完善

- 集成称重功能到应用生命周期管理
- 添加全局用户名配置
- 更新测试环境基础URL地址
- 实现表单字段动态加载和回调机制
- 优化设备选项和字典项加载逻辑
- 修复餐品搜索结果显示问题
- 统一字段值映射关系配置
This commit is contained in:
2026-06-01 19:17:32 +08:00
parent 4a2abf6eec
commit a25ee7d987
4 changed files with 73 additions and 109 deletions
@@ -1,15 +1,18 @@
package com.shuwei.dish.match.base
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.os.Bundle
import com.shuwei.dish.match.R
import com.shuwei.dish.match.db.DatabaseProvider
import com.shuwei.dish.match.utils.BootReceiver
import com.shuwei.dish.match.utils.CrashHandler
import com.shuwei.dish.match.utils.SpTool
import com.shuwei.dish.match.utils.WeightUtil
class BaseApp : Application() {
@@ -43,23 +46,23 @@ class BaseApp : Application() {
// ScaleServiceManager.start(this)
//
// // 初始化秤,进程级生命周期管理:最后一个 Activity 销毁时才停止读取
// WeightUtil.init()
// WeightUtil.getWeight()
// WeightUtil.startContinuousRead()
// registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
// private var activityCount = 0
// override fun onActivityCreated(a: Activity, b: Bundle?) { activityCount++ }
// override fun onActivityDestroyed(a: Activity) {
// if (--activityCount <= 0) {
// WeightUtil.stopContinuousRead()
// }
// }
// override fun onActivityStarted(a: Activity) {}
// override fun onActivityResumed(a: Activity) {}
// override fun onActivityPaused(a: Activity) {}
// override fun onActivityStopped(a: Activity) {}
// override fun onActivitySaveInstanceState(a: Activity, b: Bundle) {}
// })
WeightUtil.init()
WeightUtil.getWeight()
WeightUtil.startContinuousRead()
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
private var activityCount = 0
override fun onActivityCreated(a: Activity, b: Bundle?) { activityCount++ }
override fun onActivityDestroyed(a: Activity) {
if (--activityCount <= 0) {
WeightUtil.stopContinuousRead()
}
}
override fun onActivityStarted(a: Activity) {}
override fun onActivityResumed(a: Activity) {}
override fun onActivityPaused(a: Activity) {}
override fun onActivityStopped(a: Activity) {}
override fun onActivitySaveInstanceState(a: Activity, b: Bundle) {}
})
// GlobalData.deviceId = "39a7abdd06b3c7ab"
val filter = IntentFilter(Intent.ACTION_BOOT_COMPLETED)
@@ -13,7 +13,8 @@ object GlobalData {
/**
* 具体业务 BaseUrl
*/
const val TEST_BASE_URL = "http://192.168.1.201:14801"
// const val TEST_BASE_URL = "http://192.168.1.201:14801"
const val TEST_BASE_URL = "http://192.168.10.101:24801"
const val UAT_BASE_URL = "https://dev.yixiong-tech.com:8083"
const val PROD_BASE_URL = "https://api.dm.yixiong-tech.com:8443"
/**
@@ -25,6 +26,8 @@ object GlobalData {
* 当前设备角色,启动时从 SpTool 读取,默认为 SLAVE
*/
var deviceRole: DeviceRole = DeviceRole.SLAVE
var userName = "张三"
}
/**
@@ -39,12 +39,12 @@ class NetViewModelV2(
private val _dictItemsState = MutableStateFlow<UiState<List<NutDictItemVO>?>>(UiState.Idle)
val dictItemsState: StateFlow<UiState<List<NutDictItemVO>?>> = _dictItemsState.asStateFlow()
fun getDictItems(dictType: String) {
viewModelScope.launch {
_dictItemsState.value = UiState.Loading
_dictItemsState.value = repository.getDictItems(dictType)
}
}
// fun getDictItems(dictType: String) {
// viewModelScope.launch {
// _dictItemsState.value = UiState.Loading
// _dictItemsState.value = repository.getDictItems(dictType)
// }
// }
// 食材下拉列表
private val _materOptionsState = MutableStateFlow<UiState<List<NutMaterOptionVO>?>>(UiState.Idle)
@@ -3,9 +3,9 @@ package com.shuwei.dish.match.ui
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.FormFieldAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.GlobalData
import com.shuwei.dish.match.databinding.ActivityCleanPackBinding
import com.shuwei.dish.match.model.DictType
import com.shuwei.dish.match.model.FieldType
@@ -207,8 +207,9 @@ class CleanPackActivity : BaseActivity() {
// 监听溯源码输入,自动填充净菜名称
setupTraceCodeQuery()
// 加载下拉选项
loadDictItems("sup_package_method", packageMethodField!!)
loadDeviceOptions()
// loadDictItems("sup_package_method", packageMethodField!!)
loadDictItemsWithCallback("sup_package_method", packageMethodField!!)
loadDeviceOptionsWithCallback(deviceField)
}
/**
@@ -257,7 +258,13 @@ class CleanPackActivity : BaseActivity() {
// 包含食材(子列表容器)
val ingredientTemplate = listOf(
FormField(label = "食材溯源码", type = FieldType.TEXT, apiKey = "traceCode", required = true, hint = "溯源码"),
FormField(
label = "食材溯源码",
type = FieldType.TEXT,
apiKey = "traceCode",
required = true,
hint = "溯源码"
),
FormField(
label = "食材名称", type = FieldType.DROPDOWN,
extraApiKeys = mapOf("materId" to "id", "ingredientName" to "value"),
@@ -278,7 +285,13 @@ class CleanPackActivity : BaseActivity() {
DictType(id = "3", value = "水产类", type = "水产类"),
)
),
FormField(label = "每份用量", type = FieldType.TEXT, apiKey = "amount", required = true, hint = "如 120g"),
FormField(
label = "每份用量",
type = FieldType.TEXT,
apiKey = "amount",
required = true,
hint = "如 120g"
),
)
fields.add(
FormField(
@@ -316,8 +329,12 @@ class CleanPackActivity : BaseActivity() {
// 包装人
fields.add(
FormField(
label = "包装人", type = FieldType.TEXT,
apiKey = "operator", required = false, hint = "请输入包装人"
label = "包装人",
type = FieldType.FIXED,
apiKey = "operator",
required = false,
hint = "请输入包装人",
value = GlobalData.userName
)
)
@@ -329,16 +346,13 @@ class CleanPackActivity : BaseActivity() {
)
fields.add(deviceField!!)
// 操作类型(下拉
// 操作类型(暂时固定
fields.add(
FormField(
label = "操作类型", type = FieldType.DROPDOWN,
extraApiKeys = mapOf("opType" to "value"),
label = "操作类型", type = FieldType.FIXED,
apiKey = "opType",
required = true,
options = mutableListOf(
DictType(id = "1", value = "1", type = "设备自动"),
DictType(id = "2", value = "2", type = "人工录入"),
)
value = "设备自动"
)
)
@@ -347,7 +361,7 @@ class CleanPackActivity : BaseActivity() {
// 加载下拉选项
loadFoodOptionsWithKeyword()
loadDictItemsWithCallback("sup_package_spec", packagingSpecField!!)
loadDeviceOptionsWithCallbackForMeal()
loadDeviceOptionsWithCallback(deviceField)
}
/**
@@ -382,9 +396,11 @@ class CleanPackActivity : BaseActivity() {
if (idx >= 0) formAdapter.notifyItemChanged(idx)
}
}
is UiState.Error -> {
toast(state.msg)
}
else -> {}
}
}
@@ -409,8 +425,7 @@ class CleanPackActivity : BaseActivity() {
val options = state.data?.records?.map { vo ->
DictType(
id = vo.foodId?.toString() ?: "",
value = vo.foodId?.toString() ?: "",
type = vo.foodName ?: ""
value = vo.foodName ?: ""
)
} ?: emptyList()
field.options.clear()
@@ -418,9 +433,11 @@ class CleanPackActivity : BaseActivity() {
val index = fields.indexOf(field)
if (index >= 0) formAdapter.notifyItemChanged(index)
}
is UiState.Error -> {
toast("加载餐品列表失败:${state.msg}")
}
else -> {}
}
}
@@ -440,8 +457,8 @@ class CleanPackActivity : BaseActivity() {
val options = state.data?.map { vo ->
DictType(
id = vo.id?.toString() ?: "",
value = vo.dictCode ?: "",
type = vo.dictLabel ?: ""
value = vo.dictLabel ?: "",
type = vo.dictCode ?: ""
)
} ?: emptyList()
targetField.options.clear()
@@ -449,9 +466,11 @@ class CleanPackActivity : BaseActivity() {
val index = fields.indexOf(targetField)
if (index >= 0) formAdapter.notifyItemChanged(index)
}
is UiState.Error -> {
toast("加载字典项失败:${state.msg}")
}
else -> {}
}
}
@@ -461,7 +480,7 @@ class CleanPackActivity : BaseActivity() {
/**
* 加载设备下拉(回调版本),用于餐品净菜包装
*/
private fun loadDeviceOptionsWithCallbackForMeal() {
private fun loadDeviceOptionsWithCallback(deviceField: FormField?=null) {
val field = deviceField ?: return
viewModelV2.getDeviceOptionsWithCallback(
onLoading = {},
@@ -471,8 +490,8 @@ class CleanPackActivity : BaseActivity() {
val options = state.data?.map { vo ->
DictType(
id = vo.id?.toString() ?: "",
value = vo.id?.toString() ?: "",
type = "${vo.deviceName ?: ""}(${vo.deviceNo ?: ""})"
value = vo.deviceName ?: "",
type = vo.deviceNo ?: ""
)
} ?: emptyList()
field.options.clear()
@@ -480,76 +499,15 @@ class CleanPackActivity : BaseActivity() {
val index = fields.indexOf(field)
if (index >= 0) formAdapter.notifyItemChanged(index)
}
is UiState.Error -> {
toast("加载设备列表失败:${state.msg}")
}
else -> {}
}
}
)
}
/**
* 加载字典项下拉选项
* @param dictType 字典类型编码
* @param targetField 目标字段
*/
private fun loadDictItems(dictType: String, targetField: FormField) {
viewModelV2.getDictItems(dictType)
lifecycleScope.launch {
viewModelV2.dictItemsState.collect { state ->
when (state) {
is UiState.Success -> {
val options = state.data?.map { vo ->
DictType(
id = vo.id?.toString() ?: "",
value = vo.dictCode ?: "",
type = vo.dictLabel ?: ""
)
} ?: emptyList()
targetField.options.clear()
targetField.options.addAll(options)
val index = fields.indexOf(targetField)
if (index >= 0) formAdapter.notifyItemChanged(index)
}
is UiState.Error -> {
toast("加载字典项失败:${state.msg}")
}
else -> {}
}
}
}
}
/**
* 加载设备下拉选项
*/
private fun loadDeviceOptions() {
viewModelV2.getDeviceOptions()
val field = deviceField ?: return
lifecycleScope.launch {
viewModelV2.deviceOptionsState.collect { state ->
when (state) {
is UiState.Success -> {
val options = state.data?.map { vo ->
DictType(
id = vo.id?.toString() ?: "",
value = vo.id?.toString() ?: "",
type = "${vo.deviceName ?: ""}(${vo.deviceNo ?: ""})"
)
} ?: emptyList()
field.options.clear()
field.options.addAll(options)
val index = fields.indexOf(field)
if (index >= 0) formAdapter.notifyItemChanged(index)
}
is UiState.Error -> {
toast("加载设备列表失败:${state.msg}")
}
else -> {}
}
}
}
}
/**