Files
crmeb-mp/docs/分享图片获取逻辑.md

5.0 KiB
Raw Blame History

分享图片获取逻辑(box_app → 小程序 web_view)

适用项目:CRMEB 小程序(crmeb)+ box_app 应用管理平台 功能:小程序 web_view 内点"转发给好友"时,分享卡片使用 box_app 后台配置的分享图片


一、数据流全景

[box_app 管理后台]
  新建/编辑应用 → 上传"分享图片"
  → 存入 App.shareImageUrl = https://mp.yizhezhe.com/upload/picture/xxx.png

[box_app API]
  GET /api/mp/apps?identifier=xxx&isPublished=1
  → 返回 { identifier, url, shareImageUrl, ... }

[小程序 web_view(pages/annex/web_view/index.vue)]
  ① 扫码/点击应用 → 获取 shareImageUrl → 本地缓存
  ② 用户点 ··· 转发给好友  → 卡片图 = shareImageUrl(网络图,微信支持)
  ③ 用户点 ··· 分享到朋友圈 → getImageInfo 转本地路径 → 卡片图 = 本地路径

二、box_app 侧配置(已实现)

后端(backend/app/models/app.py + services/app_serv.py)

  • App 模型新增字段:shareImageUrl: str | None(微信分享卡片图,公网 https URL)
  • AppCreate / AppUpdate / AppOut 均含 shareImageUrl,查询/写入透传(find / find_all / find_one / create / update 共 5 处)
  • 上传接口:POST /api/upload(返回公网 URL)

管理后台前端(frontend/src/pages/ProductManagement.jsx)

  • 新建/编辑应用表单新增 "分享图片 (Share Image)" 上传项
  • 支持上传 /api/upload、编辑回填、单图(maxCount=1)
  • extra 提示:建议 5:4 比例,公网可访问

三、小程序端获取逻辑(web_view/index.vue)

三种获取路径(按优先级)

优先级 场景 方法 说明
① 首选 太阳码扫码 _resolveAppScene 调 mp/apps?identifier=xxx 时一次请求同时拿 H5 url + shareImageUrl,identifier 严格匹配
② 兜底 点击应用(JumpPath 直传 URL) _fetchShareImage 按 URL 前缀反查 mp/apps 列表,命中写入本地缓存
③ 覆盖 H5 postMessage 自定义 handleMessage 'share' H5 bridge.share({imageUrl}) 传了图才覆盖,为空保留 box_app 预取值

① 太阳码扫码(_resolveAppScene)

扫码 → scene=app=testapp
→ GET https://mp.yizhezhe.com/api/mp/apps?identifier=testapp&isPublished=1&pageSize=1
→ items[0] = { url, shareImageUrl, ... }
→ 同一响应取 app.url(加载 H5)+ app.shareImageUrl(分享图)
→ 严格匹配 items.find(it => it.identifier === identifier),避免张冠李戴

② 点击应用(_fetchShareImage,在 _finalizeUrl 中异步触发)

点应用 → JumpPath 传完整 H5 URL(如 https://mp.yizhezhe.com/app_03/)
→ 1. 查本地缓存 web_view_share_img:{originPath} → 命中直接复用
→ 2. 未命中 → GET /api/mp/apps?isPublished=1&pageSize=100(拉全量已上架应用)
→ 3. URL 前缀匹配:originPath === appBase || originPath.startsWith(appBase + '/')
→ 4. 命中 → this._applyShareImage(shareImageUrl) + 写入缓存

页面加载时执行,用户点转发时图已就绪。_shareFetched 标志保证页面内只请求一次。

③ H5 postMessage 覆盖(handleMessage)

H5 bridge.share({ title, imageUrl }) → postMessage → handleMessage 'share'
→ if (data.imageUrl) this.shareImageUrl = data.imageUrl  // 有值才覆盖
→ 为空则保留 box_app 预取的分享图片

四、好友转发 vs 朋友圈(微信平台差异)

场景 图片要求 实现
转发给好友 onShareAppMessage 支持 https 网络图 imageUrl: this.shareImageUrl(box_app 网络 URL 直接用)
分享到朋友圈 onShareTimeline 仅本地路径/代码包路径,网络图静默忽略 _prepareTimelineImage 用 uni.getImageInfo 转本地临时路径 shareTimelineImage

五、关键前置条件(易踩坑)

  1. box_app 已配置分享图:管理后台 → 应用 → 上传"分享图片"
  2. 图片必须公网 https 可访问(微信服务器要抓取)
  3. mp.yizhezhe.com 必须在微信后台合法域名白名单:
    • request 合法域名(拉取 mp/apps 接口)
    • downloadFile 合法域名(朋友圈转本地图 getImageInfo)
    • ⚠️ 未配置时:好友图可能正常(网络图),但朋友圈图转换失败回退默认截图,_fetchShareImage fail 分支会提示

六、相关代码位置

位置 文件
box_app 模型字段 box_app/backend/app/models/app.py
box_app 服务透传 box_app/backend/app/services/app_serv.py
box_app 表单上传 box_app/frontend/src/pages/ProductManagement.jsx
小程序扫码取图 crmeb/pages/annex/web_view/index.vue → _resolveAppScene
小程序兜底反查 同上 → _fetchShareImage / _applyShareImage / _prepareTimelineImage
小程序分享回调 同上 → onShareAppMessage / onShareTimeline / handleMessage
H5 传图 app_03/frontend/src/app/services/bridge.ts → share({imageUrl})