fix: 修复图片上传字段、航班查询接口及图片鉴权加载问题
- 国际进港舱单列表页航班查询接口改为 /flt/searchFlightList,支持多航班校验 - 修复国内进港移库编辑/交接页图片上传缺少 pic、picNumber 字段 - 国际进港舱单详情页对接交接图片展示 - 图片缩略图和大图预览加载带 Authorization header 解决 403 - CLAUDE.md 新增图片上传与展示规范 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -119,13 +119,21 @@
|
|||||||
"mcp__apifox__read_project_oas_ruugy8",
|
"mcp__apifox__read_project_oas_ruugy8",
|
||||||
"mcp__apifox__read_project_oas_ref_resources_ldmedm",
|
"mcp__apifox__read_project_oas_ref_resources_ldmedm",
|
||||||
"mcp__apifox__read_project_oas_ldmedm",
|
"mcp__apifox__read_project_oas_ldmedm",
|
||||||
"mcp__apifox__refresh_project_oas_ldmedm"
|
"mcp__apifox__refresh_project_oas_ldmedm",
|
||||||
|
"Skill(update-config)",
|
||||||
|
"mcp__apidoc__get_project_overview",
|
||||||
|
"mcp__apidoc__search_endpoints",
|
||||||
|
"mcp__apidoc__list_endpoints",
|
||||||
|
"mcp__apidoc__get_endpoint_detail"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
},
|
},
|
||||||
|
"enableAllProjectMcpServers": true,
|
||||||
"enabledMcpjsonServers": [
|
"enabledMcpjsonServers": [
|
||||||
"空港集团 - API 文档",
|
"空港集团 - API 文档",
|
||||||
"apifox"
|
"apifox",
|
||||||
|
"aerologic-app",
|
||||||
|
"apidoc"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,13 @@
|
|||||||
"env": {
|
"env": {
|
||||||
"APIFOX_ACCESS_TOKEN": "APS-S2aVVwqasbdByzPLgSqryRC8BB0ZFqhQ"
|
"APIFOX_ACCESS_TOKEN": "APS-S2aVVwqasbdByzPLgSqryRC8BB0ZFqhQ"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"apidoc": {
|
||||||
|
"type": "http",
|
||||||
|
"url": "http://localhost:3001/mcp/c6a17835-6389-446c-8334-004b998835e5",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer afk_Snhv1JVACdbd91_NS699bb-2MN237Jww"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
87
CLAUDE.md
87
CLAUDE.md
@@ -958,6 +958,93 @@ companion object {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 图片上传与展示规范
|
||||||
|
|
||||||
|
### 图片上传三字段规范
|
||||||
|
|
||||||
|
上传图片后提交表单时,**必须同时传 `pic`、`originalPic`、`picNumber` 三个字段**,缺一不可。
|
||||||
|
|
||||||
|
**`UploadUtil.upload()` 返回值**:
|
||||||
|
- `data?.newName` — 缩略图/压缩图文件名
|
||||||
|
- `data?.zipFileName` — 原图文件名
|
||||||
|
|
||||||
|
**提交时字段映射**(参考事故签证 `AccidentVisaDetailsViewModel`):
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// FileBean 字段含义:
|
||||||
|
// - FileBean.url = newName(缩略图文件名)
|
||||||
|
// - FileBean.originalPic = zipFileName(原图文件名)
|
||||||
|
|
||||||
|
// 上传新图片
|
||||||
|
val data = UploadUtil.upload(fileBean.path).data
|
||||||
|
fileBean.url = data?.newName ?: ""
|
||||||
|
fileBean.originalPic = data?.zipFileName ?: ""
|
||||||
|
|
||||||
|
// 提交时设置三个字段
|
||||||
|
bean.picNumber = list.size.toString()
|
||||||
|
bean.pic = list.joinToString(",") { MediaUtil.removeUrl(it.url) } // 缩略图
|
||||||
|
bean.originalPic = list.joinToString(",") { MediaUtil.removeUrl(it.originalPic) } // 原图
|
||||||
|
```
|
||||||
|
|
||||||
|
**常见错误**:
|
||||||
|
- ❌ 只传 `images` 或 `originalPic` 单个字段 — 接口不认或数据不完整
|
||||||
|
- ❌ 只取 `newName` 不取 `zipFileName` — 丢失原图路径
|
||||||
|
- ❌ 用 `fileBean.path.startsWith("http")` 判断已上传 — 应该用 `fileBean.url.isNotEmpty()`
|
||||||
|
|
||||||
|
### 编辑页加载已有图片
|
||||||
|
|
||||||
|
从详情接口获取图片后,需要同时解析 `pic`(缩略图)和 `originalPic`(原图),构建完整的 `FileBean`:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val picList = bean.pic.split(",").filter { it.isNotEmpty() }
|
||||||
|
val originalPicList = bean.originalPic.split(",").filter { it.isNotEmpty() }
|
||||||
|
val images = picList.mapIndexed { index, picUrl ->
|
||||||
|
val originalFile = originalPicList.getOrElse(index) { picUrl }
|
||||||
|
FileBean(
|
||||||
|
path = MediaUtil.fillUrl(picUrl), // 完整URL,用于显示
|
||||||
|
url = picUrl, // 相对路径,提交时用
|
||||||
|
originalPic = MediaUtil.fillUrl(originalFile) // 原图完整URL
|
||||||
|
)
|
||||||
|
}.toMutableList()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 图片加载必须带 Authorization Header
|
||||||
|
|
||||||
|
`/file/getImg/` 接口需要鉴权,Glide 默认不带 token,直接用 `loadImage` BindingAdapter 会 **403 Forbidden**。
|
||||||
|
|
||||||
|
**正确做法** — 在 ViewHolder 中使用 `GlideUrl` + `LazyHeaders`:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// 缩略图加载(ViewHolder 中)
|
||||||
|
val glideUrl = GlideUrl(
|
||||||
|
bean.path,
|
||||||
|
LazyHeaders.Builder()
|
||||||
|
.addHeader("Authorization", SharedPreferenceUtil.getString(Constant.Share.token))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
Glide.with(itemView.context).load(glideUrl).into(binding.ivThumbnail)
|
||||||
|
```
|
||||||
|
|
||||||
|
**同时必须去掉 XML 布局中的 `loadImage` 属性**,否则 BindingAdapter 会触发不带 token 的请求覆盖手动加载:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- ❌ 错误:会触发不带 token 的 Glide 请求 -->
|
||||||
|
<ImageView loadImage="@{bean.path}" />
|
||||||
|
|
||||||
|
<!-- ✅ 正确:只保留 id,由 ViewHolder 手动加载 -->
|
||||||
|
<ImageView android:id="@+id/iv_thumbnail" />
|
||||||
|
```
|
||||||
|
|
||||||
|
**大图预览同理** — `PreviewImageViewHolder` 也需要用 `GlideUrl` 带 token 加载网络图片。
|
||||||
|
|
||||||
|
**参考文件**:
|
||||||
|
- 缩略图加载: `module_gjj/.../GjjManifestPicViewHolder.kt`
|
||||||
|
- 大图预览: `module_base/.../PreviewImageViewHolder.kt`
|
||||||
|
- 图片上传提交: `app/.../AccidentVisaDetailsViewModel.kt`
|
||||||
|
- 带 token 的 Glide 加载: `module_mit/.../PictureAdapter.kt`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 开发原则
|
## 开发原则
|
||||||
|
|
||||||
- 资源引用必须存在 — 创建布局前确认 drawable/color/string 资源真实存在或主动创建
|
- 资源引用必须存在 — 创建布局前确认 drawable/color/string 资源真实存在或主动创建
|
||||||
|
|||||||
@@ -56,7 +56,10 @@ data class GjjManifest(
|
|||||||
var subCode: String = "", // 子代码
|
var subCode: String = "", // 子代码
|
||||||
var unNumber: String = "", // 危险品编号
|
var unNumber: String = "", // 危险品编号
|
||||||
var activeId: Long = 0, // 活动ID
|
var activeId: Long = 0, // 活动ID
|
||||||
var locationTally: String = "" // 理货库位号
|
var locationTally: String = "", // 理货库位号
|
||||||
|
var pic: String = "", // 交接图片缩略图路径
|
||||||
|
var originalPic: String = "", // 交接图片原图地址
|
||||||
|
var picNumber: String = "" // 交接图片数量
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
// 分单列表
|
// 分单列表
|
||||||
var haWbList: List<GjjHaWb>? = null
|
var haWbList: List<GjjHaWb>? = null
|
||||||
|
|||||||
@@ -1367,6 +1367,12 @@ interface Api {
|
|||||||
@POST("flt/queryFlight")
|
@POST("flt/queryFlight")
|
||||||
suspend fun queryFlightByDateAndNo(@Body data: RequestBody): BaseResultBean<FlightBean>
|
suspend fun queryFlightByDateAndNo(@Body data: RequestBody): BaseResultBean<FlightBean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据航班日期、航班号、地区类型、进出港查询航班(返回列表)
|
||||||
|
*/
|
||||||
|
@POST("flt/searchFlightList")
|
||||||
|
suspend fun searchFlightList(@Body data: RequestBody): BaseResultBean<List<FlightBean>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取航班目的站、经停站
|
* 获取航班目的站、经停站
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package com.lukouguoji.module_base.ui.page.preview
|
package com.lukouguoji.module_base.ui.page.preview
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
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.base.BaseViewHolder
|
||||||
import com.lukouguoji.module_base.bean.FileBean
|
import com.lukouguoji.module_base.bean.FileBean
|
||||||
|
import com.lukouguoji.module_base.common.Constant
|
||||||
import com.lukouguoji.module_base.databinding.ItemPreviewImageBinding
|
import com.lukouguoji.module_base.databinding.ItemPreviewImageBinding
|
||||||
|
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author:孟凡华
|
* @author:孟凡华
|
||||||
@@ -14,8 +19,26 @@ class PreviewImageViewHolder(view: View) :
|
|||||||
BaseViewHolder<FileBean, ItemPreviewImageBinding>(view) {
|
BaseViewHolder<FileBean, ItemPreviewImageBinding>(view) {
|
||||||
|
|
||||||
override fun onBind(item: Any?, position: Int) {
|
override fun onBind(item: Any?, position: Int) {
|
||||||
binding.bean = getItemBean(item)
|
val bean = getItemBean(item) ?: return
|
||||||
|
binding.bean = bean
|
||||||
|
|
||||||
|
// 加载图片
|
||||||
|
val path = bean.path
|
||||||
|
if (path.isNotEmpty()) {
|
||||||
|
if (path.startsWith("http")) {
|
||||||
|
// 网络图片带 Authorization header
|
||||||
|
val glideUrl = GlideUrl(
|
||||||
|
path,
|
||||||
|
LazyHeaders.Builder()
|
||||||
|
.addHeader("Authorization", SharedPreferenceUtil.getString(Constant.Share.token))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
Glide.with(itemView.context).load(glideUrl).into(binding.photoView)
|
||||||
|
} else {
|
||||||
|
// 本地图片直接加载
|
||||||
|
Glide.with(itemView.context).load(path).into(binding.photoView)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.luck.picture.lib.photoview.PhotoView
|
<com.luck.picture.lib.photoview.PhotoView
|
||||||
loadImage="@{bean.path}"
|
android:id="@+id/photo_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.lukouguoji.module_base.base.CommonAdapter
|
|||||||
import com.lukouguoji.module_base.ktx.addOnItemClickListener
|
import com.lukouguoji.module_base.ktx.addOnItemClickListener
|
||||||
import com.lukouguoji.module_base.router.ARouterConstants
|
import com.lukouguoji.module_base.router.ARouterConstants
|
||||||
|
|
||||||
|
@Deprecated("旧的实现")
|
||||||
@Route(path = ARouterConstants.ACTIVITY_URL_GJJ_MANIFEST)
|
@Route(path = ARouterConstants.ACTIVITY_URL_GJJ_MANIFEST)
|
||||||
class GjjManifestListActivity :
|
class GjjManifestListActivity :
|
||||||
BaseBindingActivity<ActivityGjjManifestBinding, GjjManifestListViewModel>() {
|
BaseBindingActivity<ActivityGjjManifestBinding, GjjManifestListViewModel>() {
|
||||||
|
|||||||
@@ -3,14 +3,20 @@ package com.lukouguoji.gjj.activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.alibaba.android.arouter.facade.annotation.Route
|
import com.alibaba.android.arouter.facade.annotation.Route
|
||||||
import com.lukouguoji.gjj.R
|
import com.lukouguoji.gjj.R
|
||||||
import com.lukouguoji.gjj.databinding.ActivityIntImpManifestDetailsBinding
|
import com.lukouguoji.gjj.databinding.ActivityIntImpManifestDetailsBinding
|
||||||
|
import com.lukouguoji.gjj.holder.GjjManifestPicViewHolder
|
||||||
import com.lukouguoji.gjj.viewModel.IntImpManifestDetailsViewModel
|
import com.lukouguoji.gjj.viewModel.IntImpManifestDetailsViewModel
|
||||||
import com.lukouguoji.module_base.base.BaseBindingActivity
|
import com.lukouguoji.module_base.base.BaseBindingActivity
|
||||||
|
import com.lukouguoji.module_base.base.CommonAdapter
|
||||||
|
import com.lukouguoji.module_base.bean.FileBean
|
||||||
import com.lukouguoji.module_base.bean.GjjManifest
|
import com.lukouguoji.module_base.bean.GjjManifest
|
||||||
import com.lukouguoji.module_base.common.Constant
|
import com.lukouguoji.module_base.common.Constant
|
||||||
import com.lukouguoji.module_base.router.ARouterConstants
|
import com.lukouguoji.module_base.router.ARouterConstants
|
||||||
|
import com.lukouguoji.module_base.util.MediaUtil
|
||||||
|
import com.lukouguoji.module_base.ktx.noNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际进港舱单详情
|
* 国际进港舱单详情
|
||||||
@@ -26,6 +32,29 @@ class IntImpManifestDetailsActivity :
|
|||||||
setBackArrow("进港舱单详情")
|
setBackArrow("进港舱单详情")
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
viewModel.initOnCreated(intent)
|
viewModel.initOnCreated(intent)
|
||||||
|
|
||||||
|
// 交接图片
|
||||||
|
val picAdapter = CommonAdapter(
|
||||||
|
this,
|
||||||
|
R.layout.item_gjj_manifest_pic,
|
||||||
|
GjjManifestPicViewHolder::class.java
|
||||||
|
)
|
||||||
|
binding.rvPic.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
|
||||||
|
binding.rvPic.adapter = picAdapter
|
||||||
|
|
||||||
|
viewModel.dataBean.observe(this) { bean ->
|
||||||
|
val picList = bean.pic.noNull().split(",").filter { it.isNotEmpty() }
|
||||||
|
val originalPicList = bean.originalPic.noNull().split(",").filter { it.isNotEmpty() }
|
||||||
|
val list = picList.mapIndexed { index, picUrl ->
|
||||||
|
val originalFile = originalPicList.getOrElse(index) { picUrl }
|
||||||
|
FileBean(
|
||||||
|
path = MediaUtil.fillUrl(picUrl),
|
||||||
|
url = picUrl,
|
||||||
|
originalPic = MediaUtil.fillUrl(originalFile)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
picAdapter.refresh(list)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package com.lukouguoji.gjj.holder
|
package com.lukouguoji.gjj.holder
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
|
import com.bumptech.glide.load.model.LazyHeaders
|
||||||
import com.lukouguoji.gjj.databinding.ItemGjjManifestPicBinding
|
import com.lukouguoji.gjj.databinding.ItemGjjManifestPicBinding
|
||||||
import com.lukouguoji.module_base.base.BaseViewHolder
|
import com.lukouguoji.module_base.base.BaseViewHolder
|
||||||
import com.lukouguoji.module_base.bean.FileBean
|
import com.lukouguoji.module_base.bean.FileBean
|
||||||
|
import com.lukouguoji.module_base.common.Constant
|
||||||
|
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
|
||||||
import com.lukouguoji.module_base.ktx.commonAdapter
|
import com.lukouguoji.module_base.ktx.commonAdapter
|
||||||
import com.lukouguoji.module_base.ui.page.preview.PreviewActivity
|
import com.lukouguoji.module_base.ui.page.preview.PreviewActivity
|
||||||
|
|
||||||
@@ -14,6 +19,17 @@ class GjjManifestPicViewHolder(view: View) :
|
|||||||
val bean = getItemBean(item)!!
|
val bean = getItemBean(item)!!
|
||||||
binding.bean = bean
|
binding.bean = bean
|
||||||
|
|
||||||
|
// 带 Authorization header 加载图片
|
||||||
|
if (bean.path.isNotEmpty()) {
|
||||||
|
val glideUrl = GlideUrl(
|
||||||
|
bean.path,
|
||||||
|
LazyHeaders.Builder()
|
||||||
|
.addHeader("Authorization", SharedPreferenceUtil.getString(Constant.Share.token))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
Glide.with(itemView.context).load(glideUrl).into(binding.ivThumbnail)
|
||||||
|
}
|
||||||
|
|
||||||
binding.ivThumbnail.setOnClickListener {
|
binding.ivThumbnail.setOnClickListener {
|
||||||
val items = getRecyclerView()?.commonAdapter()?.items
|
val items = getRecyclerView()?.commonAdapter()?.items
|
||||||
?.filterIsInstance<FileBean>() ?: listOf(bean)
|
?.filterIsInstance<FileBean>() ?: listOf(bean)
|
||||||
|
|||||||
@@ -64,30 +64,40 @@ class IntImpManifestViewModel : BasePageViewModel() {
|
|||||||
lastQueriedFlight = key
|
lastQueriedFlight = key
|
||||||
|
|
||||||
launchCollect({
|
launchCollect({
|
||||||
NetApply.api.getGjFlightBean(
|
NetApply.api.searchFlightList(
|
||||||
mapOf(
|
mapOf(
|
||||||
"fdate" to fdate,
|
"fdate" to fdate,
|
||||||
"fno" to fno,
|
"fno" to fno,
|
||||||
"ieFlag" to "I",
|
"status" to "1",
|
||||||
).toRequestBody()
|
).toRequestBody()
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
if (it.verifySuccess() && it.data != null) {
|
if (it.verifySuccess() && !it.data.isNullOrEmpty()) {
|
||||||
val flight = it.data!!
|
val dataList = it.data!!
|
||||||
fid = flight.fid.noNull()
|
if (dataList.size > 1) {
|
||||||
fdep = flight.fdep.noNull()
|
showToast("存在多个航班记录,请核实")
|
||||||
fdest.value = flight.fdest.noNull()
|
fid = ""
|
||||||
|
fdep = ""
|
||||||
|
fdest.value = ""
|
||||||
|
sendAddressList.value = emptyList()
|
||||||
|
sendAddress.value = ""
|
||||||
|
} else {
|
||||||
|
val flight = dataList[0]
|
||||||
|
fid = flight.fid.noNull()
|
||||||
|
fdep = flight.fdep.noNull()
|
||||||
|
fdest.value = flight.fdest.noNull()
|
||||||
|
|
||||||
// 构建始发站下拉列表:fdep + jtz(经停港)
|
// 构建始发站下拉列表:fdep + jtz(经停港)
|
||||||
val list = mutableListOf(
|
val list = mutableListOf(
|
||||||
KeyValue(flight.fdep.noNull(), flight.fdep.noNull()),
|
KeyValue(flight.fdep.noNull(), flight.fdep.noNull()),
|
||||||
)
|
)
|
||||||
if (!flight.jtz.isNullOrEmpty()) {
|
if (!flight.jtz.isNullOrEmpty()) {
|
||||||
list.add(KeyValue(flight.jtz.noNull(), flight.jtz.noNull()))
|
list.add(KeyValue(flight.jtz.noNull(), flight.jtz.noNull()))
|
||||||
|
}
|
||||||
|
sendAddressList.value = list
|
||||||
|
sendAddress.value = flight.fdep.noNull()
|
||||||
}
|
}
|
||||||
sendAddressList.value = list
|
|
||||||
sendAddress.value = flight.fdep.noNull()
|
|
||||||
} else {
|
} else {
|
||||||
fid = ""
|
fid = ""
|
||||||
fdep = ""
|
fdep = ""
|
||||||
|
|||||||
@@ -263,25 +263,14 @@
|
|||||||
android:textColor="@color/text_gray"
|
android:textColor="@color/text_gray"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/ll_images"
|
android:id="@+id/rv_pic"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="14dp"
|
android:layout_marginLeft="14dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:minHeight="80dp"
|
android:minHeight="80dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
<!-- 交接图片区域预留,后续对接图片数据 -->
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="暂无图片"
|
|
||||||
android:textColor="@color/text_gray"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/iv_thumbnail"
|
android:id="@+id/iv_thumbnail"
|
||||||
loadImage="@{bean.path}"
|
|
||||||
android:layout_width="80dp"
|
android:layout_width="80dp"
|
||||||
android:layout_height="80dp"
|
android:layout_height="80dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import com.lukouguoji.module_base.ktx.launchLoadingCollect
|
|||||||
import com.lukouguoji.module_base.ktx.showToast
|
import com.lukouguoji.module_base.ktx.showToast
|
||||||
import com.lukouguoji.module_base.ktx.toRequestBody
|
import com.lukouguoji.module_base.ktx.toRequestBody
|
||||||
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
|
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
|
||||||
|
import com.lukouguoji.module_base.util.MediaUtil
|
||||||
import com.lukouguoji.module_base.util.UploadUtil
|
import com.lukouguoji.module_base.util.UploadUtil
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -71,9 +72,18 @@ class GnjYiKuEditViewModel : BaseViewModel(), IOnItemClickListener {
|
|||||||
val bean = it.data ?: GnjYiKuBean()
|
val bean = it.data ?: GnjYiKuBean()
|
||||||
dataBean.value = bean
|
dataBean.value = bean
|
||||||
|
|
||||||
// 处理图片列表
|
// 处理图片列表:pic=缩略图(newName),originalPic=原图(zipFileName)
|
||||||
val images = bean.getImageList().map { url ->
|
val picList = bean.pic.split(",").filter { it.isNotEmpty() }
|
||||||
FileBean(path = url)
|
val originalPicList = bean.originalPic.split(",").filter { it.isNotEmpty() }
|
||||||
|
val images = picList.mapIndexed { index, picUrl ->
|
||||||
|
val fb = FileBean(
|
||||||
|
path = MediaUtil.fillUrl(picUrl),
|
||||||
|
url = picUrl
|
||||||
|
)
|
||||||
|
if (index < originalPicList.size) {
|
||||||
|
fb.originalPic = MediaUtil.fillUrl(originalPicList[index])
|
||||||
|
}
|
||||||
|
fb
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
|
|
||||||
// 如果是编辑模式,添加一个空的FileBean用于添加新图片
|
// 如果是编辑模式,添加一个空的FileBean用于添加新图片
|
||||||
@@ -108,38 +118,24 @@ class GnjYiKuEditViewModel : BaseViewModel(), IOnItemClickListener {
|
|||||||
|
|
||||||
launchLoadingCollect({
|
launchLoadingCollect({
|
||||||
// 1. 上传图片
|
// 1. 上传图片
|
||||||
val uploadedUrls = mutableListOf<String>()
|
|
||||||
images.forEach { fileBean ->
|
images.forEach { fileBean ->
|
||||||
// 判断是否为已上传的图片(在线URL)
|
if (fileBean.url.isNotEmpty()) {
|
||||||
if (fileBean.path.startsWith("http")) {
|
// 已上传的图片,保持原有的 url 和 originalPic
|
||||||
uploadedUrls.add(fileBean.path)
|
|
||||||
} else {
|
} else {
|
||||||
// 本地图片需要上传
|
// 本地新图片需要上传
|
||||||
val result = UploadUtil.upload(fileBean.path)
|
val data = UploadUtil.upload(fileBean.path).data
|
||||||
if (result.verifySuccess()) {
|
fileBean.url = data?.newName ?: ""
|
||||||
uploadedUrls.add(result.data?.newName ?: "")
|
fileBean.originalPic = data?.zipFileName ?: ""
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 提交表单数据
|
// 2. 设置图片字段
|
||||||
val params = mapOf(
|
bean.picNumber = images.size.toString()
|
||||||
"id" to id,
|
bean.pic = images.joinToString(",") { MediaUtil.removeUrl(it.url) }
|
||||||
"wbNo" to bean.wbNo,
|
bean.originalPic = images.joinToString(",") { MediaUtil.removeUrl(it.originalPic) }
|
||||||
"pc" to bean.pc,
|
|
||||||
"weight" to bean.weight,
|
|
||||||
"spCode" to bean.spCode,
|
|
||||||
"agentCode" to bean.agentCode,
|
|
||||||
"goods" to bean.goods,
|
|
||||||
"flight" to bean.flight,
|
|
||||||
"route" to bean.route,
|
|
||||||
"awbType" to bean.awbType,
|
|
||||||
"telegramNo" to bean.telegramNo,
|
|
||||||
"remark" to bean.remark,
|
|
||||||
"images" to uploadedUrls.joinToString(","),
|
|
||||||
).toRequestBody(removeEmptyOrNull = true)
|
|
||||||
|
|
||||||
NetApply.api.saveGnjYiKu(params)
|
// 3. 提交表单数据
|
||||||
|
NetApply.api.saveGnjYiKu(bean.toRequestBody())
|
||||||
}) {
|
}) {
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
showToast(if (pageType.value == DetailsPageType.Add) "新增成功" else "保存成功")
|
showToast(if (pageType.value == DetailsPageType.Add) "新增成功" else "保存成功")
|
||||||
|
|||||||
@@ -100,16 +100,14 @@ class GnjYiKuHandoverViewModel : BaseViewModel(), IOnItemClickListener {
|
|||||||
|
|
||||||
launchLoadingCollect({
|
launchLoadingCollect({
|
||||||
// 上传图片
|
// 上传图片
|
||||||
val uploadedUrls = mutableListOf<String>()
|
|
||||||
images.forEach { fileBean ->
|
images.forEach { fileBean ->
|
||||||
if (fileBean.url.isNotEmpty()) {
|
if (fileBean.url.isNotEmpty()) {
|
||||||
// 已上传的图片,直接用文件名
|
// 已上传的图片,保持原有的 url 和 originalPic
|
||||||
uploadedUrls.add(fileBean.url)
|
|
||||||
} else {
|
} else {
|
||||||
val result = UploadUtil.upload(fileBean.path)
|
// 本地新图片需要上传
|
||||||
if (result.verifySuccess()) {
|
val data = UploadUtil.upload(fileBean.path).data
|
||||||
uploadedUrls.add(result.data?.newName ?: "")
|
fileBean.url = data?.newName ?: ""
|
||||||
}
|
fileBean.originalPic = data?.zipFileName ?: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +115,9 @@ class GnjYiKuHandoverViewModel : BaseViewModel(), IOnItemClickListener {
|
|||||||
val params = mapOf(
|
val params = mapOf(
|
||||||
"mawbId" to mawbId,
|
"mawbId" to mawbId,
|
||||||
"remark" to bean.remark,
|
"remark" to bean.remark,
|
||||||
"originalPic" to uploadedUrls.joinToString(","),
|
"picNumber" to images.size.toString(),
|
||||||
|
"pic" to images.joinToString(",") { MediaUtil.removeUrl(it.url) },
|
||||||
|
"originalPic" to images.joinToString(",") { MediaUtil.removeUrl(it.originalPic) },
|
||||||
).toRequestBody(removeEmptyOrNull = true)
|
).toRequestBody(removeEmptyOrNull = true)
|
||||||
|
|
||||||
NetApply.api.modifyGnjMoveStash(params)
|
NetApply.api.modifyGnjMoveStash(params)
|
||||||
|
|||||||
Reference in New Issue
Block a user