feat: 新增图片选择控件并修正事故签证字段

- 新增 ImageSelectNewViewHolder 和 item_image_select_new 布局,支持正方形缩略图、
  加号按钮始终在末尾、详情模式隐藏加号及"暂无图片"占位
- 国际事故签证编辑页和国内进港移交页应用新图片选择控件
- 修正事故签证字段:reweight → reWeight,opName/opDate → opId/opdate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-26 12:02:16 +08:00
parent 88bbd73fa1
commit 3918ad64d6
18 changed files with 1311 additions and 573 deletions

View File

@@ -10,12 +10,12 @@ class GjAccidentVisaEditBean {
var dpc: String = "" // 不正常件数
var pc: String = "" // 运单总件数
var weight: String = "" // 运单总重量
var reweight: String = "" // 复称重量
var reWeight: String = "" // 复称重量
var goods: String = "" // 品名
var opacking: String = "" // 外包装
var damage: String = "" // 包装破损情况
var condition: String = "" // 内容物情况
var problem: String = "" // 不正常类型
var kdamage: String = "" // 不正常类型
var seachDate: String = "" // 发现时间
var photo: String = "" // 图片是否留底
var remarks: String = "" // 备注

View File

@@ -16,14 +16,19 @@ class GnjYiKuBean : ICheck {
var agentCode: String = "" // 代理人
var goods: String = "" // 品名
var flight: String = "" // 进港航班(格式: 20240712/MU2023)
var route: String = "" // 航程(格式: LAX-PEK-HFE)
var route: String = "" // 航程(格式: LAX-PEK-HFE)(旧接口字段)
var range: String = "" // 航程(格式: LAX-PEK-HFE)GnjMawb 接口字段)
var origin: String = "" // 始发港
var dest: String = "" // 目的港
var awbType: String = "" // 运单类型(转国际进港/转国内出港等)
var telegramNo: String = "" // 电报号
var telegramNo: String = "" // 电报号(旧接口字段)
var telegramId: String = "" // 电报号GnjMawb 接口字段)
var remark: String = "" // 备注
var handoverStatus: String = "" // 移交状态(未移交/已移交)
var images: String = "" // 交接图片(逗号分隔的URL列表)
var originalPic: String = "" // 交接图片原图地址
var pic: String = "" // 交接图片缩略图
var picNumber: String = "" // 交接图片数量
var fdate: String = "" // 航班日期
var fno: String = "" // 航班号
var businessType: String = "" // 业务类型
@@ -41,10 +46,17 @@ class GnjYiKuBean : ICheck {
* 获取图片列表
*/
fun getImageList(): List<String> {
return if (images.isNotEmpty()) {
images.split(",").filter { it.isNotEmpty() }
val source = originalPic.ifEmpty { images }
return if (source.isNotEmpty()) {
source.split(",").filter { it.isNotEmpty() }
} else {
emptyList()
}
}
/** 获取航程(兼容新旧接口) */
fun getRouteDisplay(): String = range.ifEmpty { route }
/** 获取电报号(兼容新旧接口) */
fun getTelegramDisplay(): String = telegramId.ifEmpty { telegramNo }
}

View File

@@ -12,8 +12,8 @@ class IntImpAccidentVisaBean {
var totalPc: Int = 0 // 运单总件数
var totalWeight: Double = 0.0 // 运单总重量
var abnPc: Int = 0 // 不正常件数
var opName: String = "" // 经办人
var opDate: String = "" // 经办时间
var opId: String = "" // 经办人
var opdate: String = "" // 经办时间
val checked: ObservableBoolean = ObservableBoolean(false)

View File

@@ -1744,6 +1744,18 @@ interface Api {
@POST("DomImpMove/save")
suspend fun saveGnjYiKu(@Body data: RequestBody): BaseResultBean<SimpleResultBean>
/**
* 获取-国内进港移库-详情(新接口)
*/
@GET("DomImpMove/detail")
suspend fun getGnjMoveStashDetail(@Query("mawbId") mawbId: String): BaseResultBean<GnjYiKuBean>
/**
* 编辑-国内进港移库(新接口)
*/
@POST("DomImpMove/modify")
suspend fun modifyGnjMoveStash(@Body data: RequestBody): BaseResultBean<String>
/**
* 执行-国内进港移库操作
*/

View File

@@ -0,0 +1,66 @@
package com.lukouguoji.module_base.impl
import android.view.View
import android.view.ViewTreeObserver
import com.lukouguoji.module_base.adapter.loadImage
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.FileBean
import com.lukouguoji.module_base.databinding.ItemImageSelectNewBinding
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.logd
import com.lukouguoji.module_base.ktx.loge
import com.lukouguoji.module_base.ui.page.preview.PreviewActivity
import com.lukouguoji.module_base.util.MediaUtil
class ImageSelectNewViewHolder(view: View) : BaseViewHolder<FileBean, ItemImageSelectNewBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item)!!
binding.bean = bean
// 让高度等于宽度,实现正方形
binding.rl.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
binding.rl.viewTreeObserver.removeOnGlobalLayoutListener(this)
val width = binding.rl.width
if (width > 0 && binding.rl.height != width) {
val lp = binding.rl.layoutParams
lp.height = width
binding.rl.layoutParams = lp
}
}
})
binding.rl.setOnClickListener {
if (bean.path.isEmpty()) {
MediaUtil.pickImage(itemView.context, maxNum = 10) { results ->
val adapter = getRecyclerView()?.commonAdapter() ?: return@pickImage
results.forEach { result ->
logd("添加了图片 : ${result.realPath}")
// 在加号按钮(最后一项)之前插入图片
val insertPos = adapter.items.size - 1
adapter.items.add(insertPos, FileBean(path = result.realPath))
adapter.notifyItemInserted(insertPos)
}
}
} else {
PreviewActivity.start(itemView.context, listOf(bean))
}
}
// 长按事件
binding.rl.setOnLongClickListener {
clickListener?.onItemClick(bindingAdapterPosition, binding.rl.id)
true
}
notifyItemClick(position, binding.ivDelete)
if (bean.isOnlineResource()) {
loge("开始下载 : ${bean.path}")
bean.download {
loadImage(binding.iv, it)
}
}
}
}

View File

@@ -106,6 +106,7 @@ object ARouterConstants {
const val ACTIVITY_URL_GNJ_YIKU_LIST = "/gnj/GnjYiKuListActivity" //国内进港 移库列表
const val ACTIVITY_URL_GNJ_YIKU_DETAILS = "/gnj/GnjYiKuDetailsActivity" //国内进港 移库详情
const val ACTIVITY_URL_GNJ_YIKU_EDIT = "/gnj/GnjYiKuEditActivity" //国内进港 移库编辑
const val ACTIVITY_URL_GNJ_YIKU_HANDOVER = "/gnj/GnjYiKuHandoverActivity" //国内进港 移交编辑/详情
///////////////// 国际出港模块
/**

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.FileBean" />
</data>
<RelativeLayout
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="5dp"
android:background="@color/white">
<ImageView
visible="@{bean.path.length() == 0}"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:src="@drawable/img_add" />
<ImageView
android:id="@+id/iv"
loadImage="@{bean.path}"
visible="@{bean.path}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<View
visible="@{bean.canDelete}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black_tran10" />
<ImageView
android:id="@+id/iv_delete"
visible="@{bean.canDelete}"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerInParent="true"
android:src="@drawable/img_delete_red" />
</RelativeLayout>
</layout>