diff --git a/module_base/src/main/java/com/lukouguoji/module_base/bean/GjcMaWb.kt b/module_base/src/main/java/com/lukouguoji/module_base/bean/GjcMaWb.kt index 3169f21..a5b605d 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/bean/GjcMaWb.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/bean/GjcMaWb.kt @@ -274,6 +274,7 @@ data class GjcStorageUse( var prefix: String? = null, // 运单前缀 var no: String? = null, // 运单号 var location: String? = null, // 库位号 + var locationId: Long? = null, // 库位id var storageCode: String? = null, // 库位号(兼容字段) var uld: String? = null, // 板箱号 var inDate: String? = null, // 入库时间 @@ -281,7 +282,8 @@ data class GjcStorageUse( var inId: String? = null, // 入库人(兼容字段) var outDate: String? = null, // 出库时间 var outOpId: String? = null, // 出库人 - var outId: String? = null // 出库人(兼容字段) + var outId: String? = null, // 出库人(兼容字段) + var cargoStatus: String? = null // 货物状态 ) { // ==================== UI扩展字段 ==================== @Transient 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 bad9704..70237aa 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 @@ -818,6 +818,13 @@ interface Api { @POST("IntExpStorageUse/updateClear") suspend fun clearIntExpStorage(@Body data: RequestBody): BaseResultBean + /** + * 国际出港库位操作-修改库位 + * 接口路径: /IntExpStorageUse/modifyStorage + */ + @POST("IntExpStorageUse/modifyStorage") + suspend fun modifyIntExpStorage(@Body data: RequestBody): BaseResultBean + /** * 国际出港仓库-分页查询 * 接口路径: /IntExpStorageUse/pageQuery diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/IntExpStorageUseActivity.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/IntExpStorageUseActivity.kt index 6854b63..14628f1 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/IntExpStorageUseActivity.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/IntExpStorageUseActivity.kt @@ -7,6 +7,7 @@ import com.alibaba.android.arouter.facade.annotation.Route import com.lukouguoji.gjc.R import com.lukouguoji.gjc.databinding.ActivityIntExpStorageUseBinding import com.lukouguoji.gjc.dialog.IntExpMoveClearDialogModel +import com.lukouguoji.gjc.dialog.IntExpModifyStorageDialogModel import com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.common.Constant @@ -54,11 +55,25 @@ class IntExpStorageUseActivity : */ fun showClearDialog() { val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return - val selectedItems = list.filterIsInstance() - .filter { it.isSelected } + val allItems = list.filterIsInstance() - if (selectedItems.isEmpty()) { - showToast("请至少选择一条运单") + // 构建清仓数据:保留主列表结构,但只包含选中的子列表项 + val maWbListForClear = allItems.mapNotNull { maWb -> + // 过滤出选中的子列表项 + val selectedStorageList = maWb.storageUseList?.filter { it.isSelected } ?: emptyList() + + // 只添加有选中子列表项的主列表项 + if (selectedStorageList.isNotEmpty()) { + // 创建主列表项的副本,只包含选中的子列表 + maWb.copy(storageUseList = selectedStorageList) + } else { +// null + maWb + } + } + + if (maWbListForClear.isEmpty()) { + showToast("请至少选择一个库位") return } @@ -66,7 +81,42 @@ class IntExpStorageUseActivity : IntExpMoveClearDialogModel { dialog -> // 用户点击保存后,执行清仓操作 val clearNormal = dialog.clearNormal.value ?: "" - viewModel.performClear(clearNormal) + viewModel.performClear(clearNormal, maWbListForClear) + }.show(this) + } + + /** + * 显示修改库位对话框 + */ + fun showModifyStorageDialog() { + val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return + val allItems = list.filterIsInstance() + + // 收集所有选中的子列表项(库位) + val selectedStorageUseList = mutableListOf() + allItems.forEach { maWb -> + maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) } + } + + // 校验:必须且只能选中一个库位 + when { + selectedStorageUseList.isEmpty() -> { + showToast("请选择要修改的库位") + return + } + selectedStorageUseList.size > 1 -> { + showToast("只能选择一个库位进行修改") + return + } + } + + val selectedStorage = selectedStorageUseList[0] + + // 显示修改库位对话框 + IntExpModifyStorageDialogModel { dialog -> + // 用户点击保存后,执行修改库位操作 + val newLocation = dialog.location.value ?: "" + viewModel.performModifyStorage(newLocation, selectedStorage) }.show(this) } diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpModifyStorageDialogModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpModifyStorageDialogModel.kt new file mode 100644 index 0000000..1520172 --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpModifyStorageDialogModel.kt @@ -0,0 +1,38 @@ +package com.lukouguoji.gjc.dialog + +import android.content.Context +import androidx.lifecycle.MutableLiveData +import com.lukouguoji.gjc.R +import com.lukouguoji.gjc.databinding.DialogIntExpModifyStorageBinding +import com.lukouguoji.module_base.base.BaseDialogModel +import com.lukouguoji.module_base.ktx.verifyNullOrEmpty + +/** + * 国际出港 - 修改库位对话框 + */ +class IntExpModifyStorageDialogModel( + private val callback: (IntExpModifyStorageDialogModel) -> Unit +) : BaseDialogModel(DIALOG_TYPE_CENTER) { + + // 库位号 + val location = MutableLiveData("") + + override fun layoutId(): Int { + return R.layout.dialog_int_exp_modify_storage + } + + override fun onDialogCreated(context: Context) { + binding.model = this + } + + /** + * 保存按钮点击 + */ + fun onSaveClick() { + if (location.value.verifyNullOrEmpty("请输入库位号")) { + return + } + dismiss() + callback(this) + } +} diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseSubViewHolder.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseSubViewHolder.kt index 491e1a0..c735855 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseSubViewHolder.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseSubViewHolder.kt @@ -1,8 +1,10 @@ package com.lukouguoji.gjc.holder import android.view.View +import androidx.recyclerview.widget.RecyclerView import com.lukouguoji.gjc.databinding.ItemIntExpStorageUseSubBinding import com.lukouguoji.module_base.base.BaseViewHolder +import com.lukouguoji.module_base.bean.GjcMaWb import com.lukouguoji.module_base.bean.GjcStorageUse /** @@ -17,10 +19,33 @@ class IntExpStorageUseSubViewHolder(view: View) : binding.position = position binding.executePendingBindings() - // 单选框点击切换选择状态 + // 单选框点击切换选择状态(反向联动主列表) binding.ivCheckbox.setOnClickListener { - bean.checked.set(!bean.checked.get()) + // 切换子列表项的选择状态 + val newCheckedState = !bean.checked.get() + bean.checked.set(newCheckedState) binding.executePendingBindings() + + // 反向联动主列表项 + updateParentCheckState() } } + + /** + * 更新父列表项的选择状态 + * 规则: + * - 如果有任何一个子列表项被勾选,则主列表项也应该被勾选 + * - 如果所有子列表项都未勾选,则主列表项也应该取消勾选 + */ + private fun updateParentCheckState() { + // 从RecyclerView的tag获取父Bean引用 + val recyclerView = itemView.parent as? RecyclerView ?: return + val parentBean = recyclerView.tag as? GjcMaWb ?: return + + // 检查是否有任何一个子列表项被勾选 + val hasAnyChecked = parentBean.storageUseList?.any { it.checked.get() } ?: false + + // 更新父列表项的选择状态 + parentBean.checked.set(hasAnyChecked) + } } diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseViewHolder.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseViewHolder.kt index df097a0..afa0696 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseViewHolder.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseViewHolder.kt @@ -20,10 +20,20 @@ class IntExpStorageUseViewHolder(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.storageUseList?.forEach { storageUse -> + storageUse.checked.set(newCheckedState) + } + + // 刷新UI binding.executePendingBindings() + binding.rvSub.adapter?.notifyDataSetChanged() } // 展开按钮点击事件 @@ -38,7 +48,10 @@ class IntExpStorageUseViewHolder(view: View) : R.layout.item_int_exp_storage_use_sub ) - // 刷新库位明细数据 - binding.rvSub.refresh(bean.storageUseList ?: emptyList()) + // 刷新库位明细数据(传递父Bean引用) + val storageUseList = bean.storageUseList ?: emptyList() + // 为每个子列表项设置父Bean引用(通过tag传递) + binding.rvSub.tag = bean + binding.rvSub.refresh(storageUseList) } } diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpStorageUseViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpStorageUseViewModel.kt index a73eeee..cfa3201 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpStorageUseViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpStorageUseViewModel.kt @@ -80,13 +80,22 @@ class IntExpStorageUseViewModel : BasePageViewModel() { } /** - * 全选按钮点击 + * 全选按钮点击(联动勾选所有子列表项) */ fun checkAllClick() { val list = pageModel.rv?.commonAdapter()?.items as? List ?: return val shouldCheckAll = !isAllChecked.value!! - list.forEach { it.checked.set(shouldCheckAll) } + + // 联动勾选/取消主列表和子列表 + list.forEach { maWb -> + maWb.checked.set(shouldCheckAll) + // 同时联动勾选/取消所有子列表项 + maWb.storageUseList?.forEach { storageUse -> + storageUse.checked.set(shouldCheckAll) + } + } + isAllChecked.value = shouldCheckAll pageModel.rv?.commonAdapter()?.notifyDataSetChanged() @@ -131,20 +140,18 @@ class IntExpStorageUseViewModel : BasePageViewModel() { /** * 执行清仓操作 * @param clearNormal 清仓正常("0"或"1") + * @param maWbListForClear 包含选中子列表项的主列表数据 */ - fun performClear(clearNormal: String) { - val list = pageModel.rv?.commonAdapter()?.items as? List ?: return - val selectedItems = list.filter { it.isSelected } - - if (selectedItems.isEmpty()) { - showToast("请至少选择一条运单") + fun performClear(clearNormal: String, maWbListForClear: List) { + if (maWbListForClear.isEmpty()) { + showToast("请至少选择一个库位") return } - // 构建请求参数 + // 构建请求参数:完整的主子列表结构 val params = mapOf( "clearNormal" to clearNormal, - "maWbList" to selectedItems + "maWbList" to maWbListForClear ).toRequestBody() launchLoadingCollect({ NetApply.api.clearIntExpStorage(params) }) { @@ -165,16 +172,38 @@ class IntExpStorageUseViewModel : BasePageViewModel() { * 修改库位 */ fun modifyStorage() { - val list = pageModel.rv?.commonAdapter()?.items as? List ?: return - val selectedItems = list.filter { it.isSelected } + // 由Activity显示对话框 + } - if (selectedItems.isEmpty()) { - showToast("请选择要修改库位的运单") + /** + * 执行修改库位操作 + * @param newLocation 新的库位号 + * @param storageUse 选中的单个库位使用对象 + */ + fun performModifyStorage(newLocation: String, storageUse: com.lukouguoji.module_base.bean.GjcStorageUse) { + if (newLocation.isEmpty()) { + showToast("请输入新的库位号") return } - // TODO: 实现修改库位接口调用或弹出对话框 - showToast("修改库位功能待实现") + // 创建更新后的库位对象(覆盖 location 字段) + val updatedStorage = storageUse.copy(location = newLocation) + + // 直接使用更新后的对象构建请求参数 + val params = updatedStorage.toRequestBody() + + launchLoadingCollect({ NetApply.api.modifyIntExpStorage(params) }) { + onSuccess = { + showToast("修改库位成功") + viewModelScope.launch { + FlowBus.with(ConstantEvent.EVENT_REFRESH).emit("refresh") + } + refresh() // 刷新列表 + } + onFailed = { _, msg -> + showToast(msg.noNull("修改库位失败")) + } + } } /** @@ -182,10 +211,15 @@ class IntExpStorageUseViewModel : BasePageViewModel() { */ fun outStorage() { val list = pageModel.rv?.commonAdapter()?.items as? List ?: return - val selectedItems = list.filter { it.isSelected } - if (selectedItems.isEmpty()) { - showToast("请选择要出库的运单") + // 收集所有选中的子列表项(库位) + val selectedStorageUseList = mutableListOf() + list.forEach { maWb -> + maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) } + } + + if (selectedStorageUseList.isEmpty()) { + showToast("请选择要出库的库位") return } @@ -198,10 +232,15 @@ class IntExpStorageUseViewModel : BasePageViewModel() { */ fun inStorage() { val list = pageModel.rv?.commonAdapter()?.items as? List ?: return - val selectedItems = list.filter { it.isSelected } - if (selectedItems.isEmpty()) { - showToast("请选择要入库的运单") + // 收集所有选中的子列表项(库位) + val selectedStorageUseList = mutableListOf() + list.forEach { maWb -> + maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) } + } + + if (selectedStorageUseList.isEmpty()) { + showToast("请选择要入库的库位") return } diff --git a/module_gjc/src/main/res/layout/activity_int_exp_storage_use.xml b/module_gjc/src/main/res/layout/activity_int_exp_storage_use.xml index 8aefcc9..845de19 100644 --- a/module_gjc/src/main/res/layout/activity_int_exp_storage_use.xml +++ b/module_gjc/src/main/res/layout/activity_int_exp_storage_use.xml @@ -228,7 +228,7 @@ diff --git a/module_gjc/src/main/res/layout/dialog_int_exp_modify_storage.xml b/module_gjc/src/main/res/layout/dialog_int_exp_modify_storage.xml new file mode 100644 index 0000000..51537c3 --- /dev/null +++ b/module_gjc/src/main/res/layout/dialog_int_exp_modify_storage.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +