Compare commits

..

8 Commits

Author SHA1 Message Date
623ebc22f7 feat: opt pic 2026-04-17 14:59:16 +08:00
1157a0c4ed fix: 修复图片上传字段语义颠倒及加载缺失鉴权头导致的 403
- 修正 UploadUtil 返回字段到 FileBean 的映射:
  newName 是原图(较大)、zipFileName 是缩略图(较小)
- 保证 bean.pic 存缩略图、bean.originalPic 存原图
- 全局 loadImage BindingAdapter 对 http(s) URL 自动包装
  GlideUrl + Authorization,避免 /file/getImg/ 接口 403
- ImageSelectViewHolder 缩略图带鉴权加载,点击预览传原图
- 覆盖国内/国际事故签证、国内进港移库/移交编辑页面
- CLAUDE.md 同步修正 UploadBean 字段语义文档

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 14:57:26 +08:00
6ad7f0d3d4 fix: fix 国内出港出库 2026-04-16 17:10:07 +08:00
9d7453d3ee fix: 进港舱单编辑页运单号改用 prefix+no 拼接取值
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 17:47:21 +08:00
60478327e2 fix: 修复图片二次编辑丢失旧图及预览模糊问题
- 国内进港移交编辑:loadData 时同时从 pic/originalPic 构建
  FileBean,确保二次编辑保存时原有图片不被覆盖
- 国际事故签证:loadDetail 改用 originalPic URL 作为 FileBean.path,
  保证全屏预览取原图而非缩略图;同时修正保存时 pic/originalPic 字段赋值颠倒的问题

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 15:02:54 +08:00
1d2b11bfd2 refactor: 确保舱单编辑页保存时始终传递 no 和 prefix 参数
重构 GjjManifestAddViewModel 的参数构建方式:
- 改用 mutableMapOf 手动处理可选字段,替代 removeEmptyOrNull = true
- 编辑模式下 mfId、no、prefix 单独追加,不受空字符串过滤影响

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 14:50:28 +08:00
4117cbb489 fix: 修复国际进港仓库入库接口参数格式,去除主子列表选中联动,更新分单理货报告字段
- 入库接口请求体改为 {location, locationId, warehouseList} 结构
- 移除主列表与子列表之间的双向选中联动,保留全选按钮同时选中两者
- 舱单子列表理货报告字段从 lastMftStatus 改为 tallyStatus
- GjjHaWb 新增 tallyStatus 字段

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 14:13:22 +08:00
4451b790de fix: 国际进港装机单编辑页库位号取 locationTally,查询详情运单信息取 awbPc/awbWeight
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 13:42:03 +08:00
19 changed files with 204 additions and 176 deletions

View File

@@ -1013,21 +1013,21 @@ companion object {
上传图片后提交表单时,**必须同时传 `pic``originalPic``picNumber` 三个字段**,缺一不可。
**`UploadUtil.upload()` 返回值**:
- `data?.newName`缩略图/压缩图文件名
- `data?.zipFileName`原图文件名
**`UploadUtil.upload()` 返回值**(注意:**与字面意思相反**:
- `data?.newName`**原图**文件名(较大)
- `data?.zipFileName`**缩略图/压缩图**文件名(较小)
**提交时字段映射**(参考事故签证 `AccidentVisaDetailsViewModel`:
**提交时字段映射**(参考事故签证 `AccidentVisaDetailsViewModel``IntImpAccidentVisaEditViewModel`:
```kotlin
// FileBean 字段含义:
// - FileBean.url = newName缩略图文件名
// - FileBean.originalPic = zipFileName原图文件名
// FileBean 字段含义(约定用途,与 UploadBean 字段名不一致)
// - FileBean.url 作缩略图标识(提交到 bean.pic
// - FileBean.originalPic 作原图标识(提交到 bean.originalPic
// 上传新图片
// 上传新图片(注意 UploadBean 字段名的误导性,按实际含义赋值)
val data = UploadUtil.upload(fileBean.path).data
fileBean.url = data?.newName ?: ""
fileBean.originalPic = data?.zipFileName ?: ""
fileBean.url = data?.zipFileName ?: "" // 缩略图
fileBean.originalPic = data?.newName ?: "" // 原图
// 提交时设置三个字段
bean.picNumber = list.size.toString()
@@ -1037,7 +1037,8 @@ bean.originalPic = list.joinToString(",") { MediaUtil.removeUrl(it.originalPic)
**常见错误**:
- ❌ 只传 `images``originalPic` 单个字段 — 接口不认或数据不完整
- ❌ 只取 `newName` 不取 `zipFileName` — 丢失原图路径
- ❌ 只取 `newName` 不取 `zipFileName` — 丢失缩略图/原图之一
- ❌ 按 `UploadBean` 字段字面含义赋值(`url = newName`)— 会导致 pic/originalPic 内容和字段语义颠倒(缩略图字段装原图、原图字段装缩略图)
- ❌ 用 `fileBean.path.startsWith("http")` 判断已上传 — 应该用 `fileBean.url.isNotEmpty()`
### 编辑页加载已有图片

View File

@@ -75,23 +75,18 @@ class AccidentVisaDetailsViewModel : BaseViewModel(), IOnItemClickListener {
onSuccess = {
dataBean.value = it.data ?: AccidentVisaBean()
// 渲染图片
val list = dataBean.value!!.pic.split(",")
.filter { url -> url.isNotEmpty() }
.map { url ->
FileBean(MediaUtil.fillUrl(url), url)
// 渲染图片pic 存缩略图文件名originalPic 存原图文件名
val picList = dataBean.value!!.pic.split(",").filter { it.isNotEmpty() }
val originalPicList = dataBean.value!!.originalPic.split(",").filter { it.isNotEmpty() }
val list = picList.mapIndexed { index, picFilename ->
val originalFilename = originalPicList.getOrElse(index) { picFilename }
FileBean(
path = MediaUtil.fillUrl(picFilename),
url = picFilename,
originalPic = MediaUtil.fillUrl(originalFilename)
)
}
val zipList = dataBean.value!!.originalPic.split(",")
.filter { url -> url.isNotEmpty() }
.map { url ->
FileBean(MediaUtil.fillUrl(url))
}
for ((index, fileBean) in list.withIndex()) {
val originalPic = zipList.get(index).path
list.get(index).originalPic = originalPic
}
rv?.commonAdapter()
?.loadMore(list)
rv?.commonAdapter()?.loadMore(list)
}
}
}
@@ -110,8 +105,10 @@ class AccidentVisaDetailsViewModel : BaseViewModel(), IOnItemClickListener {
.filter { it.path.isNotEmpty() && it.url.isEmpty() }
.onEach {
val data = UploadUtil.upload(it.path).data
it.url = data?.newName ?: ""
it.originalPic = data?.zipFileName ?: ""
// UploadUtil 返回newName=原图(较大)zipFileName=缩略图(较小)
// FileBean.url 用作缩略图标识FileBean.originalPic 用作原图标识
it.url = data?.zipFileName ?: ""
it.originalPic = data?.newName ?: ""
}
.flowOn(Dispatchers.IO)
.onStart { showLoading() }
@@ -124,8 +121,8 @@ class AccidentVisaDetailsViewModel : BaseViewModel(), IOnItemClickListener {
val list =
(rv?.commonAdapter()?.items as List<FileBean>).filter { it.path.isNotEmpty() }
bean.picnumber = list.size.toString()
bean.originalPic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.url) }
bean.pic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.originalPic) }
bean.pic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.url) }
bean.originalPic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.originalPic) }
NetApply.api.anyPost(
url = if (pageType.value == DetailsPageType.Add) "GnAccidentVisa/saveVisa" else "GnAccidentVisa/updateVisa",

View File

@@ -37,6 +37,7 @@ import com.lukouguoji.gnc.page.deposit.list.GncDepositListActivity
import com.lukouguoji.gnc.page.distribution.home.GncDistributionHomeActivity
import com.lukouguoji.gnc.page.fubang.list.GncFuBangListActivity
import com.lukouguoji.gnc.page.shouyun.unlist.GncShouYunUnListActivity
import com.lukouguoji.gnj.activity.GnjChuKuListActivity
import com.lukouguoji.module_base.MyApplication
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
@@ -314,7 +315,8 @@ class HomeFragment : Fragment() {
}
//出库
Constant.AuthName.GnjChuKuList -> {
GnjMoveStashListActivity.start(requireContext())
ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_GNJ_CHU_KU_LIST)
.navigation()
}
//仓库管理
Constant.AuthName.GnjWareHouse -> {

View File

@@ -12,12 +12,16 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.model.LazyHeaders
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.GranularRoundedCorners
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.base.CommonAdapter
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
import com.lukouguoji.module_base.ktx.loge
import com.lukouguoji.module_base.util.SizeUtils
@@ -111,10 +115,22 @@ fun loadImage(
com.bumptech.glide.request.target.Target.SIZE_ORIGINAL
)
// 对 http(s) 字符串 URL自动包装为带 Authorization header 的 GlideUrl避免 /file/getImg/ 接口 403
val actualSource: Any? = if (source is String && (source.startsWith("http://") || source.startsWith("https://"))) {
GlideUrl(
source,
LazyHeaders.Builder()
.addHeader("Authorization", SharedPreferenceUtil.getString(Constant.Share.token))
.build()
)
} else {
source
}
// 设置图片加载
val load = Glide.with(imageView)
.setDefaultRequestOptions(requestOptions)
.load(source)
.load(actualSource)
.diskCacheStrategy(diskCacheStrategy)
.encodeFormat(encodeFormat)

View File

@@ -29,7 +29,8 @@ data class GjjHaWb(
var opDate: String = "",
var billsNo: String = "",
var remark: String = "",
var response: String = ""
var response: String = "",
var tallyStatus: String = ""
) : Serializable {
@Transient
val checked: ObservableBoolean = ObservableBoolean(false)

View File

@@ -963,7 +963,7 @@ interface Api {
* 接口路径: /IntImpStorage/inStorage
*/
@POST("IntImpStorage/inStorage")
suspend fun inIntImpStorage(@Query("location") location: String, @Body data: RequestBody): BaseResultBean<Boolean>
suspend fun inIntImpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港提取记录-分页查询

View File

@@ -1,17 +1,19 @@
package com.lukouguoji.module_base.impl
import android.view.View
import com.luck.picture.lib.adapter.holder.PreviewImageHolder
import com.luck.picture.lib.basic.PictureSelector
import com.lukouguoji.module_base.adapter.loadImage
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.model.LazyHeaders
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.FileBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.databinding.ItemImageSelectBinding
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
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
import java.io.File
class ImageSelectViewHolder(view: View) : BaseViewHolder<FileBean, ItemImageSelectBinding>(view) {
@@ -19,6 +21,21 @@ class ImageSelectViewHolder(view: View) : BaseViewHolder<FileBean, ItemImageSele
val bean = getItemBean(item)!!
binding.bean = bean
// 加载缩略图
if (bean.path.isNotEmpty()) {
if (bean.isOnlineResource()) {
val glideUrl = GlideUrl(
bean.path,
LazyHeaders.Builder()
.addHeader("Authorization", SharedPreferenceUtil.getString(Constant.Share.token))
.build()
)
Glide.with(itemView.context).load(glideUrl).into(binding.iv)
} else {
Glide.with(itemView.context).load(File(bean.path)).into(binding.iv)
}
}
binding.rl.setOnClickListener {
if (bean.path.isEmpty()) {
MediaUtil.pickImage(itemView.context, maxNum = 10) {
@@ -28,7 +45,15 @@ class ImageSelectViewHolder(view: View) : BaseViewHolder<FileBean, ItemImageSele
}
}
} else {
PreviewActivity.start(itemView.context, listOf(bean))
val items = getRecyclerView()?.commonAdapter()?.items
?.filterIsInstance<FileBean>()
?.filter { it.path.isNotEmpty() }
?: listOf(bean)
val previewList = items.map { fb ->
FileBean(path = if (fb.originalPic.isNotEmpty()) fb.originalPic else fb.path)
}
val previewPosition = items.indexOfFirst { it === bean }.coerceAtLeast(0)
PreviewActivity.start(itemView.context, previewList, previewPosition)
}
}
@@ -39,13 +64,6 @@ class ImageSelectViewHolder(view: View) : BaseViewHolder<FileBean, ItemImageSele
}
notifyItemClick(position, binding.ivDelete)
if (bean.isOnlineResource()) {
loge("开始下载 : ${bean.path}")
bean.download {
loadImage(binding.iv, it)
}
}
}
}

View File

@@ -24,7 +24,6 @@
<ImageView
android:id="@+id/iv"
loadImage="@{bean.path}"
visible="@{bean.path}"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@@ -1,10 +1,8 @@
package com.lukouguoji.gjj.holder
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.gjj.databinding.ItemIntImpStorageUseSubBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.bean.GjcStorageUse
/**
@@ -19,27 +17,10 @@ class IntImpStorageUseSubViewHolder(view: View) :
binding.position = position
binding.executePendingBindings()
// 单选框点击切换选择状态(反向联动主列表)
// 单选框点击切换选择状态
binding.ivCheckbox.setOnClickListener {
// 切换子列表项的选择状态
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
// 反向联动主列表项(仅在勾选时联动)
updateParentCheckState(newCheckedState)
}
}
/**
* 更新父列表项的选择状态
*/
private fun updateParentCheckState(newCheckedState: Boolean) {
val recyclerView = itemView.parent as? RecyclerView ?: return
val parentBean = recyclerView.tag as? GjcMaWb ?: return
if (newCheckedState) {
parentBean.checked.set(true)
}
}
}

View File

@@ -20,18 +20,10 @@ class IntImpStorageUseViewHolder(view: View) :
binding.position = position
binding.executePendingBindings()
// 图标点击切换选择状态(联动子列表)
// 图标点击切换选择状态
binding.ivIcon.setOnClickListener {
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
// 联动勾选/取消所有子列表项
bean.storageUseList?.forEach { storageUse ->
storageUse.checked.set(newCheckedState)
}
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
binding.rvSub.adapter?.notifyDataSetChanged()
}
// 展开按钮点击事件

View File

@@ -279,7 +279,7 @@ class GjjManifestAddViewModel : BaseViewModel() {
prefix = manifest.prefix
// 填充表单字段
waybillNo.value = manifest.wbNo
waybillNo.value = manifest.getWaybillNo()
waybillNum.value = manifest.totalPc.toString()
actualNum.value = manifest.pc.toString()
actualWeight.value = manifest.weight.toString()
@@ -309,7 +309,7 @@ class GjjManifestAddViewModel : BaseViewModel() {
prefix = manifest.prefix
// 填充表单字段
waybillNo.value = manifest.wbNo
waybillNo.value = "${manifest.prefix}${manifest.no}"
waybillNum.value = manifest.totalPc.toString()
actualNum.value = manifest.pc.toString()
actualWeight.value = manifest.weight.toString()
@@ -373,11 +373,10 @@ class GjjManifestAddViewModel : BaseViewModel() {
return
}
val params = mapOf(
"mfId" to if (pageType.value == DetailsPageType.Modify) mfId else null,
val isModify = pageType.value == DetailsPageType.Modify
val paramsMap = mutableMapOf<String, Any?>(
"fid" to fid,
"no" to if (pageType.value == DetailsPageType.Modify) no else null,
"prefix" to if (pageType.value == DetailsPageType.Modify) prefix else null,
"wbNo" to waybillNo.value,
"agentCode" to agent.value,
"spCode" to specialCode.value.let { if (it.isNullOrEmpty()) "NOR" else it },
@@ -386,19 +385,30 @@ class GjjManifestAddViewModel : BaseViewModel() {
"pc" to actualNum.value,
"weight" to actualWeight.value,
"cashWeight" to billingWeight.value,
"packageType" to packageType.value,
"origin" to departure.value,
"dest" to destination.value,
"goods" to goodsNameEn.value,
"goodsCn" to goodsNameCn.value,
"awbType" to waybillType.value,
"cargoType" to goodsType.value,
"unNumber" to unNumber.value,
"remark" to remark.value,
).toRequestBody(removeEmptyOrNull = true)
)
// 可选字段:非空时才传
if (!packageType.value.isNullOrEmpty()) paramsMap["packageType"] = packageType.value
if (!goodsType.value.isNullOrEmpty()) paramsMap["cargoType"] = goodsType.value
if (!unNumber.value.isNullOrEmpty()) paramsMap["unNumber"] = unNumber.value
if (!remark.value.isNullOrEmpty()) paramsMap["remark"] = remark.value
// 编辑模式:必须传 mfId、no、prefix不受空字符串过滤影响
if (isModify) {
paramsMap["mfId"] = mfId
paramsMap["no"] = no
paramsMap["prefix"] = prefix
}
val params = paramsMap.toRequestBody()
launchLoadingCollect({
if (pageType.value == DetailsPageType.Modify) {
if (isModify) {
NetApply.api.gjjManifestUpdate(params)
} else {
NetApply.api.gjjManifestInsert(params)
@@ -406,7 +416,7 @@ class GjjManifestAddViewModel : BaseViewModel() {
}) {
onSuccess = {
if (it.verifySuccess()) {
val successMsg = if (pageType.value == DetailsPageType.Modify) "修改成功" else "保存成功"
val successMsg = if (isModify) "修改成功" else "保存成功"
showToast(successMsg)
// 发送刷新事件

View File

@@ -144,20 +144,19 @@ class IntImpAccidentVisaEditViewModel : BaseViewModel(), IOnItemClickListener {
onSuccess = {
dataBean.value = it.data ?: GjAccidentVisaEditBean()
// 渲染图片
// 渲染图片path 取原图 URL 确保预览清晰url 取缩略图用于提交
val bean = dataBean.value!!
val picList = bean.pic.split(",")
.filter { url -> url.isNotEmpty() }
.map { url -> FileBean(MediaUtil.fillUrl(url), url) }
val originalList = bean.originalPic.split(",")
.filter { url -> url.isNotEmpty() }
.map { url -> FileBean(MediaUtil.fillUrl(url)) }
for ((index, fileBean) in picList.withIndex()) {
if (index < originalList.size) {
picList[index].originalPic = originalList[index].path
val picList = bean.pic.split(",").filter { it.isNotEmpty() }
val originalList = bean.originalPic.split(",").filter { it.isNotEmpty() }
val images = picList.mapIndexed { index, picUrl ->
val originalUrl = originalList.getOrElse(index) { picUrl }
FileBean(
path = MediaUtil.fillUrl(originalUrl),
url = picUrl,
originalPic = originalUrl
)
}
}
rv?.commonAdapter()?.loadMore(picList)
rv?.commonAdapter()?.loadMore(images)
// 详情模式下无图片时显示占位提示
if (isDetailMode.value == true && picList.isEmpty()) {
@@ -278,8 +277,10 @@ class IntImpAccidentVisaEditViewModel : BaseViewModel(), IOnItemClickListener {
.filter { it.path.isNotEmpty() && it.url.isEmpty() }
.onEach {
val data = UploadUtil.upload(it.path).data
it.url = data?.newName ?: ""
it.originalPic = data?.zipFileName ?: ""
// UploadUtil 返回newName=原图(较大)zipFileName=缩略图(较小)
// FileBean.url 用作缩略图标识FileBean.originalPic 用作原图标识
it.url = data?.zipFileName ?: ""
it.originalPic = data?.newName ?: ""
}
.flowOn(Dispatchers.IO)
.onStart { showLoading() }
@@ -292,8 +293,8 @@ class IntImpAccidentVisaEditViewModel : BaseViewModel(), IOnItemClickListener {
val list = (rv?.commonAdapter()?.items as List<FileBean>)
.filter { it.path.isNotEmpty() }
bean.picNumber = list.size.toString()
bean.originalPic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.url) }
bean.pic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.originalPic) }
bean.pic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.url) }
bean.originalPic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.originalPic) }
bean.idFlag = "1"
if (pageType.value == DetailsPageType.Add) {

View File

@@ -36,7 +36,7 @@ class IntImpLoadingListEditViewModel : BaseViewModel() {
val bean = Gson().fromJson(jsonData, GjjManifest::class.java)
dataBean.value = bean
// 初始化可编辑字段
location.value = bean.location
location.value = bean.locationTally
totalPcStr.value = bean.totalPc.toString()
pcStr.value = bean.pc.toString()
weightStr.value = bean.weight.toString()
@@ -58,7 +58,6 @@ class IntImpLoadingListEditViewModel : BaseViewModel() {
val bean = dataBean.value ?: return
// 同步可编辑字段回 bean
bean.location = location.value ?: ""
bean.totalPc = totalPcStr.value?.toLongOrNull() ?: 0
bean.pc = pcStr.value?.toLongOrNull() ?: 0
bean.weight = weightStr.value?.toDoubleOrNull() ?: 0.0

View File

@@ -230,9 +230,13 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
return
}
val body = maWbListForInStorage.toRequestBody()
val body = mapOf(
"location" to locationName,
"locationId" to locationId.toLongOrNull(),
"warehouseList" to maWbListForInStorage
).toRequestBody()
launchLoadingCollect({ NetApply.api.inIntImpStorage(locationName, body) }) {
launchLoadingCollect({ NetApply.api.inIntImpStorage(body) }) {
onSuccess = {
showToast("入库成功")
viewModelScope.launch {

View File

@@ -148,20 +148,10 @@
title='@{"品名(中)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.goodsCn}'
value='@{viewModel.dataBean.goods}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"品名(英)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.goodsEn}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
android:layout_weight="2" />
</LinearLayout>

View File

@@ -83,7 +83,7 @@
title='@{"运单件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("pc") != null ? String.valueOf((int)Math.round(((Double)viewModel.maWbData.get("pc")))) : ``}' />
value='@{viewModel.maWbData.get("awbPc") != null ? String.valueOf((int)Math.round(((Double)viewModel.maWbData.get("awbPc")))) : ``}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
@@ -93,7 +93,7 @@
title='@{"运单重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("weight") != null ? String.valueOf(viewModel.maWbData.get("weight")) : ``}' />
value='@{viewModel.maWbData.get("awbWeight") != null ? String.valueOf(viewModel.maWbData.get("awbWeight")) : ``}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"

View File

@@ -104,7 +104,7 @@
android:gravity="center"
android:maxLines="1"
android:ellipsize="end"
android:text="@{bean.lastMftStatus ?? ``}"
android:text="@{bean.tallyStatus ?? ``}"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />

View File

@@ -72,7 +72,7 @@ class GnjYiKuEditViewModel : BaseViewModel(), IOnItemClickListener {
val bean = it.data ?: GnjYiKuBean()
dataBean.value = bean
// 处理图片列表pic=缩略图(newName)originalPic=原图(zipFileName)
// 处理图片列表pic 字段存缩略图文件名originalPic 字段存原图文件名
val picList = bean.pic.split(",").filter { it.isNotEmpty() }
val originalPicList = bean.originalPic.split(",").filter { it.isNotEmpty() }
val images = picList.mapIndexed { index, picUrl ->
@@ -123,9 +123,11 @@ class GnjYiKuEditViewModel : BaseViewModel(), IOnItemClickListener {
// 已上传的图片,保持原有的 url 和 originalPic
} else {
// 本地新图片需要上传
// UploadUtil 返回newName=原图(较大)zipFileName=缩略图(较小)
// FileBean.url 用作缩略图标识FileBean.originalPic 用作原图标识
val data = UploadUtil.upload(fileBean.path).data
fileBean.url = data?.newName ?: ""
fileBean.originalPic = data?.zipFileName ?: ""
fileBean.url = data?.zipFileName ?: ""
fileBean.originalPic = data?.newName ?: ""
}
}

View File

@@ -62,10 +62,23 @@ class GnjYiKuHandoverViewModel : BaseViewModel(), IOnItemClickListener {
val bean = it.data ?: GnjYiKuBean()
dataBean.value = bean
// 处理图片列表(拼接完整 URL
val images = bean.getImageList().map { url ->
FileBean(path = MediaUtil.fillUrl(url), url = url)
// 处理图片列表(同时保留缩略图和原图信息,确保二次编辑时不丢失
val picList = bean.pic.split(",").filter { it.isNotEmpty() }
val originalPicList = bean.originalPic.split(",").filter { it.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) {
@@ -75,7 +88,7 @@ class GnjYiKuHandoverViewModel : BaseViewModel(), IOnItemClickListener {
imageList.value = images
// 详情模式下无图片时显示占位提示
if (pageType.value == DetailsPageType.Details && bean.getImageList().isEmpty()) {
if (pageType.value == DetailsPageType.Details && images.isEmpty()) {
showNoImage.value = true
}
}
@@ -105,9 +118,11 @@ class GnjYiKuHandoverViewModel : BaseViewModel(), IOnItemClickListener {
// 已上传的图片,保持原有的 url 和 originalPic
} else {
// 本地新图片需要上传
// UploadUtil 返回newName=原图(较大)zipFileName=缩略图(较小)
// FileBean.url 用作缩略图标识FileBean.originalPic 用作原图标识
val data = UploadUtil.upload(fileBean.path).data
fileBean.url = data?.newName ?: ""
fileBean.originalPic = data?.zipFileName ?: ""
fileBean.url = data?.zipFileName ?: ""
fileBean.originalPic = data?.newName ?: ""
}
}