From f1f8f4e64aadb6a65a6a247d037ab9b7b6b6795f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 20 May 2026 13:09:26 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=88iot=EF=BC=89:=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=20ele=20=E7=9A=84=20map=20=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-ele/src/components/map/index.ts | 3 + .../src/components/map/src/map-dialog.vue | 290 ++++++++++++++++++ apps/web-ele/src/components/map/src/utils.ts | 63 ++++ 3 files changed, 356 insertions(+) create mode 100644 apps/web-ele/src/components/map/index.ts create mode 100644 apps/web-ele/src/components/map/src/map-dialog.vue create mode 100644 apps/web-ele/src/components/map/src/utils.ts 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; +};