Compare commits

...

2 Commits

Author SHA1 Message Date
af49cf4fb6 refactor: 国际进港原始舱单主子列表改为独立选择
移除主单↔分单勾选联动,改为独立选择模式;
提取公共方法 getSelectedItems() 分别收集选中的主单和分单;
补充信息操作仅校验主单选中状态;详情页品名字段增加中文品名回退逻辑。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:33:20 +08:00
76f55597db chore: 删除.playwright-mcp并加入gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:40:25 +08:00
6 changed files with 32 additions and 89 deletions

1
.gitignore vendored
View File

@@ -203,3 +203,4 @@ fabric.properties
.worktrees/ .worktrees/
.security-key .security-key
logs/security/ logs/security/
.playwright-mcp/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -1,10 +1,8 @@
package com.lukouguoji.gjj.holder package com.lukouguoji.gjj.holder
import android.view.View import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.gjj.databinding.ItemIntArrAirManifestSubBinding import com.lukouguoji.gjj.databinding.ItemIntArrAirManifestSubBinding
import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjAirManifest
import com.lukouguoji.module_base.bean.GjjImportManifest import com.lukouguoji.module_base.bean.GjjImportManifest
/** /**
@@ -19,18 +17,10 @@ class IntArrAirManifestSubViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 单选框点击切换选择状态 // 单选框点击切换选择状态(独立选择,不联动主列表)
binding.ivCheckbox.setOnClickListener { binding.ivCheckbox.setOnClickListener {
val newCheckedState = !bean.checked.get() bean.checked.set(!bean.checked.get())
bean.checked.set(newCheckedState)
binding.executePendingBindings() binding.executePendingBindings()
// 反向联动主列表项(勾选子项时自动勾选父项)
if (newCheckedState) {
val recyclerView = itemView.parent as? RecyclerView ?: return@setOnClickListener
val parentBean = recyclerView.tag as? GjjAirManifest ?: return@setOnClickListener
parentBean.checked.set(true)
}
} }
} }
} }

View File

@@ -26,14 +26,10 @@ class IntArrAirManifestViewHolder(view: View) :
// 整卡点击 - 跳转详情页 // 整卡点击 - 跳转详情页
notifyItemClick(position, binding.ll) notifyItemClick(position, binding.ll)
// 图标点击 - 切换选择状态(联动子列表) // 图标点击 - 切换选择状态(独立选择,不联动子列表)
binding.ivIcon.setOnClickListener { binding.ivIcon.setOnClickListener {
val newCheckedState = !bean.checked.get() bean.checked.set(!bean.checked.get())
bean.checked.set(newCheckedState)
// 联动子列表选中状态
bean.haWbList?.forEach { sub -> sub.checked.set(newCheckedState) }
binding.executePendingBindings() binding.executePendingBindings()
binding.rvSub.adapter?.notifyDataSetChanged()
} }
// 展开按钮点击事件 // 展开按钮点击事件
@@ -48,7 +44,6 @@ class IntArrAirManifestViewHolder(view: View) :
R.layout.item_int_arr_air_manifest_sub R.layout.item_int_arr_air_manifest_sub
) )
// 设置父Bean引用用于子列表反向联动
binding.rvSub.tag = bean binding.rvSub.tag = bean
binding.rvSub.refresh(bean.haWbList ?: emptyList()) binding.rvSub.refresh(bean.haWbList ?: emptyList())
} }

View File

@@ -113,31 +113,31 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
ScanModel.startScan(getTopActivity(), Constant.RequestCode.HNO) ScanModel.startScan(getTopActivity(), Constant.RequestCode.HNO)
} }
/**
* 收集选中的主单和分单(独立选择,互不影响)
* @return Pair<主单列表, 分单列表>,如果无任何选中返回 null
*/
private fun getSelectedItems(emptyMsg: String): Pair<List<GjjImportManifest>, List<GjjImportManifest>>? {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return null
val maWbList = list.filter { it.isSelected }.mapNotNull { it.maWb }
val haWbList = list.flatMap { it.haWbList ?: emptyList() }.filter { it.isSelected }
if (maWbList.isEmpty() && haWbList.isEmpty()) {
showToast(emptyMsg)
return null
}
return Pair(maWbList, haWbList)
}
/** /**
* 状态重置按钮点击 * 状态重置按钮点击
*/ */
fun resetStatusClick() { fun resetStatusClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return val (maWbList, haWbList) = getSelectedItems("请选择要重置的舱单") ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要重置的舱单")
return
}
// 提取主单和分单
val maWbList = mutableListOf<GjjImportManifest>()
val haWbList = mutableListOf<GjjImportManifest>()
selectedItems.forEach { airManifest ->
airManifest.maWb?.let { maWbList.add(it) }
airManifest.haWbList?.let { haWbList.addAll(it) }
}
val param = GjjDeclareParam( val param = GjjDeclareParam(
maWbList = maWbList, maWbList = maWbList,
haWbList = haWbList, haWbList = haWbList,
restStatus = null, // 未申报状态 restStatus = null,
resetReason = "状态重置" resetReason = "状态重置"
) )
@@ -153,25 +153,20 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
} }
/** /**
* 补充信息按钮点击 * 补充信息按钮点击(只针对主单)
*/ */
fun supplementInfoClick() { fun supplementInfoClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return
val selectedItems = list.filter { it.isSelected } val selectedMainItems = list.filter { it.isSelected }.mapNotNull { it.maWb }
if (selectedItems.isEmpty()) { if (selectedMainItems.isEmpty()) {
showToast("请选择要补充信息的") showToast("请选择要补充信息的")
return return
} }
// 收集所有选中项的主单数据
val manifestList = ArrayList(selectedItems.mapNotNull { it.maWb })
if (manifestList.isEmpty()) return
// 跳转到补充信息页面(传递完整列表)
com.lukouguoji.gjj.activity.IntArrSupplementInfoActivity.start( com.lukouguoji.gjj.activity.IntArrSupplementInfoActivity.start(
getTopActivity(), getTopActivity(),
manifestList ArrayList(selectedMainItems)
) )
} }
@@ -179,31 +174,14 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
* 删除申报按钮点击 * 删除申报按钮点击
*/ */
fun deleteDeclarationClick() { fun deleteDeclarationClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return val (maWbList, haWbList) = getSelectedItems("请选择要删除申报的舱单") ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要删除申报的舱单")
return
}
// 从接口获取删除原因列表 // 从接口获取删除原因列表
launchLoadingCollect({ NetApply.api.getDelReasonList() }) { launchLoadingCollect({ NetApply.api.getDelReasonList() }) {
onSuccess = { result -> onSuccess = { result ->
val deleteReasonList = result.data?.map { it.toKeyValue() } ?: emptyList() val deleteReasonList = result.data?.map { it.toKeyValue() } ?: emptyList()
// 创建并显示弹框
val dialog = com.lukouguoji.gjj.dialog.IntArrManifestDeleteDialogModel(deleteReasonList) { dialogModel -> val dialog = com.lukouguoji.gjj.dialog.IntArrManifestDeleteDialogModel(deleteReasonList) { dialogModel ->
// 弹框确认后的回调
// 提取主单和分单
val maWbList = mutableListOf<GjjImportManifest>()
val haWbList = mutableListOf<GjjImportManifest>()
selectedItems.forEach { airManifest ->
airManifest.maWb?.let { maWbList.add(it) }
airManifest.haWbList?.let { haWbList.addAll(it) }
}
val param = GjjDeclareParam( val param = GjjDeclareParam(
dcode = dialogModel.deleteReason.value ?: "", dcode = dialogModel.deleteReason.value ?: "",
dcontactsName = dialogModel.contactName.value ?: "", dcontactsName = dialogModel.contactName.value ?: "",
@@ -212,10 +190,7 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
haWbList = haWbList haWbList = haWbList
) )
val requestData = param.toRequestBody() launchLoadingCollect({ NetApply.api.deleteIntArrManifestDeclare(param.toRequestBody()) }) {
// 调用删除接口
launchLoadingCollect({ NetApply.api.deleteIntArrManifestDeclare(requestData) }) {
onSuccess = { onSuccess = {
showToast("删除申报成功") showToast("删除申报成功")
viewModelScope.launch { viewModelScope.launch {
@@ -235,27 +210,9 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
* 舱单申报按钮点击 * 舱单申报按钮点击
*/ */
fun declareClick() { fun declareClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return val (maWbList, haWbList) = getSelectedItems("请选择要申报的舱单") ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) { val param = GjjDeclareParam(maWbList = maWbList, haWbList = haWbList)
showToast("请选择要申报的舱单")
return
}
// 提取主单和分单
val maWbList = mutableListOf<GjjImportManifest>()
val haWbList = mutableListOf<GjjImportManifest>()
selectedItems.forEach { airManifest ->
airManifest.maWb?.let { maWbList.add(it) }
airManifest.haWbList?.let { haWbList.addAll(it) }
}
val param = GjjDeclareParam(
maWbList = maWbList,
haWbList = haWbList
)
launchLoadingCollect({ NetApply.api.declareIntArrManifest(param.toRequestBody()) }) { launchLoadingCollect({ NetApply.api.declareIntArrManifest(param.toRequestBody()) }) {
onSuccess = { onSuccess = {

View File

@@ -132,7 +132,7 @@
title='@{"品名(中)"}' title='@{"品名(中)"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.goodsCn}' value='@{viewModel.dataBean.goodsCn != null &amp;&amp; !viewModel.dataBean.goodsCn.isEmpty() ? viewModel.dataBean.goodsCn : viewModel.dataBean.goods}'
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:layout_weight="1" />