diff --git a/app/Models/UserBot.php b/app/Models/UserBot.php index 495b3b58d..2b264ea19 100644 --- a/app/Models/UserBot.php +++ b/app/Models/UserBot.php @@ -207,6 +207,9 @@ class UserBot extends AbstractModel if (!in_array('locat', $setting['modes'])) { return '暂未开放定位签到。'; } + if (empty($extra)) { + return '当前客户端版本低(所需版本≥v0.39.75)。'; + } if ($extra['type'] === 'bd') { // todo 判断距离 } else { diff --git a/language/original-api.txt b/language/original-api.txt index 3f9d439ce..7810b6a2f 100644 --- a/language/original-api.txt +++ b/language/original-api.txt @@ -723,7 +723,6 @@ webhook地址最长仅支持255个字符。 请填写百度地图AK 请选择允许签到位置 请选择有效的签到位置 -暂未开启签到功能。 暂未开放定位签到。 错误的定位签到。 获取地图快照失败 diff --git a/language/original-web.txt b/language/original-web.txt index 3f632b312..7147c9146 100644 --- a/language/original-web.txt +++ b/language/original-web.txt @@ -1764,13 +1764,6 @@ WiFi签到延迟时长为±1分钟。 以后再说 立即更新 -签到地点 -选择附近地点 -搜索地点 -附近没有找到地点 -定位失败 - -签到地点 选择附近地点 搜索地点 附近没有找到地点 @@ -1791,3 +1784,6 @@ WiFi签到延迟时长为±1分钟。 请先填写百度地图AK 你当前是负责人,确定要转为协助人员吗? +仅支持移动端App +暂未开放定位签到。 +错误的定位签到。 diff --git a/language/translate.json b/language/translate.json index 7b2a3c6e0..a8107e46a 100644 --- a/language/translate.json +++ b/language/translate.json @@ -25955,18 +25955,6 @@ "id": "Kata Bijak: (%T1)", "ru": "Душеподъемная цитата: (%T1)" }, - { - "key": "签到地点", - "zh": "", - "zh-CHT": "簽到地點", - "en": "Check-in Location", - "ko": "출석 장소", - "ja": "チェックイン場所", - "de": "Eingetragener Ort", - "fr": "Lieu d'enregistrement", - "id": "Lokasi Check-in", - "ru": "Место регистрации" - }, { "key": "选择附近地点", "zh": "", @@ -26279,4 +26267,4 @@ "id": "Anda saat ini adalah orang yang bertanggung jawab. Apakah Anda yakin ingin beralih menjadi asisten?", "ru": "Вы в данный момент являетесь ответственным лицом. Уверены, что хотите перейти в помощники?" } -] \ No newline at end of file +] diff --git a/public/tools/map/main.js b/public/tools/map/main.js index 0df1de222..1ca089696 100644 --- a/public/tools/map/main.js +++ b/public/tools/map/main.js @@ -290,7 +290,9 @@ class BaiduMapPicker { */ initMap() { // 初始化地图 - this.map = new BMap.Map('map-container'); + this.map = new BMap.Map('map-container', { + enableMapClick: false + }); // 初始化本地搜索,移除地图渲染 this.localSearch = new BMap.LocalSearch(this.map, { @@ -320,9 +322,7 @@ class BaiduMapPicker { this.bindEvents(); // 初始化时自动定位 - Loader.show(); this.getCurrentLocation().then((point) => { - Loader.hide(); if (point === null) { this.locationError(); } @@ -348,10 +348,7 @@ class BaiduMapPicker { // 地图定位点击事件 const mapLocation = document.getElementById('map-location'); mapLocation.addEventListener('click', () => { - Loader.show() - this.getCurrentLocation().then(() => { - Loader.hide() - }); + this.getCurrentLocation(); }); } @@ -361,7 +358,9 @@ class BaiduMapPicker { */ getCurrentLocation() { return new Promise(resolve => { + Loader.show() App.getLocation().then(res => { + Loader.hide() if (App.isJson(res) && res.longitude && res.latitude) { const bd09_coord = CoordTransform.wgs84toBd09(res.longitude, res.latitude); const point = new BMap.Point(bd09_coord[0], bd09_coord[1]); @@ -381,9 +380,13 @@ class BaiduMapPicker { */ updateCurrentPoint(point) { this.currentPoint = point; - this.map.centerAndZoom(this.currentPoint, this.params.zoom); + if (Math.abs(this.map.getZoom() - this.params.zoom) > 1) { + this.map.centerAndZoom(this.currentPoint, this.params.zoom); + } else { + this.map.setCenter(this.currentPoint); + } this.updateMarker(this.currentPoint); - this.searchNearby(); + this.searchAddress(); } /** @@ -403,95 +406,134 @@ class BaiduMapPicker { * 搜索地址 */ searchAddress() { - const keyword = document.getElementById('search-input').value; - this.searchNearby(keyword ? [keyword] : []); + const keyword = `${document.getElementById('search-input').value}`.trim(); + if (keyword) { + this.searchKeyword(this.currentPoint, keyword); + } else { + this.searchLocation(this.currentPoint); + } } /** - * 搜索附近的地点 - * @param keywords + * 通过关键词搜索附近的地点 + * @param centerPoint + * @param keyword * @param retryCount */ - searchNearby(keywords = [], retryCount = 0) { - // 当前位置未获取 - if (this.currentPoint === null) { - return; - } - + searchKeyword(centerPoint, keyword, retryCount = 0) { // 清除之前的搜索结果 this.localSearch.clearResults(); - // 搜索附近的关键词 - if (keywords.length === 0) { - keywords = ["写字楼", "公司", "银行", "餐馆", "商场", "超市", "学校", "医院", "公交站", "地铁站"] - } - // 定义一个随机数,用于判断定时器是否过期 this.searchRandom = Math.random(); // 设置搜索完成回调 Loader.show(); - this.localSearch.setSearchCompleteCallback((results) => { + this.localSearch.setSearchCompleteCallback(result => { Loader.hide(); if (this.localSearch.getStatus() !== BMAP_STATUS_SUCCESS) { - // 搜索失败 - if (retryCount < 60) { + // 搜索失败,10次重试 + if (retryCount < 10) { const tmpRand = this.searchRandom; Loader.show(); setTimeout(() => { Loader.hide(); - tmpRand === this.searchRandom && this.searchNearby(keywords, ++retryCount); - }, 1000) + tmpRand === this.searchRandom && this.searchKeyword(centerPoint, keyword, ++retryCount); + }, 300) 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.params.point ? this.map.getDistance(this.params.point, poi.point) : null; - array.push(poi); - } - }); + const pois = []; + for (let i = 0; i < result.getCurrentNumPois(); i++) { + const poi = result.getPoi(i); + if (!poi.point) { + continue; + } + poi.distance = this.params.point ? this.map.getDistance(this.params.point, poi.point) : null; + poi.distance_current = this.map.getDistance(centerPoint, poi.point); + pois.push(poi); } - this.updatePoiList(array); + this.updatePoiList(pois); }); // 执行搜索 - this.localSearch.searchNearby(keywords, this.currentPoint, this.params.radius); + this.localSearch.searchNearby(keyword, centerPoint, this.params.radius); + } + + /** + * 通过坐标搜索附近的地点 + * @param point + */ + searchLocation(point) { + const geoc = new BMap.Geocoder(); + Loader.show(); + geoc.getLocation(point, (result) => { + Loader.hide(); + const pois = []; + if (result) { + // 搜索结果 + const surroundingPois = result.surroundingPois || []; + if (surroundingPois.length === 0) { + surroundingPois.push({ + title: result.addressComponents.city + result.addressComponents.district, + address: result.address, + point: result.point, + }); + } + surroundingPois.some(poi => { + if (!poi.point) { + return false; + } + poi.distance = this.params.point ? this.map.getDistance(this.params.point, poi.point) : null; + poi.distance_current = this.map.getDistance(point, poi.point); + pois.push(poi); + }) + } + this.updatePoiList(pois) + }, { + poiRadius: this.params.radius, + numPois: 20, + }); } /** * 更新搜索结果列表 - * @param results + * @param pois */ - updatePoiList(results) { + updatePoiList(pois) { + const addressList = document.getElementById('address-list'); + addressList.style.display = 'block'; + const poiList = document.getElementById('poi-list'); poiList.innerHTML = ''; // 如果没有搜索结果 - if (results.length === 0 && this.params.noresult) { - poiList.innerHTML = '
  • ' + this.params.noresult + '
  • '; + if (pois.length === 0) { + if (this.params.noresult) { + poiList.innerHTML = '
  • ' + this.params.noresult + '
  • '; + } return; } + // 筛选距离小于搜索半径的结果(+100) + pois = pois.filter(poi => { + return poi.title && poi.point && poi.distance_current < this.params.radius + 100; + }); + // 按距离排序(如果有距离信息) - results.sort((a, b) => { - if (a.distance && b.distance) { - return a.distance - b.distance; + pois.sort((a, b) => { + if (a.distance_current && b.distance_current) { + return a.distance_current - b.distance_current; } return 0; }); - results = results.slice(0, 20); + + // 只显示前20个结果 + pois = pois.slice(0, 20); // 创建列表项 - results.forEach(poi => { + pois.forEach(poi => { const li = document.createElement('li'); const distanceFormat = poi.distance ? `
    ${this.convertDistance(Math.round(poi.distance))}
    ` : ''; li.innerHTML = ` diff --git a/public/tools/map/style.css b/public/tools/map/style.css index bd4c69660..54f2bc9c6 100644 --- a/public/tools/map/style.css +++ b/public/tools/map/style.css @@ -29,7 +29,6 @@ body { .search-box { padding: 10px; background: #fff; - box-shadow: 0 2px 5px rgba(0,0,0,0.1); position: relative; z-index: 100; } @@ -121,6 +120,7 @@ body { #poi-list { list-style: none; + padding-bottom: 10px; } #poi-list li { @@ -147,8 +147,8 @@ body { transform: scaleY(0.5); } -#poi-list li:hover { - background: #f5f5f5; +#poi-list li:last-child::before { + display: none; } .address-name { diff --git a/resources/assets/js/pages/manage/setting/components/SystemCheckin.vue b/resources/assets/js/pages/manage/setting/components/SystemCheckin.vue index 1f50cced6..9c6390554 100644 --- a/resources/assets/js/pages/manage/setting/components/SystemCheckin.vue +++ b/resources/assets/js/pages/manage/setting/components/SystemCheckin.vue @@ -76,7 +76,7 @@
    {{$L('人脸签到')}}: {{$L('通过人脸识别机签到')}}
    {{$L('WiFi签到')}}: {{$L('详情看下文安装说明')}}
    -
    {{$L('定位签到')}}: {{$L('通过在签到打卡机器人发送位置签到')}}
    +
    {{$L('定位签到')}}: {{$L('通过在签到打卡机器人发送位置签到')}} ({{$L('仅支持移动端App')}})
    {{$L('手动签到')}}: {{$L('通过在签到打卡机器人发送指令签到')}}
    diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 409041659..64faf72b8 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -978,7 +978,7 @@ export default { openAppMapPage({dispatch}, objects) { return new Promise(resolve => { const params = { - title: $A.L("签到地点"), + title: $A.L("定位签到"), label: $A.L("选择附近地点"), placeholder: $A.L("搜索地点"), noresult: $A.L("附近没有找到地点"), @@ -986,6 +986,7 @@ export default { selectclose: "true", channel: $A.randomString(6) } + $A.eeuiAppSetVariate(`location::${params.channel}`, ""); const url = $A.urlAddParams($A.eeuiAppRewriteUrl('../public/tools/map/index.html'), Object.assign(params, objects || {})) dispatch('openAppChildPage', { pageType: 'app', @@ -997,9 +998,12 @@ export default { url }, callback: ({status}) => { - if (status === 'destroy') { + if (status === 'pause') { const data = $A.jsonParse($A.eeuiAppGetVariate(`location::${params.channel}`)); - resolve(data); + if (data.point) { + $A.eeuiAppSetVariate(`location::${params.channel}`, ""); + resolve(data); + } } } }) diff --git a/resources/assets/statics/public/tools/map/main.js b/resources/assets/statics/public/tools/map/main.js index 0df1de222..1ca089696 100644 --- a/resources/assets/statics/public/tools/map/main.js +++ b/resources/assets/statics/public/tools/map/main.js @@ -290,7 +290,9 @@ class BaiduMapPicker { */ initMap() { // 初始化地图 - this.map = new BMap.Map('map-container'); + this.map = new BMap.Map('map-container', { + enableMapClick: false + }); // 初始化本地搜索,移除地图渲染 this.localSearch = new BMap.LocalSearch(this.map, { @@ -320,9 +322,7 @@ class BaiduMapPicker { this.bindEvents(); // 初始化时自动定位 - Loader.show(); this.getCurrentLocation().then((point) => { - Loader.hide(); if (point === null) { this.locationError(); } @@ -348,10 +348,7 @@ class BaiduMapPicker { // 地图定位点击事件 const mapLocation = document.getElementById('map-location'); mapLocation.addEventListener('click', () => { - Loader.show() - this.getCurrentLocation().then(() => { - Loader.hide() - }); + this.getCurrentLocation(); }); } @@ -361,7 +358,9 @@ class BaiduMapPicker { */ getCurrentLocation() { return new Promise(resolve => { + Loader.show() App.getLocation().then(res => { + Loader.hide() if (App.isJson(res) && res.longitude && res.latitude) { const bd09_coord = CoordTransform.wgs84toBd09(res.longitude, res.latitude); const point = new BMap.Point(bd09_coord[0], bd09_coord[1]); @@ -381,9 +380,13 @@ class BaiduMapPicker { */ updateCurrentPoint(point) { this.currentPoint = point; - this.map.centerAndZoom(this.currentPoint, this.params.zoom); + if (Math.abs(this.map.getZoom() - this.params.zoom) > 1) { + this.map.centerAndZoom(this.currentPoint, this.params.zoom); + } else { + this.map.setCenter(this.currentPoint); + } this.updateMarker(this.currentPoint); - this.searchNearby(); + this.searchAddress(); } /** @@ -403,95 +406,134 @@ class BaiduMapPicker { * 搜索地址 */ searchAddress() { - const keyword = document.getElementById('search-input').value; - this.searchNearby(keyword ? [keyword] : []); + const keyword = `${document.getElementById('search-input').value}`.trim(); + if (keyword) { + this.searchKeyword(this.currentPoint, keyword); + } else { + this.searchLocation(this.currentPoint); + } } /** - * 搜索附近的地点 - * @param keywords + * 通过关键词搜索附近的地点 + * @param centerPoint + * @param keyword * @param retryCount */ - searchNearby(keywords = [], retryCount = 0) { - // 当前位置未获取 - if (this.currentPoint === null) { - return; - } - + searchKeyword(centerPoint, keyword, retryCount = 0) { // 清除之前的搜索结果 this.localSearch.clearResults(); - // 搜索附近的关键词 - if (keywords.length === 0) { - keywords = ["写字楼", "公司", "银行", "餐馆", "商场", "超市", "学校", "医院", "公交站", "地铁站"] - } - // 定义一个随机数,用于判断定时器是否过期 this.searchRandom = Math.random(); // 设置搜索完成回调 Loader.show(); - this.localSearch.setSearchCompleteCallback((results) => { + this.localSearch.setSearchCompleteCallback(result => { Loader.hide(); if (this.localSearch.getStatus() !== BMAP_STATUS_SUCCESS) { - // 搜索失败 - if (retryCount < 60) { + // 搜索失败,10次重试 + if (retryCount < 10) { const tmpRand = this.searchRandom; Loader.show(); setTimeout(() => { Loader.hide(); - tmpRand === this.searchRandom && this.searchNearby(keywords, ++retryCount); - }, 1000) + tmpRand === this.searchRandom && this.searchKeyword(centerPoint, keyword, ++retryCount); + }, 300) 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.params.point ? this.map.getDistance(this.params.point, poi.point) : null; - array.push(poi); - } - }); + const pois = []; + for (let i = 0; i < result.getCurrentNumPois(); i++) { + const poi = result.getPoi(i); + if (!poi.point) { + continue; + } + poi.distance = this.params.point ? this.map.getDistance(this.params.point, poi.point) : null; + poi.distance_current = this.map.getDistance(centerPoint, poi.point); + pois.push(poi); } - this.updatePoiList(array); + this.updatePoiList(pois); }); // 执行搜索 - this.localSearch.searchNearby(keywords, this.currentPoint, this.params.radius); + this.localSearch.searchNearby(keyword, centerPoint, this.params.radius); + } + + /** + * 通过坐标搜索附近的地点 + * @param point + */ + searchLocation(point) { + const geoc = new BMap.Geocoder(); + Loader.show(); + geoc.getLocation(point, (result) => { + Loader.hide(); + const pois = []; + if (result) { + // 搜索结果 + const surroundingPois = result.surroundingPois || []; + if (surroundingPois.length === 0) { + surroundingPois.push({ + title: result.addressComponents.city + result.addressComponents.district, + address: result.address, + point: result.point, + }); + } + surroundingPois.some(poi => { + if (!poi.point) { + return false; + } + poi.distance = this.params.point ? this.map.getDistance(this.params.point, poi.point) : null; + poi.distance_current = this.map.getDistance(point, poi.point); + pois.push(poi); + }) + } + this.updatePoiList(pois) + }, { + poiRadius: this.params.radius, + numPois: 20, + }); } /** * 更新搜索结果列表 - * @param results + * @param pois */ - updatePoiList(results) { + updatePoiList(pois) { + const addressList = document.getElementById('address-list'); + addressList.style.display = 'block'; + const poiList = document.getElementById('poi-list'); poiList.innerHTML = ''; // 如果没有搜索结果 - if (results.length === 0 && this.params.noresult) { - poiList.innerHTML = '
  • ' + this.params.noresult + '
  • '; + if (pois.length === 0) { + if (this.params.noresult) { + poiList.innerHTML = '
  • ' + this.params.noresult + '
  • '; + } return; } + // 筛选距离小于搜索半径的结果(+100) + pois = pois.filter(poi => { + return poi.title && poi.point && poi.distance_current < this.params.radius + 100; + }); + // 按距离排序(如果有距离信息) - results.sort((a, b) => { - if (a.distance && b.distance) { - return a.distance - b.distance; + pois.sort((a, b) => { + if (a.distance_current && b.distance_current) { + return a.distance_current - b.distance_current; } return 0; }); - results = results.slice(0, 20); + + // 只显示前20个结果 + pois = pois.slice(0, 20); // 创建列表项 - results.forEach(poi => { + pois.forEach(poi => { const li = document.createElement('li'); const distanceFormat = poi.distance ? `
    ${this.convertDistance(Math.round(poi.distance))}
    ` : ''; li.innerHTML = ` diff --git a/resources/assets/statics/public/tools/map/style.css b/resources/assets/statics/public/tools/map/style.css index bd4c69660..54f2bc9c6 100644 --- a/resources/assets/statics/public/tools/map/style.css +++ b/resources/assets/statics/public/tools/map/style.css @@ -29,7 +29,6 @@ body { .search-box { padding: 10px; background: #fff; - box-shadow: 0 2px 5px rgba(0,0,0,0.1); position: relative; z-index: 100; } @@ -121,6 +120,7 @@ body { #poi-list { list-style: none; + padding-bottom: 10px; } #poi-list li { @@ -147,8 +147,8 @@ body { transform: scaleY(0.5); } -#poi-list li:hover { - background: #f5f5f5; +#poi-list li:last-child::before { + display: none; } .address-name {