diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 932eace..9a61963 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -222,6 +222,12 @@
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
+
+
+ /**
+ * 国际出港移库-详情
+ * 接口路径: /IntExpMove/detail
+ */
+ @POST("IntExpMove/detail")
+ suspend fun getIntExpMoveDetail(@Query("maWbId") maWbId: Long): BaseResultBean
+
+ /**
+ * 国际出港移库-编辑(仅更新备注与交接图片)
+ * 接口路径: /IntExpMove/update
+ */
+ @POST("IntExpMove/update")
+ suspend fun updateIntExpMove(@Body data: RequestBody): BaseResultBean
+
/**
* 国际出港库位操作-清仓
* 接口路径: /IntExpStorageUse/updateClear
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 ff0003c..8fe00d5 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
@@ -142,6 +142,7 @@ object ARouterConstants {
const val ACTIVITY_URL_INT_EXP_ASSEMBLE = "/gjc/IntExpAssembleActivity" //国际出港 出港组装
const val ACTIVITY_URL_INT_EXP_ASSEMBLE_START = "/gjc/IntExpAssembleStartActivity" //国际出港 开始组装
const val ACTIVITY_URL_INT_EXP_MOVE = "/gjc/IntExpMoveActivity" //国际出港 出港移库
+ const val ACTIVITY_URL_INT_EXP_MOVE_EDIT = "/gjc/IntExpMoveEditActivity" //国际出港 出港移库编辑/详情
const val ACTIVITY_URL_GJC_ASSEMBLE_ALLOCATE = "/gjc/GjcAssembleAllocateActivity" //国际出港 组装分配
const val ACTIVITY_URL_INT_EXP_OUT_HANDOVER = "/gjc/IntExpOutHandoverActivity" //国际出港 出库交接
const val ACTIVITY_URL_INT_EXP_LOAD = "/gjc/IntExpLoadActivity" //国际出港 出港装载
diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpMoveViewHolder.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpMoveViewHolder.kt
index e94899a..0173785 100644
--- a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpMoveViewHolder.kt
+++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/IntExpMoveViewHolder.kt
@@ -2,6 +2,7 @@ package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.databinding.ItemIntExpMoveBinding
+import com.lukouguoji.gjc.page.move.IntExpMoveEditActivity
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcMove
import com.lukouguoji.module_base.common.ConstantEvent
@@ -31,6 +32,17 @@ class IntExpMoveViewHolder(view: View) :
}
}
+ // 点击列表项进入移库详情
+ binding.ll.setOnClickListener {
+ IntExpMoveEditActivity.startForDetails(itemView.context, bean.maWbId)
+ }
+
+ // 侧滑菜单 - 编辑按钮
+ binding.btnEdit.setOnClickListener {
+ binding.swipeMenu.quickClose()
+ IntExpMoveEditActivity.startForEdit(itemView.context, bean.maWbId)
+ }
+
binding.executePendingBindings()
}
}
diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/page/move/IntExpMoveEditActivity.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/page/move/IntExpMoveEditActivity.kt
new file mode 100644
index 0000000..46c1759
--- /dev/null
+++ b/module_gjc/src/main/java/com/lukouguoji/gjc/page/move/IntExpMoveEditActivity.kt
@@ -0,0 +1,68 @@
+package com.lukouguoji.gjc.page.move
+
+import android.content.Context
+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.ActivityIntExpMoveEditBinding
+import com.lukouguoji.gjc.viewModel.IntExpMoveEditViewModel
+import com.lukouguoji.module_base.base.BaseBindingActivity
+import com.lukouguoji.module_base.common.Constant
+import com.lukouguoji.module_base.common.DetailsPageType
+import com.lukouguoji.module_base.ktx.addOnItemClickListener
+import com.lukouguoji.module_base.ktx.commonAdapter
+import com.lukouguoji.module_base.router.ARouterConstants
+
+/**
+ * 国际出港移库编辑/详情页
+ * 编辑模式仅支持拍照上传与备注修改
+ */
+@Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_MOVE_EDIT)
+class IntExpMoveEditActivity :
+ BaseBindingActivity() {
+
+ override fun layoutId() = R.layout.activity_int_exp_move_edit
+
+ override fun viewModelClass() = IntExpMoveEditViewModel::class.java
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ viewModel.initOnCreated(intent)
+
+ when (viewModel.pageType.value) {
+ DetailsPageType.Modify -> setBackArrow("国际出港移库编辑")
+ else -> setBackArrow("国际出港移库详情")
+ }
+
+ binding.viewModel = viewModel
+
+ // 绑定图片 RecyclerView 引用
+ viewModel.rvImages = binding.rvImages
+
+ // 绑定图片列表点击事件(编辑模式下可删除图片)
+ binding.rvImages.addOnItemClickListener(viewModel)
+
+ // 监听图片列表变化并更新 adapter
+ viewModel.imageList.observe(this) { images ->
+ binding.rvImages.commonAdapter()?.refresh(images)
+ }
+ }
+
+ companion object {
+ @JvmStatic
+ fun startForEdit(context: Context, maWbId: Long?) {
+ val starter = Intent(context, IntExpMoveEditActivity::class.java)
+ .putExtra(Constant.Key.PAGE_TYPE, DetailsPageType.Modify.name)
+ .putExtra(Constant.Key.ID, maWbId?.toString() ?: "")
+ context.startActivity(starter)
+ }
+
+ @JvmStatic
+ fun startForDetails(context: Context, maWbId: Long?) {
+ val starter = Intent(context, IntExpMoveEditActivity::class.java)
+ .putExtra(Constant.Key.PAGE_TYPE, DetailsPageType.Details.name)
+ .putExtra(Constant.Key.ID, maWbId?.toString() ?: "")
+ context.startActivity(starter)
+ }
+ }
+}
diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpMoveEditViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpMoveEditViewModel.kt
new file mode 100644
index 0000000..8d77367
--- /dev/null
+++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/IntExpMoveEditViewModel.kt
@@ -0,0 +1,164 @@
+package com.lukouguoji.gjc.viewModel
+
+import android.content.Intent
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.viewModelScope
+import androidx.recyclerview.widget.RecyclerView
+import com.lukouguoji.gjc.R
+import com.lukouguoji.module_base.base.BaseViewModel
+import com.lukouguoji.module_base.bean.FileBean
+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.common.DetailsPageType
+import com.lukouguoji.module_base.http.net.NetApply
+import com.lukouguoji.module_base.impl.FlowBus
+import com.lukouguoji.module_base.impl.ImageSelectNewViewHolder
+import com.lukouguoji.module_base.interfaces.IOnItemClickListener
+import com.lukouguoji.module_base.ktx.commonAdapter
+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.util.MediaUtil
+import com.lukouguoji.module_base.util.UploadUtil
+import kotlinx.coroutines.launch
+
+/**
+ * 国际出港移库编辑/详情 ViewModel
+ * 编辑模式仅支持修改备注与交接图片
+ */
+class IntExpMoveEditViewModel : BaseViewModel(), IOnItemClickListener {
+
+ val pageType = MutableLiveData(DetailsPageType.Details)
+ private var maWbId: Long = 0L
+
+ val dataBean = MutableLiveData(GjcMaWb())
+
+ // 备注单独用 LiveData 双向绑定,避免修改 data class 属性后需重新赋值
+ val remark = MutableLiveData("")
+
+ // 图片列表
+ val imageList = MutableLiveData>(mutableListOf())
+
+ // 图片适配器配置
+ val imageItemLayoutId = R.layout.item_image_select_new
+ val imageItemViewHolder = ImageSelectNewViewHolder::class.java
+
+ // 详情模式下无图片时显示占位提示
+ val showNoImage = MutableLiveData(false)
+
+ // 图片 RecyclerView 引用(用于从 adapter 实时获取图片)
+ var rvImages: RecyclerView? = null
+
+ fun initOnCreated(intent: Intent) {
+ pageType.value = DetailsPageType.valueOf(
+ intent.getStringExtra(Constant.Key.PAGE_TYPE) ?: DetailsPageType.Details.name
+ )
+ maWbId = intent.getStringExtra(Constant.Key.ID)?.toLongOrNull() ?: 0L
+ loadData()
+ }
+
+ private fun loadData() {
+ launchLoadingCollect({ NetApply.api.getIntExpMoveDetail(maWbId) }) {
+ onSuccess = {
+ val bean = it.data ?: GjcMaWb()
+ // 详情接口 wbNo 可能为空,回退为 前缀 + 运单号
+ if (bean.wbNo.isNullOrEmpty()) {
+ bean.wbNo = (bean.prefix ?: "") + (bean.no ?: "")
+ }
+ dataBean.value = bean
+ remark.value = bean.remark ?: ""
+
+ // 处理图片列表(同时保留缩略图和原图信息,确保二次编辑时不丢失)
+ val picList = (bean.pic ?: "").split(",").filter { p -> p.isNotEmpty() }
+ val originalPicList = (bean.originalPic ?: "").split(",").filter { p -> p.isNotEmpty() }
+ val images = if (picList.isNotEmpty()) {
+ picList.mapIndexed { index, picUrl ->
+ val originalUrl = originalPicList.getOrElse(index) { picUrl }
+ FileBean(
+ path = MediaUtil.fillUrl(originalUrl),
+ url = picUrl,
+ originalPic = originalUrl
+ )
+ }.toMutableList()
+ } else {
+ originalPicList.map { url ->
+ FileBean(path = MediaUtil.fillUrl(url), url = url, originalPic = url)
+ }.toMutableList()
+ }
+
+ // 编辑模式添加空 FileBean 用于显示“添加照片”按钮
+ if (pageType.value == DetailsPageType.Modify) {
+ images.add(FileBean())
+ }
+
+ imageList.value = images
+
+ // 详情模式下无图片时显示占位提示
+ showNoImage.value = pageType.value == DetailsPageType.Details && images.isEmpty()
+ }
+ }
+ }
+
+ /**
+ * 提交保存(只保存备注和图片)
+ */
+ fun submit() {
+ // 从 adapter 实时获取所有非空图片(ViewHolder 新增图片直接操作 adapter items)
+ val allItems = (rvImages?.commonAdapter()?.items as? List<*>)
+ ?.filterIsInstance() ?: imageList.value!!
+ val images = allItems.filter { it.path.isNotEmpty() }
+
+ if (images.size > 7) {
+ showToast("最多上传7张图片")
+ return
+ }
+
+ launchLoadingCollect({
+ // 上传本地新图片;已上传的图片保持原有 url 与 originalPic
+ images.forEach { fileBean ->
+ if (fileBean.url.isEmpty()) {
+ // UploadUtil 返回:newName=原图(较大),zipFileName=缩略图(较小)
+ // FileBean.url 用作缩略图标识,FileBean.originalPic 用作原图标识
+ val data = UploadUtil.upload(fileBean.path).data
+ fileBean.url = data?.zipFileName ?: ""
+ fileBean.originalPic = data?.newName ?: ""
+ }
+ }
+
+ val params = mapOf(
+ "maWbId" to maWbId,
+ "remark" to (remark.value ?: ""),
+ "picNumber" to images.size.toString(),
+ "pic" to images.joinToString(",") { MediaUtil.removeUrl(it.url) },
+ "originalPic" to images.joinToString(",") { MediaUtil.removeUrl(it.originalPic) },
+ ).toRequestBody(removeEmptyOrNull = true)
+
+ NetApply.api.updateIntExpMove(params)
+ }) {
+ onSuccess = {
+ showToast("保存成功")
+ viewModelScope.launch {
+ FlowBus.with(ConstantEvent.EVENT_REFRESH).emit("refresh")
+ }
+ getTopActivity().finish()
+ }
+ }
+ }
+
+ fun cancel() {
+ getTopActivity().finish()
+ }
+
+ /**
+ * 处理图片删除点击事件
+ */
+ override fun onItemClick(position: Int, type: Int) {
+ if (type == R.id.iv_delete) {
+ val adapter = rvImages?.commonAdapter() ?: return
+ if (position < adapter.items.size) {
+ adapter.removeItem(position)
+ }
+ }
+ }
+}
diff --git a/module_gjc/src/main/res/layout/activity_int_exp_move_edit.xml b/module_gjc/src/main/res/layout/activity_int_exp_move_edit.xml
new file mode 100644
index 0000000..28633fd
--- /dev/null
+++ b/module_gjc/src/main/res/layout/activity_int_exp_move_edit.xml
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/module_gjc/src/main/res/layout/item_int_exp_move.xml b/module_gjc/src/main/res/layout/item_int_exp_move.xml
index 2ecdcdf..1d8b225 100644
--- a/module_gjc/src/main/res/layout/item_int_exp_move.xml
+++ b/module_gjc/src/main/res/layout/item_int_exp_move.xml
@@ -21,8 +21,15 @@
android:layout_marginTop="10dp"
android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+