feat(inbound): 添加规格下拉选择功能
- 新增 SpecOption 数据模型定义 - 在 GlobalData 中添加 specOptionList 全局变量 - 实现 InboundApiService 中的 getSpecOptions 接口 - 添加 InboundRepository 中的 getSpecOptions 方法 - 在 StoreViewModel 中添加 specOptions 相关状态管理 - 在 StoreActivity 预加载规格选项数据 - 将入库规格字段从文本框改为下拉选择框 - 修复代码中的空字符串初始化问题
This commit is contained in:
@@ -2,6 +2,7 @@ package com.sw.inbound
|
||||
|
||||
import android.net.Uri
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.model.response.SpecOption
|
||||
import com.sw.inbound.model.response.SupplierOption
|
||||
import com.sw.inbound.model.response.User
|
||||
import com.sw.inbound.model.response.ZoneOption
|
||||
@@ -52,6 +53,11 @@ object GlobalData {
|
||||
*/
|
||||
var inboundZoneList: List<ZoneOption> = emptyList()
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
var specOptionList: List<SpecOption> = emptyList()
|
||||
|
||||
/**
|
||||
* 具体业务 BaseUrl
|
||||
*/
|
||||
|
||||
@@ -51,6 +51,7 @@ class StoreActivity : GoodsListActivity() {
|
||||
private fun preloadInboundOptions() {
|
||||
storeViewModel.loadSupplierOptions(callback = { GlobalData.inboundSupplierList = it })
|
||||
storeViewModel.loadZoneOptions(callback = { GlobalData.inboundZoneList = it })
|
||||
storeViewModel.loadSpecOptions(callback = { GlobalData.specOptionList = it })
|
||||
}
|
||||
|
||||
/** 隐藏采购单列表、仓库下拉、提交按钮等本页面不需要的控件 */
|
||||
|
||||
@@ -105,7 +105,7 @@ class InboundGoodsStoreDialog(
|
||||
FieldType.TEXT,
|
||||
apiKey = "materialName",
|
||||
required = true,
|
||||
value = goods?.materName ?:"",
|
||||
value = goods?.materName ?: "",
|
||||
hint = "请输入食材名称"
|
||||
),
|
||||
FormField(
|
||||
@@ -164,6 +164,12 @@ class InboundGoodsStoreDialog(
|
||||
val id = zone.id?.toString() ?: return@mapNotNull null
|
||||
DictType(id = id, value = zone.zoneName)
|
||||
}
|
||||
val specOptions = GlobalData.specOptionList.mapNotNull { spec ->
|
||||
if (spec.dictCode.isNullOrEmpty() || spec.dictLabel.isNullOrEmpty()) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
DictType(id = spec.dictCode, value = spec.dictLabel)
|
||||
}
|
||||
return mutableListOf(
|
||||
FormField(
|
||||
"溯源码",
|
||||
@@ -188,10 +194,11 @@ class InboundGoodsStoreDialog(
|
||||
),
|
||||
FormField(
|
||||
"入库规格",
|
||||
FieldType.TEXT,
|
||||
apiKey = "spec",
|
||||
FieldType.DROPDOWN,
|
||||
extraApiKeys = mapOf("spec" to "id", "spec_dictText" to "value"),
|
||||
required = true,
|
||||
hint = "请输入入库规格"
|
||||
hint = "请选择入库规格",
|
||||
options = specOptions
|
||||
),
|
||||
FormField(
|
||||
"入库数量",
|
||||
@@ -323,7 +330,7 @@ class InboundGoodsStoreDialog(
|
||||
val param = buildParamMap()
|
||||
// weight 来自秤,不在表单中,额外注入
|
||||
param["weight"] = realWeight / 1000.0
|
||||
param["materId"] = goods?.materId ?:""
|
||||
param["materId"] = goods?.materId ?: ""
|
||||
Loading.show(storeActivity ?: return)
|
||||
storeActivity?.storeViewModel?.submitRawInbound(param) { success, msg ->
|
||||
Loading.dismiss()
|
||||
@@ -344,7 +351,7 @@ class InboundGoodsStoreDialog(
|
||||
// inboundTime 净菜取当前时间,不在表单中
|
||||
val inboundTime = isoFormat.format(Date())
|
||||
param["inboundTime"] = inboundTime
|
||||
param["materId"] = goods?.materId ?:""
|
||||
param["materId"] = goods?.materId ?: ""
|
||||
|
||||
val expiryDate = param["expiryDate"] as? String
|
||||
param["expiryDate"] = expiryDate + " " + inboundTime.split(" ").getOrNull(1)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.sw.inbound.model.response
|
||||
|
||||
/**
|
||||
* 字典下拉,dictLabel 用于界面展示,dictCode 用于提交入参
|
||||
*/
|
||||
data class SpecOption(
|
||||
var dictLabel:String?,
|
||||
var dictCode:String?,
|
||||
)
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sw.inbound.network.api
|
||||
|
||||
import com.sw.inbound.GlobalData
|
||||
import com.sw.inbound.model.response.SpecOption
|
||||
import com.sw.inbound.model.response.IngredientByTrace
|
||||
import com.sw.inbound.model.response.InboundApiResponse
|
||||
import com.sw.inbound.model.response.SupplierOption
|
||||
@@ -41,6 +42,13 @@ interface InboundApiService {
|
||||
@Query("keyword") keyword: String? = null
|
||||
): InboundApiResponse<List<SupplierOption>>
|
||||
|
||||
/** 规格下拉列表,dictType=nut_spec_type */
|
||||
@GET
|
||||
suspend fun getSpecOptions(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/dict-items",
|
||||
@Query("dictType") dictType: String = "nut_spec_type"
|
||||
): InboundApiResponse<List<SpecOption>?>
|
||||
|
||||
/** 毛菜入库提交,入参为 Map 以便动态组装字段 */
|
||||
@POST
|
||||
suspend fun submitRawInbound(
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.sw.inbound.repository
|
||||
import com.google.gson.JsonParseException
|
||||
import com.sw.inbound.model.response.IngredientByTrace
|
||||
import com.sw.inbound.model.response.InboundApiResponse
|
||||
import com.sw.inbound.model.response.SpecOption
|
||||
import com.sw.inbound.model.response.SupplierOption
|
||||
import com.sw.inbound.model.response.ZoneOption
|
||||
import com.sw.inbound.network.api.InboundApiService
|
||||
@@ -43,6 +44,11 @@ class InboundRepository @Inject constructor(
|
||||
return safeCall { apiService.getSupplierOptions(type = type, keyword = keyword) }
|
||||
}
|
||||
|
||||
/** 规格下拉列表 */
|
||||
suspend fun getSpecOptions(): InboundApiResponse<List<SpecOption>?> {
|
||||
return safeCall { apiService.getSpecOptions() }
|
||||
}
|
||||
|
||||
/** 毛菜入库提交 */
|
||||
suspend fun submitRawInbound(param: Map<String, Any>): InboundApiResponse<Unit> {
|
||||
return safeCall { apiService.submitRawInbound(param = param) }
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.sw.inbound.viewmodel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.sw.inbound.model.response.IngredientByTrace
|
||||
import com.sw.inbound.model.response.SpecOption
|
||||
import com.sw.inbound.model.response.SupplierOption
|
||||
import com.sw.inbound.model.response.ZoneOption
|
||||
import com.sw.inbound.repository.InboundRepository
|
||||
@@ -24,6 +25,9 @@ class StoreViewModel @Inject constructor(
|
||||
private val _supplierOptions = MutableStateFlow<List<SupplierOption>>(emptyList())
|
||||
val supplierOptions: StateFlow<List<SupplierOption>> = _supplierOptions
|
||||
|
||||
private val _specOptions = MutableStateFlow<List<SpecOption>>(emptyList())
|
||||
val specOptions: StateFlow<List<SpecOption>> = _specOptions
|
||||
|
||||
/** 按溯源码查食材,结果通过 callback 返回 */
|
||||
fun getIngredientByTrace(
|
||||
traceCode: String,
|
||||
@@ -78,6 +82,21 @@ class StoreViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/** 加载规格列表,结果同时更新 StateFlow 并通过 callback 返回 */
|
||||
fun loadSpecOptions(callback: ((List<SpecOption>) -> Unit)? = null) {
|
||||
viewModelScope.launch {
|
||||
val response = repository.getSpecOptions()
|
||||
if (response.isSuccess()) {
|
||||
val list = response.data ?: emptyList()
|
||||
_specOptions.value = list
|
||||
callback?.invoke(list)
|
||||
} else {
|
||||
Timber.e("loadSpecOptions failed: ${response.msg}")
|
||||
callback?.invoke(emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 毛菜入库提交 */
|
||||
fun submitRawInbound(param: Map<String, Any>, callback: (Boolean, String?) -> Unit) {
|
||||
viewModelScope.launch {
|
||||
|
||||
Reference in New Issue
Block a user