敢为人鲜小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
4.6 KiB

5 months ago
5 months ago
5 months ago
5 months ago
  1. import config from '../config.js'
  2. /**
  3. * 计算两点之间的距离
  4. * @param {number} lat1 地点1精度
  5. * @param {number} lon1 地点1维度
  6. * @param {number} lat2 地点2精度
  7. * @param {number} lon2 地点2维度
  8. * @param {number} fixed 保留几位小数,默认0,单位km
  9. */
  10. function calculateDistance(lat1, lon1, lat2, lon2, fixed = 0) { //计算两点距离
  11. let distance = 0
  12. if (!lat2 || !lon2) return distance
  13. //先强制转换一下(后端给的字符串)
  14. lat1 = parseFloat(lat1)
  15. lon1 = parseFloat(lon1)
  16. lat2 = parseFloat(lat2)
  17. lon2 = parseFloat(lon2)
  18. // 将角度转换为弧度
  19. const R = 6371; // 地球半径,单位公里
  20. const dLat = (lat2 - lat1) * Math.PI / 180;
  21. const dLon = (lon2 - lon1) * Math.PI / 180;
  22. lat1 = lat1 * Math.PI / 180;
  23. lat2 = lat2 * Math.PI / 180;
  24. // Haversine公式
  25. const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
  26. Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
  27. const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  28. // 计算距离
  29. distance = R * c;
  30. return distance.toFixed(fixed)
  31. }
  32. function getLocation(fn) { //获取用户经纬度
  33. wxGetLocation() //此方法只用于提示用户打开gps
  34. uni.getLocation({
  35. type: 'gcj02',
  36. isHighAccuracy: true,
  37. highAccuracyExpireTime: 1000,
  38. success: function(position) {
  39. fn(position)
  40. },
  41. fail: function() { //使用ip获取定位
  42. let key = config.mapKey; //腾讯地图key
  43. getUserAddressByIp(key).then(res => {
  44. fn(res.position) //返回经纬度
  45. }).catch(err => {
  46. uni.showToast({
  47. title: '获取位置失败',
  48. icon: 'error'
  49. })
  50. })
  51. }
  52. })
  53. }
  54. function getLocationDetail() { //获取用户详细地址
  55. wxGetLocation()
  56. return new Promise((resolve, reject) => {
  57. let key = config.mapKey; //腾讯地图key
  58. uni.getLocation({
  59. type: 'gcj02',
  60. isHighAccuracy: true,
  61. highAccuracyExpireTime: 1000,
  62. success: function(position) {
  63. getUserAddress(position.latitude, position.longitude, key).then(res => {
  64. resolve(res)
  65. })
  66. },
  67. fail: function() { //使用ip获取定位
  68. getUserAddressByIp(key).then(res => {
  69. resolve(res)
  70. })
  71. }
  72. })
  73. })
  74. }
  75. function getUserAddress(latitude, longitude, key) { //通过经纬度获取用户详细地址
  76. return new Promise((resolve, reject) => {
  77. let url = `/ws/geocoder/v1/?location=${latitude},${longitude}&key=${key}`
  78. // #ifndef H5
  79. url = `https://apis.map.qq.com` + url
  80. // #endif
  81. uni.request({
  82. url,
  83. success: (res) => {
  84. let {
  85. lat,
  86. lng
  87. } = res.data.result.ad_info.location;
  88. let data = {
  89. position: {
  90. latitude: lat,
  91. longitude: lng
  92. },
  93. addressDetail: res.data.result.ad_info
  94. }
  95. resolve(data)
  96. },
  97. fail(err) {
  98. reject(err)
  99. }
  100. })
  101. })
  102. }
  103. function getUserAddressByIp(key) { //根据IP获取当前用户位置
  104. return new Promise((resolve, reject) => {
  105. uni.request({
  106. url: 'https://api.ipify.org?format=json',
  107. success: (ipInfo) => {
  108. let url = `/ws/location/v1/ip?ip=${ipInfo.data.ip}&key=${key}`
  109. // #ifndef H5
  110. url = `https://apis.map.qq.com` + url
  111. // #endif
  112. uni.request({
  113. url,
  114. success: (res) => {
  115. console.log('根据IP获取当前用户位置',res);
  116. if (!res.data.result) {
  117. reject(new Error('根据IP获取当前用户位置失败'))
  118. return
  119. }
  120. let {
  121. lat,
  122. lng
  123. } = res.data.result.location;
  124. let data = {
  125. addressDetail: res.data.result.ad_info,
  126. ip: res.data.result.ip,
  127. position: {
  128. latitude: lat,
  129. longitude: lng
  130. }
  131. }
  132. resolve(data)
  133. },
  134. fail(err) {
  135. reject(err)
  136. }
  137. })
  138. }
  139. })
  140. })
  141. }
  142. //打开地图让用户选择位置
  143. function selectAddress(longitude, latitude, successCallback) {
  144. uni.chooseLocation({
  145. // longitude, //经度
  146. // latitude, //纬度
  147. success: function(res) {
  148. successCallback && successCallback(res)
  149. }
  150. });
  151. }
  152. //sdk自带获取位置方法(只支持微信环境),这里只当提示在用了(具体获取地址逻辑上面几个方法已完成)
  153. function wxGetLocation(successCallback, failCallback) {
  154. // #ifdef MP-WEIXIN
  155. // #endif
  156. console.log('wx.getLocation');
  157. wx.getLocation({
  158. type: 'gcj02',
  159. isHighAccuracy: true,
  160. highAccuracyExpireTime: 2000,
  161. success(res) {
  162. },
  163. fail(err) {
  164. if(err.errMsg == 'getLocation:gps closed'){
  165. uni.showToast({
  166. title: '请打开GPS定位,否则定位不准确',
  167. icon: 'none'
  168. })
  169. }
  170. }
  171. })
  172. }
  173. export default {
  174. calculateDistance, //计算两点距离
  175. getLocationDetail, //获取用户详细地址
  176. getLocation, //获取用户经纬度
  177. selectAddress, //打开地图让用户选择位置
  178. wxGetLocation,
  179. }