liu
2026-09-30 91491239c5d4611b5b1404a7abeb2bb23d0edad5
docs/wxcp_activity_integration.md
@@ -52,7 +52,7 @@
| id | Long | 修改时必填 | 编号 |
| title | String | 是 | 活动标题,≤128 字符 |
| content | String | 否 | 活动详情 |
| coverUrl | String | 否 | 封面图地址 |
| blobIds | Long[] | 否 | **封面图文件编号**,最多 1 个;不传 = 不改动封面,传 `[]` = 清空封面 |
| location | String | 否 | 活动地点,≤255 字符 |
| startTime | DateTime | 否 | 活动开始时间 |
| endTime | DateTime | 否 | 活动结束时间 |
@@ -72,6 +72,7 @@
| signupCount | Integer | 已报名人数 |
| pushStatus | Integer | 0未推送 1已推送 |
| pushTime | DateTime | 最近推送时间 |
| attachmentList | Object[] | **封面图附件列表**(最多 1 条),字段同报名附件:`id`、`name`、`url`、`previewURL`、`downloadURL`。列表缩略图、表单回显都从这里取 |
### 推送与二维码
@@ -116,6 +117,18 @@
|------|------|------|
| GET | `/wxcp/activity/signup-page?id={活动编号}` | 报名落地页 HTML,由后端渲染 |
| POST | `/wxcp/activity/signup` | 提交报名(支持 `content` 文字 + `blobIds` 附件) |
**提交报名请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| activityId | Long | 是 | 活动编号 |
| name | String | 否 | 姓名,≤64 字符 |
| mobile | String | 否 | 手机号;**填了才校验** 11 位格式,留空通过 |
| wxUserId | String | 否 | 企业微信成员账号 |
| deptName | String | 否 | 部门名称 |
| content | String | 否 | 参与说明 |
| blobIds | Long[] | 否 | 附件文件编号 |
### 报名统计与附件
@@ -180,7 +193,7 @@
1. 新建活动 → 保存为**草稿**,此时扫码报名会提示「报名已结束」
2. 点「发布」→ 状态变「已发布」,此时二维码和报名页才可用
3. 点「推送」→ 成员企业微信收到卡片消息,标题为活动标题,正文含**活动时间 / 地点 / 报名截止 / 名额**,按钮「立即报名」直达报名页
4. 成员点按钮或扫码 → 打开报名页 → 填姓名和手机号 → 提交
4. 成员点按钮或扫码 → 打开报名页 →(可选)填姓名和手机号 + 传附件 → 提交
5. 报名成功 → 活动 `signupCount` 自动 +1
6. 后台在活动详情的报名记录列表里可看到该成员,可执行「取消报名」「签到」
@@ -219,9 +232,12 @@
| 推送成功后 | 活动 `pushStatus` 置 1、`pushTime` 记录时间;重复推送会覆盖这两个字段 |
| 报名时间窗口 | 未到 `signupStartTime` 或已过 `signupEndTime` 均不能报名 |
| 报名名额 | `signupLimit=0` 表示不限;已满时提示「报名人数已满」 |
| 重复报名 | 有企业微信身份按成员账号判重;普通浏览器按**手机号**判重 |
| 报名姓名/手机号 | **均为选填**。手机号填了才校验格式,留空允许提交 |
| 重复报名 | 有企业微信身份按成员账号判重;没有账号但有手机号则按手机号判重;**两者都没有时不做判重**(无法判定身份,每次提交都新建一条) |
| 取消后重新报名 | 复用原记录,不会产生第二条历史 |
| 取消报名 | 活动 `signupCount` 自动 -1 |
| 封面图 | 不存业务表字段,存 `system_storage_attachment`(`record_type = wxcp_activity`)。删除活动时一并清掉附件关系 |
| 封面图展示 | 报名页顶部以 `object-fit: cover` 展示;管理后台列表在标题左侧显示缩略图 |
## 注意事项
@@ -236,6 +252,9 @@
- **推送目标用的是 `userId`(成员账号,如 `LiuYi`),不是姓名、也不是手机号。** 从通讯录接口取 `userId` 填进 `pushTarget`。
- **附件上传走 system 模块的公共上传接口**:报名页先调 `POST /admin-api/system/storage-blob/public-upload`(表单字段名 `files`)拿到 `blobId`,再把 `blobIds` 随报名提交,由**服务端**完成与报名记录的绑定。管理后台查附件用 `/wxcp/activity/signup/attachments`。
- **报名的 `recordType` 固定为 `wxcp_activity_signup`**,已注册进 system 模块的 `StorageRecordTypeEnum` 白名单。以后新增别的附件关联类型,必须同步注册,否则绑定会报「无效的记录类型」。
- **活动封面的 `recordType` 为 `wxcp_activity`**,同样已注册进白名单。封面**不再有 `coverUrl` 字段**,`POST/PUT /wxcp/activity/create|update` 提交 `blobIds`,`GET` 读 `attachmentList`。
- **封面图在报名页显示时会去掉协议和域名**。附件地址里的域名取自 `yudao.storage.domain`(一般是内网地址),而手机扫码是从公网域名打开页面的,直连内网地址加载不出图片,所以后端只保留 `/admin-api/...` 路径交给同源代理。**如果部署时管理后台与报名页不同源,这个处理需要重新评估。**
- 表单里的封面用 `ImageUpload` 组件(`maxNumber: 1`)时,组件返回的是**单值而不是数组**,提交前必须包成数组(`blobIds` 后端签名是 `List<Long>`)。
- 通讯录接口**实时调企业微信**,有频率限制,前端务必缓存,不要随输入实时请求。
- 通知正文超过 600 字会**自动截断**(企业微信文本消息有长度上限),截断提示会写在消息末尾。