后端方案 A:PUT /profile 改预产期/昵称时先推上游用户中心,推失败返回 400 且不落库。 原来这里 .then() 不看响应、.catch() 静默 —— 用户会以为保存成功,下次加载被上游值覆盖回去 ("改了没生效")。现在:非 200 或网络失败都 toast 提示,且不触发 bustReload。 - §4 硬约定新增第 9 条,说明这个接口的失败语义,避免以后又把失败吞掉 - 版本 v26092203 → v26092204
6.4 KiB
6.4 KiB
AGENTS.md · mama-box(兜爸心选 H5)
在本仓库工作前先读。跨仓库的权威约定在
box_app/AGENTS.md(/home/jone/workspace/box_app/AGENTS.md)—— 三仓布局、身份契约、接口命名、部署与踩坑总表都在那里;本文件只写本仓库特有的部分。
1. 这是什么
微信小程序里的首页 H5:小程序首页壳(crmeb/pages/index/index.vue)用 web-view 硬编码加载
https://mp.yizhezhe.com/mama-box/,用户看到的就是本站。它同时是 H5 应用宫格入口(30+ 第三方应用的门面)。
- 纯静态站点:无框架、无构建、无测试,
index.html一个页面用.screen切换多个屏。 - 仓库
jone/mama-box;本地/home/jone/workspace/mama-box;生产/opt/app/mama-box(nginx alias 托管,非 box_app 挂载)。 - 原型参考(只读,别当改动目标):
/home/jone/workspace/dailiang-app-03。
2. 文件地图
| 文件 | 作用 |
|---|---|
index.html |
单页多屏的全部结构 + 样式引用/脚本引用(1550+ 行) |
js/app.js |
全部业务逻辑(3000+ 行):屏切换、远程数据、宫格、授权、跳转、last_app |
js/wx-auth.js |
共享助手,别的 H5 应用也引用它:环境判定 / 读授权结果 / requestProfile / goMall / reportLocation。改动等于改所有接入方,务必保守 |
mama-box.css |
样式 |
assets/ |
图片/资源 |
js/core.js |
⚠️ 本仓库内已无任何引用(MPA 原型带过来的遗留)。新代码不要基于它,改前先确认没有隐藏引用 |
3. 发布
git push origin main # 完成后在服务器:
cd /opt/app/mama-box && git fetch && git reset --hard origin/main # 静态站,无需重启
nginx:root /opt/app + Cache-Control: no-cache + etag on —— 缓存靠 ETag,所以改完必须 bump 版本号。
版本号规则(必做):改了 js/*.js 或 mama-box.css 时,两处同步 bump,且 commit message 带版本:
index.html顶部<!-- V:YYMMDDNN 缓存版本标记… -->js/app.js顶部var VER = 'YYMMDDNN';
YYMMDD = 当天日期,NN = 当日两位序号(从 01 起)。例:v26092202。
4. 硬约定
- 身份只从 URL 读:宿主把
#openid=…&unionid=…注入进来,用hashParam(name)读 (它同时读 hash 与 query,并会剥掉历史 bug 粘上的?t=)。openid是唯一身份键。 - 拿不到 openid 就显示提示条(
showIdNotice),不要造假数据:宿主拿不到身份时不会加载本页; 真出现空身份要让人一眼看出来,而不是显示--/演示值。 - 跳其它 H5 应用一律走
jumpApp(url, identifier)(或档案页的goArchiveH5()):它负责 带身份(query)、上报分享地址、上报 last_app,再location.href。禁止裸location.href跳应用。 - 不要在本仓库写死应用名单:能不能出现、叫什么、链接是什么,全部由 box_app 后台 App 表决定
(
/api/mp/apps?isPublished=1)。要下架某应用去后台下架,别在前端加过滤(历史教训:wx-h5-demo过滤已按要求移除,别加回来)。 - 授权走
wxAuth.requestProfile():它用wx.miniProgram.navigateTo跳小程序独立授权页并带backUrl; 结果由宿主写回 URL 的 hash。不要用 postMessage 做授权请求(延迟批量投递,点了没反应)。 - 分享位置上报
reportHostLocation():postMessage 非实时(微信攒到后退/销毁/分享才派发), 所以要在换页/跳转前主动上报目标地址,宿主的分享卡片才能在分享那一刻拿到正确地址。 - 换应用前上报 last_app(
reportLastApp(),navigator.sendBeacon):这是「退出小程序再进能回到上次应用」的 数据来源,新增任何跳应用的入口都要走jumpApp()以继承这个行为。 - 返回首页要清 last_app(
clearLastAppOnBackHome()→DELETE /api/mp/public/last-app): 用户已经从 H5 应用退回首页,首页才是他最后待的地方 —— 不清的话下次冷启动又把他送回刚退出的应用。 ⚠️ 只认「返回回到本页」三种情形(bfcache 的pageshow.persisted、后退重载的navigation.type === 'back_forward'、从应用页location.href回来的document.referrer); 绝不能改成「每次加载都清」 —— 宿主恢复会把本页当返回落点加载,误清会毁掉刚用上的记录。 - 保存资料失败必须提示,不能静默(2026-09-22「档案以上游为准」):
PUT /profile改预产期/昵称时,后端会先推上游用户中心、成功才落库,推失败返回code=400且 不落库。H5 必须弹提示(_putProfile已按此判断res.code)——静默的话下次加载会被上游值覆盖回去, 用户以为"改了没生效"。改这个接口的调用方时别再把失败吞掉。
5. 踩坑
- 不要给别的应用追加
#openid:部分应用自带 hash 路由(如/baobao-yingji),追加 hash 会被当非法路由 → 页面未找到。身份一律走 query(withIdentity()已封装)。 bustReload重载必须把 hash 拼回去,否则丢身份、误报「未获取到微信身份」(v26092009 修过)。- 首屏渲染与异步数据的竞态:
init()负责渲染,远程档案在init()末尾才拉(先拉会被 init 覆盖)。新增远程数据请照这个顺序。 resumeLastApp()是兜底,不是主恢复:主恢复在小程序首页壳(冷启动自己读 last-app 直接进容器页)。 本页只在「首页壳取数失败回落加载」或「浏览器直访」时恢复;被宿主加了#norestore=1时必须既不跳、也用 sessionStorage 闸门占住(否则宿主?t=重载会把返回落点也换成目标应用,back 回不到首页)。- 改
js/wx-auth.js等于改全生态:它是所有接入 H5 应用共用的授权助手,先看docs/h5-auth-standard.md的协议再动。
6. 自测
无构建、无自动化测试。改完:
node --check js/app.js # 语法
真机/微信开发者工具里走一遍:身份注入是否正常、宫格跳应用是否带身份、分享卡片地址、授权回填、
退出小程序再进是否能回到上次应用。相关接口契约与验证清单见 box_app/AGENTS.md §6。