From b06a617f13dfd502c6ddf4ea7a74ea4cb6f5ad2e Mon Sep 17 00:00:00 2001 From: Karlcarlo Date: Tue, 22 Sep 2026 11:08:41 +0800 Subject: [PATCH] =?UTF-8?q?docs(AGENTS):=20=E6=96=B0=E5=A2=9E=20AGENTS.md?= =?UTF-8?q?=20=E2=80=94=E2=80=94=20=E5=B0=8F=E7=A8=8B=E5=BA=8F(=E5=AE=BF?= =?UTF-8?q?=E4=B8=BB)=E4=BE=A7=E5=BC=80=E5=8F=91=E7=BA=A6=E5=AE=9A?= =?UTF-8?q?=E4=B8=8E=E8=B8=A9=E5=9D=91=EF=BC=88=E8=B7=A8=E4=BB=93=E7=BA=A6?= =?UTF-8?q?=E5=AE=9A=E6=8C=87=E5=90=91=20box=5Fapp/AGENTS.md=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 两个宿主页 / mixin / App.vue / 授权页 / 引导页 的职责地图,发布方式(HBuilderX→微信审核) - 硬约定:宿主页共用 mixin、身份走 query 授权结果走 hash、fail-closed、分享深链脱敏、 分享图按 webViewUrl 当场解析、tabBar 全局状态、恢复/落地走容器页、只有 options.url 算显式落地 - 踩坑:热启动(点胶囊关闭后再进)不触发 onLoad —— 恢复逻辑不能只写在 onLoad; onShow 无条件重载会把用户踢回首页(用 App.onShow 时间戳区分热启动与切 tab) - 提醒:mixins/shareCard.js 未被 git 跟踪,提交时别漏 --- AGENTS.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..7034a0e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,70 @@ +# AGENTS.md · CRMEB 小程序(web-view 宿主) + +> 在本仓库工作前先读。**跨仓库的权威约定在 `box_app/AGENTS.md`**(WSL:`/home/jone/workspace/box_app/AGENTS.md`)—— +> 三仓布局、身份契约、接口命名、部署流程都在那里。本文件只写小程序侧特有的部分。 + +--- + +## 1. 这是什么 + +CRMEB 商城小程序(uniapp,manifest `name=DoubaShop`),同时是**整个 H5 生态的 web-view 宿主**: + +- **首页壳** `pages/index/index.vue` —— tabBar 首页,硬编码加载 `https://mp.yizhezhe.com/mama-box/`; + H5 应用宫格在 mama-box 内用 `location.href` 换应用,**本页不会重新 onLoad**。 +- **容器页** `pages/annex/web_view/index.vue` —— 太阳码 / 分享落地 / 商城宫格 / JumpPath 的通用宿主。 +- H5 应用(30+)只在 box_app 后台登记,本仓库没有它们的源码。 + +| 项 | 值 | +| --- | --- | +| 本地路径 | `/mnt/c/Users/Jone/Documents/HBuilderProjects/crmeb`(Windows:`C:\Users\Jone\Documents\HBuilderProjects\crmeb`) | +| 发布 | HBuilderX 发行 → 微信小程序上传 → 微信审核 → 发布(**没有 git remote,本仓库是纯本地库**) | +| 版本 | `manifest.json` 的 `versionName` / `versionCode` | + +## 2. 关键文件 + +| 文件 | 作用 | +| --- | --- | +| `pages/index/index.vue` | 首页壳:身份 fail-closed、加载 mama-box、**冷启动恢复 last_app**、分享卡片、tabBar 显隐 | +| `pages/annex/web_view/index.vue` | 容器页:太阳码 scene 解析、身份注入(query)、`_reportLastApp` 上报 | +| `mixins/webviewHost.js` | 宿主公共能力:postMessage 分发(location/share/copyLink/setTitle/requestProfile)、原生授权面板、授权回传、静默登录复用 | +| `mixins/shareCard.js` | 分享图:按当前 H5 URL 反查 box_app App 表;朋友圈本地图转换 | +| `App.vue` | 冷启动静默登录、`globalData`(`spid` / `appShowAt`)、`onShow`(前台化时间戳) | +| `pages/annex/auth/index.vue` | 独立授权页(`navigateTo` 进入,成功写 `__AUTH_RESULT__` 后 `navigateBack`) | +| `pages/guide/index.vue` | `pages.json` 第一个页面(冷启动入口,无广告时 `switchTab` 到首页壳) | + +## 3. 硬约定 + +1. **两个宿主页必须共用 mixin**:`mixins/webviewHost.js` + `mixins/shareCard.js`。历史上两页各写一份导致能力分叉(首页壳缺 copyLink / 授权回传 / unionid),别再分叉。 +2. **身份注入走 query、授权结果走 hash**:容器页 `_applyIdentity()` 负责按当前 openid 重写 URL(含 `_v=` 缓存击穿);授权回传只走 hash(`#openid=&phone=&nickname=&avatar=`)——微信 web-view **首次加载丢 query、不丢 hash**。 +3. **拿不到 openid 就不加载 H5**(fail-closed):重试 → 兜底屏 → 手动重试;**不要匿名加载**(H5 会进访客态,反而更难排查)。 +4. **分享深链必须 `stripAuthParams()`**:别把发送者的 `openid/unionid/t` 泄露给接收者;接收者由容器页按自己身份重新注入。 +5. **分享图/标题按 `onShareAppMessage(options).webViewUrl` 当场解析**:postMessage 是延迟投递,首页壳又不随 H5 换应用 onLoad,沿用上次结果会「B 应用带 A 应用的图」。 +6. **tabBar 是全局状态**:首页壳必须 `uni.hideTabBar()`(web-view 盖不住原生条,H5 自带底栏会双条);**严禁在商城页主动 `showTabBar` 配对** —— 会与 DIY 底栏同显成双 tabBar。 +7. **恢复/落地统一 `navigateTo` 容器页**,并保留首页壳作为返回落点;不要直接把首页壳的 web-view src 指向第三方应用(首页壳的 `buildWebUrl` 是 **hash** 注入,会破坏自带 hash 路由的应用)。 +8. **只用 `options.url` 当显式落地判据**:`options.scene` **每次冷启动都有值**(1001 最近使用 / 1007 分享 / 1011 扫码…),拿它判落地会导致恢复永远不执行。 + +## 4. 踩坑:热启动 vs 冷启动(2026-09-22,付过线上代价) + +- 用户点右上角胶囊圆点「关闭」**不是销毁**,只是切后台。马上再进是**热启动**:页面栈与 web-view 都在, + **只触发 `onShow`,不触发 `onLoad`**;被回收后才是冷启动。 +- 所以「退出小程序再进要回到上次的 H5 应用」这类需求,**只写在 `onLoad` 里会失败** —— 用户测的正是「关闭后马上再进」。 +- 反过来,`onShow` 里**无条件重载 web-view** 会把用户从 H5 应用踢回首页。首页壳曾有一段「切回首页 tab 就重载」的老逻辑, + 热启动也走它,于是把恢复好的应用冲掉(`shareHref` 因 postMessage 延迟还停在 mama-box)。 +- **判据**:切 tab **不触发** `App.onShow`,热启动**会**。做法:`App.vue onShow` 记 `globalData.appShowAt`, + 页面 `onShow` 里 `Date.now() - appShowAt < 2000` 视为热启动恢复 → **跳过重载**。 +- 改任何 `onShow` 逻辑前,先想清楚触发来源(App 前后台切换 / 页内跳转 / 切 tab)。 + +## 5. 本仓库状态提醒 + +- ⚠️ `mixins/shareCard.js` **未被 git 跟踪**(untracked),但两个宿主页都 import 它 —— 提交时别漏,否则一旦丢工作区这份文件就没了。 +- `pages/index/index.vue.origin-bak`(及若干 `.bak_*`)是原装修首页/历史备份,**别当改动目标**,也别删(回退时要用)。 +- 仓库里有多次会话遗留的未提交改动(`manifest.json` / `pages.json` / `pages/index/mall.vue` 等),动手前先 `git status` 分清哪些是本次的。 + +## 6. 自测 + +微信开发者工具(HBuilderX 运行到小程序): +1. **冷启动**:点「编译」→ 有 last_app 记录时应直接进上次的 H5 应用(不经过首页)。 +2. **热启动**:点工具栏「切后台」再「切前台」→ 应停在原 H5,**不应重载回首页**。 +3. 无记录 / 断网冷启动 → 最多约 1.5s 后照常进首页。 +4. 授权页返回、分享卡片、商城宫格进应用各走一遍。 +接口契约与后端验证清单见 `box_app/AGENTS.md` §5、§6。