xiangqinxiaochengxu/需求补充计划.md
taiyi a8e6edf296 更新功能修改完版本提交:
功能需求:活动分享与嘉宾匹配系统
1. 活动分享入口
每个活动配置独立的分享链接和二维码,支持扫码或点击链接进入小程序。
2. 用户绑定流程
用户通过分享链接/二维码打开小程序,填写个人信息并绑定至对应活动。
若用户曾参与过历史活动,系统自动复用其历史信息并完成绑定,无需重复填写。
绑定成功后,在活动正式开始前,用户无法查看其他参与者的信息。
3. 信息可见性规则
活动开始前:仅允许查看自己的信息,其他用户信息不可见。
活动开始后:开放本活动内异性嘉宾资料查看与匹配,其他活动的用户信息完全隔离,不可见。
资料展示:男嘉宾、女嘉宾资料分开展示,用户仅可浏览异性嘉宾信息。
4. 嘉宾选择规则
每位用户最多可选择 3 位心仪嘉宾。
确认提交后不可再新增选择,但支持修改或撤销已选嘉宾。
管理员可设置匹配截止时间,到达截止时间后系统自动锁定,禁止任何修改。
5. 匹配判定规则
双向互选:若双方恰好互选,则判定为匹配成功,双方均可查看匹配结果。
多向匹配:用户同时与多位嘉宾匹配成功,全部同时展示。
单向选择:A选择B但B未选择A,A可在"谁选了我"页面看到B。
6. 用户页面说明
异性嘉宾列表:展示所有异性嘉宾资料,支持选择/取消选择。
我的选择:展示当前已选的3位嘉宾,支持修改/撤销(截止前)。
谁选了我:展示所有选择了自己的嘉宾(无论自己是否选择了对方)。
匹配成功:展示所有双向互选的匹配对象,支持查看对方完整资料。
2026-05-17 10:23:02 +08:00

17 KiB
Raw Blame History

需求补充计划

一、文档目标

本文档用于补充“活动分享与嘉宾匹配系统”的详细设计方案,并结合当前项目实际代码结构,明确以下内容:

  • 在保留现有“小程序滑动选择页面”的前提下,如何完成活动内匹配能力改造
  • 当前系统与目标需求之间的差距
  • 建议的数据结构、接口设计、页面设计与权限规则
  • 需要修改的后端、管理端、小程序文件范围
  • 推荐实施顺序与风险提示

二、当前系统现状总结

当前项目由三部分组成:

  • 后端:backend
  • 管理后台:admin-web
  • 微信小程序:miniprogram

当前已经具备的基础能力:

  • 微信登录与用户体系
  • 用户全局资料维护
  • 活动创建、发布、报名
  • 活动报名关系记录
  • 基础匹配能力
  • 小程序滑动选择页

当前关键代码位置:

  • 活动模型:backend/app/models/activity.py
  • 用户模型:backend/app/models/user.py
  • 活动报名模型:backend/app/models/registration.py
  • 匹配模型:backend/app/models/match.py
  • 活动服务:backend/app/services/activity_service.py
  • 匹配服务:backend/app/services/match_service.py
  • 小程序活动详情页:miniprogram/pages/activity-detail
  • 小程序滑动匹配页:miniprogram/pages/match
  • 小程序我的匹配页:miniprogram/pages/my-matches
  • 管理后台活动管理:admin-web/src/views/activities

三、本次需求的核心目标

本次不是新增一个完全独立的陌生系统,而是在现有“活动 + 用户 + 匹配”的基础上,完成“活动内隔离的嘉宾互选系统”。

必须满足的核心目标如下:

  1. 每个活动有独立分享入口,可通过链接或二维码进入。
  2. 用户通过分享入口进入后,绑定到该活动。
  3. 如用户已有历史资料,则自动复用,无需重复填写。
  4. 活动开始前,用户不能查看其他参与者信息。
  5. 活动开始后,只能查看本活动内异性嘉宾资料。
  6. 每位用户最多选择 3 位嘉宾。
  7. 截止时间前允许调整或撤销,截止时间后锁定。
  8. 支持查看“我的选择”“谁选了我”“匹配成功”。
  9. 匹配结果必须按活动隔离,不能与其他活动串数据。
  10. 保留现有滑动选择页,作为活动内异性嘉宾浏览与选择入口。

四、保留滑动选择页的设计结论

4.1 保留原则

现有页面 miniprogram/pages/match 可以保留,不建议推倒重做。

保留内容包括:

  • 滑卡式浏览体验
  • 左滑跳过、右滑选择的交互模型
  • 页面主体样式和卡片信息展示结构
  • 当前活动模式下的页面入口结构

4.2 改造原则

保留页面,不代表保留现有活动匹配的数据逻辑。

需要改造的是:

  • 页面背后的数据来源
  • 活动模式下的权限判断
  • 选择次数限制
  • 截止锁定规则
  • 活动隔离逻辑
  • 配套页面的数据结构

4.3 滑动页在新系统中的定位

建议将滑动选择页定义为:

  • “活动内异性嘉宾浏览页”
  • “我的选择”的新增入口
  • 活动开始后才可进入

建议交互规则如下:

  • 左滑:跳过当前嘉宾,不产生选择关系
  • 右滑:将该嘉宾加入“我的选择”
  • 不在滑动页执行撤销
  • 撤销和修改在“我的选择”页处理

这样可以最大程度保留现有体验,同时降低交互混乱和实现复杂度。

五、当前系统与需求之间的差距

5.1 活动分享入口缺失

当前活动系统只有活动列表和活动详情,没有活动独立分享标识,也没有二维码或分享 token 的模型支持。

缺口:

  • 活动无独立分享 token
  • 无分享链接生成逻辑
  • 无分享二维码数据字段
  • 无“通过分享入口进入活动”的后端接口

5.2 报名绑定逻辑不完整

当前已经有 registrations 表作为用户报名活动关系,但现有流程更偏向用户主动进入活动后点击报名,不是“通过分享入口进入并自动绑定”的闭环。

缺口:

  • 缺少分享入口触发的绑定流程
  • 缺少“资料不完整时先补资料再自动绑定”的回流逻辑

5.3 活动开始前的信息隔离未满足

当前活动详情页存在已报名用户预览能力,会展示其他参与者的信息预览。

这与新需求冲突:

  • 活动开始前只能看自己
  • 不能看其他参与者

5.4 现有匹配不是活动隔离

当前 match_likes 表没有 activity_id,无法保证选择关系只属于某一场活动。

这会造成以下问题:

  • A 活动中的选择影响 B 活动
  • “谁选了我”可能出现其他活动的人
  • “匹配成功”可能跨活动串联

5.5 现有匹配结果页不适合正式活动玩法

当前“我的匹配”页面里混用了服务端数据和本地缓存记录,且详情页存在演示数据兜底逻辑。

正式活动系统不能继续依赖这些临时逻辑。

六、总体设计方案

本次建议采用“保留前端滑动页,新增活动内匹配子系统”的设计。

设计原则:

  • 用户资料继续使用全局 users
  • 活动绑定继续使用 registrations
  • 活动内嘉宾选择单独建模
  • 活动内匹配接口独立建设
  • 不强行复用现有全局匹配表承载新规则

一句话总结:

“用户还是全局的,资料还是复用的,但选择关系必须是活动内独立的。”

七、数据结构设计建议

7.1 activities 表新增字段

建议为活动表新增以下字段:

  • share_token
    • 用途:每个活动独立分享标识
    • 要求:唯一
  • match_deadline
    • 用途:管理员设置匹配截止时间
  • selection_limit
    • 用途:每个活动最多可选人数
    • 默认值3
  • share_qr_url
    • 用途:保存二维码图片地址
    • 可选字段

7.2 保留 registrations 表作为活动绑定关系

现有 registrations 表可以继续承担以下职责:

  • 用户是否已绑定活动
  • 用户是否有效参与该活动
  • 活动内可见性判断基础

如需增强,可考虑新增字段:

  • bind_source
    • 值示例:share_linkqrcodemanual
  • bound_at
    • 用途:记录绑定时间

这部分属于增强项,不是第一优先级。

7.3 新增活动内嘉宾选择表

建议新增表:activity_guest_choices

字段建议如下:

  • id
  • activity_id
  • from_user_id
  • to_user_id
  • status
    • 建议取值:activecancelled
  • created_at
  • updated_at

唯一约束建议:

  • (activity_id, from_user_id, to_user_id)

此表承担的职责:

  • 记录我在某个活动中选了谁
  • 支持撤销选择
  • 支持重新选择
  • 为“谁选了我”提供基础数据
  • 为“双向互选”实时计算提供基础数据

7.4 是否保留现有 match_likes / matches

建议:

  • 保留现有表,避免影响旧功能
  • 新活动匹配逻辑不要继续依赖旧表

原因:

  • 旧表是全局匹配逻辑
  • 新需求是活动内隔离逻辑
  • 两者的约束不同,直接混用风险高

八、权限与可见性规则设计

8.1 活动开始前

用户进入活动后:

  • 可查看自己的资料和绑定状态
  • 不可查看其他参与者列表
  • 不可进入嘉宾选择页
  • 不可查看“谁选了我”
  • 不可查看“匹配成功”

系统返回建议:

  • can_view_candidates = false
  • can_match = false
  • stage = before_start

8.2 活动开始后且截止前

用户在满足以下条件后,可进行匹配:

  • 已登录
  • 已绑定当前活动
  • 当前活动已开始
  • 当前时间未超过匹配截止时间
  • 用户资料有效

此阶段允许:

  • 浏览本活动内异性嘉宾
  • 右滑选择
  • 查看我的选择
  • 撤销或修改我的选择
  • 查看谁选了我
  • 查看匹配成功

8.3 匹配截止后

系统自动锁定:

  • 不允许新增选择
  • 不允许撤销选择
  • 不允许修改选择

但可以继续查看:

  • 我的选择
  • 谁选了我
  • 匹配成功

系统返回建议:

  • can_choose = false
  • can_modify_choice = false
  • stage = matching_closed

8.4 跨活动隔离

任何与活动匹配相关的数据查询都必须带 activity_id 维度。

包括:

  • 候选人列表
  • 我的选择
  • 谁选了我
  • 双向互选列表
  • 匹配详情

不能出现以下情况:

  • 来自其他活动的用户被展示
  • 其他活动的选择记录进入当前活动
  • 跨活动的匹配结果互相污染

九、用户流程设计

9.1 分享入口流程

流程建议如下:

  1. 用户通过分享链接或二维码进入小程序。
  2. 系统识别 share_token 或活动参数。
  3. 若用户未登录,先静默登录。
  4. 根据分享标识查询活动。
  5. 若用户已存在历史资料,则直接读取全局资料。
  6. 若资料完整,则执行活动绑定。
  7. 若资料不完整,则跳转资料完善页。
  8. 资料保存成功后返回活动并自动绑定。

9.2 活动开始前流程

用户进入活动详情后:

  • 看到活动信息
  • 看到自己已绑定状态
  • 看到“活动未开始,暂不可查看嘉宾信息”的提示

9.3 活动开始后流程

用户进入活动详情后:

  • 点击“进入匹配”
  • 跳转至保留的滑动选择页
  • 系统只加载本活动内异性嘉宾
  • 右滑即加入“我的选择”

9.4 我的选择流程

用户可以查看:

  • 当前已选择的嘉宾
  • 已用名额和剩余额度

截止前允许:

  • 撤销已选嘉宾
  • 从滑动页继续新增其他人

9.5 谁选了我流程

用户可以查看:

  • 所有选择了自己的嘉宾
  • 无论自己是否选择对方,都可在这里看到

但资料展示需按权限控制,避免提前暴露过多隐私。

9.6 匹配成功流程

当双方互为 active 选择时:

  • 判定为匹配成功
  • 在“匹配成功”页展示
  • 支持查看对方完整资料

十、页面设计建议

10.1 活动详情页

页面:miniprogram/pages/activity-detail

需要新增或调整的内容:

  • 支持从分享入口进入活动
  • 显示绑定状态
  • 显示活动阶段
  • 显示匹配截止时间
  • 活动开始前不显示他人预览
  • 活动开始后显示“进入匹配”

建议移除或关闭:

  • 当前 registered_preview 的展示

10.2 滑动选择页

页面:miniprogram/pages/match

保留页面,调整活动模式下的数据来源和文案。

建议增强内容:

  • 页面顶部显示当前活动标题
  • 显示“剩余可选人数”
  • 显示匹配截止时间
  • 显示快速入口:
    • 我的选择
    • 谁选了我
    • 匹配成功

页面职责:

  • 只负责浏览与新增选择
  • 不负责撤销选择

10.3 我的匹配页

页面:miniprogram/pages/my-matches

建议重构为活动内结果页,可使用 tab 结构:

  • 我的选择
  • 谁选了我
  • 匹配成功

说明:

  • 不建议继续保留本地缓存兜底记录
  • 必须全部以服务端真实活动数据为准

10.4 匹配详情页

页面:miniprogram/pages/match-detail

建议职责调整为:

  • 仅用于查看双向互选成功对象的完整资料

需要移除:

  • 演示数据 fallback
  • 与正式逻辑无关的本地假数据

十一、后端接口设计建议

建议新增活动内匹配接口,而不是继续挤在现有全局 /matches 下。

11.1 活动分享与绑定

  • GET /activities/share/{share_token}
    • 根据分享 token 获取活动信息
  • POST /activities/{activity_id}/bind
    • 用户绑定到活动

11.2 活动匹配状态

  • GET /activities/{activity_id}/match-state
    • 返回活动阶段、是否可查看、是否可选择、剩余额度等

建议返回字段:

  • activity_id
  • stage
  • is_bound
  • can_view_candidates
  • can_choose
  • can_modify_choice
  • selection_limit
  • selected_count
  • remaining_count
  • match_deadline

11.3 候选人列表

  • GET /activities/{activity_id}/candidates
    • 获取当前活动内异性候选人

查询原则:

  • 只查本活动已绑定用户
  • 只查异性
  • 不查自己
  • 不查已撤销无效记录
  • 已选过的人可按产品需要决定是否继续显示

11.4 选择与撤销

  • POST /activities/{activity_id}/choices
    • 新增选择
  • DELETE /activities/{activity_id}/choices/{target_user_id}
    • 撤销选择

11.5 我的选择

  • GET /activities/{activity_id}/my-choices

11.6 谁选了我

  • GET /activities/{activity_id}/liked-me

11.7 匹配成功

  • GET /activities/{activity_id}/mutual-matches

11.8 匹配详情

  • GET /activities/{activity_id}/matches/{target_user_id}/detail

说明:

  • 只有在当前活动中双方互选成功时,才允许查看完整资料

十二、后端代码改造范围

12.1 需要修改的现有文件

  • backend/app/models/activity.py
  • backend/app/models/__init__.py
  • backend/app/services/activity_service.py
  • backend/app/routers/activities.py
  • backend/app/schemas/activity.py
  • backend/app/routers/__init__.py

12.2 建议新增的文件

  • backend/app/models/activity_guest_choice.py
  • backend/app/services/activity_match_service.py
  • backend/app/schemas/activity_match.py
  • backend/app/routers/activity_matches.py
  • backend/alembic/versions/新增活动内选择表与活动分享字段.py

12.3 需要谨慎处理的旧文件

  • backend/app/models/match.py
  • backend/app/services/match_service.py
  • backend/app/routers/matches.py

建议:

  • 暂不强改旧全局匹配逻辑
  • 新活动逻辑独立建设
  • 等新活动功能稳定后,再决定是否合并或下线旧逻辑

十三、管理后台改造范围

13.1 需要修改的页面

  • admin-web/src/views/activities/ActivityCreateView.vue
  • admin-web/src/views/activities/ActivitiesView.vue

13.2 需要新增的活动配置项

  • 分享 token 展示
  • 分享链接展示
  • 二维码展示
  • 匹配截止时间
  • 选择上限

13.3 后台列表建议新增展示内容

  • 匹配截止时间
  • 分享链接复制按钮
  • 二维码预览或下载
  • 活动内已选择人数统计
  • 活动内匹配成功人数统计

13.4 可选增强项

可额外增加活动匹配详情页,供管理员查看:

  • 本活动所有用户选择关系
  • 谁选了谁
  • 双向互选结果
  • 男女参与情况

十四、小程序改造范围

14.1 需要修改的页面

  • miniprogram/pages/activity-detail
  • miniprogram/pages/match
  • miniprogram/pages/my-matches
  • miniprogram/pages/match-detail
  • miniprogram/pages/profile-edit

14.2 可能需要修改的公共文件

  • miniprogram/app.js
  • miniprogram/app.json
  • miniprogram/utils/request.js

14.3 小程序重点调整项

活动详情页

  • 支持分享入口参数
  • 开始前不显示其他人
  • 显示活动阶段和进入匹配入口

滑动页

  • 保留 UI
  • 活动模式下切换到新接口
  • 增加剩余额度和快捷入口

我的匹配页

  • 改造成活动内结果聚合页
  • 不再依赖本地临时缓存

详情页

  • 只看双向匹配成功对象的完整资料

资料页

  • 支持“完善资料后自动返回活动并绑定”

十五、推荐开发顺序

建议按以下顺序实施。

第一阶段:数据层改造

  • 活动表新增分享与截止字段
  • 新增活动内嘉宾选择表
  • 补充迁移脚本

第二阶段:后端接口改造

  • 活动分享接口
  • 活动绑定接口
  • 活动匹配状态接口
  • 候选人、选择、撤销、结果查询接口

第三阶段:管理后台改造

  • 活动创建与编辑支持新字段
  • 活动列表展示分享入口和截止时间

第四阶段:小程序活动详情与分享流程

  • 分享进入活动
  • 资料补全回流
  • 活动开始前提示逻辑

第五阶段:小程序滑动页接入活动新逻辑

  • 保留滑卡交互
  • 改为调用活动内候选人接口
  • 加入剩余额度和状态展示

第六阶段:结果页与详情页改造

  • 我的选择
  • 谁选了我
  • 匹配成功
  • 完整资料查看

十六、风险与注意事项

16.1 不建议直接复用旧全局匹配表

如果强行复用:

  • 容易跨活动串数据
  • 条件判断会越来越复杂
  • 后期维护成本高

16.2 不建议在滑动页同时承担“新增”和“撤销”

如果在滑动页里也做撤销:

  • 用户认知会混乱
  • 页面状态管理复杂
  • 容易和“我的选择”页职责冲突

16.3 活动开始前的隐私控制必须后端强校验

不能只在前端隐藏按钮。

所有涉及:

  • 查看候选人
  • 查看谁选了我
  • 查看匹配成功
  • 查看完整资料

都必须由后端校验:

  • 活动是否已开始
  • 用户是否已绑定
  • 是否处于允许查看阶段

16.4 旧“我的匹配”本地缓存逻辑建议逐步清理

原因:

  • 正式业务不应依赖前端伪记录
  • 多活动场景下本地缓存容易污染数据判断

十七、最终方案结论

本次需求最合适的实施方案是:

  • 保留现有滑动选择页作为活动内异性嘉宾浏览入口
  • 用户资料继续全局复用
  • 活动绑定继续复用 registrations
  • 活动内选择关系单独建模
  • 活动内匹配接口独立实现
  • 活动开始前严格隐藏他人信息
  • 截止时间前允许修改,截止后统一锁定

这套方案的优点:

  • 最大程度保留现有前端体验
  • 改造边界清晰
  • 数据隔离正确
  • 后续扩展成本更低

十八、建议下一步输出物

基于本计划,下一步建议继续补充以下文档或内容:

  1. 数据库变更清单
  2. 后端 API 详细定义
  3. 小程序页面字段与按钮清单
  4. 管理后台字段改造清单
  5. 按文件拆分的开发任务表