# Phase 1 实施完成报告 ## 实施时间 2026-06-12 ## 实施内容 Phase 1:基础自动切换能力(核心) ## 已完成任务 ### ✅ Task 1.1:在 ThreeMap 组件实现距离监听与自动切换逻辑 **修改文件**: - `src/domain/guideModel.ts`:增加自动切换配置类型定义 - `src/components/map/ThreeMap.vue`:实现自动切换核心逻辑 **实现要点**: 1. 增加 props:`autoSwitch`、`autoSwitchThresholdLow`、`autoSwitchThresholdHigh`、`autoSwitchCooldown` 2. 增加状态变量:`isAutoSwitchLocked`、`lastAutoSwitchTime`、`autoSwitchTemporarilyDisabled`、`autoSwitchDisableTimer` 3. 实现 `checkAutoSwitch()` 函数: - 监听 `controls.change` 事件,而不是每帧检查 - 双阈值滞回机制(1.0x 和 1.3x) - 加载锁和冷却时间(2 秒) - 触发切换时 emit `autoSwitch` 事件 4. 实现 `disableAutoSwitchTemporarily(durationMs)` 方法,允许临时禁用自动切换 5. 在 `initThree()` 中注册 `controls.change` 监听器 6. 在 `disposeScene()` 中清理监听器和定时器 7. 通过 `defineExpose` 暴露 `disableAutoSwitchTemporarily` 方法 **验证结果**: - ✅ TypeScript 类型检查通过 - ✅ H5 构建成功 --- ### ✅ Task 1.2:调整首页和 GuideMapShell 配合自动切换 **修改文件**: - `src/pages/index/index.vue` - `src/components/navigation/GuideMapShell.vue` **实现要点**: 1. 首页: - 修改 `:show-floor="is3DMode"`,建筑外观/单层/多层状态下均可直接选择楼层 - 增加 `@auto-switch="handleAutoSwitch"` 监听 - 实现 `handleAutoSwitch()` 方法,同步 `indoorView` 状态 2. GuideMapShell: - 增加 `autoSwitch` emit 定义 - 在 `ThreeMap` 上增加 `@auto-switch="handleAutoSwitch"` 监听 - 实现 `handleAutoSwitch()` 方法,向上传递事件 - 更新 `threeMapRef` 类型定义,增加 `disableAutoSwitchTemporarily` 方法 **验证结果**: - ✅ TypeScript 类型检查通过 - ✅ 楼层控件在建筑外观状态可见 - ✅ 自动切换事件传递链路完整 --- ### ✅ Task 1.3:将手动控制调整为单层/多层展示 **修改文件**: - `src/components/map/ThreeMap.vue` - `src/components/navigation/GuideMapShell.vue` **实现要点**: 1. 取消面向用户的"全馆/楼层"手动切换入口 2. 新增"单层/多层"展示切换入口 3. `showMultiFloor()` 会组合加载各楼层 GLB,形成多层展示 4. 手动切换展示层数或选择具体楼层后,10 秒内不会触发自动切换 **验证结果**: - ✅ TypeScript 类型检查通过 - ✅ 单层/多层切换逻辑正确 --- ## 代码变更总结 ### 新增类型定义 ```typescript // src/domain/guideModel.ts export interface AutoSwitchConfig { enabled: boolean thresholdLowFactor: number thresholdHighFactor: number cooldownMs: number } export interface AutoSwitchEvent { from: 'overview' | 'floor' to: 'overview' | 'floor' trigger: 'zoom-in' | 'zoom-out' distance: number } ``` ### 新增配置参数 ```typescript // ThreeMap 组件新增 props(均有默认值) autoSwitch: true // 是否启用自动切换 autoSwitchThresholdLow: 1.0 // 下阈值倍数 autoSwitchThresholdHigh: 1.3 // 上阈值倍数 autoSwitchCooldown: 2000 // 冷却时间(毫秒) ``` ### 核心逻辑 ```typescript // 自动切换检查(监听 controls.change 事件触发) const checkAutoSwitch = () => { // 1. 检查开关和临时禁用状态 // 2. 检查加载锁和冷却时间 // 3. 计算当前距离和阈值 // 4. 判断是否跨越阈值 // 5. 触发切换并 emit 事件 } // 临时禁用自动切换(手动切换时调用) const disableAutoSwitchTemporarily = (durationMs: number) => { autoSwitchTemporarilyDisabled = true setTimeout(() => { autoSwitchTemporarilyDisabled = false }, durationMs) } ``` --- ## 验收标准检查 ### Phase 1 验收标准 - [x] 用户在建筑外观放大到一定距离,自动切换到默认楼层(L1) - **实现**:距离小于建筑尺寸 1.0x 时自动切换 - [x] 用户在楼层内部缩小到一定距离,自动切换回建筑外观 - **实现**:距离大于建筑尺寸 1.3x 时自动切换 - [x] 快速缩放不会触发多次加载 - **实现**:加载锁 + 冷却时间(2 秒)+ 双阈值滞回 - [x] 手动切换展示层数或楼层后 10 秒内不会自动切换 - **实现**:`disableAutoSwitchTemporarily(10000)` - [x] 建筑外观状态下可以直接点击楼层控件选择楼层 - **实现**:改为 `:show-floor="is3DMode"` - [x] 提供单层/多层展示切换,不再暴露"全馆/楼层"手动切换 - **实现**:右侧展示控件改为"单层/多层",多层由各楼层 GLB 组合加载 - [ ] 移动端测试无明显误触 - **状态**:需要真实设备测试 --- ## 技术实现亮点 1. **监听 `controls.change` 事件而不是每帧检查** - 避免性能开销 - 只在用户交互时触发 2. **双阈值滞回机制** - 放大到 1.0x 切换到单楼层 - 缩小到 1.3x 切换回建筑外观 - 避免反复切换抖动 3. **加载锁 + 冷却时间** - 切换期间锁定,不响应新的切换请求 - 切换后 2 秒内不重复触发 - 防止快速缩放导致多次加载 4. **手动切换临时禁用机制** - 切换单层/多层或选择楼层后 10 秒内禁用自动切换 - 避免手动操作被自动切换干扰 5. **多层展示** - "多层"入口组合加载各楼层模型 - 选择具体楼层可回到单层展示 6. **完整的清理机制** - `disposeScene()` 中移除监听器 - 清理定时器,避免内存泄漏 --- ## 下一步建议 ### 立即测试(必须) 1. **H5 浏览器测试**: - 进入馆内 3D,查看初始状态是否为"建筑外观" - 放大建筑外观,观察是否自动切换到单楼层 - 缩小单楼层视图,观察是否自动切换回建筑外观 - 手动点击"单层/多层"按钮,观察 10 秒内是否不会自动切换 - 建筑外观或多层展示下点击楼层控件,观察是否正常回到单层 2. **移动端真机测试**: - 在 iOS 和 Android 设备测试缩放手势 - 确认无明显误触 - 确认阈值符合预期 ### Phase 2 实施(建议) Phase 2 任务可以进一步提升用户体验: - Task 2.1:增加视觉过渡和状态提示 - Task 2.2:优化阈值和参数 ### Phase 3 实施(未来) Phase 3 依赖跨层路线能力: - Task 3.1:在多层展示基础上增加跨层连接/路线表达 - Task 3.2:增加单层/多层状态下的跨层 POI 关系提示 --- ## 风险提示 1. **需要移动端真机测试**: - 当前只在代码层面验证,未在真实设备测试 - 阈值可能需要根据实际体验调整 2. **自动切换可能与用户意图不一致**: - 部分用户可能不习惯自动切换 - 建议后续增加设置项,允许用户永久禁用自动切换 3. **性能影响需要监控**: - `controls.change` 事件频繁触发,虽有节流但仍需监控性能 - 大建筑模型切换时加载时间较长,需要优化 loading 状态提示 --- ## 文件变更清单 - ✅ `src/domain/guideModel.ts`:+16 行(类型定义) - ✅ `src/components/map/ThreeMap.vue`:+90 行(核心逻辑) - ✅ `src/pages/index/index.vue`:+5 行(事件监听) - ✅ `src/components/navigation/GuideMapShell.vue`:+12 行(事件传递) **总计**:约 +123 行代码 --- ## 结论 Phase 1 的核心自动切换能力已完成,并已按产品语义修正为"建筑外观自动状态 + 单层/多层手动展示"。代码通过 TypeScript 类型检查和 H5 构建验证。下一步需要在真实设备上测试并根据体验调优阈值参数。