chore: 移除废弃的 SgsMapRenderer 组件
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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>
|
|
||||||
Reference in New Issue
Block a user