修复馆内导览楼层点位展示
This commit is contained in:
@@ -150,7 +150,12 @@
|
||||
:id="floor.scrollId"
|
||||
:key="floor.id"
|
||||
class="floor-item"
|
||||
:class="{ active: activeFloorId === floor.id && layerMode !== 'multi' }"
|
||||
:class="{
|
||||
active: activeFloorId === floor.id && layerMode !== 'multi',
|
||||
pending: loadingFloorId === floor.id,
|
||||
failed: failedFloorId === floor.id,
|
||||
disabled: isFloorSwitchDisabled(floor.id)
|
||||
}"
|
||||
@tap.stop="handleFloorChange(floor)"
|
||||
>
|
||||
<text class="floor-label">{{ floor.label }}</text>
|
||||
@@ -247,6 +252,11 @@ interface GuideFloorOption {
|
||||
label: string
|
||||
}
|
||||
|
||||
interface FloorSwitchEvent {
|
||||
floorId: string
|
||||
floorLabel: string
|
||||
}
|
||||
|
||||
interface OutdoorNavPolyline {
|
||||
points: Array<{ latitude: number; longitude: number }>
|
||||
color: string
|
||||
@@ -381,7 +391,9 @@ const props = withDefaults(defineProps<{
|
||||
const emit = defineEmits<{
|
||||
searchTap: []
|
||||
modeChange: [mode: '2d' | '3d']
|
||||
floorRequest: [event: FloorSwitchEvent]
|
||||
floorChange: [floor: string]
|
||||
floorSwitchFailed: [event: FloorSwitchEvent]
|
||||
toolClick: [tool: string]
|
||||
moreClick: []
|
||||
indoorViewChange: [view: IndoorViewMode]
|
||||
@@ -445,8 +457,15 @@ const activeFloorId = computed(() => {
|
||||
return normalizedFloor?.id || normalizedFloorId
|
||||
})
|
||||
const activeFloorScrollIntoView = ref('')
|
||||
const pendingFloorId = ref('')
|
||||
let suppressFloorAutoScrollUntil = 0
|
||||
const requestedFloorId = ref('')
|
||||
const requestedFloorLabel = ref('')
|
||||
const loadingFloorId = ref('')
|
||||
const renderedFloorId = ref(activeFloorId.value)
|
||||
const activeFloorSwitchRequestSeq = ref(0)
|
||||
const renderedFloorSwitchRequestSeq = ref(0)
|
||||
const failedFloorId = ref('')
|
||||
let suppressFloorAutoScrollForFloorId = ''
|
||||
let floorSwitchRequestSeq = 0
|
||||
|
||||
const syncActiveFloorScroll = () => {
|
||||
if (props.mapType !== 'indoor' || props.indoorView === 'overview' || props.layerMode === 'multi') {
|
||||
@@ -454,10 +473,12 @@ const syncActiveFloorScroll = () => {
|
||||
return
|
||||
}
|
||||
|
||||
if (Date.now() < suppressFloorAutoScrollUntil) {
|
||||
if (activeFloorId.value === suppressFloorAutoScrollForFloorId) {
|
||||
activeFloorScrollIntoView.value = ''
|
||||
suppressFloorAutoScrollForFloorId = ''
|
||||
return
|
||||
}
|
||||
suppressFloorAutoScrollForFloorId = ''
|
||||
|
||||
const matchedFloor = floorItems.value.find((floor) => floor.id === activeFloorId.value)
|
||||
activeFloorScrollIntoView.value = matchedFloor?.scrollId || ''
|
||||
@@ -475,6 +496,11 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
watch(activeFloorId, (floorId) => {
|
||||
if (!floorId || loadingFloorId.value === floorId) return
|
||||
renderedFloorId.value = floorId
|
||||
})
|
||||
|
||||
const searchFieldStyle = computed(() => ({
|
||||
top: props.searchTop
|
||||
}))
|
||||
@@ -528,27 +554,77 @@ const isStaleFloorSwitchError = (error: unknown) => (
|
||||
error instanceof Error && error.message === 'STALE_MODEL_LOAD'
|
||||
)
|
||||
|
||||
const handleFloorChange = (floor: { id: string; label: string }) => {
|
||||
const floorId = floor.id || props.normalizeFloorId(floor.label)
|
||||
if (!floorId || pendingFloorId.value === floorId) return
|
||||
const findFloorItemById = (floorId: string) => (
|
||||
floorItems.value.find((floor) => floor.id === floorId)
|
||||
)
|
||||
|
||||
pendingFloorId.value = floorId
|
||||
suppressFloorAutoScrollUntil = Date.now() + 650
|
||||
const isFloorSwitchDisabled = (floorId: string) => (
|
||||
Boolean(loadingFloorId.value) && loadingFloorId.value !== floorId
|
||||
)
|
||||
|
||||
const clearFloorLoadingIfCurrent = (floorId: string) => {
|
||||
if (loadingFloorId.value === floorId) {
|
||||
loadingFloorId.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
const markFloorSwitchFailedIfUnrendered = (floorId: string, requestSeq: number) => {
|
||||
if (
|
||||
loadingFloorId.value !== floorId
|
||||
|| activeFloorSwitchRequestSeq.value !== requestSeq
|
||||
|| renderedFloorSwitchRequestSeq.value === requestSeq
|
||||
) return
|
||||
|
||||
failedFloorId.value = floorId
|
||||
clearFloorLoadingIfCurrent(floorId)
|
||||
emit('floorSwitchFailed', {
|
||||
floorId,
|
||||
floorLabel: requestedFloorId.value === floorId
|
||||
? requestedFloorLabel.value || findFloorItemById(floorId)?.label || floorId
|
||||
: findFloorItemById(floorId)?.label || floorId
|
||||
})
|
||||
}
|
||||
|
||||
const handleFloorChange = (floor: { id: string; label: string }) => {
|
||||
const floorId = floor.id
|
||||
if (!floorId || loadingFloorId.value) return
|
||||
if (floorId === renderedFloorId.value && activeFloorId.value === floorId && props.layerMode !== 'multi') {
|
||||
emit('floorChange', floorId)
|
||||
emit('indoorViewChange', 'floor')
|
||||
emit('layerModeChange', 'single')
|
||||
return
|
||||
}
|
||||
|
||||
requestedFloorId.value = floorId
|
||||
requestedFloorLabel.value = floor.label
|
||||
loadingFloorId.value = floorId
|
||||
const requestSeq = ++floorSwitchRequestSeq
|
||||
activeFloorSwitchRequestSeq.value = requestSeq
|
||||
failedFloorId.value = ''
|
||||
suppressFloorAutoScrollForFloorId = floorId
|
||||
activeFloorScrollIntoView.value = ''
|
||||
indoorRendererRef.value?.disableAutoSwitchTemporarily?.(10000)
|
||||
emit('floorRequest', {
|
||||
floorId,
|
||||
floorLabel: floor.label
|
||||
})
|
||||
emit('indoorViewChange', 'floor')
|
||||
emit('layerModeChange', 'single')
|
||||
|
||||
Promise.resolve(indoorRendererRef.value?.switchFloor?.(floorId))
|
||||
.then(() => {
|
||||
markFloorSwitchFailedIfUnrendered(floorId, requestSeq)
|
||||
})
|
||||
.catch((error) => {
|
||||
if (isStaleFloorSwitchError(error)) return
|
||||
failedFloorId.value = floorId
|
||||
clearFloorLoadingIfCurrent(floorId)
|
||||
emit('floorSwitchFailed', {
|
||||
floorId,
|
||||
floorLabel: floor.label
|
||||
})
|
||||
console.error('楼层切换失败:', error)
|
||||
})
|
||||
.finally(() => {
|
||||
if (pendingFloorId.value === floorId) {
|
||||
pendingFloorId.value = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleLayerModeChange = (mode: LayerDisplayMode) => {
|
||||
@@ -556,22 +632,45 @@ const handleLayerModeChange = (mode: LayerDisplayMode) => {
|
||||
indoorRendererRef.value?.disableAutoSwitchTemporarily?.(10000)
|
||||
|
||||
if (mode === 'multi') {
|
||||
pendingFloorId.value = ''
|
||||
loadingFloorId.value = ''
|
||||
requestedFloorId.value = ''
|
||||
requestedFloorLabel.value = ''
|
||||
void indoorRendererRef.value?.showMultiFloor?.()
|
||||
emit('indoorViewChange', 'multi')
|
||||
} else {
|
||||
const floorId = activeFloorId.value
|
||||
pendingFloorId.value = floorId
|
||||
const floorLabel = findFloorItemById(floorId)?.label || floorId
|
||||
if (!floorId) return
|
||||
if (floorId === renderedFloorId.value && props.layerMode !== 'multi') {
|
||||
emit('indoorViewChange', 'floor')
|
||||
emit('layerModeChange', mode)
|
||||
return
|
||||
}
|
||||
|
||||
requestedFloorId.value = floorId
|
||||
requestedFloorLabel.value = floorLabel
|
||||
loadingFloorId.value = floorId
|
||||
const requestSeq = ++floorSwitchRequestSeq
|
||||
activeFloorSwitchRequestSeq.value = requestSeq
|
||||
failedFloorId.value = ''
|
||||
emit('floorRequest', {
|
||||
floorId,
|
||||
floorLabel
|
||||
})
|
||||
Promise.resolve(indoorRendererRef.value?.switchFloor?.(floorId))
|
||||
.then(() => {
|
||||
markFloorSwitchFailedIfUnrendered(floorId, requestSeq)
|
||||
})
|
||||
.catch((error) => {
|
||||
if (isStaleFloorSwitchError(error)) return
|
||||
failedFloorId.value = floorId
|
||||
clearFloorLoadingIfCurrent(floorId)
|
||||
emit('floorSwitchFailed', {
|
||||
floorId,
|
||||
floorLabel
|
||||
})
|
||||
console.error('楼层切换失败:', error)
|
||||
})
|
||||
.finally(() => {
|
||||
if (pendingFloorId.value === floorId) {
|
||||
pendingFloorId.value = ''
|
||||
}
|
||||
})
|
||||
emit('indoorViewChange', 'floor')
|
||||
}
|
||||
|
||||
@@ -622,6 +721,14 @@ const handleMoreTap = () => {
|
||||
}
|
||||
|
||||
const handleThreeFloorChange = (floorId: string) => {
|
||||
renderedFloorId.value = floorId
|
||||
if (loadingFloorId.value === floorId) {
|
||||
renderedFloorSwitchRequestSeq.value = activeFloorSwitchRequestSeq.value
|
||||
}
|
||||
if (failedFloorId.value === floorId) {
|
||||
failedFloorId.value = ''
|
||||
}
|
||||
clearFloorLoadingIfCurrent(floorId)
|
||||
emit('floorChange', floorId)
|
||||
emit('indoorViewChange', 'floor')
|
||||
emit('layerModeChange', 'single')
|
||||
@@ -1120,6 +1227,28 @@ defineExpose({
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
.floor-item.pending {
|
||||
pointer-events: none;
|
||||
opacity: 0.72;
|
||||
}
|
||||
|
||||
.floor-item.pending::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 7px;
|
||||
border: 1px solid rgba(224, 225, 0, 0.9);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.floor-item.disabled {
|
||||
pointer-events: none;
|
||||
opacity: 0.46;
|
||||
}
|
||||
|
||||
.floor-item.failed:not(.pending) .floor-label {
|
||||
color: #b84a4a;
|
||||
}
|
||||
|
||||
.floor-label {
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
|
||||
Reference in New Issue
Block a user