From 317f910f3cc4fbf29810d5deaf090ea379280a7c Mon Sep 17 00:00:00 2001 From: jacy <18049821889@163.com> Date: Mon, 27 Jul 2026 23:19:40 +0800 Subject: [PATCH] feat(admin,partner): Tencent map location picker and expose LBS key Store create/edit on HQ and partner can pick coords via Tencent locpicker; client-config exposes TENCENT_LBS_KEY; seed empty system settings from env. Co-authored-by: Cursor --- .../src/components/TencentLocPickerModal.tsx | 115 +++++++++++++++ apps/admin-web/src/lib/tencentLocPicker.ts | 60 ++++++++ apps/admin-web/src/pages/StoresPage.tsx | 86 ++++++----- .../components/TencentLocPickerOverlay.tsx | 133 ++++++++++++++++++ apps/h5-partner/src/lib/tencentLocPicker.ts | 59 ++++++++ apps/h5-partner/src/pages/StoreCreatePage.tsx | 31 +++- apps/h5-partner/src/pages/StoreDetailPage.tsx | 28 ++++ .../src/pages/store-detail/index.tsx | 81 +++++++++-- apps/mini-user/src/styles/store-detail.css | 21 +++ packages/shared-types/src/wechat.ts | 2 + server/dukang-api/.env.example | 3 +- .../system-config/system-config.registry.ts | 2 +- .../common/client-config.controller.ts | 2 + 13 files changed, 571 insertions(+), 52 deletions(-) create mode 100644 apps/admin-web/src/components/TencentLocPickerModal.tsx create mode 100644 apps/admin-web/src/lib/tencentLocPicker.ts create mode 100644 apps/h5-partner/src/components/TencentLocPickerOverlay.tsx create mode 100644 apps/h5-partner/src/lib/tencentLocPicker.ts diff --git a/apps/admin-web/src/components/TencentLocPickerModal.tsx b/apps/admin-web/src/components/TencentLocPickerModal.tsx new file mode 100644 index 0000000..ad05635 --- /dev/null +++ b/apps/admin-web/src/components/TencentLocPickerModal.tsx @@ -0,0 +1,115 @@ +import { useEffect, useMemo, useState } from 'react'; +import { Modal, Spin, Typography, message } from 'antd'; +import type { ClientRuntimeConfig } from '@dukang/shared-types'; +import { request } from '../lib/api'; +import { + buildTencentLocPickerUrl, + parseTencentLocPickerMessage, + type TencentPickedLocation, +} from '../lib/tencentLocPicker'; + +type Props = { + open: boolean; + onClose: () => void; + onPick: (loc: TencentPickedLocation) => void; + latitude?: number | null; + longitude?: number | null; +}; + +let cachedKey: string | null | undefined; + +async function loadTencentLbsKey(): Promise { + if (cachedKey) return cachedKey; + const cfg = await request('/common/client-config'); + const key = (cfg.tencentLbsKey || '').trim(); + if (!key) { + throw new Error('未配置腾讯位置服务 Key,请在系统设置中填写 TENCENT_LBS_KEY'); + } + cachedKey = key; + return key; +} + +export default function TencentLocPickerModal({ + open, + onClose, + onPick, + latitude, + longitude, +}: Props) { + const [key, setKey] = useState(cachedKey ?? null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + + useEffect(() => { + if (!open) return; + let cancelled = false; + setError(''); + if (key) return; + setLoading(true); + void loadTencentLbsKey() + .then((k) => { + if (!cancelled) setKey(k); + }) + .catch((e) => { + if (!cancelled) { + const msg = e instanceof Error ? e.message : '加载地图配置失败'; + setError(msg); + message.error(msg); + } + }) + .finally(() => { + if (!cancelled) setLoading(false); + }); + return () => { + cancelled = true; + }; + }, [open, key]); + + useEffect(() => { + if (!open) return; + function onMessage(event: MessageEvent) { + const picked = parseTencentLocPickerMessage(event.data); + if (!picked) return; + onPick(picked); + onClose(); + } + window.addEventListener('message', onMessage); + return () => window.removeEventListener('message', onMessage); + }, [open, onPick, onClose]); + + const src = useMemo(() => { + if (!key) return ''; + return buildTencentLocPickerUrl(key, { + latitude: latitude != null ? Number(latitude) : undefined, + longitude: longitude != null ? Number(longitude) : undefined, + }); + }, [key, latitude, longitude]); + + return ( + + {loading ? ( +
+ +
+ ) : error ? ( +
+ {error} +
+ ) : src ? ( +