verify-my-activities-rules.md 8.8 KB

核验报告:cfc 小程序「我的活动」列表修复

  • 核验日期:2026-10-24
  • 核验范围:cfc-frontend(uni-app / Vue2)+ cfc-backend(Java Spring Boot 2.7)
  • 核验对象:另一会话完成的「我的活动列表」修复(工作树改动见 git diff HEAD,分支 cfclub)
  • 核验方式:独立读码核实,以代码实际为准(不信任任何已有报告)

一、改动集概览

文件 性质 说明
cfc-frontend/pages/activity/index.vue 核心 我的活动 Tab 加载/刷新/展示逻辑(plainText、loadData(true) 防重复、筛选芯片)
cfc-frontend/pages/activity/activity-detail/activity-detail.vue 关联 活动详情页新增 intro 短摘要显示与海报兼容
cfc-frontend/pages/activity/create.vue 关联 创建/编辑页新增 intro 字段输入与保存
cfc-backend/src/main/java/com/etotem/cfc/controller/ActivityController.java 本次新增修复 /my-registrations 读取 status 参数并透传 Service
cfc-backend/src/main/java/com/etotem/cfc/service/ActivityRegistrationService.java 本次新增修复 getMyRegistrations 增加可选 status 过滤,修复前端「待审核/已签到」筛选失效的既有 Bug

git status --short 显示后端 2 个文件为本次核验中顺手修复,前端 3 个文件为另一会话已提交/暂存的改动。


二、核验清单逐项结论

1. 定位是否准确、改动落在正确位置 — PASS

  • 真实页面:cfc-frontend/pages/activity/index.vue(子包 pages/activity 注册于 pages.json:1540),Tab mine 标签「我的活动」(L329-337)。
  • 后端端点:ActivityController@PostMapping("/my-registrations")(L150-156) → registrationService.getMyRegistrations(Service L222-265)。
  • 本次全部改动(plainText 纯文本、refresh 防重复、筛选 status 透传、后端补齐 status 过滤)均落在「我的活动」列表的数据加载、渲染、筛选链路上,无旁路修改。

2. 当前显示规则与筛选逻辑 — 明确

维度 规则 代码证据
数据来源 activity_registrations 报名表按 childId(当前所选孩子) 或 userId + childId IS NULL(手动录入) 关联 Service L226-235
展示字段 后端回填活动全量展示字段:activityTitle/activityStartTime/activityEndTime/activityCoverImage/activityLocation/四档费用 Service L238-254
状态枚举 pending/approved/rejected/cancelled/checked_in —— 后端原样返回,前端 decorateActivity 映射为卡片状态签 Service L236 status;前端 L859-877
筛选芯片 - 全部:不传 status → 返回全部状态
- 待开始(upcoming):前端 L711-725 本地过滤 startTime>now && status===approved
- 待审核(pending)/已签到(checked_in):前端 L701-703 传 status → 后端 现已补齐过滤
前端 L701-703, L711-725;Service L236-243(修复后)
分页/刷新 minePage + pageSize=10;refresh=true 时重置页码并整体替换列表(L686-689, L729-733);下拉刷新/触底加载正常 前端 L684-739, L665-683, L652-664

关键发现:原实现后端完全忽略 status 参数,导致「待审核」「已签到」两个筛选芯片失效(返回全部状态再由前端不做过滤)。本次核验顺手在后端补齐了该过滤(见上表),使筛选真实生效。

3. 已报名的活动是否会出现在列表里 — PASS

  • 前端 loadMyActivities 取 currentChildId → 传 memberId → 后端按 childId=memberId OR childId IS NULL 查 activity_registrations → 返回活动展示字段 → 前端 normalizeRegistration(L816-831)映射为卡片所需字段 → 正常渲染。
  • 只有当 currentChildId 未设置时(家长未切换身份)才会因 memberId 为空而不发请求显示空态 —— 这是既有限制,非本次引入。

4. 是否区分「我创建的」与「我报名的」 — PASS(通过 Tab 结构隔离)

Tab 数据来源 语义
我的活动 (mine) getMyActivityRegistrations(报名记录) 我报名的
管理 (manage) adminListMyActivities({mineOnly: !canDirectPublish}) 我创建/负责的(仅活动管理员/服务商可见)
历史记录 (history) 复用 getMyActivityRegistrations + 前端本地按结束时间/取消/驳回过滤 已结束的报名记录

结论:创建与报名天然落在不同 Tab,无需同一列表内再加来源 badge。

5. 已取消/已退款的处理 — PASS(行为合理)

  • cancelled 状态报名记录在「我的活动」全部筛选下可见(卡片显示"已取消",不展示取消/签到按钮);在「历史记录」也会出现(L799-800 归入已结束)。
  • 退款逻辑在 releaseQuota(Service L200-215),不直接影响列表展示。

6. 回归检查(分页/刷新/筛选/空态/异常) — PASS

项 状态 证据
语法/编译 PASS mvn clean compile -q 退出码 0;前端 script 提取 node --check 通过
反模式审计 PASS audit-mp-antipatterns.js 全项目 ERROR 0,pages/activity/index.vue 零 WARN
首屏不双发 PASS _onLoadFired 标志位模式(L392-399)符合 AGENTS.md 规则 1/4c
从详情返回刷新 PASS onShow → loadData(true) 重置页码替换列表(L395-399),修复旧版追加导致翻倍
下拉刷新 PASS onRefresh → loadXxx(true) + finally 释放 isRefreshing(L665-683)
触底加载 PASS onLoadMore 仅当前 Tab、!loading 时 page++ 追加(L652-664)
空态/加载/异常 PASS mineLoading 控制空态/加载态;catch 仅复位 loading 保留已渲染数据(L85-96, L736-738)
筛选逻辑未被破坏 PASS 全部/待开始/待审核/已签到 四筛选均按设计工作(待审核/已签到现已后端生效)

7. Java 编译验证 — PASS

cd cfc-backend && mvn clean compile -q
# 退出码 0(日志 /tmp/opencode/mvn_compile2.log 末行 MVN_EXIT=0)

三、当前「我的活动」显示规则(清晰总结)

  1. 入口:活动中心首个 Tab「我的活动」。
  2. 范围:当前登录用户(token userId)在其当前所选家庭成员(currentChildId)名下的所有报名记录(含 child_id IS NULL 的手动录入)。
  3. 筛选:全部 / 待开始(前端按 startTime>now && approved 过滤) / 待审核(后端 status=pending) / 已签到(后端 status=checked_in)。
  4. 卡片:封面/标题/报名人/开始结束时间/地点/状态签/费用;仅 approved 显示「取消报名」「签到」按钮;点卡片进详情(取 activityId)。
  5. 刷新:首次 onLoad 加载;从详情返回 onShow 全量刷新(不追加);支持下拉刷新/触底加载。
  6. 空态:无报名记录显示「暂无报名的活动 → 去发现活动」。
  7. 创建/报名区分:创建在「管理」Tab(权限控制),报名在「我的活动」Tab,互不混排。

四、遗留问题清单(低风险/非阻断)

# 级别 问题 影响 建议
1 低 currentChildId 为空时「我的活动」永不发请求(直接空态) 家长未切孩子身份时看不到任何报名 若需改善:前端无 memberId 时改传 userId 让后端按用户全量返回,或提示切换身份
2 低 「待开始」筛选为客户端分页后过滤 深翻页可能出现"当前页 0 条但 hasMore=true" 后端增加 upcoming=true SQL 过滤,或前端改为按总量翻页
3 低 plainText 未解码 ' 极少数富文本含 ' 实体时显示异常 补一行 .replace(/'/gi, "'")
4 低 onShow 与 resolveManagePermission 异步回调并发触发加载 最后一次胜出,数据正确性无影响 既有模式,可留待统一重构

五、结论

同意放行 ✅

  • 已报名活动可见:完整链路(前端 loadMyActivities → 后端 /my-registrations 回填活动字段 → 前端 normalizeRegistration → 卡片渲染)真实生效,非表面改动。
  • 筛选真实生效:本次核验顺手修复了后端忽略 status 参数的既有 Bug,「待审核」「已签到」芯片现已按服务端过滤生效。
  • 区分创建/报名:Tab 结构天然隔离,符合预期。
  • 无回归:分页/刷新/空态/异常/语法/反模式审计全通过;mvn clean compile -q 退出码 0。
  • 遗留问题 均为低风险优化项,不影响当前功能放行。

注:工作区仍有 5 个文件未提交(前端 3 + 后端 2 + 新增报告)。按任务护栏(禁止 git commit),核验未执行提交;如需推进请用户确认后另行提交。