目录
- 微信小程序地图获取地点信息(打卡签到功能为例)
- 效果图
- 前提步骤
- 首先需要了解的
- 代码部分
- 配置性代码
- 功能性代码
- demo 下载
微信小程序地图获取地点信息(打卡签到功能为例)
解决方案:利用微信小程序的地图组件获取到用户的地理位置信息(经纬度),再通过腾讯地图 SDK 获取到对应的地理位置(即地名)
效果图
- 地图已打马赛克
前提步骤
首先需要了解的
-
微信小程序地图组件
-
腾讯地图简介(很简短,很重要)
- (需要小程序负责人去申请,不要用自己账号)跟着教程把 key 申请下来,后文要用
- 并且要在微信开放平台设置合法域名
- 我们需要下载 sdk,放在对应文件夹中,去引用它(即
qqmap-wx-jssdk.min.js
文件)
- (需要小程序负责人去申请,不要用自己账号)跟着教程把 key 申请下来,后文要用
代码部分
配置性代码
app.js 部分关键代码
- key 需要换成你自己申请的
//app.js
// 引入SDK核心类
var QQMapWX = require('/utils/qqmap-wx-jssdk.min.js')App({globalData: {// ..其他全局变量..patrolForm: {checkaddress: "",},// 实例化API核心类qqmapsdk: new QQMapWX({key: '这个key是你申请下来的key' // 必填}),// ..其他全局变量..},// 其他代码
})
app.json 部分关键代码(permission那个对象)
{"pages":["pages/location_check_in/location_check_in"],"window":{"backgroundTextStyle": "light","navigationBarBackgroundColor": "#3db0fc","navigationBarTitleText": "WeChat","navigationBarTextStyle": "white"},"style": "v2","sitemapLocation": "sitemap.json","permission": {"scope.userLocation": {"desc": "您的位置信息将用于小程序签到功能"}}
}
将 https://apis.map.qq.com
添加到小程序后台-开发-开发设置-服务器域名中
- 这个操作需要小程序管理员进到后台去配置
- 我们只需要在开发工具右上角 详情-本地设置 勾上 不校验合法域名........ 即可继续开发
功能性代码
页面代码:location_check_in.wxml
<!--location_check_in/location_check_in.wxml-->
<view class="wholeContinaer"><map id="myMap" markers="{{markers}}" style="width:100%;height:100vh;" longitude="{{poi.longitude}}" latitude="{{poi.latitude}}" scale='16' show-location></map><view class="checkInPanel"><!-- <view class="checkInBtn" bindtap="checkIn" style="background:url('../../images/zcxj/checkInBj.png') center / contain no-repeat"> --><view class="checkInBtn {{canClick ? '' : 'disableClick'}}" bindtap="checkIn"><view class="checkInTitle">签到</view><view class="checkInTime">{{time}}</view></view><!-- <view class="whitePositionPanel" style="background:url('../../images/zcxj/jxk.png') center / contain no-repeat"> --><view class="whitePositionPanel"><view class="positonTextRow"><image class="positionIcon" src="../../images/zcxj/positionIcon.png"></image><view class="positionFont">{{addressName}}</view></view></view><view class="rePosition" bindtap="rePosition"><image class="positionIcon" src="../../images/zcxj/rePosition.png"></image><view class="positionFont">重新定位</view></view></view>
</view>
样式代码:location_check_in.wxss
/* location_check_in/location_check_in.wxss */
Page{background-color: #f2f2f2;
}
.wholeContinaer{position: relative;height: 100vh;
}.mapContianer{background-color: turquoise;width: 100vw;height: 100vh;
}.checkInPanel{position: absolute;width: 705rpx;height: 520rpx;bottom: 25rpx;left: 25rpx;/* background-color: #ffffff; */
}
.checkInBtn{width: 280rpx;height: 280rpx;display: flex;align-items: center;justify-content: center;flex-direction: column;position: absolute;left: calc(50% - 140rpx);z-index: 12;border-radius: 50%;background-image: linear-gradient(180deg, #00a0e9 0%, #0095e9 73%, #0089e9 100%);box-shadow: 0 0 10rpx 0rpx #0089e9;/* margin: 0 auto; */
}
.disableClick{pointer-events: none;
}
.checkInTitle{font-size: 36rpx;line-height: 34rpx;color: #ffffff;
}
.checkInTime{font-size: 24rpx;line-height: 34rpx;color: #8cd7fe;margin-top: 10rpx;
}.whitePositionPanel{width: 100%;height: 412rpx;position: absolute;bottom: 0rpx;background-color: #ffffff;border-radius: 10rpx;display: flex;align-items: center;justify-content: center;
}.positonTextRow{display: flex;align-items: center;justify-content: center;margin-top: 80rpx;
}
.positonTextRow .positionIcon{width: 20rpx;height: 26rpx;margin-right: 10rpx;
}
.positonTextRow .positionFont{font-size: 22rpx;line-height: 29rpx;color: #9c9c9c;
}.rePosition{width: 130rpx;height: 35rpx;background-color: #ffffff;border-radius: 10rpx;display: flex;align-items: center;justify-content: center;position: absolute;top: 60rpx;
}
.rePosition .positionIcon{width: 24rpx;height: 24rpx;margin-right: 10rpx;
}
.rePosition .positionFont{font-size: 18rpx;color: #333333;line-height: 35rpx;
}
逻辑代码:location_check_in.js
- 逆地址解析(坐标位置描述)函数官方文档:reverseGeocoder(options:Object)
- realyCheckIn 函数为业务逻辑代码,此前已经获取到了地理位置,缺少了部分前置业务代码,会导致代码报错,改成你自己的就好
// location_check_in/location_check_in.js
const util = require('../../utils/util')
const app = getApp()
const urlList = require("../../utils/api.js") // 根据实际项目自己配置// 实例化API核心类
const qqmapsdk = app.globalData.qqmapsdkPage({/*** 页面的初始数据*/data: {markers: '',poi: {latitude: '',longitude: ''},addressName: '',time: '',timer: '',timer2: '', // 用来每个一段时间自动刷新一次定位canClick: true},getAddress(e) {var that = this;qqmapsdk.reverseGeocoder({//位置坐标,默认获取当前位置,非必须参数/*** location: {latitude: 39.984060,longitude: 116.307520},*/// 成功后的回调success: function(res) {// console.log(res);that.setData({addressName: res.result.address})var res = res.result;var mks = [];//当get_poi为0时或者为不填默认值时,检索目标位置,按需使用mks.push({ // 获取返回结果,放到mks数组中title: res.address,id: 0,latitude: res.location.lat,longitude: res.location.lng,iconPath: '../../images/zcxj/myPosition.png', // 图标路径width: 21,height: 28,// callout: { //在markers上展示地址名称,根据需求是否需要// content: res.address,// color: '#000',// display: 'ALWAYS'// }});that.setData({ // 设置markers属性和地图位置poi,将结果在地图展示markers: mks,poi: {latitude: res.location.lat,longitude: res.location.lng}});},fail: function(error) {console.error(error);},complete: function(res) {console.log(res);}})},getTime: function () {let that = thislet time = that.data.timethat.setData({timer: setInterval(function () {time = util.formatTime(new Date())that.setData({time: time.substr(-8)});if (time == 0) {// 页面跳转后,要把定时器清空掉,免得浪费性能clearInterval(that.data.timer)}}, 1000)})},rePosition: function () {console.log('用户点了重新定位')this.getAddress()},checkIn: function () {this.setData({canClick: false})console.log('用户点击了签到')var that = thisvar nowTime = util.formatTime(new Date())wx.showModal({title: '请确认打卡信息',// content: '请确认待整改项已整改完毕!',content: `地点:${this.data.addressName}\n时间:${nowTime}`, // 开发者工具上没有换行,真机调试时会有的confirmText: '确认',success (res) {if (res.confirm) {console.log('用户点击确定')// 调起签到接口that.realyCheckIn()} else if (res.cancel) {console.log('用户点击取消')that.setData({canClick: true})}}})},realyCheckIn: function() {var that = thisvar patrolForm = app.globalData.patrolForm // 其他需要一并提交过去的业务数据console.log(app.globalData)// debugger// 要在这里给 patrolForm 补充其他的参数patrolForm.checkaddress = this.data.addressNamepatrolForm.searchtime = util.formatTime(new Date())// 应该先判断用户有没有登录,没登录就授权登录patrolForm.searchuser = app.globalData.user ? app.globalData.user.UserName : app.globalData.userInfo.nickNameconsole.log("传给后台的 searchuser:", patrolForm.searchuser)// 拼接:"经度,纬度"patrolForm.latandlon = this.data.poi.longitude + "," + this.data.poi.latitudeconsole.log(patrolForm)console.log("↑ 签到提交的post参数")var tmpNumber = 0wx.request({url: urlList.submitCheckInInfo,data: patrolForm,method: "POST",header: {'content-type': 'application/x-www-form-urlencoded'},success: function (res) {console.log(res)if(res.data.IsSuccess) {console.log(res.data.IsSuccess, typeof(res.data.IsSuccess))console.log("请求成功")var patrolId = res.data.ReturnData[0].id// // 看怎么取到返回的id// debuggerif (patrolForm.img_arr1.length > 0) {for (var i = 0; i < patrolForm.img_arr1.length; i++){tmpNumber = iwx.uploadFile({// 图片上传的接口地址url: urlList.submitCheckInPhoto + "?patrolid=" + patrolId,filePath: patrolForm.img_arr1[i],name: 'content',// formData: {// // 这里面可以携带一些参数一并传过去// patrolId: patrolId// },// header: {// Authorization: token// },success: function (res) {console.log(res)},fail: function (res) {that.setData({canClick: true})},complete: function () {// 因为上传图片是异步操作,所以会导致这里的 i 会取不到,故需要用个作用域更大点的变量来标识,否则 if 里面的代码不会执行if(tmpNumber === patrolForm.img_arr1.length - 1) {// 有图片就等图片上传完了再返回首页wx.showToast({title: '巡查签到成功!',icon: 'success',duration: 2000,complete: function(){wx.navigateBack({delta: 2 // 回退两层页面})}})}}})}} else{wx.showToast({title: '巡查签到成功!',icon: 'success',duration: 2000,complete: function(){wx.navigateBack({delta: 2})}})}}},fail: function(res) {that.setData({canClick: true})}})},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {var that = thisthat.getTime()that.getAddress()that.setData({canClick: true, // 允许用户点击,防止多次提交timer2: setInterval(function () {that.getAddress()}, 20000) // 每20秒刷新一次定位})},/*** 生命周期函数--监听页面卸载*/onUnload: function () {clearInterval(this.data.timer)clearInterval(this.data.timer2)console.log("定时器已被清除")},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {},/*** 生命周期函数--监听页面显示*/onShow: function () {},/*** 生命周期函数--监听页面隐藏*/onHide: function () {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh: function () {},/*** 页面上拉触底事件的处理函数*/onReachBottom: function () {},/*** 用户点击右上角分享*/onShareAppMessage: function () {}
})
demo 下载
gitee地址:微信小程序打卡定位签到: 微信小程序打卡定位签到代码
如果对你有帮助,还请帮忙点个 star!