This commit is contained in:
2025-11-27 17:17:17 +08:00
parent 29b1875fa5
commit 0fbb9c3704
32 changed files with 1156 additions and 4 deletions

View File

@@ -0,0 +1,20 @@
package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.databinding.ItemAssembleInfoBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.AssembleInfoBean
/**
* 组装信息ViewHolder
*/
class AssembleInfoViewHolder(view: View) :
BaseViewHolder<AssembleInfoBean, ItemAssembleInfoBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
binding.executePendingBindings()
}
}

View File

@@ -0,0 +1,26 @@
package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.databinding.ItemAssemblePositionBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.AssemblePositionBean
/**
* 组装位置ViewHolder
*/
class AssemblePositionViewHolder(view: View) :
BaseViewHolder<AssemblePositionBean, ItemAssemblePositionBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
// 点击选择位置
itemView.setOnClickListener {
clickListener?.onItemClick(position, 0)
}
binding.executePendingBindings()
}
}

View File

@@ -0,0 +1,26 @@
package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.databinding.ItemAssembleWaybillBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.AssembleWaybillBean
/**
* 运单列表ViewHolder
*/
class AssembleWaybillViewHolder(view: View) :
BaseViewHolder<AssembleWaybillBean, ItemAssembleWaybillBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
// 点击运单
itemView.setOnClickListener {
clickListener?.onItemClick(position, 0)
}
binding.executePendingBindings()
}
}

View File

@@ -32,6 +32,12 @@ class IntExpAssembleViewHolder(view: View) :
// 更新展开状态(初次绑定不需要动画)
updateExpandState(bean, animate = false)
// 点击整个item切换选中状态
binding.root.setOnClickListener {
bean.isSelected = !bean.isSelected
binding.bean = bean // 触发DataBinding更新
}
// 展开按钮点击事件
binding.btnExpand.setOnClickListener {
clickListener?.onItemClick(position, 1000) // type=1000表示展开操作

View File

@@ -0,0 +1,100 @@
package com.lukouguoji.gjc.page.assemble
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityIntExpAssembleStartBinding
import com.lukouguoji.gjc.viewModel.IntExpAssembleStartViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.base.CommonAdapter
import com.lukouguoji.module_base.router.ARouterConstants
/**
* 国际出港-开始组装页面
*/
@Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_ASSEMBLE_START)
class IntExpAssembleStartActivity :
BaseBindingActivity<ActivityIntExpAssembleStartBinding, IntExpAssembleStartViewModel>() {
private var assembleInfoAdapter: CommonAdapter? = null
private var assemblePositionAdapter: CommonAdapter? = null
private var waybillAdapter: CommonAdapter? = null
companion object {
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, IntExpAssembleStartActivity::class.java)
context.startActivity(starter)
}
}
override fun layoutId() = R.layout.activity_int_exp_assemble_start
override fun viewModelClass() = IntExpAssembleStartViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("开始组装")
binding.viewModel = viewModel
// 初始化列表
initRecyclerViews()
// 加载模拟数据
viewModel.initMockData()
// 观察数据变化
observeData()
}
/**
* 初始化RecyclerView
*/
private fun initRecyclerViews() {
// 左侧组装信息列表
assembleInfoAdapter = CommonAdapter(
this,
viewModel.assembleInfoLayoutId,
viewModel.assembleInfoViewHolder
)
binding.rvAssembleInfo.layoutManager = LinearLayoutManager(this)
binding.rvAssembleInfo.adapter = assembleInfoAdapter
// 左侧组装位置列表
assemblePositionAdapter = CommonAdapter(
this,
viewModel.assemblePositionLayoutId,
viewModel.assemblePositionViewHolder
)
binding.rvAssemblePosition.layoutManager = LinearLayoutManager(this)
binding.rvAssemblePosition.adapter = assemblePositionAdapter
// 右侧运单列表
waybillAdapter = CommonAdapter(
this,
viewModel.waybillLayoutId,
viewModel.waybillViewHolder
)
binding.rvWaybillList.layoutManager = LinearLayoutManager(this)
binding.rvWaybillList.adapter = waybillAdapter
}
/**
* 观察数据变化
*/
private fun observeData() {
viewModel.assembleInfoList.observe(this) { list ->
assembleInfoAdapter?.refresh(list)
}
viewModel.assemblePositionList.observe(this) { list ->
assemblePositionAdapter?.refresh(list)
}
viewModel.waybillList.observe(this) { list ->
waybillAdapter?.refresh(list)
}
}
}

View File

@@ -0,0 +1,138 @@
package com.lukouguoji.gjc.viewModel
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.holder.AssembleInfoViewHolder
import com.lukouguoji.gjc.holder.AssemblePositionViewHolder
import com.lukouguoji.gjc.holder.AssembleWaybillViewHolder
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.*
import com.lukouguoji.module_base.ktx.showToast
/**
* 国际出港-开始组装ViewModel静态数据
*/
class IntExpAssembleStartViewModel : BaseViewModel() {
// ========== 搜索条件 ==========
val searchWaybillNo = MutableLiveData("")
// ========== 左侧组装信息列表 ==========
val assembleInfoList = MutableLiveData<MutableList<AssembleInfoBean>>()
val assembleInfoLayoutId = R.layout.item_assemble_info
val assembleInfoViewHolder = AssembleInfoViewHolder::class.java
// ========== 左侧组装位置列表 ==========
val assemblePositionList = MutableLiveData<MutableList<AssemblePositionBean>>()
val assemblePositionLayoutId = R.layout.item_assemble_position
val assemblePositionViewHolder = AssemblePositionViewHolder::class.java
// ========== 右侧运单列表 ==========
val waybillList = MutableLiveData<MutableList<AssembleWaybillBean>>()
val waybillLayoutId = R.layout.item_assemble_waybill
val waybillViewHolder = AssembleWaybillViewHolder::class.java
// ========== ULD信息 ==========
val uldInfo = MutableLiveData(UldInfoBean().apply {
uldNo = "AKE12345HK"
planeType = "B777"
weightLimit = "1500"
totalPieces = "120"
totalWeight = "2450.5"
status = "进行中"
})
// ========== 运单信息 ==========
val waybillInfo = MutableLiveData(WaybillInfoBean().apply {
waybillNo = "99912345678"
pieces = "25"
weight = "350.5"
destination = "LAX"
specialCode = "GEN"
goodsName = "ELECTRONICS"
})
/**
* 初始化模拟数据
*/
fun initMockData() {
// 组装信息列表(左侧)
assembleInfoList.value = mutableListOf(
AssembleInfoBean().apply {
waybillNo = "99912345678"
pieces = "25"
},
AssembleInfoBean().apply {
waybillNo = "99912345679"
pieces = "18"
},
AssembleInfoBean().apply {
waybillNo = "99912345680"
pieces = "32"
},
AssembleInfoBean().apply {
waybillNo = "99912345681"
pieces = "15"
}
)
// 组装位置列表(左侧)
assemblePositionList.value = mutableListOf(
AssemblePositionBean().apply {
positionName = "A区-01号位"
isSelected = true
},
AssemblePositionBean().apply {
positionName = "A区-02号位"
isSelected = false
},
AssemblePositionBean().apply {
positionName = "B区-01号位"
isSelected = false
}
)
// 运单列表(右侧)
waybillList.value = mutableListOf(
AssembleWaybillBean().apply {
waybillNo = "99912345678"
pieces = "25"
weight = "350.5"
isMarked = false
},
AssembleWaybillBean().apply {
waybillNo = "99912345679"
pieces = "18"
weight = "280.0"
isMarked = true // 标记为红色
},
AssembleWaybillBean().apply {
waybillNo = "99912345680"
pieces = "32"
weight = "520.8"
isMarked = false
}
)
}
/**
* 扫码运单
*/
fun scanWaybill() {
showToast("扫码功能(静态页面暂不实现)")
}
/**
* 卸货按钮点击
*/
fun onUnloadClick() {
showToast("卸货操作(静态页面暂不实现)")
}
/**
* 装货按钮点击
*/
fun onLoadClick() {
showToast("装货操作(静态页面暂不实现)")
}
}

View File

@@ -1,7 +1,11 @@
package com.lukouguoji.gjc.viewModel
import android.text.InputType
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.alibaba.android.arouter.launcher.ARouter
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.holder.IntExpAssembleViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel
@@ -12,6 +16,8 @@ import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.router.ARouterConstants
import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch
@@ -129,4 +135,119 @@ class IntExpAssembleViewModel : BasePageViewModel() {
toggleExpand(position)
}
}
/**
* 加号按钮点击 - 跳转到开始组装页面
*/
fun onAddClick() {
ARouter.getInstance()
.build(ARouterConstants.ACTIVITY_URL_INT_EXP_ASSEMBLE_START)
.navigation()
}
/**
* 删除按钮点击
*/
fun onDeleteClick() {
// 获取选中的数据
val adapter = pageModel.rv?.commonAdapter() ?: return
val allItems = adapter.items
val selectedItems = allItems
.filterIsInstance<GjcUldUseBean>()
.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要删除的记录")
return
}
// 显示确认对话框
val activity = getTopActivity()
AlertDialog.Builder(activity)
.setTitle("删除确认")
.setMessage("确定要删除选中的 ${selectedItems.size} 条记录吗?")
.setPositiveButton("删除") { _, _ ->
deleteSelectedItems(selectedItems)
}
.setNegativeButton("取消", null)
.show()
}
/**
* 删除选中项
*/
private fun deleteSelectedItems(items: List<GjcUldUseBean>) {
val ids = items.mapNotNull { it.useId }.joinToString(",")
launchLoadingCollect({ NetApply.api.deleteIntExpAssemble(ids) }) {
onSuccess = {
showToast("删除成功")
refresh()
}
}
}
/**
* 回填重量按钮点击
*/
fun onBackfillWeightClick() {
// 获取选中的数据
val adapter = pageModel.rv?.commonAdapter() ?: return
val allItems = adapter.items
val selectedItems = allItems
.filterIsInstance<GjcUldUseBean>()
.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要回填重量的记录")
return
}
// 显示输入对话框
showBackfillWeightDialog(selectedItems)
}
/**
* 显示回填重量对话框
*/
private fun showBackfillWeightDialog(items: List<GjcUldUseBean>) {
val activity = getTopActivity()
// 创建输入框
val input = EditText(activity).apply {
hint = "请输入重量(KG)"
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
setPadding(40, 40, 40, 40)
}
AlertDialog.Builder(activity)
.setTitle("回填重量")
.setMessage("共选中 ${items.size} 条记录")
.setView(input)
.setPositiveButton("确定") { _, _ ->
val weight = input.text.toString()
if (weight.verifyNullOrEmpty("请输入重量")) return@setPositiveButton
backfillWeight(items, weight)
}
.setNegativeButton("取消", null)
.show()
}
/**
* 回填重量API调用
*/
private fun backfillWeight(items: List<GjcUldUseBean>, weight: String) {
val ids = items.mapNotNull { it.useId }.joinToString(",")
val params = mapOf(
"ids" to ids,
"weight" to weight
).toRequestBody()
launchLoadingCollect({ NetApply.api.backfillIntExpAssembleWeight(params) }) {
onSuccess = {
showToast("回填重量成功")
refresh()
}
}
}
}