feat(inbound): 新增入库秤毛菜/净材入库功能
- 新增入库专用网络层(InboundApiService、InboundRepository、InboundNetworkModule、InboundInterceptor) - 新增入库相关数据模型(IngredientByTrace、SupplierOption、ZoneOption、GoodsSearchModel、CleanInboundParam、RawInboundParam、InboundApiResponse) - 新增 FormField 动态表单模型(FieldType 枚举、apiKey 字段映射、submitValueId 控制提交值) - 新增 FormFieldAdapter,基于 FlexboxLayoutManager 实现两列自动换行表单,支持五种字段类型 - 新增 InboundGoodsSearchDialog(溯源码检索食材)和 InboundGoodsStoreDialog(入库录入,表单转 Map 提交) - 新增 StoreViewModel,提交接口入参改为 Map<String, Any> - 重构 StoreActivity:注入 StoreViewModel,onResume 预加载供应商/区域列表到 GlobalData - 修改 GoodsListActivity:抽取 onGoodsSearchRequested() 供子类重写 - 修改 GoodsRecognizeDialog:StoreActivity 场景下打开 InboundGoodsStoreDialog - GlobalData 新增 inboundSupplierList / inboundZoneList 全局缓存 - build.gradle.kts 新增 flexbox:3.0.0 依赖 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.sw.inbound.activity.StoreActivity
|
||||
import com.sw.inbound.adapter.InboundSearchAdapter
|
||||
import com.sw.inbound.databinding.DialogInboundGoodsSearchBinding
|
||||
import com.sw.inbound.databinding.LayoutEmptySearchBinding
|
||||
import com.sw.inbound.model.response.GoodsSearchModel
|
||||
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
||||
import com.sw.inbound.utils.ext.hideKeyboard
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
|
||||
/** 入库物品检索弹窗,使用溯源码查询食材,供 StoreActivity 使用 */
|
||||
class InboundGoodsSearchDialog(
|
||||
context: Context
|
||||
) : BaseDialog(context) {
|
||||
|
||||
private lateinit var inflater: LayoutInflater
|
||||
private var emptyBinding: LayoutEmptySearchBinding? = null
|
||||
private lateinit var binding: DialogInboundGoodsSearchBinding
|
||||
|
||||
override fun getRootView(): View {
|
||||
inflater = LayoutInflater.from(context)
|
||||
binding = DialogInboundGoodsSearchBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private var storeActivity: StoreActivity? = null
|
||||
|
||||
override fun initView() {
|
||||
storeActivity = getReceiptActivity() as? StoreActivity
|
||||
binding.ivClose.setOnClickListener { dismiss() }
|
||||
binding.ivGoodsSearch.setOnClickListener { searchGoods() }
|
||||
binding.etInputGoods.addOnActionSearchListener { searchGoods() }
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
if (list.isEmpty()) {
|
||||
context.toast("请搜索物品")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (clickIndex == -1) {
|
||||
context.toast("请选择物品")
|
||||
return@setOnClickListener
|
||||
}
|
||||
InboundGoodsStoreDialog(
|
||||
context = context,
|
||||
goods = list[clickIndex]
|
||||
) {
|
||||
storeActivity?.goodsRecognizeDialog?.dismiss()
|
||||
dismiss()
|
||||
}.show()
|
||||
}
|
||||
binding.rvSearch.let {
|
||||
it.layoutManager = GridLayoutManager(context, 2, LinearLayoutManager.VERTICAL, false)
|
||||
it.adapter = searchAdapter
|
||||
}
|
||||
binding.refreshLayout.let {
|
||||
it.setEnableRefresh(false)
|
||||
it.setEnableLoadMore(false)
|
||||
}
|
||||
loadEmptyView()
|
||||
}
|
||||
|
||||
private fun searchGoods() {
|
||||
val traceCode = binding.etInputGoods.text.toString().trim()
|
||||
if (traceCode.isBlank()) {
|
||||
context.toast("请输入溯源码")
|
||||
return
|
||||
}
|
||||
storeActivity?.storeViewModel?.getIngredientByTrace(traceCode) { items ->
|
||||
binding.etInputGoods.hideKeyboard()
|
||||
val models = items.map { GoodsSearchModel.from(it) }
|
||||
if (models.isEmpty()) {
|
||||
loadEmptyView()
|
||||
searchAdapter.submitList(emptyList())
|
||||
return@getIngredientByTrace
|
||||
}
|
||||
list.clear()
|
||||
list.addAll(models)
|
||||
binding.rvSearch.layoutManager =
|
||||
GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, false)
|
||||
searchAdapter.submitList(list.toList())
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadEmptyView() {
|
||||
binding.rvSearch.layoutManager =
|
||||
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
if (emptyBinding == null) {
|
||||
emptyBinding = LayoutEmptySearchBinding.inflate(inflater, binding.rvSearch, false)
|
||||
}
|
||||
emptyBinding?.root?.let { layout ->
|
||||
layout.setOnClickListener { layout.hideKeyboard() }
|
||||
searchAdapter.stateView = layout
|
||||
}
|
||||
}
|
||||
|
||||
private var clickIndex = -1
|
||||
private val list: MutableList<GoodsSearchModel> = mutableListOf()
|
||||
|
||||
private val searchAdapter by lazy {
|
||||
InboundSearchAdapter().apply {
|
||||
isStateViewEnable = true
|
||||
setOnItemClickListener { _, _, position ->
|
||||
clickIndex = position
|
||||
if (list[position].isSelected) return@setOnItemClickListener
|
||||
list.forEach { it.isSelected = false }
|
||||
list[position].isSelected = true
|
||||
submitList(list.toList())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user