feat(web_view): 太阳码 scene 解析支持 app=identifier

box_app /api/wxacode 新增 app=identifier 模式,scene 编码
"app=<identifier>"。CRMEB 收到后解析 scene,调 box_app
/api/mp/apps 找对应 H5 url,加载应用。

场景示例:
  太阳码 path=pages/annex/web_view/index
  太阳码 scene="app=pregnancy"
  → CRMEB 调 box_app /api/mp/apps
  → 遍历 items 找 identifier=pregnancy 的 App
  → 拿到 App.url
  → 注入到 web-view src
  → 加载孕育无忧 H5

兼容性:
  - 原 ?url=xxx 模式完全保留
  - scene 解析失败/响应异常时降级到 CRMEB 首页
  - 不影响原有分享/复制链接功能

实现细节:
  - 遍历 items 找 identifier(不依赖 items[0] 排序假设)
  - 找不到时回退 items[0](保底)
  - 未来 box_app 支持 ?identifier= 直接过滤时,CRMEB 端无需改动
This commit is contained in:
2026-07-08 16:38:45 +08:00
parent 69da6597d9
commit c184108f45

View File

@@ -107,6 +107,62 @@ export default {
} }
}, },
onLoad(option) { onLoad(option) {
// 太阳码 scene 解析:scene="app=<identifier>" 时调 box_app 查 url
// 例如 box_app /api/wxacode?app=pregnancy → scene="app=pregnancy"
// CRMEB 收到后查 box_app /api/mp/apps?isPublished=1 找 url,跳对应 H5
if (option.scene && option.scene.indexOf('app=') === 0) {
const identifier = option.scene.slice(4);
console.log('[web_view] 太阳码 scene 解析: identifier=' + identifier);
// 异步处理:uni.request 拿 H5 url,赋值给 option.url 走后续逻辑
this._resolveAppScene(identifier, option);
return;
}
this._initWebView(option);
},
methods: {
/**
* 太阳码 scene 解析:调 box_app /api/mp/apps 找 url,找到后注入到 option.url
* 然后调用 _initWebView(option) 走标准 web_view 加载流程
*/
_resolveAppScene(identifier, option) {
const appToken = store.state.app.token || '';
uni.request({
url: 'https://mp.yizhezhe.com/api/mp/apps?identifier=' + encodeURIComponent(identifier) + '&isPublished=1&pageSize=1',
method: 'GET',
header: appToken ? { 'Authorization': 'Bearer ' + appToken } : {},
success: (res) => {
console.log('[web_view] 太阳码 scene 解析响应:', JSON.stringify(res.statusCode));
const items = res.data && res.data.result && res.data.result.items;
if (res.statusCode === 200 && items && items.length > 0) {
// box_app /api/mp/apps 当前不支持 identifier 过滤,遍历找
const app = items.find(it => it.identifier === identifier) || items[0];
if (app && app.url) {
const appUrl = app.url;
console.log('[web_view] 解析到 H5 url:', appUrl);
// 编码到 option.url,复用标准流程
option.url = encodeURIComponent(appUrl);
} else {
// 解析失败:降级到 CRMEB 首页
console.warn('[web_view] 太阳码 scene 解析失败,降级到 CRMEB 首页');
option.url = encodeURIComponent('https://shop.douba.top');
}
} else {
// 响应异常:降级到 CRMEB 首页
console.warn('[web_view] 太阳码 scene 解析响应异常,降级到 CRMEB 首页');
option.url = encodeURIComponent('https://shop.douba.top');
}
this._initWebView(option);
},
fail: (err) => {
console.error('[web_view] 太阳码 scene 网络请求失败:', err);
option.url = encodeURIComponent('https://shop.douba.top');
this._initWebView(option);
}
});
},
_initWebView(option) {
try { try {
let targetUrl = decodeURIComponent(option.url); let targetUrl = decodeURIComponent(option.url);
console.log('[web_view] 原始URL:', targetUrl); console.log('[web_view] 原始URL:', targetUrl);