feat(project): align store delivery pages with live APIs and geocode status

This commit is contained in:
2026-02-19 17:15:19 +08:00
parent 435626ca55
commit 3b96b3f92d
62 changed files with 6813 additions and 250 deletions

View File

@@ -0,0 +1,129 @@
/**
* 文件职责:按需加载腾讯地图 JS SDK。
* 1. 使用全局 callback + 单例 Promise避免重复注入脚本。
* 2. 与 AdminUI 的加载策略保持一致,降低多实例冲突风险。
*/
declare global {
interface Window {
TMap?: any;
__tenantTencentMapInit?: () => void;
}
}
const SCRIPT_ID = 'tenant-tencent-map-gljs-sdk';
const CALLBACK_NAME = '__tenantTencentMapInit';
const SCRIPT_LOAD_TIMEOUT_MS = 12_000;
const TENCENT_MAP_LIBRARIES = 'visualization,geometry,vector,tools,service';
let mapSdkPromise: null | Promise<any> = null;
let scriptLoading = false;
const pendingResolvers: Array<(value: any) => void> = [];
const pendingRejectors: Array<(error: Error) => void> = [];
function getTencentMapKey() {
return (import.meta.env.VITE_TENCENT_MAP_KEY as string | undefined)?.trim();
}
function flushSuccess(tmap: any) {
const resolvers = pendingResolvers.splice(0);
pendingRejectors.splice(0);
resolvers.forEach((resolve) => resolve(tmap));
}
function flushError(error: Error) {
const rejectors = pendingRejectors.splice(0);
pendingResolvers.splice(0);
rejectors.forEach((reject) => reject(error));
}
function buildScriptUrl(mapKey: string) {
return `https://map.qq.com/api/gljs?v=1.exp&key=${encodeURIComponent(
mapKey,
)}&libraries=${TENCENT_MAP_LIBRARIES}&callback=${CALLBACK_NAME}`;
}
export async function loadTencentMapSdk() {
if (typeof window === 'undefined') {
throw new TypeError('当前环境不支持加载地图');
}
if (window.TMap) {
return window.TMap;
}
const mapKey = getTencentMapKey();
if (!mapKey) {
throw new Error('未配置腾讯地图 KeyVITE_TENCENT_MAP_KEY');
}
if (mapSdkPromise) {
return mapSdkPromise;
}
mapSdkPromise = new Promise<any>((resolve, reject) => {
pendingResolvers.push(resolve);
pendingRejectors.push(reject);
if (scriptLoading) {
return;
}
scriptLoading = true;
const completeWithError = (error: Error) => {
scriptLoading = false;
mapSdkPromise = null;
flushError(error);
};
const timeoutHandle = window.setTimeout(() => {
completeWithError(new Error('腾讯地图 SDK 加载超时'));
}, SCRIPT_LOAD_TIMEOUT_MS);
window[CALLBACK_NAME] = () => {
window.clearTimeout(timeoutHandle);
scriptLoading = false;
if (!window.TMap) {
completeWithError(new Error('腾讯地图 SDK 加载失败'));
return;
}
flushSuccess(window.TMap);
};
const existingScript = document.querySelector<HTMLScriptElement>(
`#${SCRIPT_ID}`,
);
if (existingScript) {
existingScript.addEventListener(
'error',
() => {
window.clearTimeout(timeoutHandle);
completeWithError(new Error('腾讯地图 SDK 加载失败'));
},
{ once: true },
);
return;
}
const script = document.createElement('script');
script.id = SCRIPT_ID;
script.type = 'text/javascript';
script.async = true;
script.defer = true;
script.src = buildScriptUrl(mapKey);
script.addEventListener(
'error',
() => {
window.clearTimeout(timeoutHandle);
completeWithError(new Error('腾讯地图 SDK 加载失败'));
},
{ once: true },
);
document.body.append(script);
});
return mapSdkPromise;
}