wechat_yxcl/pages/additionalFeatures/positionPunching.vue
2021-12-10 20:18:59 +08:00

436 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="page-body">
<div >
<div class="uni-flex today" >
<image src="/static/images/puching/time.png" mode="aspectFit" class="uni-icon-timefill"></image>
<text class="date-text ml-1">{{signin.day}} {{$util.cutDate(nowDay,"YYYY年MM月DD日")}}</text>
</div>
<div class="company-title">我的位置{{signin.nowAddress}}</div>
<div class="map-box" v-if="workLocale.ClockLat">
<map style="width: 100%; height: 200rpx;" id="myMap"
:latitude="workLocale.ClockLat" :longitude="workLocale.ClockLng" show-location="true"
:markers="mudi" :circles="circles"></map>
</div>
<div>
<div class="punching-date-box">
<div class="title"><div class="circle" :class="{'now': workLocale.ClockType==1000}"></div>上班时间 <span class="ml-1" v-if="workLocale"> {{workLocale.AMStarttime}}</span></div>
<!-- 是否是上午打卡 -->
<div class="date-text" v-if="workLocale.isAmclock"> {{pageMsg ? pageMsg.ClockIn+' 已打卡' : '未打卡'}}</div>
<div class="date-text" v-else-if="pageMsg && pageMsg.ClockIn">{{pageMsg.ClockIn}} 已打卡<span class="clockState" v-if="pageMsg.ClockInResult!==1000">{{pageMsg.ClockInResultText}}</span></div>
<div class="date-text" v-else>缺卡</div>
</div>
<div class="punching-date-box" v-if="!workLocale.isAmclock">
<div class="title"><div class="circle" :class="{'now': workLocale.ClockType==2000}"></div>下班时间 <span class="ml-1" v-if="workLocale">{{workLocale.PMEndtime}}</span></div>
<div class="date-text" v-if="pageMsg && pageMsg.ClockOut">{{pageMsg.ClockOut}} 已打卡<span class="clockState" v-if="pageMsg.ClockOutResult!==1000"> {{ pageMsg.ClockOutResultText}}</span></div>
</div>
</div>
<div class="btn-box" >
<div class="btn" :class="{'bg-gray':!signin.isAble}" @click="takePhoto">
<div class="fs-14">{{!workLocale.isAmclock ? '下班打卡': '上班打卡'}}</div>
<div class="fs-52">{{signin.time}}</div>
</div>
<div class="uni-flex able-text">
<image src="/static/images/puching/in.png" mode="aspectFit" v-if="signin.isAble"></image>
<image src="/static/images/puching/out.png" mode="aspectFit" v-else></image>
<span>{{signin.isAble ? '已进入考勤范围' : '当前位置超出打卡范围'}}</span>
</div>
</div>
</div>
<uniPopup type="middle" :show="showPop">
<div class="pop-body">
<image src="/static/images/puching/succes.png" mode="aspectFill"></image>
<div class="tip-time">{{clockDate}}</div>
<div class="tip-text">打卡成功!</div>
<div class="pop-btn" @click="showPop=!showPop">知道了</div>
</div>
</uniPopup>
</div>
</template>
<script>
import uniPopup from '@/components/uni-popup'
// import { mapMutations } from 'vuex';
export default{
data(){
const nowday = this.$util.cutDate(new Date())
return {
loading: true,
clockDate:'',
nowDay: nowday,
mudi: [],
circles: [{
latitude: 37.775006,
longitude: 112.616312,
color:"#b0d0e7",
fillColor: "#b0d0e730",
strokeWidth: 1,
radius: 100
}],
signinTime:'',
signin:{
time:'',
nowAddress:'',
day: '',
latitude:'',
longitude: '',
isAble:false
},
pageMsg: null,
showPop: false,
mapCtx: null,
workLocale: null,
userPhoto: '' //用户打卡头像
}
},
// computed:{
// ...mapState({
// 'userPhoto':(state)=>{return state.userPhoto}
// })
// },
components:{
uniPopup
},
methods: {
// ...mapMutations(['setPhoto']),
getLocation(){
let _this = this
uni.getLocation({
type: 'gcj02', //返回可以用于uni.openLocation的经纬度
altitude: true, // 高精度定位
success: function (res) {
_this.signin.latitude = res.latitude;
_this.signin.longitude = res.longitude;
const latitude = res.latitude
const longitude = res.longitude
let { ClockLng,ClockLat } = _this.workLocale
_this.$util.calculateDistance(
{latitude:latitude, longitude:longitude},
{latitude: ClockLat, longitude: ClockLng})
.then(data => {
let distance = data.result.elements[0].distance
_this.signin.isAble = (distance!=-1 && distance<100) ? true :false
})
wx.request({
url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=SVKBZ-P6QCJ-NH7F7-KOPJW-CBNEV-FUBRT`,
success: res => {
_this.signin.nowAddress = res.data.result.address
}
})
}
})
},
// 获取当前时间时分秒
getTime (time) {
time = time ? new Date(time) : new Date()
this.signin.time = this.$util.cutDate(time,'hh:mm:ss')
},
getDay (){
var a = new Array("日", "一", "二", "三", "四", "五", "六");
var week = new Date().getDay();
this.signin.day = "星期"+ a[week];
},
getWorkLocale(){ //获取 考勤地址、坐标,打卡范围,上、下班时间
let _this= this
let nowDay = this.nowDay
this.$request.$get('GetWorkLocale',{}).then(res =>{
if(res.Result_Code==100) {
if( res.Data){
let msg = res.Data
let [ClockLng,ClockLat] = _this.$util.bMapToQQMap(msg.ClockLng,msg.ClockLat)
msg.ClockLng =ClockLng
msg.ClockLat = ClockLat
_this.mudi = [{
id: "sx1",
latitude: ClockLat,
longitude: ClockLng,
title: msg.ClockAddress,
}]
_this.circles[0].latitude = ClockLat
_this.circles[0].longitude = ClockLng
_this.circles[0].radius = msg.ClockRange
let am = new Date(nowDay+' '+msg.AMEndtime+':00')
msg.isAmclock = am.getTime()-(new Date()).getTime() >0 ? true: false
_this.workLocale = msg
_this.loading = false
_this.getLocation()
}
}else {
uni.showModal({
title:'温馨提示',
content: res.Result_Desc,
showCancel:false
})
}
})
},
getMsg(){ // 更新用户当前打卡时间
let _this= this
let nowDay = this.nowDay
this.$request.$get('GetWorkTimeRecord',{
startDate: nowDay,
endDate: nowDay
}).then(res =>{
if(res.Result_Code==100) {
if( res.Data.List.length>0){
let msg = res.Data.List[0]
_this.pageMsg = msg
}
}
})
},
faceClock(){ // 提交打卡
let _this= this
let location = this.signin
if(!this.signin.isAble) return
_this.signinTime = this.signin.time
uni.showLoading({
title: "正在识别人脸,请稍后",
mask:true,
})
this.$request.$post('FaceClock',{
clockLat: location.latitude,
clockLng: location.longitude,
photo: this.userPhoto || ''
}).then(res =>{
_this.loading = false
uni.hideLoading()
if(res.Result_Code==100) {
_this.clockDate = res.Data.ClockDate
_this.getMsg()
_this.showPop = true
}else{
uni.showModal({
content:'打卡失败:'+res.Result_Desc
})
}
_this.userPhoto=null
})
},
clearTime (){
clearInterval(this.setTime)
this.setTime = null
},
takePhoto() { // 跳转页面拍照
let _this = this
if(!this.signin.isAble) return // 是否可以打卡
if(this.loading ) return // 是否正在上传
uni.navigateTo({
url:'/pages/additionalFeatures/takePhoto'
})
},
photoTobase64(photoPath){ // 把图片转为base64
let _this= this
uni.getFileSystemManager().readFile({
filePath: photoPath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: res => { //
let base64 = res.data.replace(/\+/ig,'%2B') //不加上这串字符,在页面无法显示的哦
_this.userPhoto = base64
_this.faceClock()
}
})
}
},
onLoad() {
let _this = this
this.getWorkLocale()
_this.setTime = setInterval(function(){_this.getTime()},1000)
_this.getMsg()
uni.$on('addUserPhoto',function(data){ // 监听打卡拍照的数据,接收拍照的照片地址
_this.photoTobase64(data)
// console.log(data)
// uni.$off('addUserPhoto')
})
},
onPullDownRefresh() {
let _this = this
_this.getLocation()
setTimeout(function() {
uni.stopPullDownRefresh()
}, 1000)
},
onUnload() {
// console.log(1)
uni.$off('addUserPhoto')
this.clearTime()
}
}
</script>
<style scoped>
.fs-14 {
font-size: 28rpx;
}
.fs-52 {
font-size: 52rpx;
}
.ml-1 {
margin-left: 4rpx;
}
.uni-icon {
font-size: 28rpx;
}
.uni-icon-timefill {
color: #CCCCCC;
width: 26rpx;
height: 26rpx;
}
.page-body {
padding: 0 24rpx;
background-color: #fff;
height: 100%;
box-sizing: border-box;
}
.today {
padding: 20rpx 0;
align-items: center;
}
.date-text {
color: #A3A3A3;
font-size: 22rpx;
/* line-height: 50rpx; */
/* margin-left: 8rpx; */
}
.company-title {
font-size: 28rpx;
line-height: 1.5;
font-weight: bolder;
padding-top: 32rpx;
padding-bottom: 20rpx;
border-top: 2rpx solid #edeef2;
}
.map-box {
margin-bottom: 40rpx;
}
.punching-date-box {
padding-left: 30rpx;
position: relative;
}
.punching-date-box:nth-child(2)::before {
content: '';
position: absolute;
height: 190rpx;
width: 2rpx;
display: block;
background-color: #e0e0e0;
top: -172rpx;
left: 36rpx;
z-index: 0;
}
.punching-date-box + .punching-date-box {
margin-top: 96rpx;
}
.punching-date-box .circle {
background-color: #b2b2b2;
width: 16rpx;
height: 16rpx;
border-radius: 50%;
margin-right: 8rpx;
}
.punching-date-box .circle.now {
background-color: #57AAEE;
}
.punching-date-box .title {
font-size: 28rpx;
color: #9EA2A4;
display: flex;
align-items: center;
}
.punching-date-box .clockState {
color: #FF8556;
margin-left: 12rpx;
font-size: 24rpx;
font-weight: 700;
}
.punching-date-box .date-text {
color: #353638;
font-size: 30rpx;
padding-left: 30rpx;
line-height: 60rpx;
}
.btn-box {
margin-top: 80rpx;
}
.btn {
border-radius: 50%;
margin: 0 auto;
width: 252rpx;
height: 252rpx;
color: #fff;
text-align: center;
padding-top: 42rpx;
background: linear-gradient(#65bef9 0%, #50a0e8 100%);
box-sizing: border-box;
}
.bg-gray.btn {
background:linear-gradient(#cdd4d8 0%, #ADB2BF 100%);
}
.able-text {
color: #8B8D8E;
font-size: 22rpx;
margin-top: 32rpx;
justify-content: center;
align-items: center;
}
.able-text image {
width: 24rpx;
height: 24rpx;
margin-right: 8rpx;
}
.pop-body {
height: 664rpx;
width: 564rpx;
position: relative;
}
.pop-body image {
width: 497rpx;
height: 363rpx;
position: absolute;
top: -46px;
transform: translateX(-48%);
margin: 0 50%;
}
.tip-text {
font-size: 46rpx;
text-align: center;
color: #7B95A9;
}
.tip-time {
text-align: center;
color: #5EB4F3;
font-size: 72rpx;
margin-top: 260rpx;
}
.pop-btn {
border-top: 2rpx solid #ececec;
font-size: 28rpx;
height: 90rpx;
line-height: 90rpx;
text-align: center;
color: #56A8ED;
margin-top: 120rpx;
}
</style>