推进活动系统最小成品闭环与游客体验

This commit is contained in:
2026-04-07 19:05:18 +08:00
parent 1a6008449e
commit 6cd16f08dd
102 changed files with 16087 additions and 3556 deletions

View File

@@ -0,0 +1,388 @@
# 准备页地图预览方案
> 文档版本v1.0
> 最后更新2026-04-07 12:18:00
本文档用于说明活动准备页的地图预览能力如何设计与落地。
当前目标不是直接进入实现,而是先把方案边界、分层、前后端职责和分阶段路径定清。
---
## 1. 目标
准备页当前已经具备:
- 活动状态摘要
- 赛道选择
- 设备准备
- 进入地图
但“本局对象预览”仍然主要是文字占位,对玩家帮助有限。
准备页地图预览的目标是:
1. 在进入地图前,让玩家建立空间预期
2. 在多赛道活动中,让玩家能直观看到当前赛道差异
3. 让准备页更像“出发前准备”,而不是工程参数页
4. 不打断当前 runtime 主链,也不额外制造一套重资源地图体系
---
## 2. 推荐方案
当前推荐采用:
**低级别正式瓦片做底图,前端动态叠加赛道**
也就是:
- 底图来源:现有正式瓦片资源
- 底图级别:选择一个较低 zoom 作为预览缩略底图
- 叠加层:前端根据当前赛道数据在预览图上动态绘制起点、终点、控制点和腿线
这是一个“混合预览方案”:
- 不单独制作新的预览地图资源
- 不在前端完整拼装高精度交互地图
- 只在准备页做只读预览
---
## 3. 为什么选这个方案
### 3.1 不新增独立地图资源
如果单独为准备页制作预览地图资源,会带来:
- 资源重复
- 发布链复杂度上升
- 底图与正式地图不一致风险
使用低级别正式瓦片作为预览底图,可以保持:
- 同源
- 一致
- 低成本
### 3.2 多赛道切换更自然
多赛道场景下:
- 底图通常是同一张地图
- 差异主要在赛道叠加层
因此最合理的方式是:
- 底图固定
- 切换赛道时仅重绘 overlay
这样:
- 切换更快
- 数据结构更清楚
- 不需要为每个 variant 重新生成整张预览图
### 3.3 前后端职责清楚
后端负责:
- 提供底图预览所需元数据
- 提供赛道叠加所需坐标数据
前端负责:
- 展示底图
- 动态叠加赛道
- 在准备页进行只读预览
这符合当前项目一直坚持的分层原则。
---
## 4. 整体分层
准备页地图预览建议分成 4 层。
### 4.1 地图底图层
来源:
- 当前正式瓦片资源
形式:
- 低级别缩略底图
职责:
- 提供地点区域的空间背景
### 4.2 预览元数据层
来源:
- 后端预览元数据
职责:
- 告诉前端如何把经纬度投到预览图坐标系中
### 4.3 赛道叠加层
来源:
- variant 控制点与腿线数据
职责:
- 在准备页上画出当前赛道
### 4.4 准备页展示层
职责:
- 只读展示
- 切换赛道联动预览
- 不承担局内交互
---
## 5. 后端需要提供的最小字段
V1 不要求后端提供完整预览图 URL而是先提供“底图元数据 + 赛道 overlay 元数据”。
建议后端提供以下最小结构:
```json
{
"preview": {
"mode": "full",
"baseTiles": {
"tileBaseUrl": "https://.../tiles/",
"zoom": 15,
"tileSize": 256
},
"viewport": {
"width": 800,
"height": 450,
"minLon": 117.0000,
"minLat": 36.6000,
"maxLon": 117.0800,
"maxLat": 36.6600
},
"variants": [
{
"variantId": "variant_a",
"name": "A线",
"routeCode": "route-variant-a",
"controls": [
{ "id": "start", "kind": "start", "lon": 117.01, "lat": 36.61 },
{ "id": "c1", "kind": "control", "lon": 117.02, "lat": 36.615 },
{ "id": "finish", "kind": "finish", "lon": 117.03, "lat": 36.62 }
],
"legs": [
{ "from": "start", "to": "c1" },
{ "from": "c1", "to": "finish" }
]
}
]
}
}
```
其中关键字段是:
- `baseTiles.tileBaseUrl`
- `baseTiles.zoom`
- `viewport.width / height`
- `viewport.minLon / minLat / maxLon / maxLat`
- `variants[].controls`
- `variants[].legs`
这些字段足够前端做只读预览。
---
## 6. 前端如何消费
前端准备页的消费方式建议如下:
### 6.1 底图渲染
- 使用低级别瓦片作为底图来源
-`viewport``zoom` 计算需要的瓦片范围
- 只在准备页内绘制一张静态缩略底图
### 6.2 赛道叠加
- 根据 `viewport` 把控制点经纬度投影到预览图坐标
- 在 canvas 或同等绘制层上叠加:
- 起点
- 终点
- 控制点
- 腿线
### 6.3 多赛道切换
- 切换赛道时不重新换底图
- 只重绘叠加层
### 6.4 展示层级
准备页只做:
- 只读预览
- 不拖拽
- 不缩放
- 不交互打点
---
## 7. 多赛道场景如何处理
多赛道场景是这套方案的重点。
当前建议规则:
1. 同一活动下,所有 variant 共用一张底图
2. 当前选中的 variant 决定叠加层内容
3. 如果活动允许手动选赛道,切换赛道时预览同步切换
4. 如果活动是随机分配或后台指定:
- 准备页在最终绑定前可只显示地点底图
- 一旦后端返回最终绑定赛道,再显示该赛道 overlay
这套设计和当前多赛道 Variant 架构是一致的:
- 底图属于地图对象
- 叠加属于 variant 对象
---
## 8. 预览级别建议
建议预览能力分成 3 档:
### 8.1 `none`
- 不显示地图预览
- 只显示地点、地图、赛道文字信息
适用于:
- 不允许赛前预览的正式比赛
### 8.2 `summary`
- 显示底图
- 只显示简化赛道范围、起终点或大致区域
- 不暴露完整点位和腿线
适用于:
- 需要局前空间感,但不允许完整剧透路线
### 8.3 `full`
- 显示底图
- 显示完整点位与腿线
适用于:
- 体验活动
- 教学活动
- 低门槛公开活动
V1 建议先直接支持:
- `none`
- `full`
后面再补 `summary`
---
## 9. 分阶段实施建议
### 9.1 V1
只做:
- 低级别瓦片底图
- 前端动态赛道叠加
- 支持多赛道切换联动
- 只读展示
不做:
- 复杂预览交互
- 预览模式细分
- 缩放与拖拽
### 9.2 V2
补:
- `none / summary / full`
- 不同活动类型的预览策略
- 更细的赛道保密规则
### 9.3 V3
考虑扩展到:
- 活动详情页缩略预览
- 活动列表卡片缩略图
- 赛后结果页路线回看缩略图
---
## 10. 不建议的方案
当前不建议:
### 10.1 单独制作一套预览地图资源
问题:
- 成本高
- 一致性差
- 发布链复杂
### 10.2 前端直接现场拼完整高精度瓦片地图
问题:
- 性能波动大
- 首次加载慢
- 多端一致性差
### 10.3 后端为每个 variant 预生成完整大图
问题:
- 多赛道下资源重复
- 每次改赛道都要重生图
- 扩展性不如“底图固定 + 叠加切换”
---
## 11. 当前建议结论
准备页地图预览最推荐的路线是:
**使用低级别正式瓦片作为预览底图,由前端在准备页动态叠加当前赛道。**
这条路线的优点是:
- 不新增独立地图资源
- 底图与正式地图同源
- 多赛道切换成本低
- 前后端职责清晰
- 易于分阶段落地
当前建议优先推进:
1. 后端补预览元数据最小字段
2. 前端在准备页实现只读底图 + overlay
3. 先支持 `full`
4. 后续再扩 `summary / none`