143 lines
6.4 KiB
Markdown
143 lines
6.4 KiB
Markdown
# 小程序订阅消息:配置与使用(怎么让用户收到提示)
|
||
|
||
## 一、先分清两条通道
|
||
|
||
| | 消息推送(服务器配置) | 订阅消息 |
|
||
| --- | --- | --- |
|
||
| 方向 | **用户 → 你**(用户发客服消息给你) | **你 → 用户**(你主动推提示给用户) |
|
||
| 触发 | 用户在小程序点「客服」发消息 | 业务事件发生(审批待办、日程提醒、站内信…) |
|
||
| 前置条件 | 无 | 用户必须在微信弹窗里点「允许」(一次性订阅:授权一次 = 1 次推送机会) |
|
||
| 微信后台位置 | 开发管理 → 开发设置 → 消息推送 | 功能 → 订阅消息 |
|
||
| 本工程实现 | `services/wechatmini/push.go` + `controllers/api_wechat_mini.go` | `services/wechatmini/subscribe.go` + `controllers/api_mini_subscribe.go` |
|
||
|
||
**结论**:想让用户「收到提示」,靠的是**订阅消息**,不是消息推送。消息推送只是接收端(顺带做客服自动回复)。
|
||
|
||
---
|
||
|
||
## 二、完整流程(4 步)
|
||
|
||
### 第 1 步:微信后台选一个订阅消息模板
|
||
|
||
小程序后台 → **功能 → 订阅消息 → 公共模板库 → 选用模板**(例如「审批进度通知」「待办提醒」)。
|
||
|
||
选完后记下两样东西:
|
||
|
||
- **模板 ID**(一串字母数字)
|
||
- **模板的字段名**(如 `thing1`、`phrase2`、`time3`、`character_string4`)
|
||
|
||
> 模板选错会导致推送报 40066 / 47003,字段名对不上则报「模板字段不匹配」。
|
||
|
||
### 第 2 步:平台端登记模板
|
||
|
||
平台后台 → **系统设置 → 小程序配置 → 编辑小程序 → 订阅消息模板 → 新增模板**
|
||
|
||
| 字段 | 填什么 |
|
||
| --- | --- |
|
||
| 场景码 | `notice`(站内通知/通用提醒;同一个小程序下唯一) |
|
||
| 场景名称 | 如「站内通知」 |
|
||
| 模板 ID | 第 1 步复制的模板 ID |
|
||
| 跳转页面 | 用户点击消息进入的小程序页面,如 `pages/index/index` |
|
||
| 字段映射 | JSON:`{"thing1":"title","phrase2":"content","time3":"time"}` |
|
||
|
||
**字段映射怎么读**:左边是微信模板的字段名,右边是平台这边的变量名。平台会提供三个变量:
|
||
|
||
- `title` —— 标题(如「您有新的审批待办」)
|
||
- `content` —— 内容
|
||
- `time` —— 推送时间(`2026-10-31 19:00`)
|
||
|
||
映射里写了哪个字段,就把对应变量填进去;模板有但没映射的字段会自动填 `-`。
|
||
|
||
### 第 3 步:小程序端让用户授权
|
||
|
||
已接入的位置:**小程序「我的 → 消息通知」**,点一下会拉起微信的订阅授权弹窗。
|
||
|
||
```js
|
||
import { requestSubscribeNotice } from '@/utils/subscribe.js'
|
||
await requestSubscribeNotice()
|
||
```
|
||
|
||
建议在**用户确实可能需要收到提醒**的时机也调用一次(比如进入工作台、提交完审批之后)——因为微信一次性订阅,授权一次只有一次推送机会,用完了要再授权。
|
||
|
||
小程序端也可以直接调接口:
|
||
|
||
- `GET /api/mini/subscribe/templates` 取模板列表
|
||
- `POST /api/mini/subscribe/authorize` 上报授权结果
|
||
- `POST /api/mini/subscribe/test` 给自己发一条测试消息
|
||
|
||
### 第 4 步:业务侧触发
|
||
|
||
已接入的触发点(业务照常发,订阅消息自动跟上,**不影响主流程**,失败只记日志):
|
||
|
||
| 业务 | 代码位置 |
|
||
| --- | --- |
|
||
| 站内信(平台端手动发通知) | `services/system_sitereminder.go` → `SendSiteReminder` |
|
||
| OA 日程提醒(定时任务) | `services/reminder_scheduler.go` → `SiteMsgSender.Send` |
|
||
| 审批待办(租户侧审批人生成待办) | `services/approval/engine.go` → `createTasks` |
|
||
|
||
自己接新场景时,直接调:
|
||
|
||
```go
|
||
wechatmini.PushTenantNotice(租户用户ID, "标题", "内容")
|
||
// 或指定场景码:
|
||
wechatmini.PushSubscribeToTenantUser(租户用户ID, "notice", "", map[string]string{
|
||
"title": "标题", "content": "内容", "time": "2026-10-31 19:00",
|
||
})
|
||
```
|
||
|
||
---
|
||
|
||
## 三、一次性订阅的规则(最容易踩坑)
|
||
|
||
- 用户点一次「允许」= **1 次**推送机会,服务器记在 `yz_platform_wechat_mini_subscribe.remain`
|
||
- 推送成功自动 `remain - 1`;用户拒绝或机会用尽(微信返回 43101)自动清零
|
||
- `remain = 0` 时不会调微信接口,直接跳过(不浪费配额)
|
||
- 微信一次弹窗最多 3 个模板,前端已自动分批
|
||
- 「长期订阅」只有部分类目能用,��务小程序基本用不了,所以要设计好**再次引导授权**的时机
|
||
|
||
---
|
||
|
||
## 四、常见错误码
|
||
|
||
| errcode | 含义 | 处理 |
|
||
| --- | --- | --- |
|
||
| 43101 | 用户未订阅 / 拒绝订阅 | 引导用户在小程序里重新点「消息通知」授权 |
|
||
| 40066 | 模板 ID 无效 | 检查是不是填了「功能 → 订阅消息」里真正的模板 ID |
|
||
| 47003 | 模板字段不匹配 | 检查字段映射与微信模板字段是否一致 |
|
||
| 40003 | openid 无效 | 该用户不是用这个小程序登录的,或 openid 与 AppID 不匹配 |
|
||
| 40001 | access_token 失效 | 工具会自动刷新,稍后重试 |
|
||
|
||
平台端「测试」按钮会直接返回中文排查建议。
|
||
|
||
---
|
||
|
||
## 五、接口清单
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/api/mini/subscribe/templates` | 小程序端:可订阅模板列表(含剩余次数) |
|
||
| POST | `/api/mini/subscribe/authorize` | 小程序端:上报授权结果 |
|
||
| POST | `/api/mini/subscribe/test` | 小程序端:给自己发一条测试消息 |
|
||
| GET | `/platform/wechatMini/templates` | 平台端:模板列表 |
|
||
| POST | `/platform/wechatMini/template/save` | 平台端:保存模板 |
|
||
| POST | `/platform/wechatMini/template/delete/:id` | 平台端:删除模板 |
|
||
| POST | `/platform/wechatMini/template/test` | 平台端:给指定租户用户发测试消息 |
|
||
|
||
## 六、相关文件
|
||
|
||
| 文件 | 作用 |
|
||
| --- | --- |
|
||
| `go/services/wechatmini/subscribe.go` | 订阅消息 / 客服消息发送、模板 CRUD、授权记录、推送编排 |
|
||
| `go/controllers/api_mini_subscribe.go` | 小程序端接口 |
|
||
| `go/controllers/platform_wechat_mini.go` | 平台端模板管理接口 |
|
||
| `go/models/wechat_mini.go` | `WechatMiniTemplate` / `WechatMiniSubscribe` 模型 |
|
||
| `go/docs/sql/create_wechat_mini_template.sql` | 建表脚本 |
|
||
| `uniapp/utils/subscribe.js` | 小程序端授权助手 |
|
||
| `uniapp/api/subscribe.js` | 小程序端接口封装 |
|
||
| `uniapp/pages/profile/profile.vue` | 「我的 → 消息通知」授权入口 |
|
||
|
||
建表脚本:
|
||
|
||
```bash
|
||
mysql -h <host> -P <port> -u <user> -p <db> < go/docs/sql/create_wechat_mini_template.sql
|
||
```
|