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 android.net.Uri
|
||||||
import com.sw.inbound.model.response.DictType
|
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.SupplierOption
|
||||||
import com.sw.inbound.model.response.User
|
import com.sw.inbound.model.response.User
|
||||||
import com.sw.inbound.model.response.ZoneOption
|
import com.sw.inbound.model.response.ZoneOption
|
||||||
@@ -52,6 +53,11 @@ object GlobalData {
|
|||||||
*/
|
*/
|
||||||
var inboundZoneList: List<ZoneOption> = emptyList()
|
var inboundZoneList: List<ZoneOption> = emptyList()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 规格
|
||||||
|
*/
|
||||||
|
var specOptionList: List<SpecOption> = emptyList()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 具体业务 BaseUrl
|
* 具体业务 BaseUrl
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class StoreActivity : GoodsListActivity() {
|
|||||||
private fun preloadInboundOptions() {
|
private fun preloadInboundOptions() {
|
||||||
storeViewModel.loadSupplierOptions(callback = { GlobalData.inboundSupplierList = it })
|
storeViewModel.loadSupplierOptions(callback = { GlobalData.inboundSupplierList = it })
|
||||||
storeViewModel.loadZoneOptions(callback = { GlobalData.inboundZoneList = it })
|
storeViewModel.loadZoneOptions(callback = { GlobalData.inboundZoneList = it })
|
||||||
|
storeViewModel.loadSpecOptions(callback = { GlobalData.specOptionList = it })
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 隐藏采购单列表、仓库下拉、提交按钮等本页面不需要的控件 */
|
/** 隐藏采购单列表、仓库下拉、提交按钮等本页面不需要的控件 */
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class InboundGoodsStoreDialog(
|
|||||||
FieldType.TEXT,
|
FieldType.TEXT,
|
||||||
apiKey = "materialName",
|
apiKey = "materialName",
|
||||||
required = true,
|
required = true,
|
||||||
value = goods?.materName ?:"",
|
value = goods?.materName ?: "",
|
||||||
hint = "请输入食材名称"
|
hint = "请输入食材名称"
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
@@ -164,6 +164,12 @@ class InboundGoodsStoreDialog(
|
|||||||
val id = zone.id?.toString() ?: return@mapNotNull null
|
val id = zone.id?.toString() ?: return@mapNotNull null
|
||||||
DictType(id = id, value = zone.zoneName)
|
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(
|
return mutableListOf(
|
||||||
FormField(
|
FormField(
|
||||||
"溯源码",
|
"溯源码",
|
||||||
@@ -188,10 +194,11 @@ class InboundGoodsStoreDialog(
|
|||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"入库规格",
|
"入库规格",
|
||||||
FieldType.TEXT,
|
FieldType.DROPDOWN,
|
||||||
apiKey = "spec",
|
extraApiKeys = mapOf("spec" to "id", "spec_dictText" to "value"),
|
||||||
required = true,
|
required = true,
|
||||||
hint = "请输入入库规格"
|
hint = "请选择入库规格",
|
||||||
|
options = specOptions
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"入库数量",
|
"入库数量",
|
||||||
@@ -323,7 +330,7 @@ class InboundGoodsStoreDialog(
|
|||||||
val param = buildParamMap()
|
val param = buildParamMap()
|
||||||
// weight 来自秤,不在表单中,额外注入
|
// weight 来自秤,不在表单中,额外注入
|
||||||
param["weight"] = realWeight / 1000.0
|
param["weight"] = realWeight / 1000.0
|
||||||
param["materId"] = goods?.materId ?:""
|
param["materId"] = goods?.materId ?: ""
|
||||||
Loading.show(storeActivity ?: return)
|
Loading.show(storeActivity ?: return)
|
||||||
storeActivity?.storeViewModel?.submitRawInbound(param) { success, msg ->
|
storeActivity?.storeViewModel?.submitRawInbound(param) { success, msg ->
|
||||||
Loading.dismiss()
|
Loading.dismiss()
|
||||||
@@ -344,7 +351,7 @@ class InboundGoodsStoreDialog(
|
|||||||
// inboundTime 净菜取当前时间,不在表单中
|
// inboundTime 净菜取当前时间,不在表单中
|
||||||
val inboundTime = isoFormat.format(Date())
|
val inboundTime = isoFormat.format(Date())
|
||||||
param["inboundTime"] = inboundTime
|
param["inboundTime"] = inboundTime
|
||||||
param["materId"] = goods?.materId ?:""
|
param["materId"] = goods?.materId ?: ""
|
||||||
|
|
||||||
val expiryDate = param["expiryDate"] as? String
|
val expiryDate = param["expiryDate"] as? String
|
||||||
param["expiryDate"] = expiryDate + " " + inboundTime.split(" ").getOrNull(1)
|
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
|
package com.sw.inbound.network.api
|
||||||
|
|
||||||
import com.sw.inbound.GlobalData
|
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.IngredientByTrace
|
||||||
import com.sw.inbound.model.response.InboundApiResponse
|
import com.sw.inbound.model.response.InboundApiResponse
|
||||||
import com.sw.inbound.model.response.SupplierOption
|
import com.sw.inbound.model.response.SupplierOption
|
||||||
@@ -41,6 +42,13 @@ interface InboundApiService {
|
|||||||
@Query("keyword") keyword: String? = null
|
@Query("keyword") keyword: String? = null
|
||||||
): InboundApiResponse<List<SupplierOption>>
|
): 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 以便动态组装字段 */
|
/** 毛菜入库提交,入参为 Map 以便动态组装字段 */
|
||||||
@POST
|
@POST
|
||||||
suspend fun submitRawInbound(
|
suspend fun submitRawInbound(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.sw.inbound.repository
|
|||||||
import com.google.gson.JsonParseException
|
import com.google.gson.JsonParseException
|
||||||
import com.sw.inbound.model.response.IngredientByTrace
|
import com.sw.inbound.model.response.IngredientByTrace
|
||||||
import com.sw.inbound.model.response.InboundApiResponse
|
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.SupplierOption
|
||||||
import com.sw.inbound.model.response.ZoneOption
|
import com.sw.inbound.model.response.ZoneOption
|
||||||
import com.sw.inbound.network.api.InboundApiService
|
import com.sw.inbound.network.api.InboundApiService
|
||||||
@@ -43,6 +44,11 @@ class InboundRepository @Inject constructor(
|
|||||||
return safeCall { apiService.getSupplierOptions(type = type, keyword = keyword) }
|
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> {
|
suspend fun submitRawInbound(param: Map<String, Any>): InboundApiResponse<Unit> {
|
||||||
return safeCall { apiService.submitRawInbound(param = param) }
|
return safeCall { apiService.submitRawInbound(param = param) }
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.sw.inbound.viewmodel
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sw.inbound.model.response.IngredientByTrace
|
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.SupplierOption
|
||||||
import com.sw.inbound.model.response.ZoneOption
|
import com.sw.inbound.model.response.ZoneOption
|
||||||
import com.sw.inbound.repository.InboundRepository
|
import com.sw.inbound.repository.InboundRepository
|
||||||
@@ -24,6 +25,9 @@ class StoreViewModel @Inject constructor(
|
|||||||
private val _supplierOptions = MutableStateFlow<List<SupplierOption>>(emptyList())
|
private val _supplierOptions = MutableStateFlow<List<SupplierOption>>(emptyList())
|
||||||
val supplierOptions: StateFlow<List<SupplierOption>> = _supplierOptions
|
val supplierOptions: StateFlow<List<SupplierOption>> = _supplierOptions
|
||||||
|
|
||||||
|
private val _specOptions = MutableStateFlow<List<SpecOption>>(emptyList())
|
||||||
|
val specOptions: StateFlow<List<SpecOption>> = _specOptions
|
||||||
|
|
||||||
/** 按溯源码查食材,结果通过 callback 返回 */
|
/** 按溯源码查食材,结果通过 callback 返回 */
|
||||||
fun getIngredientByTrace(
|
fun getIngredientByTrace(
|
||||||
traceCode: String,
|
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) {
|
fun submitRawInbound(param: Map<String, Any>, callback: (Boolean, String?) -> Unit) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|||||||
Reference in New Issue
Block a user