This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: shenzhen-natural-museum-dev
|
||||
description: Shenzhen Natural Museum mobile H5 spatial content guide architecture and client visual specification standards. Use when working in this frontend-miniapp project on guide and explain businesses, visual styling, typography, hall icons, homepage tab labels, indoor 3D/Three.js/GLB, SGS Map SDK H5 integration, iframe/postMessage SDK rendering, API/static data-source switching, POI/location preview, exhibit/hall/facility content, audio explanation, transcript/media data, Tencent Map/outdoor reference logic, static nav assets, Museum Content/Guide/Explain Data Access Layers, provider/adapter/repository architecture, route_graph/nav_data readiness, browser-simulated H5 user-flow audits, business-logic audits, engineering architecture reviews, legacy demo data cleanup, mobile overlay/canvas compatibility, and quality gates. Treat mini-program/mp-weixin as out of scope unless the user explicitly asks for it.
|
||||
description: Shenzhen Natural Museum mobile H5 guide/explain architecture, indoor spatial rendering, content data, and client visual standards. Use in frontend-miniapp for guide/explain flows; visual styling, typography, hall icons, and homepage tabs; Three.js/GLB; unified guide-model initial state; deterministic overview/floor camera baselines; POI-detail return resets; async request invalidation; SGS Map SDK/iframe/postMessage integration; static/API data-source switching; POI/location previews; exhibit, hall, facility, audio, transcript, or media work; Tencent Map/outdoor logic; nav assets and data-layer architecture; route readiness; H5 browser-flow or business-logic audits; legacy-data cleanup; mobile canvas overlays; and quality gates. Treat mp-weixin as out of scope unless explicitly requested.
|
||||
---
|
||||
|
||||
# Shenzhen Natural Museum Dev
|
||||
@@ -234,6 +234,9 @@ Use this workflow when the user asks to connect the SGS Map SDK to the H5 guide
|
||||
|
||||
- Indoor 3D should load GLB/GLTF resources from the clean package under `static/nav-assets/...` while preserving texture/bin relationships.
|
||||
- Initial indoor 3D entry should load the full building model when that is the product requirement; switch to a single floor only after zoom/focus/explicit floor action.
|
||||
- Treat guide-model state restoration as one state-management contract, not as page-specific cleanup. Read and follow [references/guide-model-state-baseline.md](references/guide-model-state-baseline.md) whenever work touches initial model state, overview/floor camera baselines, POI focus, detail navigation/return, floor loading, reset behavior, or model async races.
|
||||
- Keep `GUIDE_MODEL_INITIAL_STATE`, floor-view baselines, reset actions, and one-shot POI-detail return context behind the existing shared guide-model state boundary. Do not let search, map-click, hall, exhibit, or facility flows own separate reset behavior.
|
||||
- Preserve the mounted `ThreeMap`, WebGL renderer, scene, and valid model cache during business-state reset. Never use reload, `reLaunch`, component keys, renderer recreation, or repeated cached GLB parsing as a reset mechanism.
|
||||
- Provide side controls or equivalent for full-building/multi-floor versus single-floor views.
|
||||
- Always provide loading, error, retry, and recovery paths for model loading.
|
||||
- Keep canvas sizing constrained by the guide layout. It must not cover fixed navigation, cards, buttons, floor controls, search, top tabs, or explain/player controls.
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# 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:
|
||||
|
||||
```ts
|
||||
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:
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user