chore: 移除废弃的 SgsMapRenderer 组件

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
lyf
2026-06-26 04:22:01 +08:00
parent cc7c21a285
commit 3d6dea2872

View File

@@ -1,316 +0,0 @@
<template>
<view class="sgs-map-renderer">
<view ref="containerRef" class="sgs-map-container"></view>
<view v-if="isLoading" class="sdk-state-overlay">
<view class="sdk-state-card">
<view class="loading-spinner"></view>
<text class="sdk-state-title">正在连接 SGS 三维地图</text>
<text class="sdk-state-desc">{{ statusMessage }}</text>
</view>
</view>
<view v-else-if="loadError" class="sdk-state-overlay error-overlay">
<view class="sdk-state-card error-card">
<text class="sdk-state-title">SGS 地图加载失败</text>
<text class="sdk-state-desc">{{ statusMessage }}</text>
<view class="retry-btn" @tap="retryLoad">
<text class="retry-text">重新连接</text>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import {
dataSourceConfig,
getSgsMapTargetOrigin
} from '@/config/dataSource'
import { SgsMapService } from '@/services/sgs/SgsMapService'
import {
toAppFloorId,
toErrorResult,
toFloorLabel,
toFocusedResult,
toFocusNodeName,
toNumericFloorId,
type SgsTargetFocusRequest,
type SgsTargetFocusResult
} from '@/services/sgs/SgsMapEventAdapter'
import type {
SgsMapEvents
} from '@/types/sgs-map-sdk'
interface FloorOption {
id: string
label: string
}
type ContainerRef = HTMLElement | { $el?: HTMLElement } | null
type ViewMode = 'overview' | 'floor' | 'multi'
const props = withDefaults(defineProps<{
initialFloorId?: string
initialView?: ViewMode
floors?: FloorOption[]
targetFocus?: SgsTargetFocusRequest | null
}>(), {
initialFloorId: 'L1',
initialView: 'floor',
floors: () => [] as FloorOption[],
targetFocus: null
})
const emit = defineEmits<{
floorChange: [floorId: string]
poiClick: [poi: SgsMapEvents['poiClick']]
targetFocus: [result: SgsTargetFocusResult]
}>()
const containerRef = ref<ContainerRef>(null)
const isLoading = ref(true)
const loadError = ref(false)
const statusMessage = ref('正在加载 SDK 脚本与地图基座...')
let service: SgsMapService | null = null
let currentFocusRequestId: number | string | null = null
const getContainerElement = () => {
const container = containerRef.value
if (!container || typeof HTMLElement === 'undefined') return null
if (container instanceof HTMLElement) return container
const element = '$el' in container ? container.$el : null
return element instanceof HTMLElement ? element : null
}
const disposeService = () => {
service?.destroy()
service = null
}
const registerEvents = () => {
service?.on('floorChanged', (payload) => {
emit('floorChange', toAppFloorId(payload.floorId))
})
service?.on('poiClick', (poi) => {
emit('poiClick', poi)
})
service?.on('loadError', (error) => {
loadError.value = true
isLoading.value = false
statusMessage.value = error.detail || '地图基座 iframe 加载失败,请检查 VITE_SGS_H5_ENGINE_URL。'
})
service?.on('error', (error) => {
loadError.value = true
isLoading.value = false
statusMessage.value = error.message || error.code || 'SGS Map SDK 运行异常'
})
}
const initSdk = async () => {
disposeService()
isLoading.value = true
loadError.value = false
statusMessage.value = '正在加载 SDK 脚本与地图基座...'
await nextTick()
const container = getContainerElement()
if (!container) {
isLoading.value = false
loadError.value = true
statusMessage.value = '未找到 SGS 地图容器。'
return
}
service = new SgsMapService({
container,
scriptUrl: dataSourceConfig.sgsSdkScriptUrl,
sdkUrl: dataSourceConfig.sgsMapEngineUrl,
targetOrigin: getSgsMapTargetOrigin(),
floorId: toNumericFloorId(props.initialFloorId),
timeout: dataSourceConfig.sgsSdkTimeoutMs
})
registerEvents()
try {
await service.init()
isLoading.value = false
loadError.value = false
statusMessage.value = 'SGS 三维地图已连接。'
if (props.initialView === 'overview' || props.initialView === 'multi') {
await service.resetView().catch(() => undefined)
}
if (props.targetFocus) {
await focusTargetPoi(props.targetFocus)
}
} catch (error) {
isLoading.value = false
loadError.value = true
statusMessage.value = error instanceof Error ? error.message : 'SGS Map SDK 初始化失败。'
}
}
const switchFloor = async (floorId: string) => {
try {
await service?.changeFloor(toNumericFloorId(floorId))
} catch (error) {
loadError.value = true
statusMessage.value = error instanceof Error ? error.message : `楼层切换失败:${toFloorLabel(floorId)}`
}
}
const focusTargetPoi = async (request: SgsTargetFocusRequest) => {
if (currentFocusRequestId === request.requestId) return
currentFocusRequestId = request.requestId
try {
await switchFloor(request.floorId)
await service?.focusTo(toFocusNodeName(request))
emit('targetFocus', toFocusedResult(request))
} catch (error) {
emit('targetFocus', toErrorResult(request, error))
}
}
const showOverview = async () => {
await service?.resetView().catch(() => undefined)
}
const showMultiFloor = async () => {
await service?.resetView().catch(() => undefined)
}
const disableAutoSwitchTemporarily = () => {
// SGS SDK does not expose the local zoom auto-switch contract.
}
const retryLoad = () => {
void initSdk()
}
watch(() => props.targetFocus, (request) => {
if (request && !isLoading.value && !loadError.value) {
void focusTargetPoi(request)
}
})
onMounted(() => {
void initSdk()
})
onUnmounted(() => {
disposeService()
})
defineExpose({
switchFloor,
showOverview,
showMultiFloor,
disableAutoSwitchTemporarily
})
</script>
<style scoped lang="scss">
.sgs-map-renderer {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: #eef2f0;
}
.sgs-map-container {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.sdk-state-overlay {
position: absolute;
inset: 0;
z-index: 4;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
box-sizing: border-box;
background: rgba(245, 247, 244, 0.82);
backdrop-filter: blur(10px);
}
.sdk-state-card {
width: min(280px, 100%);
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 18px;
box-sizing: border-box;
border-radius: 14px;
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(255, 255, 255, 0.8);
box-shadow: 0 12px 30px rgba(24, 32, 21, 0.12);
text-align: center;
}
.error-card {
border-color: rgba(255, 122, 89, 0.28);
}
.loading-spinner {
width: 24px;
height: 24px;
border: 3px solid rgba(31, 35, 41, 0.12);
border-top-color: #1f2329;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
.sdk-state-title {
font-size: 16px;
line-height: 22px;
font-weight: 700;
color: #1f2329;
}
.sdk-state-desc {
font-size: 12px;
line-height: 18px;
color: #626a73;
}
.retry-btn {
min-width: 96px;
height: 34px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 14px;
border-radius: 17px;
background: #1f2329;
}
.retry-text {
font-size: 13px;
line-height: 18px;
color: #ffffff;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>