## 微信小程序订阅消息推送流程(前后端协同) ### 前置条件 - 后端配置 `system.wechat.appid`、`system.wechat.secret`,并确保服务器可访问微信开放接口。 - 小程序后台已创建订阅消息模板并拿到 `templateId`。 - 前端页面在需要推送的位置调用 `wx.requestSubscribeMessage` 完成用户授权。 ### 交互时序 1. **前端获取用户身份** - 调用 `wx.login` 得到 `code`。 - 将 `code` 发送给后端(可复用现有登录接口),后端换取 `session_key` 和 `openid`,并存入 Redis `wx_session_id_{sessionId}`。 2. **(可选)获取手机号** - 前端携带 `code` 调用 `POST /api/wx/phone`,后端使用 `getAccessToken` + `getUserPhoneNumber` 获取并返回手机号。 3. **用户授权订阅** - 前端调用 `wx.requestSubscribeMessage({tmplIds: [templateId]})`。 4. **后端发送订阅消息** - 前端将 `openid`、`templateId`、`page`、`data` 传给 `POST /api/wx/send`。 - 后端封装 `TemplateMessage`,通过 `WxService.sendTemplateMessage` 调用微信 `message/subscribe/send` 完成推送。 ### 后端接口(SendMessageController) - `GET /api/wx/access-token`:调试用,查看当前 token。 - `POST /api/wx/phone`:请求体 `{ "code": "" }`,返回 `{ "phoneNumber": "..." }`。 - `POST /api/wx/send`:请求体示例: ```json { "openid": "用户openid", "templateId": "模板ID", "page": "pages/index/index", "data": { "thing1": { "value": "张三" }, "time2": { "value": "2024-01-01 12:00" } }, "clientMsgId": "可选-幂等ID" } ``` 返回 `{ "success": true/false }`。 ### 数据要点 - `data` 的 key 必须与模板的关键词 ID 对应,value 为 `{ "value": "展示内容" }`。 - `page` 需是已发布的小程序页面路径。 - `clientMsgId` 可用于防止重复推送(微信侧支持幂等)。 ### 调试建议 - 使用微信开发者工具调用接口时,需确保请求域名在小程序后台「开发设置-服务器域名」里配置。 - 微信接口有调用频率限制;本例未做 token 缓存,生产环境需增加 Redis 缓存与过期处理。 - 控制器仅用于联调,请根据需要加鉴权、限流与异常告警。