diff --git a/module_base/src/main/java/com/lukouguoji/module_base/bean/GjjImportTally.kt b/module_base/src/main/java/com/lukouguoji/module_base/bean/GjjImportTally.kt index cf9dcca..8a9be3f 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/bean/GjjImportTally.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/bean/GjjImportTally.kt @@ -85,6 +85,14 @@ data class GjjImportTally( get() = checked.get() set(value) = checked.set(value) + // 展开/折叠状态 - 不参与序列化 + @Transient + val showMore: ObservableBoolean = ObservableBoolean(false) + + // 已加载的分单数据 - 不参与序列化 + @Transient + var haWbList: MutableList? = null + // 获取完整运单号 fun getWaybillNo() = "$prefix$no" } diff --git a/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt b/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt index 31d6a29..e598426 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt @@ -1896,6 +1896,12 @@ interface Api { @POST("IntImpTally/pageQueryTotal") suspend fun getIntImpTallyTotal(@Body data: RequestBody): BaseResultBean + /** + * 国际进港理货报告-查询分单列表 + */ + @POST("IntImpTally/listHaWb") + suspend fun getIntImpTallySubList(@Body data: RequestBody): BaseResultBean> + /** * 国际进港舱单-货物发放 */ diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpManifestViewHolder.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpManifestViewHolder.kt index 1ae3949..7754940 100644 --- a/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpManifestViewHolder.kt +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpManifestViewHolder.kt @@ -62,6 +62,29 @@ class IntImpManifestViewHolder(view: View) : // 设置父Bean引用(用于子列表反向联动) binding.rvSub.tag = bean - binding.rvSub.refresh(bean.haWbList ?: emptyList()) + val subList = bean.haWbList ?: emptyList() + binding.rvSub.refresh(subList) + updateSubListVisibility(bean.haWbList != null, subList.isNotEmpty()) + } + + /** + * 根据分单数据状态,切换表头/列表与空数据提示的显隐 + * @param loaded 是否已加载过数据(haWbList != null) + * @param hasData 是否有数据 + */ + private fun updateSubListVisibility(loaded: Boolean, hasData: Boolean) { + if (!loaded || hasData) { + // 未加载或有数据:显示表头+列表,隐藏空提示 + binding.llHeader.visibility = View.VISIBLE + binding.dividerHeader.visibility = View.VISIBLE + binding.rvSub.visibility = View.VISIBLE + binding.tvEmpty.visibility = View.GONE + } else { + // 已加载但无数据:隐藏表头+列表,显示空提示 + binding.llHeader.visibility = View.GONE + binding.dividerHeader.visibility = View.GONE + binding.rvSub.visibility = View.GONE + binding.tvEmpty.visibility = View.VISIBLE + } } } diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpTallySubViewHolder.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpTallySubViewHolder.kt new file mode 100644 index 0000000..4c67657 --- /dev/null +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpTallySubViewHolder.kt @@ -0,0 +1,43 @@ +package com.lukouguoji.gjj.holder + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import com.lukouguoji.gjj.databinding.ItemIntImpTallySubBinding +import com.lukouguoji.module_base.base.BaseViewHolder +import com.lukouguoji.module_base.bean.GjjImportTally + +/** + * 国际进港理货报告 分单子列表 ViewHolder + */ +class IntImpTallySubViewHolder(view: View) : + BaseViewHolder(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() + + // 反向联动主列表项(勾选时联动主项也勾选) + updateParentCheckState(newCheckedState) + } + } + + /** + * 更新父列表项的选择状态 + */ + private fun updateParentCheckState(newCheckedState: Boolean) { + val recyclerView = itemView.parent as? RecyclerView ?: return + val parentBean = recyclerView.tag as? GjjImportTally ?: return + + if (newCheckedState) { + parentBean.checked.set(true) + } + } +} diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpTallyViewHolder.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpTallyViewHolder.kt index daf9d78..9190cab 100644 --- a/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpTallyViewHolder.kt +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpTallyViewHolder.kt @@ -1,9 +1,16 @@ package com.lukouguoji.gjj.holder import android.view.View +import com.lukouguoji.gjj.R import com.lukouguoji.gjj.databinding.ItemIntImpTallyBinding +import com.lukouguoji.module_base.adapter.setCommonAdapter import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.bean.GjjImportTally +import com.google.gson.Gson +import com.lukouguoji.module_base.http.net.NetApply +import com.lukouguoji.module_base.ktx.launchCollect +import com.lukouguoji.module_base.ktx.refresh +import com.lukouguoji.module_base.ktx.toRequestBody /** * 国际进港理货报告 ViewHolder @@ -17,10 +24,79 @@ class IntImpTallyViewHolder(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() + } + + // 展开按钮点击事件 + binding.ivShow.setOnClickListener { + if (bean.haWbList != null) { + // 已加载过数据,直接切换显隐 + bean.showMore.set(!bean.showMore.get()) + } else { + // 首次展开,调用接口加载分单数据 + loadSubList(bean) + } + } + + // 初始化分单子列表 RecyclerView + setCommonAdapter( + binding.rvSub, + IntImpTallySubViewHolder::class.java, + R.layout.item_int_imp_tally_sub + ) + + // 刷新分单数据(传递父Bean引用用于反向联动) + binding.rvSub.tag = bean + val subList = bean.haWbList ?: emptyList() + binding.rvSub.refresh(subList) + updateSubListVisibility(subList.isNotEmpty()) + } + + /** + * 加载分单列表数据(将主单整体作为请求参数) + */ + private fun loadSubList(bean: GjjImportTally) { + // 将 bean 转为 Map 并补充 wbNo 字段(prefix + no) + val map = Gson().fromJson(Gson().toJson(bean), HashMap::class.java) as HashMap + map["wbNo"] = bean.getWaybillNo() + val params = map.toRequestBody() + + launchCollect({ NetApply.api.getIntImpTallySubList(params) }) { + onSuccess = { result -> + val list = result.data?.toMutableList() ?: mutableListOf() + bean.haWbList = list + bean.showMore.set(true) + binding.rvSub.refresh(list) + updateSubListVisibility(list.isNotEmpty()) + } + } + } + + /** + * 根据分单数据是否为空,切换表头/列表与空数据提示的显隐 + */ + private fun updateSubListVisibility(hasData: Boolean) { + if (hasData) { + binding.llHeader.visibility = View.VISIBLE + binding.dividerHeader.visibility = View.VISIBLE + binding.rvSub.visibility = View.VISIBLE + binding.tvEmpty.visibility = View.GONE + } else { + binding.llHeader.visibility = View.GONE + binding.dividerHeader.visibility = View.GONE + binding.rvSub.visibility = View.GONE + binding.tvEmpty.visibility = View.VISIBLE } } } diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpManifestViewModel.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpManifestViewModel.kt index 9433b7f..f812b90 100644 --- a/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpManifestViewModel.kt +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpManifestViewModel.kt @@ -496,19 +496,13 @@ class IntImpManifestViewModel : BasePageViewModel() { * 加载主单下的分单列表(按需加载,加载完成后自动展开) */ private fun loadHaWbList(bean: GjjManifest) { - val params = mapOf( - "mfId" to bean.mfId - ).toRequestBody() + val params = bean.toRequestBody() launchLoadingCollect({ NetApply.api.getIntImpManifestHaWbList(params) }) { onSuccess = { result -> - if (result.verifySuccess() && !result.data.isNullOrEmpty()) { - bean.haWbList = result.data - bean.showMore.set(true) - pageModel.rv?.commonAdapter()?.notifyDataSetChanged() - } else { - showToast("暂无分单数据") - } + bean.haWbList = result.data ?: emptyList() + bean.showMore.set(true) + pageModel.rv?.commonAdapter()?.notifyDataSetChanged() } } } diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpTallyViewModel.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpTallyViewModel.kt index bd12eda..d7423fa 100644 --- a/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpTallyViewModel.kt +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpTallyViewModel.kt @@ -40,10 +40,13 @@ class IntImpTallyViewModel : BasePageViewModel() { val isAllChecked = MutableLiveData(false) init { - // 监听全选状态,自动更新所有列表项 + // 监听全选状态,自动更新所有列表项(联动子列表) isAllChecked.observeForever { checked -> val list = pageModel.rv?.commonAdapter()?.items as? List ?: 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() } } @@ -65,9 +68,12 @@ class IntImpTallyViewModel : BasePageViewModel() { fun checkAllClick() { val list = pageModel.rv?.commonAdapter()?.items as? List ?: 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() diff --git a/module_gjj/src/main/res/layout/activity_int_imp_tally.xml b/module_gjj/src/main/res/layout/activity_int_imp_tally.xml index 0bec259..c1deb17 100644 --- a/module_gjj/src/main/res/layout/activity_int_imp_tally.xml +++ b/module_gjj/src/main/res/layout/activity_int_imp_tally.xml @@ -51,6 +51,11 @@ + + + diff --git a/module_gjj/src/main/res/layout/item_int_imp_tally.xml b/module_gjj/src/main/res/layout/item_int_imp_tally.xml index b4ec792..826fde3 100644 --- a/module_gjj/src/main/res/layout/item_int_imp_tally.xml +++ b/module_gjj/src/main/res/layout/item_int_imp_tally.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:loadImage="http://schemas.android.com/tools"> @@ -15,271 +16,439 @@ type="Integer" /> + + android:layout_marginHorizontal="10dp" + android:layout_marginTop="10dp" + android:orientation="vertical"> - - - - + - + + android:orientation="horizontal" + android:padding="15dp"> - + + + + + android:layout_marginLeft="15dp" + android:layout_weight="1" + android:orientation="vertical"> - + + android:gravity="center_vertical" + android:orientation="horizontal"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_marginTop="10dp" + android:gravity="center_vertical" + android:orientation="horizontal"> - + + - - + - + - + - + + - - + - + - + - + + - - + - + - + - + + - - + - + - + + + + + + + + + + + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="20dp" + android:layout_marginTop="5dp" + android:layout_marginBottom="5dp" + android:padding="5dp" + android:src="@mipmap/img_down" /> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjj/src/main/res/layout/item_int_imp_tally_sub.xml b/module_gjj/src/main/res/layout/item_int_imp_tally_sub.xml new file mode 100644 index 0000000..f1743d3 --- /dev/null +++ b/module_gjj/src/main/res/layout/item_int_imp_tally_sub.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +