From 7b0c7f5ed4973f9b8cbf1c618df1fa55c4adce42 Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Thu, 10 Sep 2026 19:48:22 +0800 Subject: [PATCH] 1 --- public/config.js | 4 +- src/libs/amapLoader.js | 124 ++++ src/libs/coordTransform.js | 88 +++ .../app/business/logistics/logistics.vue | 1 + src/views/app/shop/addEdit.vue | 1 + src/views/app/shopArea/shopArea.vue | 180 ++++- src/views/my-components/hiver/map.vue | 676 +++++++++--------- src/views/my-components/hiver/mapLocate.vue | 581 +-------------- 8 files changed, 719 insertions(+), 936 deletions(-) create mode 100644 src/libs/amapLoader.js create mode 100644 src/libs/coordTransform.js diff --git a/public/config.js b/public/config.js index ff26c4a..fd6f748 100644 --- a/public/config.js +++ b/public/config.js @@ -1,5 +1,7 @@ // 打包后仍可修改的配置 const config = { baseApi: "/hiver", // 请求路径统一前缀 - mapboxToken: "pk.eyJ1IjoiZGVsaWNhY3lsZWUiLCJhIjoiY2o4b3U2eWx0MDh2ODJxcnNra2ZrM3l1dyJ9.z6CNmgaMEbC0Ks8AMM72Tw" // mapbox地图accessToken + mapboxToken: "pk.eyJ1IjoiZGVsaWNhY3lsZWUiLCJhIjoiY2o4b3U2eWx0MDh2ODJxcnNra2ZrM3l1dyJ9.z6CNmgaMEbC0Ks8AMM72Tw", // mapbox地图accessToken + amapKey: "4732ddeaa9ce280fa01864ff256426a8", // 高德地图 Web端(JS API) Key + amapSecurityJsCode: "05d7751de12e72a8e764a21e66d2e16f" // 高德安全密钥 } \ No newline at end of file diff --git a/src/libs/amapLoader.js b/src/libs/amapLoader.js new file mode 100644 index 0000000..84fc1f4 --- /dev/null +++ b/src/libs/amapLoader.js @@ -0,0 +1,124 @@ +let amapLoading = null; + +function ensureSecurityConfig(securityJsCode) { + const code = + securityJsCode || + (typeof config !== "undefined" && config.amapSecurityJsCode) || + ""; + if (code) { + window._AMapSecurityConfig = { + securityJsCode: code, + }; + } +} + +/** + * 项目里有 monaco AMD loader,加载高德时需临时屏蔽 define, + * 且不要用高德 loader.js(会触发 “Can only have one anonymous define”)。 + */ +function loadAmapScript(key) { + return new Promise((resolve, reject) => { + if (window.AMap) { + resolve(window.AMap); + return; + } + + const previousDefine = window.define; + const hadAmd = + typeof previousDefine === "function" && previousDefine.amd; + if (hadAmd) { + window.define = undefined; + } + + const restoreDefine = () => { + if (hadAmd) { + window.define = previousDefine; + } + }; + + const script = document.createElement("script"); + script.type = "text/javascript"; + script.charset = "utf-8"; + // 不用 async/callback/plugin,避免 _cssload_ 与 AMD 冲突 + script.src = + "https://webapi.amap.com/maps?v=2.0&key=" + encodeURIComponent(key); + script.onload = () => { + restoreDefine(); + if (window.AMap) { + resolve(window.AMap); + } else { + reject(new Error("高德地图加载失败")); + } + }; + script.onerror = () => { + restoreDefine(); + reject(new Error("高德地图脚本加载失败")); + }; + document.head.appendChild(script); + }); +} + +/** + * 按需加载高德 JS API + */ +export function loadAmap(key, securityJsCode) { + if (typeof window === "undefined") { + return Promise.reject(new Error("非浏览器环境")); + } + const finalKey = key || (typeof config !== "undefined" && config.amapKey) || ""; + if (!finalKey) { + return Promise.reject(new Error("未配置高德地图 Key")); + } + if (window.AMap) { + return Promise.resolve(window.AMap); + } + if (amapLoading) { + return amapLoading; + } + ensureSecurityConfig(securityJsCode); + amapLoading = loadAmapScript(finalKey).catch((err) => { + amapLoading = null; + throw err; + }); + return amapLoading; +} + +/** + * 使用高德定位,返回 GCJ-02 { lng, lat, accuracy, address } + */ +export function getAmapLocation(key, securityJsCode) { + return loadAmap(key, securityJsCode).then((AMap) => { + return new Promise((resolve, reject) => { + const runLocate = () => { + const geolocation = new AMap.Geolocation({ + enableHighAccuracy: true, + timeout: 15000, + convert: true, + getCityWhenFail: false, + }); + geolocation.getCurrentPosition((status, result) => { + if (status === "complete" && result && result.position) { + const position = result.position; + resolve({ + lng: + typeof position.getLng === "function" + ? position.getLng() + : position.lng, + lat: + typeof position.getLat === "function" + ? position.getLat() + : position.lat, + accuracy: result.accuracy, + address: result.formattedAddress || "", + }); + } else { + const message = + (result && (result.message || result.info)) || "定位失败"; + reject(new Error(message)); + } + }); + }; + AMap.plugin("AMap.Geolocation", runLocate); + }); + }); +} diff --git a/src/libs/coordTransform.js b/src/libs/coordTransform.js new file mode 100644 index 0000000..c6cfadd --- /dev/null +++ b/src/libs/coordTransform.js @@ -0,0 +1,88 @@ +/** + * 国内坐标系转换(高德 GCJ-02 ↔ GPS WGS84) + * Mapbox 使用 WGS84,高德定位返回 GCJ-02 + */ + +const PI = Math.PI; +const A = 6378245.0; +const EE = 0.00669342162296594323; + +function outOfChina(lng, lat) { + return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271; +} + +function transformLat(lng, lat) { + let ret = + -100.0 + + 2.0 * lng + + 3.0 * lat + + 0.2 * lat * lat + + 0.1 * lng * lat + + 0.2 * Math.sqrt(Math.abs(lng)); + ret += + ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * + 2.0) / + 3.0; + ret += + ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / + 3.0; + ret += + ((160.0 * Math.sin((lat / 12.0) * PI) + + 320 * Math.sin((lat * PI) / 30.0)) * + 2.0) / + 3.0; + return ret; +} + +function transformLng(lng, lat) { + let ret = + 300.0 + + lng + + 2.0 * lat + + 0.1 * lng * lng + + 0.1 * lng * lat + + 0.1 * Math.sqrt(Math.abs(lng)); + ret += + ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * + 2.0) / + 3.0; + ret += + ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / + 3.0; + ret += + ((150.0 * Math.sin((lng / 12.0) * PI) + + 300.0 * Math.sin((lng / 30.0) * PI)) * + 2.0) / + 3.0; + return ret; +} + +function delta(lng, lat) { + let dLat = transformLat(lng - 105.0, lat - 35.0); + let dLng = transformLng(lng - 105.0, lat - 35.0); + const radLat = (lat / 180.0) * PI; + let magic = Math.sin(radLat); + magic = 1 - EE * magic * magic; + const sqrtMagic = Math.sqrt(magic); + dLat = (dLat * 180.0) / (((A * (1 - EE)) / (magic * sqrtMagic)) * PI); + dLng = (dLng * 180.0) / ((A / sqrtMagic) * Math.cos(radLat) * PI); + return { lat: dLat, lng: dLng }; +} + +/** GCJ-02 -> WGS84 */ +export function gcj02ToWgs84(lng, lat) { + if (outOfChina(lng, lat)) { + return [lng, lat]; + } + const d = delta(lng, lat); + return [lng - d.lng, lat - d.lat]; +} + +/** WGS84 -> GCJ-02 */ +export function wgs84ToGcj02(lng, lat) { + if (outOfChina(lng, lat)) { + return [lng, lat]; + } + const d = delta(lng, lat); + return [lng + d.lng, lat + d.lat]; +} diff --git a/src/views/app/business/logistics/logistics.vue b/src/views/app/business/logistics/logistics.vue index b9f00fc..c7b390d 100644 --- a/src/views/app/business/logistics/logistics.vue +++ b/src/views/app/business/logistics/logistics.vue @@ -323,6 +323,7 @@ xiangtong: false, sortField: "avgTime", regionId: regionId, + fromAdmin: true, pageNum: 1, pageSize: 10 }, diff --git a/src/views/app/shop/addEdit.vue b/src/views/app/shop/addEdit.vue index 34fec71..eebab34 100644 --- a/src/views/app/shop/addEdit.vue +++ b/src/views/app/shop/addEdit.vue @@ -218,6 +218,7 @@ diff --git a/src/views/app/shopArea/shopArea.vue b/src/views/app/shopArea/shopArea.vue index 8939989..d890e9c 100644 --- a/src/views/app/shopArea/shopArea.vue +++ b/src/views/app/shopArea/shopArea.vue @@ -7,6 +7,13 @@ white-space: normal; line-height: 1.5; } + +.geo-tip { + margin-top: 6px; + color: #808695; + font-size: 12px; + line-height: 1.4; +} + - \ No newline at end of file +.amap-container { + min-height: 360px; +} +.locate-tip { + margin-top: 6px; + color: #808695; + font-size: 12px; + line-height: 1.4; +} +.modal-fullscreen { + position: absolute; + right: 42px; + top: 10px; + font-size: 18px; + color: #999; +} + diff --git a/src/views/my-components/hiver/mapLocate.vue b/src/views/my-components/hiver/mapLocate.vue index 3a83198..24fd001 100644 --- a/src/views/my-components/hiver/mapLocate.vue +++ b/src/views/my-components/hiver/mapLocate.vue @@ -1,583 +1,12 @@ + - \ No newline at end of file