Files
frontend-miniapp/.claude/skills/shenzhen-natural-museum-dev/references/guide-model-state-baseline.md
lyf 6566d38cb0
Some checks failed
CI / verify (push) Has been cancelled
修复馆内模型初始视图与点位返回复位
2026-07-15 18:20:18 +08:00

7.4 KiB

Guide Model State And View Baseline Contract

Use this contract for every change or audit involving the indoor guide model, POI focus, floor switching, detail-page return, camera reset, or model async work.

Contents

  • State ownership and initial state
  • Overview and floor baselines
  • Reset action contract
  • POI detail return contract
  • Async invalidation
  • Prohibited reset mechanisms
  • Required tests and audit checks

State Ownership And Initial State

  • Keep one shared business-state owner, preferably the existing useGuideModelState boundary. Do not introduce per-page reset flags or duplicate state managers.
  • Keep GUIDE_MODEL_INITIAL_STATE immutable. Define it as the stable overview state captured only after the exterior/full-building model becomes ready for the first time.
  • Derive the default floor and initial camera from model configuration, floor data, or the first stable ready state. Never hardcode 1F, a floor ID, camera coordinates, target, or distance.
  • Route state changes through explicit actions such as initializeModel, enterOverview, switchFloor, focusPoi, clearPoiSelection, enterRoutePreview, and resetToViewBaseline.
  • Include at least these business fields in the shared contract:
    • 3D/indoor mode, indoorView, and layerMode.
    • Default active floor, requested floor, loading floor, and committed/rendered floor.
    • Camera position, up, fov, zoom, controls target, and camera distance.
    • Selected POI, active/highlighted POI, target focus request, and pending target focus.
    • Visible POI IDs, temporary focus markers, focus labels, pulses, and hall highlights.
    • Route preview, navigation simulation, and automatic floor-switch state.
    • Model ready/loading/error state, model-load version, focus request ID, and reset generation.

Overview And Floor Baselines

  • Preserve the first stable exterior/full-building ready snapshot as the overview baseline.
  • Maintain deterministic FloorViewBaseline values keyed by stable floor ID and a baseline cache key.
  • Inherit observation direction, camera up, fov, zoom, composition, and screen-offset rules from the overview baseline.
  • Compute each floor's controls target and camera distance from that floor's visible model bounding box. Do not copy the overview's absolute position and target to every floor.
  • Never capture a floor baseline from a user-dragged camera, an animated camera, or a POI-focus camera.
  • Return identical position, target, distance, direction, tilt, occupied-screen ratio, and visual center for repeated resets of the same floor within a reasonable epsilon.
  • Invalidate a cached floor baseline when model/package version, visible model bounds, composition rules, or canvas aspect ratio changes.

Reset Action Contract

Expose one renderer operation:

resetToViewBaseline({
  view: 'overview' | 'floor',
  floorId?: string,
  reason: 'poi-detail-close' | 'manual-reset' | 'floor-reset'
})

Perform a floor reset in this order:

  1. Increment the shared generation/request ID so old floor loads and focus requests become stale.
  2. Cancel camera animation, target-focus work, and queued focus callbacks.
  3. Clear selected POI, active/highlighted POI, target focus request, and pending target focus.
  4. Dispose temporary markers, focus labels/pulses/bases, hall highlights, route previews, and navigation simulation.
  5. Restore visiblePoiIds to null, reset search state, and collapse the search dock.
  6. Switch to or confirm the target floor without remounting the renderer.
  7. Apply the deterministic floor baseline only after that floor's model commit succeeds.
  8. Reset automatic floor switching using the final restored camera distance.
  9. Keep ThreeMap, WebGL, scene resources, and valid loaded-model caches alive.
  • Make reset idempotent. Repeated calls with the same target view and floor must converge on the same business and camera state.
  • If the renderer is not ready, retain only the newest reset request and apply it after ready. A failed model state must fail safely without reviving old POI state.

POI Detail Return Contract

  • Use a one-shot context instead of a boolean:
type PoiDetailReturnContext = Readonly<{
  floorId: string
  resetMode: 'floor-baseline'
  requestId: number
}>
  • Set the context before every guide-originated POI detail navigation, including search results, direct model/map POI selection, hall detail, exhibit detail, facility detail, and related-explanation actions.
  • Cancel the context when navigateTo fails or the target cannot be resolved/opened.
  • Consume it once in the guide homepage onShow, clear it immediately, and then reset to that POI's floor baseline.
  • Do not set it for explain-home, deep-link, or other non-guide entry paths to the same detail pages.
  • Keep top close, custom back, browser/system back, and other successful detail exits on the normal page-stack return path. Do not make detail pages mutate ThreeMap internals.
  • Preserve the first normal homepage entry as overview. Never treat initial onShow as a detail return.
  • Audit all navigation call sites, not only facility/detail. Search for navigateTo, hall/exhibit/facility detail URLs, map poiClick, and related-explanation actions.

Async Invalidation

  • Give floor loads, model commits, POI loads, focus requests, camera animations, and queued resets a comparable request ID, generation, epoch, or abort signal.
  • Increment generation before reset cleanup. Check it before every async commit that mutates floor, selection, focus, marker, or camera state.
  • Allow only the newest POI/floor request to commit. A completed old cross-floor request must not overwrite a later selection or reset.
  • Invalidate preloads separately when necessary, but never let a preload commit become active business state after reset.
  • Treat stale-request completion as a no-op, not as a user-visible load failure.

Prohibited Reset Mechanisms

  • Do not use window.location.reload(), location.href, or equivalent page reloads.
  • Do not use uni.reLaunch() to reopen the current guide homepage.
  • Do not change a component key to remount GuideMapShell or ThreeMap.
  • Do not destroy and recreate ThreeMap, WebGLRenderer, controls, or scene solely to reset business state.
  • Do not redownload or reparse an already valid cached GLB/model package.
  • Do not add floor-, category-, type-, or POI-ID-specific reset branches.

Required Tests And Audit Checks

  • Cover search-result and direct map/model POI entry paths for facilities, halls, exhibits, and temporary focus markers.
  • Cover same-floor and cross-floor targets, focus animation in progress, floor load in progress, repeated close/onShow, detail-open failure, model-not-ready, and model-error states.
  • Assert after return that shared business state matches the target baseline contract, selection/highlight/focus are empty, visiblePoiIds is null, and search is collapsed.
  • Assert camera position, controls target, direction, and distance match the appropriate overview/floor baseline within epsilon.
  • Assert an old cross-floor focus/load request cannot commit after reset.
  • Assert ThreeMap mount count, WebGL initialization count, model-package fetch count, and cached GLB parse count do not increase on detail return.
  • Assert non-guide detail entry does not reset the guide model.
  • Browser-test at least three POI types on different floors and verify identical same-floor reset composition, no white flash, no URL/load-time reset, and no duplicate GLB network request.