diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c752534..88a4303 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -133,6 +133,12 @@ android:configChanges="orientation|keyboardHidden" android:exported="false" android:screenOrientation="userLandscape" /> + + { + ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_INT_EXP_STORAGE_USE) + .navigation() + } /** * 国际进港 */ @@ -744,6 +749,14 @@ class HomeFragment : Fragment() { ) ) + list.add( + RightMenu( + Constant.AuthName.GjcIntExpStorageUse, + R.mipmap.gjc_cang_ku_icon, + "仓库" + ) + ) + // list.add( // RightMenu( // Constant.AuthName.GjcWareHouseActivity, 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 6dd6945..a9d05e1 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 @@ -243,9 +243,22 @@ data class GjcStorageUse( var maWbId: Long? = null, // 运单id var prefix: String? = null, // 运单前缀 var no: String? = null, // 运单号 - var storageCode: String? = null, // 库位号 + var location: String? = null, // 库位号 + var storageCode: String? = null, // 库位号(兼容字段) + var uld: String? = null, // 板箱号 var inDate: Date? = null, // 入库时间 - var inId: String? = null, // 入库人 + var inOpId: String? = null, // 入库人 + var inId: String? = null, // 入库人(兼容字段) var outDate: Date? = null, // 出库时间 - var outId: String? = null // 出库人 -) + var outOpId: String? = null, // 出库人 + var outId: String? = null // 出库人(兼容字段) +) { + // ==================== UI扩展字段 ==================== + @Transient + val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态 + + // 兼容现有API的isSelected属性 + var isSelected: Boolean + get() = checked.get() + set(value) = checked.set(value) +} diff --git a/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt b/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt index 85b98ec..0a0d4d8 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt @@ -253,6 +253,7 @@ interface Constant { const val GjcIntExpLoad = "AppIntExpLoad" //出港装载 const val GjcIntExpTally = "AppIntExpTally" //出港理货 const val GjcIntExpArrive = "AppIntExpArrive" //出港运抵 + const val GjcIntExpStorageUse = "AppIntExpStorageUse" //仓库 /** * 国际进港 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 714e402..27bbef5 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 @@ -811,6 +811,27 @@ interface Api { @POST("IntExpMove/move") suspend fun submitIntExpMove(@Body data: RequestBody): BaseResultBean + /** + * 国际出港仓库-分页查询 + * 接口路径: /IntExpStorageUse/pageQuery + */ + @POST("IntExpStorageUse/pageQuery") + suspend fun getIntExpStorageUseList(@Body data: RequestBody): PageInfo + + /** + * 国际出港仓库-分页合计 + * 接口路径: /IntExpStorageUse/pageQueryTotal + */ + @POST("IntExpStorageUse/pageQueryTotal") + suspend fun getIntExpStorageUseTotal(@Body data: RequestBody): BaseResultBean + + /** + * 国际出港仓库-运单号模糊查询(后四位) + * 接口路径: /IntExpStorageUse/queryWbNoList + */ + @POST("IntExpStorageUse/queryWbNoList") + suspend fun getIntExpStorageWbNoList(@Body data: RequestBody): BaseResultBean> + /** * 国际出港待计重-分页搜索 * 接口路径: /IntExpCheckIn/pageQuery diff --git a/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt b/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt index e11891a..747c193 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt @@ -146,6 +146,7 @@ object ARouterConstants { const val ACTIVITY_URL_INT_EXP_LOAD = "/gjc/IntExpLoadActivity" //国际出港 出港装载 const val ACTIVITY_URL_INT_EXP_TALLY = "/gjc/IntExpTallyActivity" //国际出港 出港理货 const val ACTIVITY_URL_INT_EXP_ARRIVE = "/gjc/IntExpArriveActivity" //国际出港 出港运抵 + const val ACTIVITY_URL_INT_EXP_STORAGE_USE = "/gjc/IntExpStorageUseActivity" //国际出港 仓库 ///////////////// 国际进港模块 /** 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 new file mode 100644 index 0000000..f876f58 --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/IntExpStorageUseActivity.kt @@ -0,0 +1,55 @@ +package com.lukouguoji.gjc.activity + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import com.alibaba.android.arouter.facade.annotation.Route +import com.lukouguoji.gjc.R +import com.lukouguoji.gjc.databinding.ActivityIntExpStorageUseBinding +import com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel +import com.lukouguoji.module_base.base.BaseBindingActivity +import com.lukouguoji.module_base.common.Constant +import com.lukouguoji.module_base.common.ConstantEvent +import com.lukouguoji.module_base.impl.FlowBus +import com.lukouguoji.module_base.impl.observe +import com.lukouguoji.module_base.router.ARouterConstants + +/** + * 国际出港-仓库 + */ +@Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_STORAGE_USE) +class IntExpStorageUseActivity : + BaseBindingActivity() { + + override fun layoutId() = R.layout.activity_int_exp_storage_use + override fun viewModelClass() = IntExpStorageUseViewModel::class.java + + override fun initOnCreate(savedInstanceState: Bundle?) { + setBackArrow("国际出港仓库") + binding.viewModel = viewModel + + // 观察全选状态,更新图标透明度 + viewModel.isAllChecked.observe(this) { isAllChecked -> + binding.checkIcon.alpha = if (isAllChecked) 1.0f else 0.5f + } + + // 绑定分页 + viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this) + + // 监听刷新事件 + FlowBus.with(ConstantEvent.EVENT_REFRESH).observe(this) { + viewModel.refresh() + } + + // 初始加载数据 + viewModel.refresh() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) { + viewModel.wbNo.value = data?.getStringExtra(Constant.Result.CODED_CONTENT) + viewModel.searchClick() + } + } +} 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 new file mode 100644 index 0000000..491e1a0 --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseSubViewHolder.kt @@ -0,0 +1,26 @@ +package com.lukouguoji.gjc.holder + +import android.view.View +import com.lukouguoji.gjc.databinding.ItemIntExpStorageUseSubBinding +import com.lukouguoji.module_base.base.BaseViewHolder +import com.lukouguoji.module_base.bean.GjcStorageUse + +/** + * 国际出港-仓库 库位明细行 ViewHolder + */ +class IntExpStorageUseSubViewHolder(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 { + bean.checked.set(!bean.checked.get()) + binding.executePendingBindings() + } + } +} 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 new file mode 100644 index 0000000..df097a0 --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpStorageUseViewHolder.kt @@ -0,0 +1,44 @@ +package com.lukouguoji.gjc.holder + +import android.view.View +import com.lukouguoji.gjc.R +import com.lukouguoji.gjc.databinding.ItemIntExpStorageUseBinding +import com.lukouguoji.module_base.adapter.setCommonAdapter +import com.lukouguoji.module_base.base.BaseViewHolder +import com.lukouguoji.module_base.bean.GjcMaWb +import com.lukouguoji.module_base.ktx.refresh + +/** + * 国际出港-仓库 ViewHolder + */ +class IntExpStorageUseViewHolder(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.ivIcon.setOnClickListener { + bean.checked.set(!bean.checked.get()) + binding.executePendingBindings() + } + + // 展开按钮点击事件 + binding.ivShow.setOnClickListener { + bean.showMore.set(!bean.showMore.get()) + } + + // 初始化库位明细子列表 RecyclerView + setCommonAdapter( + binding.rvSub, + IntExpStorageUseSubViewHolder::class.java, + R.layout.item_int_exp_storage_use_sub + ) + + // 刷新库位明细数据 + binding.rvSub.refresh(bean.storageUseList ?: emptyList()) + } +} 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 new file mode 100644 index 0000000..f1d77fb --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpStorageUseViewModel.kt @@ -0,0 +1,194 @@ +package com.lukouguoji.gjc.viewModel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import com.lukouguoji.gjc.R +import com.lukouguoji.gjc.holder.IntExpStorageUseViewHolder +import com.lukouguoji.module_base.base.BasePageViewModel +import com.lukouguoji.module_base.bean.GjcMaWb +import com.lukouguoji.module_base.common.Constant +import com.lukouguoji.module_base.common.ConstantEvent +import com.lukouguoji.module_base.http.net.NetApply +import com.lukouguoji.module_base.impl.FlowBus +import com.lukouguoji.module_base.ktx.commonAdapter +import com.lukouguoji.module_base.ktx.launchCollect +import com.lukouguoji.module_base.ktx.launchLoadingCollect +import com.lukouguoji.module_base.ktx.showToast +import com.lukouguoji.module_base.ktx.toRequestBody +import com.lukouguoji.module_base.model.ScanModel +import dev.utils.app.info.KeyValue +import kotlinx.coroutines.launch + +/** + * 国际出港-仓库 ViewModel + */ +class IntExpStorageUseViewModel : BasePageViewModel() { + + // ========== 筛选条件 ========== + val flightDate = MutableLiveData("") // 航班日期 + val flightNo = MutableLiveData("") // 航班号 + val clearResult = MutableLiveData("") // 清仓综合结果 + val clearResultList = MutableLiveData>() // 清仓综合结果列表 + val wbNo = MutableLiveData("") // 运单号 + val storageCode = MutableLiveData("") // 库位号 + + // ========== 统计信息 ========== + val totalWbNumber = MutableLiveData("0") // 总票数 + val totalPc = MutableLiveData("0") // 总件数 + val totalWeight = MutableLiveData("0") // 总重量 + + // ========== 全选状态 ========== + val isAllChecked = MutableLiveData(false) + + init { + // 初始化清仓综合结果列表(根据实际需求配置) + clearResultList.value = listOf( + KeyValue("全部", ""), + KeyValue("正常", "0"), + KeyValue("异常", "1") + ) + + // 监听全选状态,自动更新所有列表项 + isAllChecked.observeForever { checked -> + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return@observeForever + list.forEach { it.checked.set(checked) } + pageModel.rv?.commonAdapter()?.notifyDataSetChanged() + } + } + + // ========== 适配器配置 ========== + val itemViewHolder = IntExpStorageUseViewHolder::class.java + val itemLayoutId = R.layout.item_int_exp_storage_use + + /** + * 搜索按钮点击 + */ + fun searchClick() { + refresh() + } + + /** + * 全选按钮点击 + */ + fun checkAllClick() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + + val shouldCheckAll = !isAllChecked.value!! + list.forEach { it.checked.set(shouldCheckAll) } + isAllChecked.value = shouldCheckAll + + pageModel.rv?.commonAdapter()?.notifyDataSetChanged() + } + + /** + * 扫码运单号 + */ + fun scanWbNo() { + ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL) + } + + /** + * 清仓操作 + */ + fun clearStorage() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + val selectedItems = list.filter { it.isSelected } + + if (selectedItems.isEmpty()) { + showToast("请选择要清仓的运单") + return + } + + // TODO: 实现清仓接口调用 + showToast("清仓功能待实现") + } + + /** + * 修改库位 + */ + fun modifyStorage() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + val selectedItems = list.filter { it.isSelected } + + if (selectedItems.isEmpty()) { + showToast("请选择要修改库位的运单") + return + } + + // TODO: 实现修改库位接口调用或弹出对话框 + showToast("修改库位功能待实现") + } + + /** + * 出库操作 + */ + fun outStorage() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + val selectedItems = list.filter { it.isSelected } + + if (selectedItems.isEmpty()) { + showToast("请选择要出库的运单") + return + } + + // TODO: 实现出库接口调用 + showToast("出库功能待实现") + } + + /** + * 入库操作 + */ + fun inStorage() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + val selectedItems = list.filter { it.isSelected } + + if (selectedItems.isEmpty()) { + showToast("请选择要入库的运单") + return + } + + // TODO: 实现入库接口调用 + showToast("入库功能待实现") + } + + /** + * 获取数据 (重写BasePageViewModel) + */ + override fun getData() { + // 构建搜索条件 + val filterParams = mapOf( + "fdate" to flightDate.value?.ifEmpty { null }, + "fno" to flightNo.value?.ifEmpty { null }, + "wbNo" to wbNo.value?.ifEmpty { null }, + "storageCode" to storageCode.value?.ifEmpty { null } + ) + + // 列表参数 (含分页) + val listParams = (filterParams + mapOf( + "pageNum" to pageModel.page, + "pageSize" to pageModel.limit + )).toRequestBody() + + // 统计参数 (无分页) + val totalParams = filterParams.toRequestBody() + + // 获取列表 (带Loading) + launchLoadingCollect({ NetApply.api.getIntExpStorageUseList(listParams) }) { + onSuccess = { result -> + // 手动处理 PageInfo 数据 + pageModel.handleDataList(result.list) + pageModel.haveMore.postValue((result.pages) > pageModel.page) + } + } + + // 获取统计信息 (后台请求,不阻塞列表) + launchCollect({ NetApply.api.getIntExpStorageUseTotal(totalParams) }) { + onSuccess = { result -> + val data = result.data + totalWbNumber.value = (data?.wbNumber ?: 0).toString() + totalPc.value = (data?.totalPc ?: 0).toString() + totalWeight.value = (data?.totalWeight ?: 0.0).toString() + } + } + } +} 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 new file mode 100644 index 0000000..b17b796 --- /dev/null +++ b/module_gjc/src/main/res/layout/activity_int_exp_storage_use.xml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/item_int_exp_storage_use.xml b/module_gjc/src/main/res/layout/item_int_exp_storage_use.xml new file mode 100644 index 0000000..5df4666 --- /dev/null +++ b/module_gjc/src/main/res/layout/item_int_exp_storage_use.xml @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/item_int_exp_storage_use_sub.xml b/module_gjc/src/main/res/layout/item_int_exp_storage_use_sub.xml new file mode 100644 index 0000000..a5dcc3d --- /dev/null +++ b/module_gjc/src/main/res/layout/item_int_exp_storage_use_sub.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +