AGENTS.md 14.1 KB

仓库指南

项目功能概览

当前项目不是一个只有单页示例的小程序壳,而是一套已经串起“首页内容分发 + 动态底部导航 + 资讯/应用/我的 WebView 承接 + 授权 + 微信支付桥接”的业务骨架。

  • 首页主链路在 src/pages/index/,通过 src/api/index.js 拉取 banner、宫格导航和图片入口;点击后要么跳内部页面,要么通过 src/utils/webview.js 组装参数进入通用 WebView 容器。
  • 底部导航不是写死在页面里的,核心在 src/components/AppTabbar.vuesrc/stores/tabbar.jssrc/api/tabbar.jssrc/utils/tabbar.js。应用启动时会预加载 tabbar 配置,messageapplicationmine 现在都按接口返回地址承接 WebView。
  • 当前底部导航的真实结构是“后台动态菜单 + 固定 pages/webview-preview/index 承接页”,不是“每个 tab 都有一个固定业务页”。因此不要因为菜单地址来自后台,就把这条链路改回 redirectTo;非 home 按钮需要用 navigateTo 保留页面栈,这样进入 webview-preview 后微信原生左上角返回按钮才会出现。只有小程序冷启动直接进入某个 WebView 场景时,才会因为没有上一页而天然没有原生返回按钮。
  • src/pages/message/ 现在已经切到和导航栏“应用 / 我的”一致的 WebView 容器模式;src/pages/message-detail/src/api/message.js 更适合作为旧版原生资讯列表/详情演示链路参考,不应再默认当作线上资讯主入口继续扩展。
  • 支付相关目前有三类页面:src/pages/pay-test/ 用于手工调试授权和支付参数;src/pages/pay-confirm/ 是用户确认金额后点击支付的正式按钮页,支付成功后会按 getTabbarConfigAPI 返回的 data.user.link 进入“我的”对应的 WebView,如果接口里连 user 字段都没有,则直接回首页;src/pages/pay-bridge/ 是给 H5/WebView 调起小程序支付用的桥页,负责自动授权、拉起支付、展示结果并返回上一页。
  • src/pages/webview-preview/ 是通用外链承接页,src/pages/application/src/pages/mine/、首页外链入口都会复用这类能力;src/pages/map-guide/ 是固定地图签到 H5 页;src/pages/auth/ 是统一授权页,不能绕过。
  • src/pages/mine-backup/ 目前更适合作为旧版“我的”页视觉与交互备份参考,不应默认当作线上主链路去扩展新业务。

项目结构与模块组织

源码位于 src/,应用入口为 src/app.jssrc/app.config.js。当前目录分工建议按下面理解,而不是只把它当成普通 Taro 模板:

  • src/pages/:页面路由主目录。当前重点页面包括 indexmessagemessage-detailapplicationminepay-testpay-confirmpay-bridgewebview-previewmap-guideauth;其中 message / application / mine 都更偏 WebView 容器,pay-bridge 更偏桥接页,message-detailmine-backup 更偏旧链路参考页。
  • src/components/:通用组件目录。当前最关键的是 AppTabbar.vuePosterBuilder/、二维码组件、时间选择器等属于可复用能力模块。
  • src/composables/:组合式业务逻辑目录。useWechatMiniPay.js 是当前支付链路核心,和页面解耦较强;离线预约缓存相关逻辑也集中在这里。
  • src/hooks/:较轻量的通用 hooks,目前主要是 useGo.js 这类导航辅助。
  • src/api/:接口封装层。fn.js 是统一返回格式与 mock 接入的总入口,index.jstabbar.jswx/pay.js 分别承接首页、底部导航、微信支付等当前主链路接口;message.js 目前更偏旧版原生资讯列表/详情演示接口。
  • src/mock/:本地 mock 体系。目录拆分规则是 index.js 统一入口、modules/ 放 handler、shared/ 放公共解析能力、stores/ 放有状态 mock 数据、fixtures/ 放静态样本。
  • src/utils/:公共工具层。当前高频核心文件是 authRedirect.jsrequest.jsconfig.jswebview.jstabbar.jspaySuccessRedirect.jswechatPay.jsassetUrl.js;改动授权、环境、WebView 路由、支付或 CDN 静态图缓存时优先先看这里。若是“小程序内支付成功后该跳到哪里”这类问题,先看 paySuccessRedirect.js,不要在页面里各自重复写一份 app_menu -> data.user.link -> webview-preview / 首页 判断。
  • src/stores/:Pinia 状态目录。当前重点是 tabbar.js(底部导航配置)和 router.js(授权回跳来源页),其他 store 多为基础能力或历史保留。
  • src/assets/src/constants/:分别承接静态资源和常量;其中 src/constants/ 目前较轻,新增共享枚举或键名时再往这里收。
  • config/:构建与环境配置目录,dev.js / prod.js 控制 API_RUNTIME_ENV,不要把环境切换逻辑重新分散回页面层。

构建、调试与开发命令

使用 pnpm install 安装依赖。开发微信小程序时运行 pnpm dev:weapp,调试 H5 时运行 pnpm dev:h5。生产构建常用 pnpm build:weapp,如有多端需求,也可使用 pnpm build:h5pnpm build:alipay 等命令。提交前必须执行 pnpm lint,当前仓库已配置的自动检查主要就是 ESLint。

代码风格与命名约定

项目基于 JavaScript、Vue 3 单文件组件、Less 和 Taro 4。请遵循现有风格:.vue 文件统一使用 2 空格缩进,业务逻辑保持简洁,优先使用组合式写法。可复用组件使用 PascalCase 命名,例如 PosterBuilder;组合式函数和 hooks 使用 useXxx.js 命名,例如 useGo.js;接口方法统一使用 xxxAPI 后缀,例如 getUserInfoAPI。导入路径优先使用 @/utils@/components 等别名,避免过深的相对路径。

测试要求

当前 package.json 中没有独立的单元测试框架,因此默认验证方式为 pnpm lint 加手工联调。修改页面、路由、认证或请求逻辑后,请至少在微信开发者工具中走通相关流程。若变更涉及 src/utils/authRedirect.jssrc/utils/request.jssrc/api/,需要重点检查登录态、页面回跳和接口请求是否正常。后续如新增自动化测试,建议贴近功能放置,并使用 *.spec.js 命名。

Mock 环境与接口联调约定

仓库当前支持“正式环境 / 本地 Mock 环境”两套 API 运行模式,且环境切换只允许通过配置文件统一控制,不要在页面里单独写开关。开发环境默认读取 config/dev.js 里的 env.API_RUNTIME_ENV,生产构建默认读取 config/prod.js;当 API_RUNTIME_ENVmock 时,本地所有接口统一走 src/mock/,当其为 production 时,统一走真实接口。若只是临时联调某个页面,也不要在页面组件里直接写 USE_MOCK_DATA 之类的局部布尔开关,优先保持“一个地方切整个环境”的规则稳定。

Mock 目录也有明确分工:src/mock/index.js 只做统一入口和分发;src/mock/modules/*.mock.js 按业务模块注册 handler;src/mock/shared/ 放请求解析、响应包装、handler 匹配等公共能力;src/mock/stores/*.store.js 只处理需要状态变化的 mock 数据;src/mock/fixtures/*.fixture.js 只放静态样本和数据工厂。新增 mock 时,优先按“fixture -> store(如有状态)-> module handler -> modules/index.js 注册”的顺序扩展,不要再回到一个超大 mockData.js 式文件里堆条件分支。页面层不应该知道 mock 细节,只应该继续调用正常的 xxxAPI

授权与支付链路约定

授权逻辑的核心在 src/app.jssrc/utils/authRedirect.jssrc/utils/request.jssrc/pages/auth/index。应用启动时会优先尝试静默授权,sessionid 统一写入 Taro 本地缓存,并由请求拦截器动态注入到请求头;接口返回 401 时,会先尝试 refreshSession 静默续期并重放原请求,失败后再降级跳转授权页。因此除非明确重构整条链路,否则不要随意改动 sessionid 的存取方式、saveCurrentPagePath / returnToOriginalPage 的回跳机制、navigateToAuth 的防重逻辑,也不要跳过 src/pages/auth/index 直接在业务页硬编码授权流程。若修改分享进入、启动授权、401 重试或来源页回填逻辑,需至少手工验证一次“未授权进入页面 -> 自动或手动授权 -> 成功回跳原页面”的完整闭环。

如果改动底部动态菜单、webview-preview、授权回跳或页面跳转方式,还要额外验证一次“首页 -> 底部动态菜单进入 WebView -> 如未授权则去授权页 -> 授权成功后回到原 WebView 页 -> 左上角仍可返回首页”的完整闭环。这里的关键前提是保住页面栈,所以除 home 外不要随手把 tab 点击改成 redirectTo

支付链路现在至少有两种入口,不要再把它理解成只有一个测试桥页。第一种是当前线上主支付链路:业务页把 order_id、金额等参数带到 src/pages/pay-confirm/index.vue,用户确认后通过 src/composables/useWechatMiniPay.js 调用 /srv/?a=pay,再由请求层统一补上公共参数 fclient_id,最后由小程序侧执行 Taro.requestPayment。第二种是 H5/WebView 发起支付:外部页面先进入 pages/webview-preview/index 或 tabbar 对应的 WebView 容器,再把 order_id 传给 pages/pay-bridge/index;桥页负责检查授权状态、必要时补做静默授权、拉起支付、展示成功/取消/失败结果,并自动返回上一页。

仓库实现上,共享支付能力核心在 src/composables/useWechatMiniPay.jssrc/api/index.js;调试入口在 src/pages/pay-test/index.vue,正式确认页在 src/pages/pay-confirm/index.vue,H5 桥接页在 src/pages/pay-bridge/index.vue。另一条是历史保留的通用支付封装,位于 src/utils/wechatPay.jssrc/api/wx/pay.js,通过 pay_id 调用 /srv/?a=icbc_pay_wxamp。当前若处理支付问题,默认先看 order_id -> useWechatMiniPay -> /srv/?a=pay 这条主链路;其中 fclient_id 由请求层公共参数统一补齐,不要在单个支付接口 URL 上重复手写。若没有用户明确点名 pay_idwechatPay.jssrc/api/wx/pay.js,暂时不要把排查范围扩到这条历史链路,也不要顺手改它。修改支付逻辑时务必先确认当前页面接的是哪一条接口链路,不要混用 order_idpay_id,也不要在未拿到后端有效支付参数时直接调用 requestPayment。涉及 H5/WebView 唤起支付时,应优先保持 pages/pay-bridge 的桥接职责与返回参数约定稳定;涉及小程序内直接支付时,应优先保持 pages/pay-confirm 的“展示金额 -> 用户点击 -> 调用共享支付能力 -> 成功后按 app_menu.data.user.linkwebview-preview,无 user 则回首页”职责单一。这个成功跳转规则当前集中在 src/utils/paySuccessRedirect.js,如果以后还有别的小程序内支付入口要复用同样落点,优先复用它,不要在各页面里各写一版菜单判断。无论改哪条链路,都需要区分成功、取消、失败三类状态,并至少在微信开发者工具或真机中验证一次“授权状态检查 -> 拉起支付 -> 返回结果展示/回跳”的流程。

CDN 静态图片缓存约定

仓库里如果有直接写死的 https://cdn.ipadbiz.cn/jls_weapp/images/ 图片地址,不要再在页面里裸写完整 URL,也不要每张图各自手工拼时间戳。当前约定是统一走 src/utils/assetUrl.js:应用启动时会预加载 https://cdn.ipadbiz.cn/jls_weapp/version.json,并给本地写死的 CDN 图片自动补上 ?v=<image_version>

这里的边界要守住:

  • 当前这套版本参数机制只用于“仓库里本地写死的 CDN 图片地址”,主要目的是 CDN 覆盖同名图后,让小程序端也能跟着拿到新图。
  • 接口动态返回的图片 URL 默认先不要动,除非用户明确要求把某一类接口图也接入同一套版本机制。
  • 新增这类本地写死图片时,优先用 getVersionedImageAssetByName('xxx.png'),不要继续手抄完整 CDN 地址。
  • 如果只是替换同名图片内容,标准流程应该是:上传同名图片到 CDN -> 手动刷新图片 CDN 缓存 -> 更新 version.json 里的 image_version -> 再刷新 version.json 自己的 CDN 缓存。
  • 如果后续发现某个页面用了 jls_weapp/images 下的本地写死图但没有走 assetUrl.js,应视为漏接入,优先补到这一层,而不是在页面里临时各写一版缓存参数。

提交与合并请求规范

当前 Git 历史以简短中文提交为主,例如 初始化觉林寺小程序项目。后续提交信息也请保持中文、简洁、祈使语气,并聚焦单一改动。提交 PR 时请附上:变更背景与解决方案、关联任务或问题、影响的页面或模块、手工验证步骤;涉及界面改动时,需补充截图或录屏。

文档与描述语言要求

本仓库默认使用中文沟通与书写。今后新增或修改的说明性文字请统一使用中文,包括但不限于文档、注释说明、提交说明、PR 描述、变更摘要和协作备注;如必须保留英文术语,请同时提供中文语义,避免只写英文描述。

安全与配置提示

不要提交真实的 AppID、令牌或生产环境域名。首次接手项目时,请优先检查 src/utils/config.jsconfig/dev.jsconfig/prod.jsproject.config.json。授权与支付测试环境当前会复用既有后端配置,调整域名、client_id、支付接口地址或 WebView 跳转地址前,必须先确认不会影响 openid、会话续期和微信支付参数生成。若调整 CDN 静态图片更新策略,也要同时确认 https://cdn.ipadbiz.cn/jls_weapp/version.json 仍然返回 { "image_version": "..." } 这类结构,避免 assetUrl.js 读不到版本号。除非明确要重构认证链路,否则不要随意删除或绕过 src/pages/auth/index 认证页;同理,除非明确要废弃本地 mock 联调能力,否则不要把 API_RUNTIME_ENVsrc/mock/index.jssrc/mock/modules/ 里的统一分发能力改回页面内局部开关。