Appearance
里程挑战模块 (Mileage Challenge)
文档版本: V2.0 更新日期: 2026-02-25 状态: 评审中 V2 变更: 新增"挑战类型"顶层分层,新增"雪道打卡"挑战,修正统计维度(最高速度→滑行时长)
0. 背景与目标 (Context & Goals)
问题陈述 (Problem Statement)
- 活跃度激励: 仅仅记录滑雪轨迹缺乏显性的激励机制,用户容易流失。
- 社群凝聚力: 俱乐部缺乏组织线上比赛的工具,传统的"晒数据截图"方式统计繁琐且难以验证真伪。
- 官方运营: 平台需要通过全网挑战赛(如"百万落差挑战")来维持雪季期间的 DAU。
- V2 新增 — 雪场深度绑定: 现有积累型挑战与具体雪场的关联较弱(仅作为数据过滤条件),缺乏让用户"深度探索一座雪场"的玩法。雪道打卡填补了这一空白,同时为雪场合作(B2B)开辟了新的运营工具。
成功指标 (Success Metrics)
- 参与度: 挑战赛的报名人数与完赛率。
- 粘性: 参与挑战赛用户的周均启动次数提升 20%。
- V2 新增: 雪道打卡挑战的平均打卡完成率(目标 > 40%);挑战期间用户在目标雪场的平均滑行天数(目标 > 3天)。
一、 核心逻辑与业务规则
1.1 双重身份 (Dual Identity)
本模块同时服务于 官方 (Official) 和 俱乐部 (Club)。
- 官方: 发起全网活动,具备最高权重,奖品通常由品牌赞助。
- 俱乐部: 发起私域活动,可限制仅本俱乐部成员参加,增强社群归属感。
1.2 数据来源 (Data Source)
- 自动采集: 依托 APP 内置的 GPS 轨迹记录功能。
- 有效性校验: 仅统计挑战赛时间范围内且数据有效(非车载/缆车异常数据)的滑行记录。
1.3 挑战类型分层(V2 新增)
里程挑战分为两大类型,底层逻辑完全不同:
挑战类型
├── 积累型 (Accumulation)
│ ├── 累计里程 (KM)
│ ├── 累计落差 (Vertical Drop)
│ └── 累计滑行时长 (Duration)
│
└── 打卡型 (Check-in)
└── 雪道打卡 (Trail Check-in)
├── 打卡范围:全部雪道 / 初级道 / 中级道 / 高级道
└── 排名依据:最先集齐者排名靠前两种类型的核心差异:
| 维度 | 积累型 | 打卡型 |
|---|---|---|
| 排名逻辑 | 数值累加,大者居前 | 集齐打卡,先完成者居前 |
| 成绩表示 | 单一数值 (128.5km) | 进度 + 完成时间 (12/12 ✅ 01.25 14:32) |
| 技术依赖 | 轨迹的里程/落差/时长计算 | 轨迹 × 雪道检查点匹配 |
| 激励语 | "再滑 2km 即可超越" | "还差 3 条雪道即可集齐" |
| 上榜条件 | 有有效成绩即可 | 仅集齐全部目标雪道才上榜 |
二、 积累型挑战 — 详细功能定义
2.1 发布端 (官方/Club管理台)
| 板块 | 字段/功能 | 说明/规则 |
|---|---|---|
| 基础信息 | 挑战名称 | e.g., "崇礼开板首滑挑战" |
| 挑战时间 | 开始时间 ~ 结束时间。 | |
| 排名规则 | 统计维度 | 单选: 1. 累计里程 (KM) 2. 累计落差 (Vertical Drop) 3. 累计滑行时长 (Duration) |
| 范围限制 | 可选指定雪场 (e.g., 仅限"万龙滑雪场"的数据)。 | |
| 奖励配置 | 排名奖 | 前 [3] 名的奖品描述 (支持图文)。 |
| 参与奖 | 完赛(达到基础门槛)即可获得的奖励。通常为积分/勋章。 | |
| 参与门槛 | 达标数据 | 设定最低有效数据 (e.g., 累计滑行 > 10km) 才算"完赛"。 |
| 权限控制 | 参与范围 | 1. 全网公开 (仅官方可发) 2. 仅限俱乐部成员 (Club 默认) 3. 指定群组 (关联 IM 群) |
2.2 用户端 (C-Side Flow)
A. 挑战列表
- 我的挑战: 展示已报名且进行中的挑战进度条。
- 发现挑战: 推荐官方热门挑战及用户所在俱乐部的挑战。
B. 挑战详情与排行榜
- 实时榜单: 动态刷新 Top 100 排名。
- 显示:头像、昵称、所属俱乐部、成绩数值。
- 我的战绩:
- 当前排名。
- 距离上一名/获奖区的差距 ("再滑 2km 即可超越/获奖") -> 核心激励点。
C. 数据同步逻辑
mermaid
sequenceDiagram
participant U as 用户 (App)
participant S as 服务端 (Challenge Svc)
U->>U: 结束滑行,上传轨迹
U->>S: 提交 Track Data
S->>S: 校验数据有效性 (去噪)
S->>S: 检索用户参与的所有"进行中"挑战
loop 遍历挑战
S->>S: 过滤是否符合挑战规则 (时间/雪场)
S->>S: 累加成绩 (Increment Score)
end
S->>S: 更新排行榜 (Redis ZSet)
S-->>U: 返回本次滑行更新的挑战进度三、 打卡型挑战 — 雪道打卡(V2 新增)
3.1 核心概念
一句话定义:发起人选择一个雪场,参与者通过滑行自动打卡该雪场的雪道,最先集齐指定分类(全部/初/中/高级道)的所有雪道者排名靠前。
核心机制:
- 挑战必须绑定一个具体雪场(不可选多雪场或不限雪场)。
- 系统根据雪场的雪道数据库自动生成打卡清单。
- 打卡判定基于检查点机制(非全段覆盖):每条雪道设置若干 GPS 检查点,用户的滑行轨迹经过全部检查点即判定该雪道打卡成功。
- 仅集齐目标分类全部雪道的用户才上榜,按完成时间的先后排名。未集齐者不排名。
3.2 检查点机制
3.2.1 选点规则
核心原则:基于雪道 GIS 数据自动生成,避开首尾,中段等距采样。
系统读取雪道的中心线 (Polyline) 数据,自动执行以下算法:
- 计算雪道全长 L
- 跳过首尾各 20%(起点/终点多道交汇区,GPS 无法区分)
- 在中段 60% 区间内,按雪道长度自动等距选取检查点
雪道中心线(GIS Polyline):
|--20%--|------60%------|--20%--|
跳过 ● C1 ● C2 ● C3 跳过
↑ 系统自动等距采样检查点数量(自动计算):
| 雪道长度 | 检查点数 |
|---|---|
| < 500m | 2 个 |
| 500m - 1.5km | 3 个 |
| > 1.5km | 4-5 个 |
检查点参数:
- 半径:40m(兼容 GPS 误差 + 雪道宽度)
3.2.3 匹配算法
用户上传一条完整的滑行轨迹后,服务端对每条未打卡雪道执行以下匹配流程:
输入:
- 轨迹 T = [P1, P2, ..., Pn],每个点含 (经度, 纬度, 时间戳, 海拔, 速度)
- 雪道 S 的检查点序列 C = [C1, C2, ..., Cm],每个点含 (经度, 纬度, 半径)
Step 1 — 空间命中
遍历轨迹点 T,找出进入每个检查点半径范围内的轨迹点:
- 对每个 Ci,找到第一个满足 distance(Pj, Ci) ≤ Ci.半径 的轨迹点 Pj
- 记录 hit(Ci) = Pj(首次命中的轨迹点)
- 如果某个 Ci 没有任何轨迹点命中 → 匹配失败,退出
Step 2 — 有序性校验
验证检查点的命中顺序与轨迹时间线一致:
- 要求 hit(C1).时间戳 < hit(C2).时间戳 < ... < hit(Cm).时间戳
- 如果顺序不一致 → 匹配失败(可能是反向滑行或轨迹乱序)
Step 3 — 时间窗口过滤
验证通过所有检查点的总耗时合理:
- 总耗时 = hit(Cm).时间戳 - hit(C1).时间戳
- 最短耗时 = 雪道长度 / 最大合理速度(80km/h)
- 最长耗时 = 雪道长度 / 最小合理速度(3km/h)
- 要求 最短耗时 ≤ 总耗时 ≤ 最长耗时
- 超出范围 → 匹配失败(太快=车载/数据异常,太慢=步行/排队)
Step 4 — 速度特征校验(辅助)
命中区间内的轨迹点平均速度应在合理范围:
- 平均速度 ≥ 5 km/h(排除步行上山)
- 平均速度 ≤ 80 km/h(排除车载)
全部通过 → 判定该雪道打卡成功,记录完成时间 = hit(Cm).时间戳3.2.4 检查点数据管理
- 自动生成:导入雪场雪道 GIS 数据后,系统自动计算检查点坐标,无需人工标注。
- 运营可微调:自动生成后,运营可在后台查看和微调检查点位置(极端情况下的兜底手段)。
- 版本管理:雪场开放/关闭雪道时,更新 GIS 数据后系统自动重新生成检查点。已进行中的挑战不受影响(快照机制)。
3.3 打卡范围
一个"雪道打卡"挑战对应一个打卡范围,发起人在创建时选择:
| 打卡范围 | 打卡目标 | 示例 |
|---|---|---|
| 全部雪道 | 该雪场所有雪道 | 0/25 条 |
| 初级道 | 仅初级雪道 | 0/8 条 |
| 中级道 | 仅中级雪道 | 0/10 条 |
| 高级道 | 仅高级雪道 | 0/7 条 |
一个挑战 = 一个打卡范围 = 一个排行榜 = 一套奖励。 如需覆盖多个分类,发起人创建多个挑战。
排名规则:
- 仅限集齐该范围全部雪道的用户才上榜。
- 集齐者按完成时间(最后一条雪道的打卡时间戳)升序排名。
- 未集齐者不出现在榜单中。
3.4 奖励配置
与积累型一致,发起人配置一套奖励:
- 排名奖: 前 N 名,支持雪币 + 实物奖品描述。
- 完赛奖: 集齐该范围全部雪道即可获得,支持雪币 + 实物奖品描述。
3.5 发布端配置
发起人选择"打卡型 - 雪道打卡"后的发布流程:
| 步骤 | 字段/功能 | 说明/规则 |
|---|---|---|
| Step 1 | 目标雪场 | 发布第一步,单选一个雪场(仅展示有 GIS 数据的雪场) |
| Step 2 | 打卡范围 | 单选:全部雪道 / 初级道 / 中级道 / 高级道。选后展示对应雪道清单及数量 |
| Step 3 | 挑战名称 | e.g., "万龙初级道打卡挑战" |
| 挑战时间 | 开始时间 ~ 结束时间 | |
| Step 4 | 排名奖 | 前 [3] 名的奖品描述(雪币 + 实物) |
| 完赛奖 | 集齐即获得(雪币 + 可选实物奖品描述) | |
| Step 5 | 参与范围 | 同积累型 |
与积累型的差异:打卡型以"选雪场 - 选打卡范围"开头,没有"统计维度"和"参与门槛"字段。完赛由系统自动判定(集齐 = 完赛)。
3.6 用户端 — 挑战详情页
┌────────────────────────────────────┐
│ 🏔️ 万龙初级道打卡挑战 │
│ 01/15 - 02/15 · 进行中 │
├────────────────────────────────────┤
│ 📍 万龙滑雪场 · 初级道 8 条 │
├────────────────────────────────────┤
│ 📋 我的打卡进度 5/8 │
│ ┌────────────────────────────────┐ │
│ │ ✅ 银龙道 01/16 打卡 │ │
│ │ ✅ 玉龙道 01/17 打卡 │ │
│ │ ✅ 白龙道 01/18 打卡 │ │
│ │ ✅ 小龙道 01/19 打卡 │ │
│ │ ✅ 青龙道 01/20 打卡 │ │
│ │ ⬜ 云龙道 未打卡 │ │
│ │ ⬜ 雪龙道 未打卡 │ │
│ │ ⬜ 冰龙道 未打卡 │ │
│ │ 还差 3 条雪道 💪 │ │
│ └────────────────────────────────┘ │
├────────────────────────────────────┤
│ 🏆 排行榜(已集齐 2 人) │
│ ┌────────────────────────────────┐ │
│ │ 🥇 雪疯子 8/8 01/22 完成 │ │
│ │ 🥈 粉雪控 8/8 01/24 完成 │ │
│ └────────────────────────────────┘ │
│ 💡 集齐全部初级道后,你将出现在榜单 │
└────────────────────────────────────┘3.7 数据同步逻辑
mermaid
sequenceDiagram
participant U as 用户 (App)
participant S as 服务端 (Challenge Svc)
participant G as 地理围栏服务
U->>U: 结束滑行,上传轨迹
U->>S: 提交 Track Data
S->>S: 校验数据有效性 (去噪)
S->>S: 检索用户参与的所有"进行中"挑战
loop 遍历打卡型挑战
S->>G: 轨迹 GPS 点 × 雪场检查点匹配
G-->>S: 返回本次轨迹命中的雪道列表
S->>S: 更新用户打卡记录 (新增已打卡雪道)
S->>S: 检查是否集齐该挑战全部目标雪道
S->>S: 更新排行榜 (仅集齐者)
end
S-->>U: 返回本次滑行的打卡结果
Note over U: 弹出打卡成功动画<br/>"恭喜!银龙道 打卡成功 🎉<br/>还差 3 条即可集齐"四、 验收标准 (Acceptance Criteria)
4.1 积累型挑战(原有 + 修正)
- 俱乐部隔离: 俱乐部 A 发起的内部挑战,非成员无法报名(或报名时提示加入俱乐部)。
- 数据过滤:
- 验证时间范围: 挑战开始前或结束后的滑行数据不计入。
- 验证雪场限制: 若挑战限定"北大壶",在"松花湖"的滑行数据不计入。
- 榜单更新: 上传一条 5km 的轨迹后,关联的"里程挑战"个人成绩应增加 5km,排名相应变动。
- 奖励发放: 模拟挑战结束,系统应自动向达标用户发放"参与奖"(如积分),并生成排名报表供管理员核对"排名奖"。
- V2 修正: "滑行时长"维度下,成绩单位为小时:分钟,累加用户所有有效滑行记录的时长。
4.2 打卡型挑战(V2 新增)
- 雪场首选: 打卡型挑战发布第一步必须选择雪场,无 GIS 数据的雪场不可选。
- 单一打卡范围: 一个挑战 = 一个打卡范围(全部/初级/中级/高级),一个排行榜,一套奖励。
- 打卡判定: 用户滑行轨迹经过某雪道的全部检查点(有序),该雪道自动标记为已打卡。
- 去重: 同一雪道重复滑行不重复打卡,仅记录首次打卡时间。
- 集齐才上榜: 未集齐该范围全部雪道的用户不出现在排行榜中。
- 时间排序: 多位集齐用户按完成时间(最后一条雪道的打卡时间戳)升序排列。
- 打卡反馈: 每次滑行结束后,若有新雪道被打卡成功,App 弹出打卡成功通知,显示当前进度。
五、 文档修订记录
| 版本 | 日期 | 变更内容 |
|---|---|---|
| V1.0 | 2024-05-20 | 初始版本,定义积累型挑战(里程/落差/速度) |
| V2.0 | 2026-02-25 | 1. 新增"挑战类型"顶层分层(积累型 / 打卡型) 2. 新增"雪道打卡"挑战(一个挑战=一个打卡范围=一个榜单) 3. 统计维度修正为"累计滑行时长" 4. 基于 GIS 数据自动生成检查点 |
