feat: 国际进港舱单添加分单子列表展开/收起功能

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 15:05:36 +08:00
parent a1c53dd9fe
commit 7413a8d159
9 changed files with 763 additions and 291 deletions

View File

@@ -0,0 +1,36 @@
package com.lukouguoji.gjj.holder
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.gjj.databinding.ItemIntImpManifestSubBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjHaWb
import com.lukouguoji.module_base.bean.GjjManifest
/**
* 国际进港舱单 - 分单子列表 ViewHolder
*/
class IntImpManifestSubViewHolder(view: View) :
BaseViewHolder<GjjHaWb, ItemIntImpManifestSubBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
binding.executePendingBindings()
// 单选框点击切换选择状态
binding.ivCheckbox.setOnClickListener {
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
binding.executePendingBindings()
// 反向联动主列表项(勾选子项时自动勾选父项)
if (newCheckedState) {
val recyclerView = itemView.parent as? RecyclerView ?: return@setOnClickListener
val parentBean = recyclerView.tag as? GjjManifest ?: return@setOnClickListener
parentBean.checked.set(true)
}
}
}
}

View File

@@ -1,9 +1,12 @@
package com.lukouguoji.gjj.holder
import android.view.View
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ItemIntImpManifestBinding
import com.lukouguoji.module_base.adapter.setCommonAdapter
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.ktx.refresh
/**
* 国际进港舱单 ViewHolder
@@ -17,10 +20,14 @@ class IntImpManifestViewHolder(view: View) :
binding.position = position
binding.executePendingBindings()
// 选中图标点击 - 切换选择状态
// 选中图标点击 - 切换选择状态(联动子列表)
binding.ivIcon.setOnClickListener {
bean.checked.set(!bean.checked.get())
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
// 联动子列表选中状态
bean.haWbList?.forEach { sub -> sub.checked.set(newCheckedState) }
binding.executePendingBindings()
binding.rvSub.adapter?.notifyDataSetChanged()
}
// 编辑按钮点击
@@ -32,5 +39,21 @@ class IntImpManifestViewHolder(view: View) :
binding.btnDelete.setOnClickListener {
clickListener?.onItemClick(position, 102) // 102=删除
}
// 展开按钮点击事件
binding.ivShow.setOnClickListener {
bean.showMore.set(!bean.showMore.get())
}
// 初始化分单子列表 RecyclerView
setCommonAdapter(
binding.rvSub,
IntImpManifestSubViewHolder::class.java,
R.layout.item_int_imp_manifest_sub
)
// 设置父Bean引用(用于子列表反向联动)
binding.rvSub.tag = bean
binding.rvSub.refresh(bean.haWbList ?: emptyList())
}
}

View File

@@ -37,6 +37,70 @@ class IntImpManifestViewModel : BasePageViewModel() {
val fdep = MutableLiveData("") // 目的站
val waybillNo = MutableLiveData("") // 运单号
// ========== 航班级联查询 ==========
private var lastQueriedFlight = ""
private var fid = ""
fun onFlightDateInputComplete() {
lastQueriedFlight = ""
queryFlightIfReady()
}
fun onFlightNoInputComplete() {
queryFlightIfReady()
}
private fun queryFlightIfReady() {
val fdate = flightDate.value
val fno = flightNo.value
if (fdate.isNullOrEmpty() || fno.isNullOrEmpty()) return
val key = "$fdate-$fno"
if (key == lastQueriedFlight) return
lastQueriedFlight = key
launchCollect({
NetApply.api.getGjFlightBean(
mapOf(
"fdate" to fdate,
"fno" to fno,
"ieFlag" to "I",
).toRequestBody()
)
}) {
onSuccess = {
if (it.verifySuccess() && it.data != null) {
val flight = it.data!!
fid = flight.fid.noNull()
fdep.value = flight.fdest.noNull()
// 构建始发站下拉列表:fdep + jtz(经停港)
val list = mutableListOf(
KeyValue(flight.fdep.noNull(), flight.fdep.noNull()),
)
if (!flight.jtz.isNullOrEmpty()) {
list.add(KeyValue(flight.jtz.noNull(), flight.jtz.noNull()))
}
sendAddressList.value = list
sendAddress.value = flight.fdep.noNull()
} else {
fid = ""
fdep.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
showToast(it.msg.noNull("获取航班信息失败"))
}
}
onFailed = { _, _ ->
fid = ""
fdep.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
}
}
}
// ========== 统计信息 ==========
val totalCount = MutableLiveData("0") // 合计票数
val totalPc = MutableLiveData("0") // 总件数
@@ -45,11 +109,17 @@ class IntImpManifestViewModel : BasePageViewModel() {
// ========== 全选状态 ==========
val isAllChecked = MutableLiveData(false)
// ========== 展开/收起 ==========
val isAllExpanded = MutableLiveData(false)
init {
// 监听全选状态,自动更新所有列表项
// 监听全选状态,自动更新所有列表项(联动子列表)
isAllChecked.observeForever { checked ->
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return@observeForever
list.forEach { it.checked.set(checked) }
list.forEach {
it.checked.set(checked)
it.haWbList?.forEach { sub -> sub.checked.set(checked) }
}
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
}
@@ -66,19 +136,37 @@ class IntImpManifestViewModel : BasePageViewModel() {
}
/**
* 全选按钮点击(切换全选状态)
* 全选按钮点击(切换全选状态,联动子列表)
*/
fun checkAllClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
// 切换全选状态
val shouldCheckAll = !isAllChecked.value!!
list.forEach { it.checked.set(shouldCheckAll) }
list.forEach {
it.checked.set(shouldCheckAll)
it.haWbList?.forEach { sub -> sub.checked.set(shouldCheckAll) }
}
isAllChecked.value = shouldCheckAll
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
/**
* 全部展开/收起
*/
fun toggleAllExpand() {
val shouldExpand = !isAllExpanded.value!!
isAllExpanded.value = shouldExpand
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
list.forEach {
if (!it.haWbList.isNullOrEmpty()) {
it.showMore.set(shouldExpand)
}
}
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
/**
* 扫码运单号
*/
@@ -90,25 +178,14 @@ class IntImpManifestViewModel : BasePageViewModel() {
* 新增按钮点击
*/
fun onAddClick() {
// 获取当前航班信息
val fid = getCurrentFlightId()
GjjManifestAddActivity.start(
context = getTopActivity(),
fid = fid,
dep = fdep.value ?: "",
dest = "" // 目的站暂时留空
dep = sendAddress.value ?: "",
dest = fdep.value ?: ""
)
}
/**
* 获取当前航班ID(从列表第一项获取)
*/
private fun getCurrentFlightId(): String {
val firstItem = pageModel.rv?.commonAdapter()?.items?.firstOrNull() as? GjjManifest
return firstItem?.fid?.toString() ?: ""
}
/**
* Item点击处理(侧滑按钮)
*/
@@ -217,6 +294,14 @@ class IntImpManifestViewModel : BasePageViewModel() {
launchLoadingCollect({ NetApply.api.getIntImpManifestList(listParams) }) {
onSuccess = { result ->
pageModel.handleListBean(result.data?.toBaseListBean())
// 列表加载完成后,加载分单数据
val items = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest>
items?.forEach { bean ->
if (bean.haWbNum > 0) {
loadHaWbList(bean)
}
}
}
}
@@ -230,4 +315,22 @@ class IntImpManifestViewModel : BasePageViewModel() {
}
}
}
/**
* 加载主单下的分单列表
*/
private fun loadHaWbList(bean: GjjManifest) {
val params = mapOf(
"mfId" to bean.mfId
).toRequestBody()
launchCollect({ NetApply.api.getIntImpManifestHaWbList(params) }) {
onSuccess = { result ->
if (result.verifySuccess() && !result.data.isNullOrEmpty()) {
bean.haWbList = result.data
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
}
}
}
}