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:
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 资源真实存在或主动创建
|
||||
|
||||
Reference in New Issue
Block a user