微信小程序实现位置对比和人脸识别(需后端)
我们在微信小程序项目比如签到功能中可能需要用到位置对比和人脸识别,而小程序自带的人脸识别接口不好申请(作为学生来说),而就可以让后端写几个接口进行对接完成位置对比和人脸识别。下面开始介绍前端部分的实现。
因为涉及个人信息,所以后端需要对每个用户赋予不同的id进行识别,用户访问后端接口都需要上传自己的id,而这部分信息我们通过token上传,但是因为app.js和其他页面的jsfang访问速度后端不一样,通常是其他页面的js访问的快一些,所以在app.js里面获取token可能造成错误的现象,所以在app.js内设置回调函数,其他页面在onShow或onLoad里面先检查是否已获得token,如果没有则访问回调函数去获取token。
app.js
App({globalData:{taskid:'',Token:"",userid:'',userInfo: null,user:{},},onLaunch() {// 展示本地存储能力const logs = wx.getStorageSync('logs') || []logs.unshift(Date.now())wx.setStorageSync('logs', logs)var that=this// 登录wx.showLoading({title: '加载中',})wx.login({success: res => {console.log(res.code)wx.request({url:'http://43.142.99.39:99/api/wechatLogin/'+res.code, //必填,其他的都可以不填data:{ },// header:{ // 'content-type':'application/json',// },method:'GET',// dataType:'JSON',// responseType:'text',success(res){console.log(res.data.item)var userid=res.data.item.user.id;//console.log(res.data)var token=res.data.item.token;that.globalData.userid=userid;that.globalData.Token=token;that.globalData.user=res.data.item.user;console.log('success');//console.log(userid,token)//console.log(that.globalData.Token)wx.hideLoading({success: (res) => {},})//回调函数if(that.userInfoCallback&&typeof that.userInfoCallback=='function'){that.userInfoCallback()}wx.showToast({title: '发布成功',icon: 'success',duration: 1000//持续的时间});setTimeout(()=>{wx.reLaunch({url: 'test?id=1'})},600 );},fail(){ console.log('fail')},complete(){ console.log('complete') }})}})},
}) 用户需要先上传签到的位置和个人的照片。
上传签到的位置:
需要先添加微信小程序使用地图的js文件
在utils文件夹内添加两份js文件
下载的链接:https://pan.baidu.com/s/1XgPj17-yBE93qmOFUspwAw
提取码:k0g6
add_location.wxml
add_location.js
var QQMapWX = require('../../utils/qqmap-wx-jssdk.min.js');
var app=getApp()
// 实例化API核心类
var qqmapsdk = new QQMapWX({key: 'JTPBZ-6AFK6-MTASH-E24LJ-RSNSH-F5BUB' // 必填
});Page({data:{token:'',id:'',//默认经纬度distance:[],name: '',address: '',latitude:26.05248089096305,longitude:119.19106543064117,latitude_t:'',longitude_t:'',},onShow(e){//此时需要判断全局数据是否获取到var that=this//如果已经获取到,则直接使用if(app.globalData.Token){console.log(app.globalData.Token)//如果此处的逻辑较多可以提炼为一个函数that.setData({token:app.globalData.Token,userid:app.globalData.userid})}else{//如果还未请求到数据,则创建一个回调函数,等待数据获取完成后调用app.userInfoCallback = res => {that.setData({token:app.globalData.Token,userid:app.globalData.userid})//console.log(that.data.token)}}//var that=thiswx.getLocation({type:"gcj02",// altitude: 'altitude',success(res){//console.log(res)that.setData({latitude:res.latitude,longitude:res.longitude,})}})},getLocation: function () {var token=this.data.tokenvar id=this.data.idvar _this = this;wx.chooseLocation({success: function (res) {//console.log(res.address)console.log(res)var name = res.namevar address = res.addressvar latitude = res.latitudevar longitude = res.longitude_this.setData({name: name,address: address,latitude_t: latitude,longitude_t: longitude})wx.request({url: 'https://www.web4j.top/location/insert',//这部分就是后端需要完成的内容,后端需要提供一个上传的接口data:{latitude:res.latitude,longitude:res.longitude},header:{'content-type':'application/json','Access-Token':token},method:"POST",success(res){console.log(res)},fail(){console.log('fail')}})},complete(r){console.log('complete')//console.log(222)}})},address(e){qqmapsdk.geocoder({address: e.detail.value, //用户输入的地址(注:地址中请包含城市名称,否则会影响解析效果),如:'北京市海淀区彩和坊路海淀西大街74号'complete: res => {console.log(res.result.location); //经纬度对象} ,// else{// console.log('无法定位到该地址,请确认地址信息!');// }})}
})
上传照片:
add_face.wxml
add_face.wxss
/* pages/face-recognition/face-recognition.wxss */
.camera{height: 600px;width: 100%;display: flex;justify-content: center;background-color: rgb(218, 214, 214);
}
.camera_c{margin-top: 30px;border-radius: 50%;height: 300px;width: 300px;
}
.whitephoto{margin-top: 30px;border-radius: 50%;height: 300px;width: 300px;
} add_face.js
var app=getApp()
// const token=app.globalData.Token;
// const user=app.globalData.user;
Page({/*** 页面的初始数据*/data: {userid:'',token:'',src:'https://gss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/902397dda144ad34ea5205bdd3a20cf431ad851f.jpg',flag_c:0,flag_f:1,flag_s:0,photo:'',},showcamera(){this.setData({flag_c:1,flag_f:0,flag_s:1})},takePhoto() {var id=this.data.useridvar token=this.data.token// console.log(token)var that=thisconst ctx = wx.createCameraContext()ctx.takePhoto({quality: 'high',success: (res) => {var path=res.tempImagePathconsole.log(path)this.setData({src: res.tempImagePath,flag_c:0})// console.log(path)wx.uploadFile({url: 'https://www.web4j.top/face-information/uploadPhoto',//这部分就是后端需要完成的内容,后端需要提供一个上传的接口filePath: path,name: 'file',header: {'content-type':'application/json','Access-Token':token},// formData: {// 'filename': 'img', //参数名// 'method':'post'// },success: (result) => {var records=JSON.parse(result.data);var photopath=records.item.filePathconsole.log(result.data);console.log(photopath);console.log('success');that.setData({photo:photopath})wx.request({url: 'https://www.web4j.top/face-information/insert',data:{userid:id,picture:photopath},header:{'content-type':'application/json','Access-Token':token},method:"POST",success(res){console.log(res)},fail(){console.log('fail')}})},fail(){console.log('fail');}})}})},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {//此时需要判断全局数据是否获取到var that=this//如果已经获取到,则直接使用if(app.globalData.Token){console.log(app.globalData.Token)//如果此处的逻辑较多可以提炼为一个函数that.setData({token:app.globalData.Token,userid:app.globalData.userid})}else{//如果还未请求到数据,则创建一个回调函数,等待数据获取完成后调用app.userInfoCallback = res => {that.setData({token:app.globalData.Token,userid:app.globalData.userid})//console.log(that.data.token)}}},/*** 生命周期函数--监听页面隐藏*/onHide() {},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
})
上传之后根据用户所处的位置与之前上传的位置(比如公司位置,宿舍位置,教学楼位置等)进行对比,如果在这范围内在进行人脸识别,否则无法进行人脸识别即也无法完成签到。
location_compare.wxml
location_compare.js
var app=getApp();
var QQMapWX = require('../../utils/qqmap-wx-jssdk.min.js');// 实例化API核心类
var qqmapsdk = new QQMapWX({key: 'JTPBZ-6AFK6-MTASH-E24LJ-RSNSH-F5BUB' // 必填
});Page({data:{token:"",//默认经纬度distance:[],name: '',address: '',latitude:26.05248089096305,longitude:119.19106543064117,latitude_t:'',longitude_t:'',},onShow(e){//此时需要判断全局数据是否获取到var that=this//如果已经获取到,则直接使用if(app.globalData.Token){// console.log(app.globalData.Token)//如果此处的逻辑较多可以提炼为一个函数that.setData({token:app.globalData.Token})var token=app.globalData.Tokenwx.getLocation({type:"gcj02",// altitude: 'altitude',success(res){console.log(res)that.setData({latitude:res.latitude,longitude:res.longitude,})wx.request({url: 'https://www.web4j.top/location/compareLocation',data:{latitude:res.latitude,longitude:res.longitude},header:{'content-type':'application/json','Access-Token':token},method:"POST",success(res){console.log(res.data.success)if(res.data.success){wx.showModal({title: '已在签到范围内',content: '是否进行人脸识别',success (res) {if (res.confirm) {wx.navigateTo({url: '../face-recognition/face-recognition',})} else if (res.cancel) {// wx.navigateTo({// url: '../face-recognition/face-recognition',// })}}})}else{wx.showToast({title: '未在签到范围内',icon: 'error',duration: 2000})}},fail(){console.log('fail')}})},fail(){console.log('fail');}})}else{//如果还未请求到数据,则创建一个回调函数,等待数据获取完成后调用app.userInfoCallback = res => {that.setData({token:app.globalData.Token})// console.log(that.data.token)var token=app.globalData.Tokenwx.getLocation({type:"gcj02",// altitude: 'altitude',success(res){console.log(res)that.setData({latitude:res.latitude,longitude:res.longitude,})wx.request({url: 'https://www.web4j.top/location/compareLocation',data:{latitude:res.latitude,longitude:res.longitude},header:{'content-type':'application/json','Access-Token':token},method:"POST",success(res){console.log(res.data.success)if(res.data.success){wx.showModal({title: '已在签到范围内',content: '是否进行人脸识别',success (res) {if (res.confirm) {wx.navigateTo({url: '../face-recognition/face-recognition',})} else if (res.cancel) {// wx.navigateTo({// url: '../face-recognition/face-recognition',// })}}})}else{wx.showToast({title: '未在签到范围内',icon: 'error',duration: 2000})}},fail(){console.log('fail')}})},fail(){console.log('fail');}})}}},
}) face-recognition.wxml
face-recognition.wxss
/* pages/face-recognition/face-recognition.wxss */
.camera{height: 600px;width: 100%;display: flex;justify-content: center;background-color: rgb(218, 214, 214);
}
.camera_c{margin-top: 30px;border-radius: 50%;height: 300px;width: 300px;
}
.whitephoto{margin-top: 30px;border-radius: 50%;height: 300px;width: 300px;
} face-recognition.js
// pages/face-recognition/face-recognition.js
var app=getApp()
// const token=app.globalData.Token;
// const user=app.globalData.user;
Page({/*** 页面的初始数据*/data: {taskid:'',token:'',src:'https://gss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/902397dda144ad34ea5205bdd3a20cf431ad851f.jpg',flag_c:0,flag_f:1,flag_s:0,photo:''},showcamera(){this.setData({flag_c:1,flag_f:0,flag_s:1})},takePhoto() {var taskid=this.data.taskidvar token=this.data.tokenconsole.log(taskid)var that=thisconst ctx = wx.createCameraContext()ctx.takePhoto({quality: 'high',success: (res) => {var path=res.tempImagePaththis.setData({src: res.tempImagePath,flag_c:0})// console.log(path)wx.uploadFile({url: 'https://www.web4j.top/face-information/uploadPhoto',filePath: path,name: 'file',header: {'content-type':'application/json','Access-Token':token},// formData: {// 'filename': 'img', //参数名// 'method':'post'// },success: (result) => {var records=JSON.parse(result.data);var filepath=records.item.filePathconsole.log(taskid);console.log(filepath);console.log('success');this.setData({photo:filepath})wx.request({url: 'https://www.web4j.top/face-information/compareFace',data:{picture:filepath,taskId:taskid},header:{'content-type':'application/json','Access-Token':token},method:"POST",success(res){console.log(res)if(res.data.success){wx.showToast({title: '签到成功!',icon: 'success',duration: 1000//持续的时间});setTimeout(()=>{wx.navigateTo({url: "../roll_call_details/roll_call_details?id="+taskid,})},600);}else{wx.showToast({title: '人脸识别失败!',icon: 'success',duration: 1000//持续的时间});setTimeout(()=>{wx.navigateTo({url: "../face-recognition/face-recognition",})},600);}},fail(){console.log('fail')}})},fail(){console.log('fail');}})}})},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {//此时需要判断全局数据是否获取到var that=this//如果已经获取到,则直接使用if(app.globalData.Token){console.log(app.globalData.Token)//如果此处的逻辑较多可以提炼为一个函数that.setData({token:app.globalData.Token,taskid:app.globalData.taskid})}else{//如果还未请求到数据,则创建一个回调函数,等待数据获取完成后调用app.userInfoCallback = res => {that.setData({token:app.globalData.Token,taskid:app.globalData.taskid})console.log(that.data.token)}}},/*** 生命周期函数--监听页面隐藏*/onHide() {},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
}) 用户上传人脸识别照片后,同样需要后端与之前上传的个人照片进行对比,如果识别成功则签到成功,同样需要后端更改用户在该签名活动中的状态,比如从0->1,从未签到更改为已签到。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
