WeChat 公众号/小程序能力
oak-general-business 里最复杂的一块通用能力,几乎一定是微信生态。
这里不是只有“微信登录”这么简单,而是同时覆盖了:
- 网页微信登录;
- 小程序登录;
- 公众号网页登录;
- 公众号回调;
- 微信用户绑定;
- 微信二维码;
- 菜单管理;
- 公众号标签;
- 微信模板;
- 素材管理;
- 短信跳小程序 openlink。
如果把这些能力都混在一起看,会非常乱。所以这一章的重点,是把它们在 Oak 里的边界讲清楚。
主要对象
微信相关的主要实体包括:
WechatUserWechatLoginWechatQrCodeWechatMenuWechatPublicTagUserWechatPublicTagWechatTemplateWechatPublicAutoReplyWechatMpJump
此外,很多微信能力其实还依赖 Application.config 里的微信配置,所以 Application 仍然是微信能力的根配置入口。
组件
这一章涉及的组件非常多,常见的有:
src/components/passport/wechatMpsrc/components/passport/wechatMpForWebsrc/components/passport/wechatPublicsrc/components/passport/wechatPublicForWebsrc/components/wechatLogin/qrCodesrc/components/wechatLogin/confirmsrc/components/wechatUser/loginsrc/components/wechatUser/bindingListsrc/components/wechatUser/unbindBtnsrc/components/wechatQrCode/scansrc/components/wechatQrCode/sharesrc/components/wechatMenu/*src/components/wechatPublicTag/*src/components/userWechatPublicTag/*src/components/wechatMaterialLibrarysrc/components/wechatPublicAutoReplysrc/components/common/weChatLoginGrantsrc/components/common/weChatLoginQrCode
从这些组件命名就能看出来,微信能力在这个包里已经不只是“一个登录按钮”了。
wechatUser/login 常用参数
这个组件本身几乎不要求项目层传很多东西,最常见的就是:
codestateoakPath
taicang/src/pages/frontend/wechatUser/login/web.pc.tsx 和 haina-busi/src/pages/wechat/wechatUser/login/web.pc.tsx 的写法都很薄:
<WechatUserLogin code={code} state={state} oakPath="$wechatUser/login-cpn" />
它内部会自己读取当前 URL 上的 code / state,调用 features.token.loginWechat(...),成功后按 state 跳回业务页。
wechatQrCode/scan 常用参数
扫码组件最关键的两个参数是:
scene:小程序码扫码场景值q:普通链接二维码携带的值
组件内部会把它们展开成二维码记录 id,然后按二维码里保存的 pathname / props / state 自动跳转。
自定义微信授权确认页
除了公共组件,haina-busi 里还有一个很值得参考的项目层包装:components/wechatLogin/confirm。它会先拼好公众号 OAuth 地址,再把 redirectUri 指向:
/wechat/wechatUser/login
这种做法适合项目需要在真正跳微信授权前,先展示一层“确认登录到哪个业务对象”的页面。
wechatUser/bindingList / wechatUser/unbindBtn
这两个组件更偏“账号绑定管理”,通常不会放在登录页,而会放在:
- 个人中心
- 账号安全页
- 后台用户详情页
wechatUser/bindingList 的真实行为很轻量:
- 读取
wechatUser列表 - 只保留已经绑定到本地用户的记录,也就是
userId不为空的项
所以它适合做“我当前绑定了哪些微信身份”的列表视图,而不是通用的微信用户管理页。
wechatUser/unbindBtn 更简单,它只读取当前 wechatUser.id 和 userId,作用就是给解绑按钮提供当前记录上下文。项目层通常会把它和:
unbindingWechat
这类 aspect 动作一起用,而不是自己去查 wechatUser 再手工拼按钮。
公众号后台管理组件
除了登录和扫码,oak-general-business 还把公众号后台常用能力拆成了几组现成组件。它们最适合直接挂在 application/panel 自动生成的微信页签里。
wechatMenu
这个组件最关键的参数是:
applicationIdtabKey
它在进入页面时会先拉当前 applicationId 下、没有 wechatPublicTagId 的默认菜单,并把 menuId 放到内部状态里。也就是说,它默认管理的是“公众号主菜单”,不是泛化的任意菜单树。
wechatPublicTag/list
这个列表组件的关键参数只有:
applicationId
但它内部已经带了几个实际动作:
- 单条
sync oneKeySync- 删除标签
这意味着项目后台如果只是做公众号标签同步,不需要自己调用 feature 拼一个管理页,直接复用它就够了。
userWechatPublicTag/subscribedList
这也是公众号运营后台里很实用的一个组件,关键参数同样只有:
applicationId
它默认只查:
origin: 'public'subscribed: true
所以它适合做“已关注用户与标签”的运营列表,而不是泛化的全部微信用户列表。它内部还能直接调用:
userWechatPublicTag.tagging(...)userWechatPublicTag.syncToLocale(...)
wechatMaterialLibrary
这个组件最重要的参数是:
applicationIdtypegetMenuContent
其中 type 决定它去拉:
news图文素材- 其它永久素材类型,例如
image、voice、video
它内部会直接调 features.wechatMenu.batchGetArticle(...)、batchGetMaterialList(...)、createMaterial(...)、getMaterial(...),所以非常适合给菜单编辑、自动回复编辑器或图文选择弹窗做素材选择面板。
wechatPublicAutoReply
这个组件也只要求:
applicationId
但它有一个很关键的默认行为:如果当前公众号还没有自动回复配置,ready() 阶段会自动补一条:
type: 'text'event: 'subscribe'
所以项目层不需要担心“第一次进入页面没有任何回复配置时界面空掉”,公共组件已经把首条默认记录准备好了。
前端 feature 与 aspect
前端直接可用的微信相关 feature 主要有:
features.tokenfeatures.wechatSdkfeatures.wechatMenufeatures.wechatPublicTagfeatures.userWechatPublicTagfeatures.template
这里要特别注意两点:
- 微信登录虽然是“微信能力”,但前端真正调用的通常是
features.token.loginWechatMp()、features.token.loginByWechatInWebEnv(...)这一层; - 微信模板同步虽然属于微信生态,但前端入口并不是单独的
wechat feature,而是features.template。
对应的 aspect 也很丰富,主要包括:
- 登录相关:
loginWechat、loginWechatMp、loginWechatNative、loginByWechat - 用户同步相关:
syncUserInfoWechatMp、refreshWechatPublicUserInfo、getWechatMpUserPhoneNumber、setUserAvatarFromWechat - 微信登录中间态:
createWechatLogin - 微信解绑:
unbindingWechat - 二维码:
getMpUnlimitWxaCode - 菜单:
getCurrentMenu、getMenu、createMenu、createConditionalMenu、deleteConditionalMenu、deleteMenu - 标签:
createTag、getTags、editTag、deleteTag、syncTag、oneKeySync - 用户标签:
getTagUsers、batchtagging、batchuntagging、getUserTags、getUsers、tagging、syncToLocale、syncToWechat - openlink:
wechatMpJump - 微信素材与模板:
signatureJsSDK、uploadWechatMedia、batchGetArticle、getArticle、batchGetMaterialList、getMaterial、deleteMaterial、syncWechatTemplate
这已经是一整套相当成型的微信业务中台能力了。
endpoint
这一章必须单独强调真实暴露出来的 endpoint 名称,而不只是文件名。
src/endpoints/wechat.ts 里注册了三个 endpoint:
wechatPublicEventwechatMpEventwechatMaterial
其中:
wechatPublicEvent同时包含 GET 验证接口和 POST 回调接口;wechatMpEvent同时包含 GET 验证接口和 POST 回调接口;wechatMaterial用于读取素材二进制内容,通常会被素材库、菜单预览等界面间接使用。
src/endpoints/index.ts 则在导出这些 endpoint 的同时,额外导出了:
registerWeChatPublicEventCallback
它允许项目层在不改公共包 endpoint 主流程的情况下,继续挂接自己的公众号事件处理逻辑。
这些 endpoint 共同承担了微信服务器回调入口,用于处理:
- 公众号事件;
- 小程序事件;
- 扫码、订阅、菜单点击等回调。
也正因为有这一层 endpoint,WechatLogin、WechatQrCode、WechatUser 等对象之间的联动才真正成立。
后台规则
后台规则主要散落在这些 trigger / checker 里:
triggers/wechatLogin.ts:创建登录中间态时自动生成二维码,过期时同步二维码过期;triggers/wechatQrCode.ts:按二维码类型真正生成公众号二维码、小程序码或跳转链接;triggers/wechatMenu.ts:删除个性化菜单前调用微信删除接口;triggers/wechatPublicTag.ts:删除标签前同步删除微信端标签并清理关联数据;triggers/wechatMpJump.ts:创建WechatMpJump时生成 openlink;checkers/wechatPublicTag.ts、checkers/wechatQrCode.ts:校验微信标签和二维码数据。
这一套规则说明,微信相关对象并不是“你手工写好数据再去用”,很多关键字段和远端副作用都是由 trigger 自动完成的。
注入点
微信能力的注入点非常明确:
- 前端在
create(...)时注入wechatSdk、wechatMenu、wechatPublicTag、userWechatPublicTag; - 登录相关能力通过
features.token暴露给页面和组件; - 模板同步能力通过
features.template暴露给页面和组件; initialize(...)在 web 环境下调用features.wechatSdk.setLandingUrl(window.location.href);initialize(...)在小程序环境下会按需自动登录;- 后端通过
ogb0Aspects、ogb0Checkers、ogb0Endpoints、ogb0Triggers合并微信相关能力; - 如果项目需要补充公众号或小程序事件处理,直接从
src/registry.backend.ts注册registerWeChatPublicEventHandler(...)/registerWeChatPublicEventAfterHandler(...)和registerWeChatMpEventHandler(...)/registerWeChatMpEventAfterHandler(...);主处理器先于默认逻辑执行,after 处理器在默认逻辑后补充收尾。
换句话说,微信生态的前后台装配都已经在 oak-general-business 里设计好了。
真实项目里的接法
taicang 和 haina-busi 实际都采用了一条统一链路:
- 登录页或业务页里的
user/login把redirectUri指向/wechatUser/login /wechatUser/login页面只包wechatUser/login- 二维码场景再单独提供
/wechatQrCode/scan - 公众号或小程序回调最终还是落回
features.token
这样做的好处是,项目层不用到处自己处理 code/state,而是统一交给公共组件。
项目中如何接入
微信能力在项目里的接入,通常分成三段:
Application.config里配好wechatMp/wechatPublic/web.wechat- 初始化时执行
initializeOgb0Features(...),让wechatSdk、token、template、application这些 feature 串起来 - 后台把
ogb0Aspects / ogb0Checkers / ogb0Triggers / ogb0Endpoints合并进去,真正暴露微信回调入口并接上默认规则
所以项目层真正要关心的,通常是“应用配置是否正确”“路由和回调地址是否对上”,而不是从零写微信协议处理。
使用示例
1. Web 端调用微信 JSSDK
oak-general-business/src/features/wechatSdk.web.ts 已经把签名和 wx.config 包好了,项目里直接这样用:
await this.features.wechatSdk.loadWxAPi('chooseImage', { count: 1 });
await this.features.wechatSdk.loadWxAPi('scanQRCode', { needResult: 1 });
通常不需要页面自己再去调用 signatureJsSDK(...),因为 WechatSdk feature 会先完成签名初始化。
2. 管理公众号标签和模板
这些能力已经有直接可调用的 feature:
const applicationId = this.features.application.getApplication().id!;
await this.features.wechatPublicTag.createTag({
applicationId,
name: '核心用户',
});
await this.features.template.syncWechatTemplate(applicationId);
3. 小程序端显式触发登录
如果项目关闭了自动登录,也可以手工调用:
await this.features.token.loginWechatMp();
4. 项目侧补充公众号事件处理
如果默认的 wechatPublicEvent 流程之外,你还要补项目自己的事件逻辑,可以注册带 msgType / event 的处理器:
import {
registerWeChatPublicEventAfterHandler,
registerWeChatPublicEventHandler,
} from '@oak-general-business/registry.backend';
registerWeChatPublicEventHandler({
applicationId: 'wx-public-app-id',
msgType: 'event',
event: 'subscribe',
handler: async ({ data, context }) => {
// 项目自己的补充逻辑
},
});
registerWeChatPublicEventAfterHandler({
applicationId: 'wx-public-app-id',
msgType: 'event',
event: 'subscribe',
handler: async ({ response }) => {
// 默认逻辑后的收尾处理
},
});
5. 项目侧补充小程序事件处理
小程序回调也走同一套注册表:
import { registerWeChatMpEventHandler } from '@oak-general-business/registry.backend';
registerWeChatMpEventHandler({
applicationId: 'wx-mp-app-id',
msgType: 'event',
event: 'subscribe',
handler: async ({ data }) => {
// 小程序项目自己的补充逻辑
},
});
6. 用统一扫码页承接二维码跳转
如果项目里有活动页、分享页、落地页需要二维码跳转,推荐像 taicang / haina-busi 一样单独挂一个扫码页:
<WechatQrCodeScan
scene={scene}
q={q}
oakPath="$wechatQrCode/scan-cpn"
/>
这样二维码失效、非法二维码、跳转目标解析这些细节都会由公共组件统一处理。
使用建议
最推荐的理解方式是按链路拆:
- 登录链路:
Passport/ApplicationPassport+Token aspect+WechatLogin - 用户绑定链路:
WechatUser - 二维码链路:
WechatQrCode - 管理后台链路:
WechatMenu/WechatPublicTag/UserWechatPublicTag - 素材模板链路:
WechatTemplate+ 素材相关 aspect
这样读,你会发现这并不是零散功能,而是围绕微信生态拆出来的一整层业务基础设施。