diff --git a/apps/web-ele/src/components/map/index.ts b/apps/web-ele/src/components/map/index.ts new file mode 100644 index 000000000..c8b84da5a --- /dev/null +++ b/apps/web-ele/src/components/map/index.ts @@ -0,0 +1,3 @@ +export { default as MapDialog } from './src/map-dialog.vue'; + +export { loadBaiduMapSdk } from './src/utils'; diff --git a/apps/web-ele/src/components/map/src/map-dialog.vue b/apps/web-ele/src/components/map/src/map-dialog.vue new file mode 100644 index 000000000..9bc34790b --- /dev/null +++ b/apps/web-ele/src/components/map/src/map-dialog.vue @@ -0,0 +1,290 @@ + + + + diff --git a/apps/web-ele/src/components/map/src/utils.ts b/apps/web-ele/src/components/map/src/utils.ts new file mode 100644 index 000000000..c5ff378e1 --- /dev/null +++ b/apps/web-ele/src/components/map/src/utils.ts @@ -0,0 +1,63 @@ +/* eslint-disable @typescript-eslint/no-dynamic-delete */ +/** + * 百度地图 SDK 加载工具 + */ + +// 扩展 Window 接口以包含百度地图 GL API +declare global { + interface Window { + BMapGL: any; + } +} + +// 全局回调名称 +const CALLBACK_NAME = '__BAIDU_MAP_LOAD_CALLBACK__'; + +// SDK 加载状态 +let loadPromise: null | Promise = null; + +/** + * 加载百度地图 GL SDK + * @param timeout 超时时间(毫秒),默认 10000 + * @returns Promise + */ +export const loadBaiduMapSdk = (timeout = 10_000): Promise => { + // 已加载完成 + if (window.BMapGL) { + return Promise.resolve(); + } + + // 正在加载中,返回同一个 Promise + if (loadPromise) { + return loadPromise; + } + + loadPromise = new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + loadPromise = null; + reject(new Error('百度地图 SDK 加载超时')); + }, timeout); + + // 全局回调 + (window as any)[CALLBACK_NAME] = () => { + clearTimeout(timeoutId); + delete (window as any)[CALLBACK_NAME]; + resolve(); + }; + + // 创建 script 标签 + const script = document.createElement('script'); + script.src = `https://api.map.baidu.com/api?v=1.0&type=webgl&ak=${ + import.meta.env.VITE_BAIDU_MAP_KEY + }&callback=${CALLBACK_NAME}`; + script.addEventListener('onerror', () => { + clearTimeout(timeoutId); + loadPromise = null; + delete (window as any)[CALLBACK_NAME]; + reject(new Error('百度地图 SDK 加载失败')); + }); + document.body.append(script); + }); + + return loadPromise; +};