6.4 KiB
工作留痕 — VR 票务详情页演出详情内容渲染修复
创建时间:2026-06-12 关联对话:2fb4912f-8100-45fc-b11f-d2ac37536abf 涉及文件:
pages/goods-vr-ticket/goods-vr-ticket.vuepages/goods-vr-ticket/goods-vr-ticket.cssdocs/test.json(后端返回的 tree API 示例数据)
一、问题描述
票务商品详情页 /pages/goods-vr-ticket/goods-vr-ticket?id=121 的"演出详情"区域完全不显示内容。
1.1 现象
- 页面加载后,"演出详情" section 只有标题,无正文
- 图片和文字详情均不渲染
1.2 根因分析
原因 A(模板层面):演出详情 section 在模板中只有 <section-header>,没有渲染 body:
<!-- 原来的模板 -->
<view class="section-card mt-10">
<view class="section-header">
<text class="section-title">演出详情</text>
</view>
<!-- ❌ 没有任何内容渲染 -->
</view>
原因 B(数据层面):handleTreeData 方法从未从 tree API 响应中提取 content_app 字段。
1.3 数据来源确认
后端 vr_ticket 插件的 tree 接口已更新,data.goods.content_app 包含详情内容:
tree API: plugins/index?pluginsname=vr_ticket&pluginscontrol=goods&pluginsaction=tree&...&goods_id=121
响应结构(关键字段):
{
"code": 0,
"data": {
"goods": {
"id": 121,
"title": "一个多日测试票务商品2",
"content_app": [
{
"id": 13,
"images": "http://localhost:10000/static/upload/images/goods/2026/05/29/1779992828577719.jpeg",
"content": ["这是一条测试详情,这是一条测试详情,这是一条测试详情..."],
"content_old": "这是一条测试详情,这是一条测试详情..."
}
]
}
}
}
二、修复方案
2.1 数据层:提取 content_app
文件:pages/goods-vr-ticket/goods-vr-ticket.vue
在 handleTreeData 方法中添加对 apiData.goods.content_app 的提取:
handleTreeData(apiData) {
this.treeData = apiData.tree;
this.seatTemplates = apiData.seat_templates;
// 提取会话元数据和同场次商品
this.sessionMeta = apiData.session_meta || [];
this.peerGoods = apiData.peer_goods || [];
// 提取 goods 属性中的 content_app(演出详情) ✅ 新增
if (apiData.goods && apiData.goods.content_app) {
this.detailContent = apiData.goods.content_app;
console.log('[VR Ticket] detailContent loaded:', this.detailContent);
}
// 提取场馆数据...
}
同步在 data() 中新增字段:
data() {
return {
// ...
detailContent: [], // 详情内容(从 tree API 的 goods.content_app 获取)
// ...
}
}
2.2 渲染层:嵌套循环渲染
参考 pages/goods-detail/goods-detail.vue(lines 401-408)的渲染模式:
<!-- goods-detail.vue 原版 -->
<view v-for="(item, index) in goods_content_app" :key="index" class="goods-detail-app">
<image v-if="(item.images || null) != null" ... :src="item.images" mode="widthFix" />
<view v-if="(item.content || null) != null" class="content-items">
<view v-for="(items, index2) in item.content" :key="index2" class="item">{{ items }}</view>
</view>
</view>
关键点:item.content 是一个字符串数组,不能直接传给 rich-text,而需要对每个字符串做嵌套循环渲染。
修复后的模板(goods-vr-ticket.vue):
<view class="detail-content" v-if="detailContent && detailContent.length > 0">
<view v-for="(item, index) in detailContent" :key="index" class="detail-item">
<image
v-if="item.images"
:src="item.images"
class="detail-image"
mode="widthFix"
:lazy-load="true"
/>
<view v-if="item.content && item.content.length > 0" class="content-items">
<view v-for="(text, i2) in item.content" :key="i2" class="item">{{ text }}</view>
</view>
</view>
</view>
<view v-else class="detail-empty">暂无演出详情</view>
2.3 样式层:CSS 类名对齐
文件:pages/goods-vr-ticket/goods-vr-ticket.css
新增样式(与 goods-detail.vue 的 .goods-detail-app / .content-items / .item 体系对齐):
.detail-empty {
font-size: 13px;
color: #999;
padding: 20px 0;
text-align: center;
}
.detail-content {
margin-top: 16px;
}
.detail-item {
margin-bottom: 16px;
}
.detail-image {
width: 100%;
border-radius: 8px;
margin-bottom: 8px;
}
.content-items {
padding: 0 4px;
}
.content-items .item {
font-size: 14px;
color: #333;
line-height: 1.8;
text-align: left;
margin-bottom: 8px;
}
三、变更文件清单
| 文件 | 变更类型 | 说明 |
|---|---|---|
pages/goods-vr-ticket/goods-vr-ticket.vue |
修改 | 新增 detailContent data 字段、handleTreeData 提取逻辑、模板渲染 body |
pages/goods-vr-ticket/goods-vr-ticket.css |
修改 | 新增 .detail-content、.detail-item、.content-items、.item 等样式 |
docs/vr-ticket-work-record-20260612.md |
新增 | 本工作留痕文档 |
docs/test.json |
修改 | 后端返回的 tree API 完整示例数据(goods.content_app 字段) |
四、验证方式
- 启动 H5 编译:
npm run dev:h5(端口 8082) - 访问:
http://localhost:8082/#/pages/goods-vr-ticket/goods-vr-ticket?id=121 - 滚动到"演出详情"区域,应能看到:
- 图片(如有):宽度 100%,圆角 8px
- 文字详情:每行文字独立渲染,14px,行高 1.8
五、技术备注
5.1 为什么不用 rich-text?
content_app 中的 item.content 是字符串数组(如 ["文字1", "文字2"])。之前错误地将整个数组传给 rich-text :nodes="item.content",导致渲染失败。正确做法是对数组中每个字符串做 v-for 嵌套循环渲染,与 goods-detail.vue 保持一致。
5.2 tree API vs detail API
VR 票务商品详情页不再调用 goods/detail 接口,直接通过 goods/tree (pluginsname=vr_ticket) 接口获取所有数据(含 goods.content_app),符合 vr_ticket 插件的数据自包含设计。
六、参考文件
| 文件 | 用途 |
|---|---|
pages/goods-detail/goods-detail.vue (L389-L408) |
content_app 渲染模式参考 |
docs/test.json |
tree API 完整响应示例 |
docs/vr-ticket-uniapp-supplement.md |
VR 票务 UniApp 移植完整文档 |