fix(订单详情): 自定义表单按 type=img 识别图片,并统一名称左内容右布局

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
吴昊天 2026-10-28 11:01:04 +08:00
parent 6491946882
commit 60e55bc2ac
2 changed files with 74 additions and 15 deletions

View File

@ -372,12 +372,12 @@
</el-row>
</div>
<!-- 表单信息 -->
<!-- 表单信息(图片字段按 type=img 判断,与订单中台 DetailOrderInfo 同口径) -->
<div class="section" v-if="detailData.custom_form && detailData.custom_form.length">
<div class="section-title">表单信息</div>
<el-row :gutter="24" class="detail-grid">
<template v-for="(item, idx) in detailData.custom_form" :key="idx">
<el-col :span="8" v-if="item.label !== 'img'">
<el-col :span="8" v-if="!isImageItem(item)">
<div class="detail-item">
<span class="label">{{ item.title }}:</span><span class="value">{{ item.value }}</span>
</div>
@ -386,7 +386,13 @@
<div class="detail-item">
<span class="label">{{ item.title }}:</span>
<span class="value">
<img v-for="(img, i) in item.value" :key="i" :src="img" class="form-img" v-viewer />
<img
v-for="(img, i) in formImageUrls(item)"
:key="i"
:src="img"
class="form-img"
v-viewer
/>
</span>
</div>
</el-col>
@ -601,6 +607,28 @@ function formatDate(ts) {
.padStart(2, '0')}`;
}
// 图片扩展名判断
const IMAGE_EXT_RE = /\.(jpe?g|png|gif|webp|bmp)(\?.*)?$/i;
/** 自定义表单字段值规范化为图片 URL 数组(兼容字符串单图 / 数组多图) */
function formImageUrls(item) {
if (!item || !item.value) return [];
const list = Array.isArray(item.value) ? item.value : [item.value];
return list.filter((v) => typeof v === 'string' && v.indexOf('http') === 0);
}
/**
* 图片字段判断:新订单 type=img,或存量订单无类型但值是图片链接
* (新数据 label 是 custom_field_N,不能再按 label == 'img' 判断)
*/
function isImageItem(item) {
if (!item) return false;
if (item.type === 'img') return true;
if (item.type) return false;
const urls = formImageUrls(item);
return urls.length > 0 && urls.every((v) => IMAGE_EXT_RE.test(v) || v.indexOf('/uploads/') !== -1);
}
/** 将 "Y-m-d H:i:s" 或 "Y-m-d H:i" 字符串转为时间戳,用于时间线排序 */
function parseTimeToTimestamp(timeStr) {
if (!timeStr) return 0;

View File

@ -7,9 +7,9 @@
<view class="info-card custom-form-card" v-if="items && items.length > 0">
<view class="card-title">{{ $t('自定义信息') }}</view>
<template v-for="(item, idx) in items" :key="idx">
<!-- 图片字段:类型为 img,或存量订单无类型但值是图片链接 -->
<view class="info-row info-row--block" v-if="isImageItem(item)">
<view class="info-label">{{ item.title || item.label }}:</view>
<!-- 图片字段:名称左、图片右(多图可换行) -->
<view class="info-row info-row--image" v-if="isImageItem(item)">
<text class="info-label">{{ item.title || item.label }}</text>
<view class="info-images">
<image
v-for="(url, i) in imageList(item)"
@ -21,9 +21,9 @@
/>
</view>
</view>
<!-- 文本字段:值跟随标签左对齐,长文本自动换行 -->
<!-- 文本字段:名称左、内容右,与订单信息卡片左右分离一致 -->
<view class="info-row" v-else>
<text class="info-label">{{ item.title || item.label }}:</text>
<text class="info-label">{{ item.title || item.label }}</text>
<text class="info-value">{{ item.value }}</text>
</view>
</template>
@ -97,11 +97,42 @@ function previewImages(item, index) {
<style scoped>
.custom-form-card { margin: 20rpx; background: #fff; border-radius: 16rpx; padding: 30rpx; }
.card-title { font-size: 30rpx; font-weight: bold; color: #333; margin-bottom: 20rpx; }
.info-row { display: flex; align-items: baseline; padding: 12rpx 0; font-size: 26rpx; }
.info-label { color: #999; flex-shrink: 0; }
.info-value { color: #333; flex: 1; margin-left: 16rpx; line-height: 1.5; word-break: break-all; text-align: left; }
/* 图片字段:标签在上、图片缩略图在下 */
.info-row--block { display: block; padding: 12rpx 0; }
.info-images { display: flex; flex-wrap: wrap; margin-top: 12rpx; }
.info-image { width: 160rpx; height: 160rpx; border-radius: 12rpx; margin: 0 12rpx 12rpx 0; background: #f5f5f5; }
.info-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 12rpx 0;
font-size: 26rpx;
gap: 24rpx;
}
.info-label {
color: #999;
flex-shrink: 0;
max-width: 40%;
line-height: 1.5;
}
.info-value {
color: #333;
flex: 1;
min-width: 0;
line-height: 1.5;
word-break: break-all;
text-align: right;
}
/* 图片字段:名称左、缩略图右对齐 */
.info-row--image { align-items: flex-start; }
.info-images {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
flex: 1;
min-width: 0;
}
.info-image {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
margin: 0 0 12rpx 12rpx;
background: #f5f5f5;
}
</style>