|
|
@@ -0,0 +1,80 @@
|
|
|
+# 活动报名表单设计
|
|
|
+
|
|
|
+**日期:** 2026-07-31
|
|
|
+**状态:** 设计稿 v1
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 概述
|
|
|
+
|
|
|
+在活动报名流程中增加报名表单,支持选择家庭成员和手动输入报名人信息,支持多人同时报名。
|
|
|
+
|
|
|
+## 2. 流程
|
|
|
+
|
|
|
+```
|
|
|
+活动详情页 → 点击"立即报名" → 弹出报名表单 Modal
|
|
|
+ → 加载家庭成员列表(/api/family/user/family-members)
|
|
|
+ → 勾选成员 / 添加手动输入
|
|
|
+ → 确认 → POST /api/activity/register(批量)→ 成功返回详情页
|
|
|
+```
|
|
|
+
|
|
|
+## 3. 后端改动
|
|
|
+
|
|
|
+### 3.1 表结构
|
|
|
+
|
|
|
+`activity_registrations` 表新增列:
|
|
|
+
|
|
|
+| 列名 | 类型 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| `registrant_name` | VARCHAR(100) | 报名人姓名 |
|
|
|
+| `registrant_phone` | VARCHAR(20) | 联系方式 |
|
|
|
+
|
|
|
+### 3.2 API 变更
|
|
|
+
|
|
|
+**`POST /api/activity/register`** 请求体改为:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 123,
|
|
|
+ "registrants": [
|
|
|
+ { "name": "张三", "phone": "13800138000", "childId": null },
|
|
|
+ { "name": "李四", "phone": "", "childId": 456 }
|
|
|
+ ]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+- `childId` 可选,从家庭成员中选择时传入,手动输入时为 null
|
|
|
+- `name` 必填
|
|
|
+- 校验:已报名的 childId 不能重复提交
|
|
|
+- 返回:`{ "registrationIds": [1,2], "count": 2 }`
|
|
|
+
|
|
|
+### 3.3 响应变化
|
|
|
+
|
|
|
+`my-registrations` 和活动报名列表增加返回 `registrantName`、`registrantPhone`。
|
|
|
+
|
|
|
+### 3.4 迁移
|
|
|
+
|
|
|
+`DatabaseInitializer.runMigrations()` 通过 `ensureColumn` 添加两列。
|
|
|
+
|
|
|
+## 4. 前端改动
|
|
|
+
|
|
|
+### 4.1 报名表单 Modal
|
|
|
+
|
|
|
+在 `activity-detail.vue` 中新增报名弹窗:
|
|
|
+
|
|
|
+- 加载家庭成员(`getFamilyMembers()`),区分孩子和家长
|
|
|
+- 每个成员显示复选框 + 姓名 + 手机号(可编辑)
|
|
|
+- "添加手动输入" 按钮 → 新增空白行
|
|
|
+- 底部显示:共 N 人,合计 ¥price × N
|
|
|
+- 确认按钮 → 调 API
|
|
|
+- 不允许重复选择同一个 childId
|
|
|
+
|
|
|
+### 4.2 报名流程
|
|
|
+
|
|
|
+- 点击"立即报名" → 打开报名弹窗
|
|
|
+- 填写完毕后确认 → 调用 `registerActivity()`
|
|
|
+- 成功后刷新报名状态回到详情页
|
|
|
+
|
|
|
+## 5. 付费活动
|
|
|
+
|
|
|
+报名弹窗底部显示总价 = 单价 × 人数。确认弹窗内容更新为:"共 N 人,需支付 ¥XXX,报名成功后不支持退费。是否继续?"
|