mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 19:35:50 +00:00
feat: 添加定位签到
This commit is contained in:
parent
dcd87f86f1
commit
9ffb2de2c8
20
resources/assets/js/functions/eeui.js
vendored
20
resources/assets/js/functions/eeui.js
vendored
@ -71,7 +71,13 @@
|
|||||||
// 打开app新页面
|
// 打开app新页面
|
||||||
eeuiAppOpenPage(object, callback) {
|
eeuiAppOpenPage(object, callback) {
|
||||||
if (!$A.isEEUiApp) return;
|
if (!$A.isEEUiApp) return;
|
||||||
if (typeof callback !== "function") callback = _ => {};
|
if (typeof callback !== "function") {
|
||||||
|
callback = _ => {};
|
||||||
|
}
|
||||||
|
if (typeof object.callback === "function") {
|
||||||
|
callback = object.callback;
|
||||||
|
delete object.callback
|
||||||
|
}
|
||||||
$A.eeuiModule("eeui").then(obj => {
|
$A.eeuiModule("eeui").then(obj => {
|
||||||
obj.openPage(object, callback);
|
obj.openPage(object, callback);
|
||||||
})
|
})
|
||||||
@ -182,12 +188,24 @@
|
|||||||
$A.eeuiModuleSync("eeui").setVariate(key, value);
|
$A.eeuiModuleSync("eeui").setVariate(key, value);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 获取全局变量
|
||||||
|
eeuiAppGetVariate(key, defaultVal = "") {
|
||||||
|
if (!$A.isEEUiApp) return;
|
||||||
|
return $A.eeuiModuleSync("eeui").getVariate(key, defaultVal);
|
||||||
|
},
|
||||||
|
|
||||||
// 设置缓存数据
|
// 设置缓存数据
|
||||||
eeuiAppSetCachesString(key, value, expired = 0) {
|
eeuiAppSetCachesString(key, value, expired = 0) {
|
||||||
if (!$A.isEEUiApp) return;
|
if (!$A.isEEUiApp) return;
|
||||||
$A.eeuiModuleSync("eeui").setCachesString(key, value, expired);
|
$A.eeuiModuleSync("eeui").setCachesString(key, value, expired);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 获取缓存数据
|
||||||
|
eeuiAppGetCachesString(key, defaultVal = "") {
|
||||||
|
if (!$A.isEEUiApp) return;
|
||||||
|
return $A.eeuiModuleSync("eeui").getCachesString(key, defaultVal);
|
||||||
|
},
|
||||||
|
|
||||||
// 长按内容震动(仅支持android、iOS无效)
|
// 长按内容震动(仅支持android、iOS无效)
|
||||||
eeuiAppSetHapticBackEnabled(val) {
|
eeuiAppSetHapticBackEnabled(val) {
|
||||||
if (!$A.isEEUiApp) return;
|
if (!$A.isEEUiApp) return;
|
||||||
|
|||||||
39
resources/assets/js/store/actions.js
vendored
39
resources/assets/js/store/actions.js
vendored
@ -969,6 +969,45 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取定位(App)
|
||||||
|
* @param dispatch
|
||||||
|
* @param objects
|
||||||
|
* @returns {Promise<unknown>}
|
||||||
|
*/
|
||||||
|
openAppMapPage({dispatch}, objects) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const params = {
|
||||||
|
// key: "xxxxxx",
|
||||||
|
// point: "116.404,39.925",
|
||||||
|
title: $A.L("签到地点"),
|
||||||
|
label: $A.L("选择附近地点"),
|
||||||
|
placeholder: $A.L("搜索地点"),
|
||||||
|
noresult: $A.L("附近没有找到地点"),
|
||||||
|
errtip: $A.L("定位失败"),
|
||||||
|
selectclose: "true",
|
||||||
|
channel: $A.randomString(6)
|
||||||
|
}
|
||||||
|
const url = $A.urlAddParams($A.eeuiAppRewriteUrl('../public/tools/map/index.html'), Object.assign(params, objects))
|
||||||
|
dispatch('openAppChildPage', {
|
||||||
|
pageType: 'app',
|
||||||
|
pageTitle: params.title,
|
||||||
|
url: 'web.js',
|
||||||
|
params: {
|
||||||
|
titleFixed: true,
|
||||||
|
allowAccess: true,
|
||||||
|
url
|
||||||
|
},
|
||||||
|
callback: ({status}) => {
|
||||||
|
if (status === 'destroy') {
|
||||||
|
const data = $A.jsonParse($A.eeuiAppGetVariate(`location::${params.channel}`));
|
||||||
|
resolve(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开子窗口(客户端)
|
* 打开子窗口(客户端)
|
||||||
* @param dispatch
|
* @param dispatch
|
||||||
|
|||||||
3
resources/assets/statics/public/tools/map/empty.svg
Normal file
3
resources/assets/statics/public/tools/map/empty.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1" height="1" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 122 B |
31
resources/assets/statics/public/tools/map/index.html
Normal file
31
resources/assets/statics/public/tools/map/index.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
|
<title></title>
|
||||||
|
<!-- 百度地图API -->
|
||||||
|
<link rel="stylesheet" href="./style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-box">
|
||||||
|
<div class="search-input-wrapper">
|
||||||
|
<svg class="search-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M950.784 899.584l-168.448-167.936c64.512-74.752 99.84-168.96 99.84-268.8 0-110.08-43.008-212.992-120.32-290.816S581.12 51.2 471.552 51.2c-110.08 0-212.992 43.008-290.816 120.32-77.824 77.824-120.832 181.248-120.832 291.328s43.008 212.992 120.32 290.816c77.824 77.824 181.248 120.32 290.816 120.32 90.624 0 177.152-29.184 248.32-82.944l169.984 169.984c8.192 8.192 19.456 12.8 30.72 12.8s22.016-4.096 30.72-12.8c16.896-16.896 16.896-44.544 0-61.44zM146.432 462.848C146.432 283.648 292.352 138.24 471.04 138.24c179.2 0 324.608 145.92 324.608 324.608 0 179.2-145.408 324.608-324.608 324.608s-324.608-145.92-324.608-324.608z" fill="#646A73"></path>
|
||||||
|
</svg>
|
||||||
|
<input type="text" id="search-input" placeholder="" enterkeyhint="search">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="map-container"></div>
|
||||||
|
<div id="address-list" class="address-list">
|
||||||
|
<h3 id="address-label"></h3>
|
||||||
|
<ul id="poi-list"></ul>
|
||||||
|
</div>
|
||||||
|
<div class="loading">
|
||||||
|
<div class="loading-spinner"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="./main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
404
resources/assets/statics/public/tools/map/main.js
vendored
Normal file
404
resources/assets/statics/public/tools/map/main.js
vendored
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
class LocationPicker {
|
||||||
|
constructor() {
|
||||||
|
this.map = null;
|
||||||
|
this.marker = null;
|
||||||
|
this.geolocation = null;
|
||||||
|
this.localSearch = null;
|
||||||
|
this.currentPoint = null;
|
||||||
|
this.loadNum = 0;
|
||||||
|
this.config = {
|
||||||
|
key: null, // 百度地图 API Key
|
||||||
|
title: null, // 页面标题,如:选择打卡地点
|
||||||
|
label: null, // 搜索列表标签,如:附近的地点
|
||||||
|
placeholder: null, // 搜索框占位符,如:搜索附近的地点
|
||||||
|
point: null, // 初始坐标,如:116.404,39.915
|
||||||
|
noresult: null, // 无搜索结果提示,如:附近没有找到地点
|
||||||
|
radius: 300, // 搜索半径,单位:300
|
||||||
|
zoom: 16, // 地图缩放级别
|
||||||
|
errtip: null, // 定位失败提示
|
||||||
|
errclose: false, // 定位失败是否关闭页面
|
||||||
|
channel: null, // 回传数据通道
|
||||||
|
selectclose: false, // 选择地点是否关闭页面
|
||||||
|
};
|
||||||
|
this.init().then(() => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
// 先初始化参数
|
||||||
|
this.initParams();
|
||||||
|
|
||||||
|
// 如果没有 key,直接返回
|
||||||
|
if (!this.config.key) {
|
||||||
|
console.error('未提供百度地图 API Key');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 等待地图 JS 加载完成
|
||||||
|
await this.loadBaiduMapScript();
|
||||||
|
// 初始化地图
|
||||||
|
this.initMap();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载百度地图失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initParams() {
|
||||||
|
// 获取当前URL的查询参数
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
// 遍历 config 对象的所有属性
|
||||||
|
Object.keys(this.config).forEach(key => {
|
||||||
|
// 从 URL 参数中获取值
|
||||||
|
const value = urlParams.get(key);
|
||||||
|
if (value !== null) {
|
||||||
|
// 根据参数类型进行转换
|
||||||
|
switch (key) {
|
||||||
|
case 'radius':
|
||||||
|
// 转换为数字
|
||||||
|
this.config[key] = parseInt(value) || 300;
|
||||||
|
break;
|
||||||
|
case 'point':
|
||||||
|
// 转换为坐标数组
|
||||||
|
const [lng, lat] = value.replace(/[|-]/, ',').split(',').map(parseFloat);
|
||||||
|
if (lng && lat) {
|
||||||
|
this.config[key] = {lng, lat};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 字符串类型直接赋值
|
||||||
|
this.config[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置标题
|
||||||
|
if (this.config.title) {
|
||||||
|
document.title = this.config.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置搜索框占位符
|
||||||
|
if (this.config.placeholder) {
|
||||||
|
document.getElementById('search-input').placeholder = this.config.placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置label
|
||||||
|
if (this.config.label) {
|
||||||
|
document.getElementById('address-label').innerText = this.config.label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initMap() {
|
||||||
|
// 初始化地图
|
||||||
|
this.map = new BMap.Map('map-container');
|
||||||
|
|
||||||
|
// 创建定位控件
|
||||||
|
const locationControl = new BMap.GeolocationControl({
|
||||||
|
anchor: BMAP_ANCHOR_BOTTOM_RIGHT,
|
||||||
|
showAddressBar: false,
|
||||||
|
enableAutoLocation: false,
|
||||||
|
locationIcon: new BMap.Icon("empty.svg", new BMap.Size(0, 0))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听定位事件
|
||||||
|
locationControl.addEventListener("locationSuccess", (e) => {
|
||||||
|
// 定位成功事件
|
||||||
|
this.updateCurrentPoint(e.point);
|
||||||
|
});
|
||||||
|
|
||||||
|
locationControl.addEventListener("locationError", (e) => {
|
||||||
|
// 定位失败事件
|
||||||
|
console.error('定位失败:', e.message);
|
||||||
|
this.locationError();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加定位控件到地图
|
||||||
|
this.map.addControl(locationControl);
|
||||||
|
|
||||||
|
// 初始化本地搜索,移除地图渲染
|
||||||
|
this.localSearch = new BMap.LocalSearch(this.map, {
|
||||||
|
renderOptions: {
|
||||||
|
autoViewport: false // 关闭自动视野调整
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置地图中心点
|
||||||
|
if (this.config.point) {
|
||||||
|
const {lng, lat} = this.config.point;
|
||||||
|
this.config.point = new BMap.Point(lng, lat);
|
||||||
|
// 设置地图中心点和缩放级别
|
||||||
|
this.map.centerAndZoom(this.config.point, this.config.zoom);
|
||||||
|
// 创建圆形区域
|
||||||
|
const circle = new BMap.Circle(this.config.point, this.config.radius, {
|
||||||
|
fillColor: "#333333",
|
||||||
|
fillOpacity: 0.1,
|
||||||
|
strokeColor: "#333333",
|
||||||
|
strokeWeight: 1,
|
||||||
|
strokeOpacity: 0.3
|
||||||
|
});
|
||||||
|
this.map.addOverlay(circle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定事件
|
||||||
|
this.bindEvents();
|
||||||
|
|
||||||
|
// 初始化时自动定位
|
||||||
|
this.getCurrentLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents() {
|
||||||
|
const searchInput = document.getElementById('search-input');
|
||||||
|
|
||||||
|
// 监听回车键
|
||||||
|
searchInput.addEventListener('keyup', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
searchInput.blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听失去焦点
|
||||||
|
searchInput.addEventListener('blur', () => {
|
||||||
|
this.searchAddress();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentLocation() {
|
||||||
|
this.loaderShow();
|
||||||
|
this.geolocation = new BMap.Geolocation();
|
||||||
|
this.geolocation.getCurrentPosition((result) => {
|
||||||
|
this.loaderHide();
|
||||||
|
if (result && result.point) {
|
||||||
|
this.updateCurrentPoint(result.point)
|
||||||
|
} else {
|
||||||
|
console.error('定位失败');
|
||||||
|
this.locationError();
|
||||||
|
}
|
||||||
|
}, {enableHighAccuracy: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCurrentPoint(point) {
|
||||||
|
this.currentPoint = point;
|
||||||
|
this.map.centerAndZoom(this.currentPoint, this.config.zoom);
|
||||||
|
this.updateMarker(this.currentPoint);
|
||||||
|
this.searchNearby();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMarker(point) {
|
||||||
|
if (this.marker) {
|
||||||
|
this.marker.setPosition(point);
|
||||||
|
} else {
|
||||||
|
this.marker = new BMap.Marker(point);
|
||||||
|
this.map.addOverlay(this.marker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
searchAddress() {
|
||||||
|
const keyword = document.getElementById('search-input').value;
|
||||||
|
this.searchNearby(keyword ? [keyword] : []);
|
||||||
|
}
|
||||||
|
|
||||||
|
searchNearby(keywords = [], retryCount = 0) {
|
||||||
|
// 当前位置未获取
|
||||||
|
if (this.currentPoint === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除之前的搜索结果
|
||||||
|
this.localSearch.clearResults();
|
||||||
|
|
||||||
|
// 搜索附近的关键词
|
||||||
|
if (keywords.length === 0) {
|
||||||
|
keywords = ["写字楼", "公司", "银行", "餐馆", "商场", "超市", "学校", "医院", "公交站", "地铁站"]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义一个随机数,用于判断定时器是否过期
|
||||||
|
this.searchRandom = Math.random();
|
||||||
|
|
||||||
|
// 设置搜索完成回调
|
||||||
|
this.loaderShow();
|
||||||
|
this.localSearch.setSearchCompleteCallback((results) => {
|
||||||
|
this.loaderHide();
|
||||||
|
if (this.localSearch.getStatus() !== BMAP_STATUS_SUCCESS) {
|
||||||
|
// 搜索失败
|
||||||
|
if (retryCount < 60) {
|
||||||
|
const tmpRand = this.searchRandom;
|
||||||
|
this.loaderShow();
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loaderHide();
|
||||||
|
tmpRand === this.searchRandom && this.searchNearby(keywords, ++retryCount);
|
||||||
|
}, 1000)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 搜索结果
|
||||||
|
document.getElementById('address-list').style.display = 'block';
|
||||||
|
const array = [];
|
||||||
|
if (results instanceof Array) {
|
||||||
|
results.some(result => {
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < result.getCurrentNumPois(); i++) {
|
||||||
|
const poi = result.getPoi(i);
|
||||||
|
poi._distance = this.config.point ? this.map.getDistance(this.config.point, poi.point) : null;
|
||||||
|
array.push(poi);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.updatePoiList(array);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 执行搜索
|
||||||
|
this.localSearch.searchNearby(keywords, this.currentPoint, this.config.radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePoiList(results) {
|
||||||
|
const poiList = document.getElementById('poi-list');
|
||||||
|
poiList.innerHTML = '';
|
||||||
|
|
||||||
|
// 如果没有搜索结果
|
||||||
|
if (results.length === 0 && this.config.noresult) {
|
||||||
|
poiList.innerHTML = '<li>' + this.config.noresult + '</li>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按距离排序(如果有距离信息)
|
||||||
|
results.sort((a, b) => {
|
||||||
|
if (a._distance && b._distance) {
|
||||||
|
return a._distance - b._distance;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
results = results.slice(0, 20);
|
||||||
|
|
||||||
|
// 创建列表项
|
||||||
|
results.forEach(poi => {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
const distance = poi._distance ? `<div class="address-distance">${this.convertDistance(Math.round(poi._distance))}</div>` : '';
|
||||||
|
li.innerHTML = `
|
||||||
|
<div class="address-name">${poi.title}</div>
|
||||||
|
<div class="address-detail">${poi.address || ""}${distance}</div>
|
||||||
|
`;
|
||||||
|
li.addEventListener('click', () => {
|
||||||
|
const point = poi.point;
|
||||||
|
this.updateMarker(point);
|
||||||
|
this.map.setCenter(point);
|
||||||
|
//
|
||||||
|
if (typeof requireModuleJs === "function") {
|
||||||
|
const eeui = requireModuleJs("eeui");
|
||||||
|
eeui.setVariate("location::" + this.config.channel, JSON.stringify(poi))
|
||||||
|
}
|
||||||
|
if (this.config.selectclose) {
|
||||||
|
this.closePage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
poiList.appendChild(li);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 列表更新后,重新将当前标记点居中显示
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.marker) {
|
||||||
|
this.map.setCenter(this.marker.getPosition());
|
||||||
|
}
|
||||||
|
}, 100); // 添加小延时确保DOM已更新
|
||||||
|
}
|
||||||
|
|
||||||
|
convertDistance(d) {
|
||||||
|
if (d > 1000) {
|
||||||
|
return (d / 1000).toFixed(1) + 'km';
|
||||||
|
}
|
||||||
|
return d.toFixed(0) + 'm';
|
||||||
|
}
|
||||||
|
|
||||||
|
locationError() {
|
||||||
|
if (this.config.errtip) {
|
||||||
|
alert(this.config.errtip);
|
||||||
|
}
|
||||||
|
if (this.config.errclose) {
|
||||||
|
this.closePage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loaderShow() {
|
||||||
|
this.loadNum++;
|
||||||
|
this.loaderJudge();
|
||||||
|
}
|
||||||
|
|
||||||
|
loaderHide() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loadNum--;
|
||||||
|
this.loaderJudge();
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
loaderJudge() {
|
||||||
|
if (this.loadNum > 0) {
|
||||||
|
document.querySelector('.loading').classList.add('show');
|
||||||
|
} else if (this.loadNum <= 0) {
|
||||||
|
document.querySelector('.loading').classList.remove('show');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closePage() {
|
||||||
|
try {
|
||||||
|
// 方法1: 如果是在 eeui 环境中
|
||||||
|
if (typeof requireModuleJs === "function") {
|
||||||
|
const eeui = requireModuleJs("eeui");
|
||||||
|
eeui.closePage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法2: 如果是从其他页面打开的,可以关闭当前窗口
|
||||||
|
window.close();
|
||||||
|
|
||||||
|
// 方法3: 如果是在 iOS WKWebView 中
|
||||||
|
try {
|
||||||
|
window.webkit.messageHandlers.closeWindow.postMessage(null);
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// 方法4: 如果是在 Android WebView 中
|
||||||
|
try {
|
||||||
|
window.android.closeWindow();
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// 方法5: 如果以上方法都失败,返回上一页
|
||||||
|
window.history.back();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('关闭页面失败', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadBaiduMapScript() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 如果已经加载过,直接返回
|
||||||
|
if (window.BMap) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建script标签
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.type = 'text/javascript';
|
||||||
|
script.src = `https://api.map.baidu.com/api?v=3.0&ak=${this.config.key}&callback=initBaiduMap`;
|
||||||
|
|
||||||
|
// 添加回调函数
|
||||||
|
window.initBaiduMap = () => {
|
||||||
|
resolve();
|
||||||
|
delete window.initBaiduMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理加载错误
|
||||||
|
script.onerror = () => {
|
||||||
|
reject(new Error('百度地图脚本加载失败'));
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加到页面
|
||||||
|
document.body.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
new LocationPicker();
|
||||||
|
});
|
||||||
170
resources/assets/statics/public/tools/map/style.css
vendored
Normal file
170
resources/assets/statics/public/tools/map/style.css
vendored
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||||
|
position: relative;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #EEF1F2;
|
||||||
|
border-radius: 6px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-icon {
|
||||||
|
margin: 0 10px 0 12px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-input {
|
||||||
|
flex: 1;
|
||||||
|
width: 0;
|
||||||
|
padding: 8px 8px 8px 0;
|
||||||
|
font-size: 15px;
|
||||||
|
border: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
outline: none;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
-webkit-user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#map-container {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-list {
|
||||||
|
display: none;
|
||||||
|
min-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-list h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 12px 14px 10px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#poi-list {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#poi-list li {
|
||||||
|
padding: 10px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#poi-list li::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
#poi-list li::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 1px;
|
||||||
|
background-color: #eee;
|
||||||
|
transform: scaleY(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#poi-list li:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-detail {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.address-distance {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #999;
|
||||||
|
float: right;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
.loading {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 1000;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-top-color: #fff;
|
||||||
|
border-left-color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user