用户使用流程图 — 活动管理
端口说明: 📱 小程序 | 🖥 管理后台 | 📋 规划师端 | ⚙️ 系统自动
分层说明: 🏠 页面 → 🔗 API → ⚙️ Service → 📦 数据实体
flowchart TD
%% ============ 颜色定义 ============
classDef page fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef api fill:#fff3e0,stroke:#f57c00,stroke-width:1px
classDef service fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
classDef data fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px
classDef external fill:#fce4ec,stroke:#d32f2f,stroke-width:1px,stroke-dasharray:3 2
classDef actor fill:#e1f5fe,stroke:#0288d1,stroke-width:2px,stroke-dasharray:5 3
%% ============ 角色 ============
A0(("🔧 活动管理员")):::actor
B0(("👤 家长")):::actor
C0(("👶 孩子")):::actor
D0(("🖥 管理员")):::actor
%% ================================================================
%% 阶段一:活动创建(规划师端)
%% ================================================================
subgraph 阶段一[阶段一:活动创建]
direction TB
P1["📋 规划师端:活动管理页"]:::page
P1 -->|"点击创建"| P1a["📋 规划师端:创建活动表单"]:::page
P1a -->|"活动标题, 描述, 封面, 分类, 地点, 日期, 最大人数, 价格"| A1["🔗 POST /api/guide/activities/create"]:::api
A1 -->|"activity(含上述字段)"| S1["⚙️ GuideActivityService.createActivity()"]:::service
S1 -->|"初始状态=draft, currentParticipants=0"| D1["📦 guide_activities 表"]:::data
P1 -->|"编辑活动"| P1b["📋 规划师端:编辑活动表单"]:::page
P1b -->|"活动ID, 修改字段"| A2["🔗 POST /api/guide/activities/update"]:::api
A2 -->|"活动ID, 变更字段"| S2["⚙️ GuideActivityService.updateActivity()"]:::service
S2 -->|"更新对应字段"| D1
P1 -->|"发布活动"| P1c["📋 规划师端:发布确认"]:::page
P1c -->|"活动ID"| A3["🔗 POST /api/guide/activities/publish"]:::api
A3 -->|"活动ID"| S3["⚙️ GuideActivityService.updateStatus(published)"]:::service
S3 -->|"状态=published"| D1
P1 -->|"取消活动"| P1d["📋 规划师端:取消确认"]:::page
P1d -->|"活动ID"| A4["🔗 POST /api/guide/activities/cancel"]:::api
A4 -->|"活动ID"| S4["⚙️ GuideActivityService.updateStatus(cancelled)"]:::service
S4 -->|"状态=cancelled"| D1
end
%% ================================================================
%% 阶段二:活动审核(管理后台)
%% ================================================================
subgraph 阶段二[阶段二:活动审核(管理后台)]
D1 -->|"待审核活动"| P2["🖥 管理后台:活动列表页"]:::page
P2 -->|"查看列表"| A5["🔗 POST /api/admin/activity/list"]:::api
A5 -->|"status, dimensionCode, auditStatus 过滤"| S5["⚙️ ActivityAdminService.list()"]:::service
S5 -->|"含草稿的所有活动"| D2["📦 activities 表(查询)"]:::data
D2 -->|"选择活动"| P2a["🖥 管理后台:活动详情页"]:::page
P2a -->|"活动ID"| A6["🔗 POST /api/admin/activity/detail"]:::api
A6 -->|"id"| S6["⚙️ ActivityAdminService.getDetail()"]:::service
S6 -->|"Activity对象"| D2
P2a -->|"提交审核"| A7["🔗 POST /api/admin/activity/submit-review"]:::api
A7 -->|"id"| S7["⚙️ ActivityAdminService.submitForReview()"]:::service
S7 -->|"状态=pending, auditStatus=pending"| D2
P2a -->|"审核通过/驳回"| A8["🔗 POST /api/admin/activity/audit"]:::api
A8 -->|"id, action=approved/rejected, rejectReason"| S8["⚙️ ActivityAdminService.auditActivity()"]:::service
S8 -->|"approved→published / rejected→rejected"| D2
P2a -->|"发布操作(简洁模式)"| A9["🔗 POST /api/admin/activity/review"]:::api
A9 -->|"id, action=publish/reject"| S9["⚙️ ActivityAdminService.review()"]:::service
S9 -->|"publish→published / reject→删除记录"| D2
P2a -->|"撤回活动"| A10["🔗 POST /api/admin/activity/withdraw"]:::api
A10 -->|"id"| S10["⚙️ ActivityAdminService.withdraw()"]:::service
S10 -->|"状态=withdrawn"| D2
P2a -->|"转草稿(驳回后)"| A11["🔗 POST /api/admin/activity/re-draft"]:::api
A11 -->|"id"| S11["⚙️ ActivityAdminService.reDraft()"]:::service
S11 -->|"状态=draft, 清空审核信息"| D2
end
%% ================================================================
%% 阶段三:活动前台创建/管理(管理后台直发)
%% ================================================================
subgraph 阶段三[阶段三:管理后台直接活动管理]
P3["🏠 管理后台:活动管理页"]:::page
P3 -->|"创建活动"| P3a["🏠 填写活动信息表单"]:::page
P3a -->|"title, description, dimensionCode, activityType, startTime, endTime, location, maxParticipants, price, memberPrice, checkinPoints, visibility, requireRegistration, requireCheckinReview, energyPenaltyUnregistered, feedbackDimensions"| A12["🔗 POST /api/activity/create"]:::api
A12 -->|"activity对象, 需admin/activity_admin角色"| S12["⚙️ ActivityService.create()"]:::service
S12 -->|"状态=draft, currentParticipants=0"| D3["📦 activities 表"]:::data
P3 -->|"修改活动"| P3b["🏠 修改活动信息"]:::page
P3b -->|"活动ID+修改字段"| A13["🔗 POST /api/activity/update"]:::api
A13 -->|"activity对象, 需admin/activity_admin角色"| S13["⚙️ ActivityService.update()"]:::service
S13 -->|"更新对应字段"| D3
P3 -->|"发布活动"| P3c["🏠 发布确认"]:::page
P3c -->|"活动ID"| A14["🔗 POST /api/activity/publish"]:::api
A14 -->|"id, 需admin/activity_admin"| S14["⚙️ ActivityService.publish()"]:::service
S14 -->|"状态=published(仅draft可发布)"| D3
P3 -->|"结束活动"| P3d["🏠 结束确认"]:::page
P3d -->|"活动ID"| A15["🔗 POST /api/activity/end"]:::api
A15 -->|"id, 需admin/activity_admin"| S15["⚙️ ActivityService.end()"]:::service
S15 -->|"状态=ended"| D3
end
%% ================================================================
%% 阶段四:用户浏览、报名与分享
%% ================================================================
subgraph 阶段四[阶段四:用户浏览、报名与分享]
D3 -->|"已发布活动"| P4["📱 小程序:活动列表页"]:::page
P4 -->|"按维度/分页过滤"| A16["🔗 POST /api/activity/list"]:::api
A16 -->|"dimensionCode, page, size, userId(自动)"| S16["⚙️ ActivityService.list()"]:::service
S16 -->|"已发布活动列表(含会员价计算)"| D3
P4 -->|"查看详情"| P4a["📱 小程序:活动详情页"]:::page
P4a -->|"活动ID"| A17["🔗 POST /api/activity/detail"]:::api
A17 -->|"id"| S17["⚙️ ActivityService.detail()"]:::service
S17 -->|"ActivityDTO(含维度/价格/报名状态)"| D3
%% 活动详情页操作按钮
P4a -->|"❤️ 分享按钮"| A17a["🔗 调用小程序分享API<br>onShareAppMessage"]:::api
A17a -->|"活动标题, 封面, 详情页路径"| S17a["⚙️ 生成分享卡片<br>含活动ID参数"]:::service
S17a -->|"分享给好友/群"| P4e["📱 微信分享卡片"]:::page
P4a -->|"📝 报名按钮"| P4b["📱 小程序:选择参与孩子"]:::page
P4b -->|"活动ID, 孩子ID"| A18["🔗 POST /api/activity/register"]:::api
A18 -->|"activityId, childId, userId"| S18["⚙️ ActivityRegistrationService.register()"]:::service
S18 -->|"校验: 是否已报名/人数已满/活动状态<br>→ 状态=pending(需审核)或approved"| D4["📦 activity_registrations 表"]:::data
P4b -->|"取消报名"| P4c["📱 小程序:取消报名确认"]:::page
P4c -->|"活动ID, 孩子ID"| A19["🔗 POST /api/activity/cancel-registration"]:::api
A19 -->|"activityId, childId, userId"| S19["⚙️ ActivityRegistrationService.cancel()"]:::service
S19 -->|"状态=cancelled"| D4
P4 -->|"我的报名"| P4d["📱 小程序:我的报名页"]:::page
P4d -->|"孩子ID, 分页"| A20["🔗 POST /api/activity/my-registrations"]:::api
A20 -->|"childId, page, size"| S20["⚙️ ActivityRegistrationService.getMyRegistrations()"]:::service
S20 -->|"报名记录列表(含活动标题/状态)"| D4
end
%% ================================================================
%% 阶段五:报名管理(管理后台)
%% ================================================================
subgraph 阶段五[阶段五:报名审批]
D4 -->|"待审批报名"| P5["🖥 管理后台:报名列表页"]:::page
P5 -->|"按活动/状态过滤"| A21["🔗 POST /api/admin/activity/registration/list"]:::api
A21 -->|"activityId, status"| S21["⚙️ ActivityRegistrationService.getRegistrationsByActivity()"]:::service
S21 -->|"报名记录列表"| D4
P5 -->|"通过"| A22["🔗 POST /api/admin/activity/registration/approve"]:::api
A22 -->|"registrationId, adminUserId"| S22["⚙️ ActivityRegistrationService.approve()"]:::service
S22 -->|"状态=approved, approvedAt, approvedBy"| D4
P5 -->|"拒绝"| A23["🔗 POST /api/admin/activity/registration/reject"]:::api
A23 -->|"registrationId, adminUserId"| S23["⚙️ ActivityRegistrationService.reject()"]:::service
S23 -->|"状态=rejected"| D4
end
%% ================================================================
%% 阶段六:签到
%% ================================================================
subgraph 阶段六[阶段六:签到]
D3 -->|"进行中的活动"| P6["📱 小程序:活动签到页"]:::page
P6 -->|"扫码/按钮签到"| A24["🔗 POST /api/activity/checkin"]:::api
A24 -->|"id(活动ID), childId, userId"| S24["⚙️ ActivityService.checkin()"]:::service
S24 -->|"创建Task(状态=completed), 发放积分, 扣能量(未报名), 更新currentParticipants, PointsLog, 发放五维能量"| D5["📦 tasks + points_logs + energy_records"]:::data
end
%% ================================================================
%% 阶段七:活动评价
%% ================================================================
subgraph 阶段七[阶段七:活动评价]
D5 -->|"已签到/已结束的活动"| P7["📱 小程序:活动评价页"]:::page
P7 -->|"提交评价"| A25["🔗 POST /api/activity/feedback/submit"]:::api
A25 -->|"活动ID, 孩子ID, 评分(JSON), 评论文本"| S25["⚙️ ActivityFeedbackService.submit()"]:::service
S25 -->|"写入评价记录"| D6["📦 activity_feedback 表"]:::data
D6 -->|"已有评价"| P7a["📱 小程序:查看评价列表"]:::page
P7a -->|"活动ID"| A26["🔗 POST /api/activity/feedback/list"]:::api
A26 -->|"活动ID"| S26["⚙️ ActivityFeedbackService.getFeedbackList()"]:::service
S26 -->|"该活动的所有评价"| D6
D6 -->|"我的评价"| P7b["📱 小程序:我的评价"]:::page
P7b -->|"活动ID, 孩子ID"| A27["🔗 POST /api/activity/feedback/my"]:::api
A27 -->|"活动ID, 孩子ID"| S27["⚙️ ActivityFeedbackService.getMyFeedback()"]:::service
S27 -->|"我的评价记录"| D6
end
%% ================================================================
%% 角色关联
%% ================================================================
A0 -.- P3
B0 -.- P4
B0 -.- P4b
C0 -.- P6
D0 -.- P2
端点明细
活动前台
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/activity/list |
活动列表(支持维度/分页过滤) |
📱小程序 |
{dimensionCode, page, size} |
{records: [ActivityDTO], total, page, size} |
POST /api/activity/detail |
活动详情 |
📱小程序 |
{id} |
ActivityDTO |
POST /api/activity/register |
报名活动 |
📱小程序 |
{id, childId} |
{registrationId, status} |
POST /api/activity/cancel-registration |
取消报名 |
📱小程序 |
{id, childId} |
null |
POST /api/activity/my-registrations |
我的报名列表 |
📱小程序 |
{childId, page, size} |
{records: [{activityTitle, status, ...}], total} |
POST /api/activity/checkin |
活动签到 |
📱小程序 |
{id, childId} |
{taskId, pointsEarned, alreadyCompleted, energyPenalty} |
POST /api/activity/feedback/submit |
提交活动评价 |
📱小程序 |
{activityId, childId, ratings(JSON), comment} |
{id, status} |
POST /api/activity/feedback/list |
查看活动评价列表 |
📱小程序 |
{activityId} |
[{ratings, comment, userName, createdAt}] |
POST /api/activity/feedback/my |
查看我的评价 |
📱小程序 |
{activityId, childId} |
{ratings, comment, createdAt} |
POST /api/activity/create |
创建活动(管理后台) |
🖥管理后台 |
Activity对象(全部字段) |
ActivityDTO |
POST /api/activity/update |
修改活动 |
🖥管理后台 |
Activity对象(含ID) |
ActivityDTO |
POST /api/activity/publish |
发布活动 |
🖥管理后台 |
{id} |
"发布成功" |
POST /api/activity/end |
结束活动 |
🖥管理后台 |
{id} |
"活动已结束" |
活动管理后台(Admin)
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/admin/activity/list |
活动管理列表(含草稿,支持过滤) |
🖥管理后台 |
{status, dimensionCode, auditStatus, page, size} |
{records: [Activity], total} |
POST /api/admin/activity/detail |
活动详情 |
🖥管理后台 |
{id} |
Activity |
POST /api/admin/activity/submit-review |
提交审核 |
🖥管理后台 |
{id} |
"已提交审核" |
POST /api/admin/activity/audit |
审核通过/驳回 |
🖥管理后台 |
{id, action, rejectReason} |
"已审核" |
POST /api/admin/activity/review |
审核活动(简版:发布/驳回删除) |
🖥管理后台 |
{id, action(publish/reject)} |
"发布成功" / "已驳回并删除" |
POST /api/admin/activity/withdraw |
撤回已发布活动 |
🖥管理后台 |
{id} |
"已撤回" |
POST /api/admin/activity/re-draft |
驳回后转草稿 |
🖥管理后台 |
{id} |
"已转为草稿" |
POST /api/admin/activity/registration/list |
报名列表 |
🖥管理后台 |
{activityId, status} |
[{registrationId, childId, status, ...}] |
POST /api/admin/activity/registration/approve |
审批报名通过 |
🖥管理后台 |
{id} |
null |
POST /api/admin/activity/registration/reject |
拒绝报名 |
🖥管理后台 |
{id} |
null |
规划师端活动
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/guide/activities/list |
规划师活动列表 |
📋规划师端 |
{status} |
[GuideActivity] |
POST /api/guide/activities/detail |
规划师活动详情 |
📋规划师端 |
{activityId} |
GuideActivity |
POST /api/guide/activities/create |
创建活动 |
📋规划师端 |
GuideActivity对象(title, description, coverImage, category, location, activityDate, maxParticipants, price) |
{id} |
POST /api/guide/activities/update |
更新活动 |
📋规划师端 |
GuideActivity对象(含id及修改字段) |
true |
POST /api/guide/activities/publish |
发布活动 |
📋规划师端 |
{activityId} |
true |
POST /api/guide/activities/cancel |
取消活动 |
📋规划师端 |
{activityId} |
true |
POST /api/guide/activities/delete |
删除活动 |
📋规划师端 |
{activityId} |
true |
完整性分析
| # |
维度 |
评估 |
说明 |
| 1 |
流程完整性 |
✅ 完整 |
覆盖活动创建(规划师端+管理后台)、审核(提交→通过/驳回→转草稿/撤回)、用户浏览、分享、报名、报名审批、签到、评价全链路 |
| 2 |
异常路径 |
⚠️ 部分覆盖 |
签到时的未报名能量扣减已覆盖;人数已满自动截止由Service层校验;报名状态检查(已报名去重、活动未发布、无需报名等)在 Service 层处理 |
| 3 |
端点覆盖 |
✅ 完整 |
24个端点全部映射到流程图中,与代码实际暴露的 /api/activity/*、/api/admin/activity/*、/api/guide/activities/*、/api/activity/feedback/* 一致 |
| 4 |
角色覆盖 |
✅ 完整 |
活动管理员(activity_admin/admin)、家长(parent)、孩子(child)、规划师(teacher)四种角色均已覆盖 |
| 5 |
数据实体 |
✅ 完整 |
activities表、guide_activities表、activity_registrations表、activity_feedback表、tasks表、points_logs表、energy_records表均在图中映射 |
| 6 |
前端页面 |
⚠️ 已补充 |
活动详情页已增加分享按钮(调用小程序分享API)和报名按钮(跳转选择孩子);签到后增加评价入口 |
数据实体关系
erDiagram
Activity ||--o{ ActivityRegistration : "一个活动多个报名"
Activity ||--o{ Task : "签到生成任务"
GuideActivity ||--o{ GuideActivityRegistration : "规划师活动报名"
Activity {
Long id PK
string title
string description
string dimensionCode
string dimensionWeights "JSON维度权重"
string activityType "offline/online/campaign"
string status "draft/pending/rejected/published/withdrawn/ended"
string auditStatus
string auditReason
date startTime
date endTime
string location
int maxParticipants
int currentParticipants
int price "普通价(分)"
int memberPrice "会员价(分)"
int checkinPoints "签到积分"
int requireRegistration "是否需要报名"
int requireCheckinReview "签到需审核"
int energyPenaltyUnregistered "未报名签到扣减"
string visibility "public/restricted/member"
}
ActivityRegistration {
Long id PK
Long activityId FK
Long userId FK
Long childId FK
string status "pending/approved/rejected/cancelled"
date registeredAt
date approvedAt
Long approvedBy
}
GuideActivity {
Long id PK
Long guideId FK
string title
string description
string coverImage
string category
string location
date activityDate
int maxParticipants
int currentParticipants
Long price
string status "draft/published/cancelled/completed"
}