Files
frontend-miniapp/docs/superpowers/specs/2026-06-29-sgs-hall-poi-display-design.md
lyf 8fed715235
Some checks failed
CI / verify (push) Has been cancelled
chore: sync latest project updates
2026-07-03 14:42:38 +08:00

7.0 KiB
Raw Blame History

SGS SDK 展厅/公共展陈空间点位展示修复设计

日期2026-06-29

背景

当前 H5 导览在 VITE_DATA_SOURCE_MODE=sdk3D 模型点位由 GuideModelRepository.loadFloorPois(floorId) 提供,链路为:

index.vue
  -> GuideMapShell.vue
    -> ThreeMap.vue
      -> GuideModelRepository.loadFloorPois(floorId)
        -> SgsSdkGuideModelRepository
          -> sgsSdkApiProvider.getFloorPois/getFloorSpaces/getNavigablePlaces
          -> sgsSdkGuideAdapter
          -> GuideRenderPoi[]

现有 SGS 后端已经提供多楼层的 spacespoisnavigablePlaces,其中 B2、1F、2F 等楼层具备展厅空间与出入口点位。但当前展厅点位展示不稳定,原因包括:

  • spaces 仅识别 type === 'exhibition_hall',漏掉影院、报告厅、活动室、展览坡道等业务上属于公共展陈体验的空间。
  • 展厅渲染点依赖 navigablePlaces 坐标;没有匹配入口时不会展示。
  • getFloorSpaces / getNavigablePlaces 请求失败会被 .catch(() => []) 静默吞掉,运行时看起来像“没有展厅点位”。
  • ThreeMap 在 overview / multi 模式下有点位密度裁剪;用户可能误以为展厅点位没有生成。

本设计选择推荐方案 B在不做完整行业模型重构的前提下修复展厅/公共展陈空间点位的生成、诊断与单层展示稳定性。

目标

  1. SDK 模式下3D 单层模型能稳定展示展厅/公共展陈空间点位。
  2. theatereducation_activityramp 等明确公共展陈体验空间纳入展示范围。
  3. 保持数据边界清晰:spaces 表示空间,navigablePlaces 表示入口/可达目的地,渲染层只消费 GuideRenderPoi
  4. 路线能力仍以入口 routeNodeId 为准;没有路线数据或入口坐标时只做“位置预览”。
  5. 增加诊断可观测性,避免接口失败或适配失败无声发生。

非目标

本次不做完整专业化重构:

  • 不新增完整 MuseumSpace 渲染层。
  • 不绘制空间 polygon / boundary。
  • 不新增独立 label layer。
  • 不把 explain/content 仓储切换为 SGS spaces 远程数据源。
  • 不宣称正式导航、到达引导或定位精度。

设计方案

1. 扩展展陈空间识别

src/data/adapters/sgsSdkGuideAdapter.ts 中,将当前 isExhibitionHallSpace(space) 从单一类型判断扩展为公共展陈空间识别。

建议白名单:

  • exhibition_hall:正式展厅。
  • theater:球幕影院、巨幕影院、动感多维影院、报告厅等。
  • education_activity:科普实验室、活动室等可面向公众的教育展陈空间。
  • ramp:名称包含“展览坡道”时纳入。

名称辅助关键词:

  • 展厅、临展、展览
  • 影院、球幕、巨幕、报告厅
  • 活动室、科普、实验室
  • 展览坡道
  • 宇宙、地球、演化、恐龙、人类、生物、生态、家园

输出仍保持为 MuseumPoi(kind: 'hall')primaryCategory.id 保持 exhibition_hall,避免扩大页面和组件改动范围。

2. 空间与入口匹配策略

展厅点位生成继续由 toMuseumHallPoisFromSgs(spaces, navigablePlaces, floors, fallbackFloorId) 负责,但匹配规则增强:

  1. 先筛选 eligible spaces。
  2. navigablePlaces 中筛选与 eligible spaces 相关的入口/目的地。
  3. 优先用 ownerName 匹配空间名称。
  4. 其次用清洗后的 place.name 去掉“出入口/入口/出口/门”等后缀后匹配空间名称。
  5. 如果一个空间有多个入口,保留在 entrances 中。
  6. 展厅 POI 的主坐标优先取第一个有坐标的入口。

3. 空间中心点 fallback

为避免“有空间但没有入口坐标就完全不显示”,增加 fallback

  1. 如果有匹配入口且入口有坐标,使用入口坐标。
  2. 如果没有可用入口坐标,但 space.center 有坐标,生成仅位置预览的 hall POI。
  3. 如果入口坐标和空间中心都没有,则不生成渲染点,但计入诊断。

需要注意:使用 space.center 的 hall POI 不能被当作可路线规划的目的地;其 navigationReadiness 保持“位置预览”,并且不要伪造 routeNodeId

4. 诊断与错误可观测性

当前 repository 中对 getFloorPois/getFloorSpaces/getNavigablePlaces 的错误处理是 .catch(() => [])。本次保留页面容错,但增加诊断输出。

建议实现轻量 dev 诊断函数或局部 warn

每层记录:

  • pois 数量
  • spaces 数量
  • eligibleSpaces 数量
  • navigablePlaces 数量
  • hallPois 数量
  • hallPoisWithPosition 数量
  • 请求失败的 endpoint

生产环境不刷屏;开发环境可以 console.warn('[SGS guide model] ...')。如果项目已有 diagnostics 面板或数据完整性报告入口,优先复用。

5. ThreeMap 展示策略

不做大 UI 改造,仅保证单层模式可验证:

  • exhibition_hall 保持 core category 与高优先级。
  • floor/detail 模式展示所有有效展厅点位。
  • overview/multi 模式继续允许密度裁剪,避免满屏标签。
  • 聚焦/选中的点位继续不受裁剪影响。

如果源码确认 floor 模式仍会裁剪展厅点位,则只在 floor/detail 模式放宽展厅点位裁剪,不改变 overview/multi 策略。

数据与用户语义

  • 展厅空间:来自 SGS spaces
  • 展厅入口:来自 SGS navigablePlaces
  • 普通设施:来自 SGS pois
  • 模型渲染:统一消费 GuideRenderPoi
  • 用户文案:继续使用“位置预览”“查看位置”,不使用“开始馆内导航”“到达引导”等正式导航表述。

测试与验证

代码级验证

至少覆盖以下样例:

  • B2宇宙厅、地球厅、演化厅、恐龙厅。
  • 1F临展厅01、临展厅02、展厅5人类厅以及影院类公共展陈空间。
  • 2F生物厅、生态厅、家园厅。
  • 4F报告厅或活动室类公共空间在白名单定义内时可生成预览点。

命令验证

实现完成后运行:

pnpm type-check
pnpm lint
pnpm build:h5

H5 手动验证

如可启动 H5

  1. 使用 SDK 模式进入首页。
  2. 切换到 B2、1F、2F 单层模型。
  3. 检查展厅/公共展陈空间点位是否可见。
  4. 点击点位后确认仍是位置预览语义。
  5. 检查控制台诊断不出现接口失败或 hallPois 为 0 的异常。

风险与约束

  • 后端空间类型命名可能继续变化,因此类型白名单要集中定义,避免散落在组件中。
  • 使用 space.center 只能支持位置预览,不能作为路线规划 node。
  • overview/multi 模式仍可能因密度裁剪隐藏部分点位,这是预期行为。
  • 本次不处理 explain 内容源与 SGS spaces 的正式打通。

交付标准

  1. SDK 模式下 SgsSdkGuideModelRepository.loadFloorPois() 可生成展厅/公共展陈空间 GuideRenderPoi
  2. 单层模型中展厅点位稳定可见。
  3. 请求失败或适配失败有开发诊断,不再完全无声。
  4. 类型检查、lint、H5 build 通过或如实报告失败原因。