fix(link_view): 转发路径跟随 H5 当前页面,避免「卡片是 A、点开是 B」

H5 的 share 消息可带 page/slug:
- page 是本目标能打开的页面(l→'s' 商品,f→'a' 活动)且 slug 合法 → 转发路径用该 slug;
- 其他页面(如链接系统集合页 'c',壳页打不开)→ 清空图和标题,退回入口页 + 默认标题;
- 不带 page/slug 的旧版消息 → 视为入口页信息(兼容)。

Co-Authored-By: AI 助手
This commit is contained in:
box-tool-f6b714fa
2026-11-11 18:52:19 +00:00
parent 8543447df2
commit 9b41ba19fb

View File

@@ -40,8 +40,8 @@
/* 目标表(方案第三节):短键 → 地址前缀 + 标识规则。
base 写死在小程序里:换域名或新增系统要发版过审,这一点在方案第八节已知。 */
const TARGETS = {
l: { base: 'https://wenda.douba.top/s/', re: /^[0-9A-Za-z]{1,30}$/, title: '兜爸心选 · 好物推荐' },
f: { base: 'https://fuli.douba.top/a/', re: /^[a-z0-9-]{1,30}$/, title: '兜爸心选 · 福利活动' },
l: { base: 'https://wenda.douba.top/s/', re: /^[0-9A-Za-z]{1,30}$/, title: '兜爸心选 · 好物推荐', page: 's' },
f: { base: 'https://fuli.douba.top/a/', re: /^[a-z0-9-]{1,30}$/, title: '兜爸心选 · 福利活动', page: 'a' },
}
/* 微信给小程序的 scene 是 URL 编码的("l%3Dslug"),个别机型/版本还会二次编码。
@@ -137,6 +137,7 @@
loading: false, // 正在取票据(不显示兜底屏)
shareImage: '', // H5 上报的转发卡片图(https)
shareTitle: '', // H5 上报的转发卡片标题
shareK: '', // H5 上报的当前页面标识:用户在 web-view 里跳到别的商品后,转发的是当前商品而不是入口商品
}
},
onLoad(options) {
@@ -164,21 +165,38 @@
if (!this.url) return { title: '兜爸心选', path: '/pages/index/index' }
const card = {
title: this.shareTitle || TARGETS[this.t].title,
path: '/pages/annex/link_view/index?t=' + this.t + '&k=' + this.k,
path: '/pages/annex/link_view/index?t=' + this.t + '&k=' + (this.shareK || this.k),
}
// 没收到 H5 的图就不传 imageUrl,微信用页面截图
if (this.shareImage) card.imageUrl = this.shareImage
return card
},
methods: {
/* web-view 的 postMessage 只在转发、后退等时机批量送达,e.detail.data 是数组;取最后一条 share。 */
/* web-view 的 postMessage 只在转发、后退等时机批量送达,e.detail.data 是数组;按顺序处理,最后一条 share 生效。
消息:{action:'share', imageUrl, title, page, slug}
- 带 page/slug:page 必须是本目标能打开的页面(l→'s' 商品,f→'a' 活动)且 slug 合法,转发路径就用这个 slug;
否则(如链接系统集合页 'c',壳页打不开)清空图和标题,转发退回入口页 + 默认标题,避免「卡片是 A、点开是 B」。
- 不带 page/slug(H5 旧版):视为入口页的信息。 */
onH5Message(e) {
const raw = e && e.detail && e.detail.data
const list = Array.isArray(raw) ? raw : (raw ? [raw] : [])
const target = TARGETS[this.t]
list.forEach((m) => {
if (!m || m.action !== 'share') return
if (typeof m.imageUrl === 'string' && /^https:\/\//.test(m.imageUrl)) this.shareImage = m.imageUrl
if (typeof m.title === 'string' && m.title.trim()) this.shareTitle = m.title.trim().slice(0, 40)
if (!m || m.action !== 'share' || !target) return
let k = ''
if (m.page != null || m.slug != null) {
const ok = m.page === target.page && typeof m.slug === 'string' && target.re.test(m.slug)
if (!ok) {
this.shareImage = ''
this.shareTitle = ''
this.shareK = ''
return
}
k = m.slug
}
this.shareK = k
this.shareImage = typeof m.imageUrl === 'string' && /^https:\/\//.test(m.imageUrl) ? m.imageUrl : ''
this.shareTitle = typeof m.title === 'string' && m.title.trim() ? m.title.trim().slice(0, 40) : ''
})
},
goHome() {