From e2f6cdde04af661410ebc6c1f50d05f07816836e Mon Sep 17 00:00:00 2001 From: YANGJIANKUAN Date: Sat, 17 Jan 2026 16:30:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9B=BD=E9=99=85=E5=87=BA=E6=B8=AF=20?= =?UTF-8?q?=E5=87=BA=E6=B8=AF=E4=BB=93=E5=BA=93=20finish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lukouguoji/module_base/http/net/Api.kt | 15 ++++ .../gjc/activity/IntExpStorageUseActivity.kt | 41 ++++++++- .../gjc/dialog/IntExpInStorageDialogModel.kt | 74 ++++++++++++++++ .../dialog/IntExpModifyStorageDialogModel.kt | 42 ++++++++- .../viewModel/IntExpStorageUseViewModel.kt | 70 +++++++++++---- .../layout/activity_int_exp_storage_use.xml | 2 +- .../res/layout/dialog_int_exp_in_storage.xml | 87 +++++++++++++++++++ .../layout/dialog_int_exp_modify_storage.xml | 7 +- 8 files changed, 312 insertions(+), 26 deletions(-) create mode 100644 module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpInStorageDialogModel.kt create mode 100644 module_gjc/src/main/res/layout/dialog_int_exp_in_storage.xml 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 80f8b5d..e0a3c3c 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 @@ -832,6 +832,13 @@ interface Api { @POST("IntExpStorageUse/outStorage") suspend fun outIntExpStorage(@Body data: RequestBody): BaseResultBean + /** + * 国际出港库位操作-入库 + * 接口路径: /IntExpStorageUse/inStorage + */ + @POST("IntExpStorageUse/inStorage") + suspend fun inIntExpStorage(@Body data: RequestBody): BaseResultBean + /** * 国际出港仓库-分页查询 * 接口路径: /IntExpStorageUse/pageQuery @@ -853,6 +860,14 @@ interface Api { @POST("IntExpStorageUse/queryWbNoList") suspend fun getIntExpStorageWbNoList(@Body data: RequestBody): BaseResultBean> + /** + * 获取库位列表 + * 接口路径: /typeCode/locationByFlag + * @param flag 库位标志,2表示国际出港库位 + */ + @GET("typeCode/locationByFlag") + suspend fun getLocationList(@Query("flag") flag: Int): BaseResultBean> + /** * 国际出港待计重-分页搜索 * 接口路径: /IntExpCheckIn/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 01dc11f..d726f68 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 @@ -9,6 +9,7 @@ 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.dialog.IntExpInStorageDialogModel import com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.common.Constant @@ -115,8 +116,9 @@ class IntExpStorageUseActivity : // 显示修改库位对话框 IntExpModifyStorageDialogModel { dialog -> // 用户点击保存后,执行修改库位操作 - val newLocation = dialog.location.value ?: "" - viewModel.performModifyStorage(newLocation, selectedStorage) + val locationName = dialog.locationName + val locationId = dialog.locationId + viewModel.performModifyStorage(locationName, locationId, selectedStorage) }.show(this) } @@ -151,6 +153,41 @@ class IntExpStorageUseActivity : .show() } + /** + * 显示入库操作对话框 + */ + fun showInStorageDialog() { + val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return + val allItems = list.filterIsInstance() + + // 构建入库数据:保留主列表结构,但只包含选中的子列表项 + val maWbListForInStorage = allItems.mapNotNull { maWb -> + // 过滤出选中的子列表项 + val selectedStorageList = maWb.storageUseList?.filter { it.isSelected } ?: emptyList() + + // 只添加有选中子列表项的主列表项 + if (selectedStorageList.isNotEmpty() || maWb.isSelected) { + // 创建主列表项的副本,只包含选中的子列表 + maWb.copy(storageUseList = selectedStorageList) + } else { + null + } + } + + if (maWbListForInStorage.isEmpty()) { + showToast("请至少选择一个单据") + return + } + + // 显示入库对话框 + IntExpInStorageDialogModel { dialog -> + // 用户点击保存后,执行入库操作 + val locationName = dialog.locationName + val locationId = dialog.locationId + viewModel.performInStorage(locationName, locationId, maWbListForInStorage) + }.show(this) + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) { diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpInStorageDialogModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpInStorageDialogModel.kt new file mode 100644 index 0000000..bac3a9c --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpInStorageDialogModel.kt @@ -0,0 +1,74 @@ +package com.lukouguoji.gjc.dialog + +import android.content.Context +import androidx.lifecycle.MutableLiveData +import com.lukouguoji.gjc.R +import com.lukouguoji.gjc.databinding.DialogIntExpInStorageBinding +import com.lukouguoji.module_base.base.BaseDialogModel +import com.lukouguoji.module_base.http.net.NetApply +import com.lukouguoji.module_base.ktx.launchCollect +import com.lukouguoji.module_base.ktx.showToast +import com.lukouguoji.module_base.ktx.verifyNullOrEmpty +import dev.utils.app.info.KeyValue + +/** + * 国际出港仓库 - 入库操作对话框 + */ +class IntExpInStorageDialogModel( + private val callback: (IntExpInStorageDialogModel) -> Unit +) : BaseDialogModel(DIALOG_TYPE_CENTER) { + + // 库位列表 + val locationList = MutableLiveData>() + + // 选中的库位(存储的是code) + val selectedLocationCode = MutableLiveData("") + + // 库位ID (后端需要的code) + var locationId: String = "" + + // 库位名称 (后端需要的name) + var locationName: String = "" + + override fun layoutId(): Int { + return R.layout.dialog_int_exp_in_storage + } + + override fun onDialogCreated(context: Context) { + binding.model = this + loadLocationList() + + // 监听选择变化,更新locationId和locationName + selectedLocationCode.observeForever { code -> + val selectedItem = locationList.value?.find { it.value == code } + locationId = selectedItem?.value ?: "" + locationName = selectedItem?.key ?: "" + } + } + + /** + * 加载库位列表 + */ + private fun loadLocationList() { + launchCollect({ NetApply.api.getLocationList(flag = 2) }) { + onSuccess = { result -> + val list = result.data?.map { it.toKeyValue() } ?: emptyList() + locationList.value = list + } + onFailed = { _, msg -> + showToast(msg ?: "加载库位列表失败") + } + } + } + + /** + * 保存按钮点击 + */ + fun onSaveClick() { + if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) { + return + } + dismiss() + callback(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 index 1520172..2f5fca8 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpModifyStorageDialogModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/dialog/IntExpModifyStorageDialogModel.kt @@ -5,7 +5,11 @@ 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.http.net.NetApply +import com.lukouguoji.module_base.ktx.launchCollect +import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.verifyNullOrEmpty +import dev.utils.app.info.KeyValue /** * 国际出港 - 修改库位对话框 @@ -14,8 +18,17 @@ class IntExpModifyStorageDialogModel( private val callback: (IntExpModifyStorageDialogModel) -> Unit ) : BaseDialogModel(DIALOG_TYPE_CENTER) { - // 库位号 - val location = MutableLiveData("") + // 库位列表 + val locationList = MutableLiveData>() + + // 选中的库位(存储的是code) + val selectedLocationCode = MutableLiveData("") + + // 库位ID (后端需要的code) + var locationId: String = "" + + // 库位名称 (后端需要的name) + var locationName: String = "" override fun layoutId(): Int { return R.layout.dialog_int_exp_modify_storage @@ -23,13 +36,36 @@ class IntExpModifyStorageDialogModel( override fun onDialogCreated(context: Context) { binding.model = this + loadLocationList() + + // 监听选择变化,更新locationId和locationName + selectedLocationCode.observeForever { code -> + val selectedItem = locationList.value?.find { it.value == code } + locationId = selectedItem?.value ?: "" + locationName = selectedItem?.key ?: "" + } + } + + /** + * 加载库位列表 + */ + private fun loadLocationList() { + launchCollect({ NetApply.api.getLocationList(flag = 2) }) { + onSuccess = { result -> + val list = result.data?.map { it.toKeyValue() } ?: emptyList() + locationList.value = list + } + onFailed = { _, msg -> + showToast(msg ?: "加载库位列表失败") + } + } } /** * 保存按钮点击 */ fun onSaveClick() { - if (location.value.verifyNullOrEmpty("请输入库位号")) { + if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) { return } dismiss() 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 9341b4a..d5ac607 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 @@ -177,17 +177,25 @@ class IntExpStorageUseViewModel : BasePageViewModel() { /** * 执行修改库位操作 - * @param newLocation 新的库位号 + * @param locationName 新的库位名称 (后端的location字段) + * @param locationId 新的库位ID (后端的locationId字段) * @param storageUse 选中的单个库位使用对象 */ - fun performModifyStorage(newLocation: String, storageUse: com.lukouguoji.module_base.bean.GjcStorageUse) { - if (newLocation.isEmpty()) { - showToast("请输入新的库位号") + fun performModifyStorage( + locationName: String, + locationId: String, + storageUse: com.lukouguoji.module_base.bean.GjcStorageUse + ) { + if (locationName.isEmpty() || locationId.isEmpty()) { + showToast("请选择库位") return } - // 创建更新后的库位对象(覆盖 location 字段) - val updatedStorage = storageUse.copy(location = newLocation) + // 创建更新后的库位对象(覆盖 location 和 locationId 字段) + val updatedStorage = storageUse.copy( + location = locationName, + locationId = locationId.toLongOrNull() ?: 0 + ) // 直接使用更新后的对象构建请求参数 val params = updatedStorage.toRequestBody() @@ -244,21 +252,49 @@ class IntExpStorageUseViewModel : BasePageViewModel() { * 入库操作 */ fun inStorage() { - val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + // 由Activity显示对话框 + } - // 收集所有选中的子列表项(库位) - val selectedStorageUseList = mutableListOf() - list.forEach { maWb -> - maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) } - } - - if (selectedStorageUseList.isEmpty()) { - showToast("请选择要入库的库位") + /** + * 执行入库操作 + * @param locationName 库位名称 (后端的location字段) + * @param locationId 库位ID (后端的locationId字段) + * @param maWbListForInStorage 包含选中子列表项的主列表数据 + */ + fun performInStorage( + locationName: String, + locationId: String, + maWbListForInStorage: List + ) { + if (maWbListForInStorage.isEmpty()) { + showToast("请至少选择一个单据") return } - // TODO: 实现入库接口调用 - showToast("入库功能待实现") + if (locationName.isEmpty() || locationId.isEmpty()) { + showToast("请选择库位") + return + } + + // 构建请求参数:库位名称 + 库位ID + 完整的主子列表结构 + val params = mapOf( + "location" to locationName, + "locationId" to locationId.toLongOrNull(), + "maWbList" to maWbListForInStorage + ).toRequestBody() + + launchLoadingCollect({ NetApply.api.inIntExpStorage(params) }) { + onSuccess = { + showToast("入库成功") + viewModelScope.launch { + FlowBus.with(ConstantEvent.EVENT_REFRESH).emit("refresh") + } + refresh() // 刷新列表 + } + onFailed = { _, msg -> + showToast(msg.noNull("入库失败")) + } + } } /** 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 553ffbf..158303f 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 @@ -240,7 +240,7 @@ diff --git a/module_gjc/src/main/res/layout/dialog_int_exp_in_storage.xml b/module_gjc/src/main/res/layout/dialog_int_exp_in_storage.xml new file mode 100644 index 0000000..8b64f3b --- /dev/null +++ b/module_gjc/src/main/res/layout/dialog_int_exp_in_storage.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 index 51537c3..ab52d8f 100644 --- 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 @@ -55,9 +55,10 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - type="@{SearchLayoutType.INPUT}" - hint='@{"请输入库位号"}' - value="@={model.location}" /> + type="@{SearchLayoutType.SPINNER}" + hint='@{"请选择库位"}' + list="@{model.locationList}" + value="@={model.selectedLocationCode}" />