429 lines
11 KiB
Vue
429 lines
11 KiB
Vue
<template>
|
||
<view class="fullHeight">
|
||
<headers :showBack="true" :themeType="'white'">
|
||
<view class="headerName">
|
||
移动考勤
|
||
</view>
|
||
</headers>
|
||
<view class="box personInfoBox">
|
||
<!-- <image v-if="personDetail.fieldAcquisitionUrl" :src="url_config+'image/'+personDetail.fieldAcquisitionUrl" class="profile_photo"></image> -->
|
||
<image src="/static/profile_photo.png" class="profile_photo"></image>
|
||
<view class="info">
|
||
<view class="personName">
|
||
{{realName}}
|
||
</view>
|
||
<!-- <view class="groupName">
|
||
木工班组
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
<view class="box" :style="{'height':(screenHeight - statusBarHeight - 44 - 105 - 15 - 30)+'px'}">
|
||
<view class="top">
|
||
<view class="item">
|
||
<view class="type">
|
||
上班
|
||
</view>
|
||
<view class="time" v-if="attendenceData.enterTime">
|
||
<uni-icons class="backImg" type="checkbox-filled" size="14" color="#5181F6"></uni-icons>
|
||
{{enterTime}} 已打卡
|
||
</view>
|
||
<view class="time" v-else>
|
||
未打卡
|
||
</view>
|
||
</view>
|
||
<view class="item">
|
||
<view class="type">
|
||
下班
|
||
</view>
|
||
<view class="time" v-if="attendenceData.outTime">
|
||
<uni-icons class="backImg" type="checkbox-filled" size="14" color="#5181F6"></uni-icons>
|
||
{{outTime}}已打卡
|
||
</view>
|
||
<view class="time" v-else>
|
||
未打卡
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="bottom">
|
||
<view class="">
|
||
<view class="circleBox" :class="canClick?'':'grey'" @click="clockIn">
|
||
<view class="name">
|
||
{{!attendenceData.enterTime?'上班':!attendenceData.outTime?'下班':'更新'}}打卡
|
||
</view>
|
||
<view class="time">
|
||
{{nowTime}}
|
||
</view>
|
||
</view>
|
||
<view class="address" v-if="canClick">
|
||
<uni-icons class="backImg" type="checkbox-filled" size="14"
|
||
color="#0bb44e"></uni-icons>已进入考勤范围:{{electricFence.addr}}
|
||
</view>
|
||
<view class="address" v-else>
|
||
<uni-icons class="backImg" type="location-filled" size="14"
|
||
color="rgba(38, 45, 71, 0.7)"></uni-icons>未进入考勤区域
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import uniIcons from "@/components/uni-icons/uni-icons.vue"
|
||
export default {
|
||
components: {
|
||
uniIcons
|
||
},
|
||
data() {
|
||
return {
|
||
statusBarHeight: 0,
|
||
screenHeight: 667,
|
||
personDetail: {
|
||
fieldAcquisitionUrl: ''
|
||
},
|
||
canClick: false,
|
||
projectDetail: {},
|
||
electricFence: {},
|
||
attendenceData: {
|
||
enterTime: null,
|
||
outTime: null
|
||
},
|
||
currentTime: '',
|
||
photoUrl: '',
|
||
timer: null,
|
||
realName: '',
|
||
phoneClockImageType: 0,
|
||
faceScore: 0,
|
||
timer: '', //定义一个定时器
|
||
nowTime: '',
|
||
|
||
|
||
}
|
||
},
|
||
computed: {
|
||
enterTime: function() {
|
||
if (this.attendenceData.enterTime) {
|
||
var a = this.attendenceData.enterTime.split(' ')[1]
|
||
return a
|
||
} else {
|
||
return null
|
||
}
|
||
},
|
||
outTime: function() {
|
||
if (this.attendenceData.outTime) {
|
||
var a = this.attendenceData.outTime.split(' ')[1]
|
||
return a
|
||
} else {
|
||
return null
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
this.getTime()
|
||
},
|
||
beforeDestroy() {
|
||
if (this.timer) {
|
||
clearInterval(this.timer)
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.statusBarHeight = uni.getStorageSync('systemInfo').statusBarHeight
|
||
this.screenHeight = uni.getStorageSync('systemInfo').screenHeight
|
||
this.projectDetail = JSON.parse(uni.getStorageSync('projectDetail'))
|
||
var userInfo = JSON.parse(uni.getStorageSync('userInfo'))
|
||
this.workerId = userInfo.workerId
|
||
this.realName = userInfo.realName
|
||
// 校验是否在考勤范围内
|
||
this.GetLOcation()
|
||
// 获取考勤时间
|
||
this.getAttendenceData()
|
||
// this.getNowTime()
|
||
// 判断是否需要人脸-后台配置
|
||
this.getAttendenceTypeFn()
|
||
},
|
||
|
||
onShow() {
|
||
// 线上代码1-后台配置人脸识别,this.photoUrl-代表人脸识别成功
|
||
// if (this.phoneClockImageType == 1 && this.photoUrl) {
|
||
// 本地测试
|
||
if (this.photoUrl) {
|
||
console.log("==================人脸识别成功-开始考勤===================", this.photoUrl);
|
||
this.addPhoneAttendanceFn()
|
||
}
|
||
},
|
||
methods: {
|
||
// 判断是否需要人脸识别
|
||
getAttendenceTypeFn() {
|
||
var that = this
|
||
this.sendRequest({
|
||
url: 'xmgl/projectConfig/getProjectConfigList',
|
||
data: {
|
||
projectSn: this.projectDetail.projectSn
|
||
},
|
||
method: "POST",
|
||
success(res) {
|
||
if (res.result) {
|
||
console.log("============是否需要人脸===========", res.result);
|
||
that.phoneClockImageType = res.result[0].phoneClockImageType
|
||
that.faceScore = res.result[0].faceScore
|
||
}
|
||
|
||
}
|
||
})
|
||
},
|
||
// 计时器
|
||
getTime() {
|
||
this.timer = setInterval(() => {
|
||
let timeDate = new Date()
|
||
let year = timeDate.getFullYear()
|
||
let mounth = timeDate.getMonth() + 1
|
||
let day = timeDate.getDate()
|
||
let hours = timeDate.getHours()
|
||
hours = hours >= 10 ? hours : '0' + hours
|
||
let minutes = timeDate.getMinutes()
|
||
minutes = minutes >= 10 ? minutes : '0' + minutes
|
||
let seconds = timeDate.getSeconds()
|
||
seconds = seconds >= 10 ? seconds : '0' + seconds
|
||
let week = timeDate.getDay()
|
||
let weekArr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||
this.nowTime = ` ${hours}:${minutes}:${seconds}`
|
||
}, 1000)
|
||
},
|
||
// 获取考勤信息
|
||
getAttendenceData() {
|
||
// 获取经纬度
|
||
var that = this
|
||
this.sendRequest({
|
||
url: 'xmgl/workerAttendance/getPersonAttendanceTime',
|
||
data: {
|
||
workerId: this.workerId
|
||
},
|
||
method: "POST",
|
||
success(res) {
|
||
console.log('getAttendenceData', res)
|
||
that.attendenceData = res.result
|
||
}
|
||
})
|
||
},
|
||
GetLOcation: function() {
|
||
var that = this;
|
||
uni.getLocation({
|
||
type: 'gcj02',
|
||
success: (res) => {
|
||
console.log('success', res)
|
||
var latitude = parseFloat(res.latitude);
|
||
var longitude = parseFloat(res.longitude);
|
||
that.isInArea(longitude, latitude)
|
||
},
|
||
fail(res) {
|
||
console.log('fail', res)
|
||
// uni.showModal({
|
||
// title:'提示',
|
||
// content:res.errMsg
|
||
// })
|
||
}
|
||
});
|
||
},
|
||
// 校验坐标位置是否在考勤区域中
|
||
isInArea(longitude, latitude) {
|
||
var that = this
|
||
this.sendRequest({
|
||
url: 'xmgl/electricFence/checkLocation',
|
||
data: {
|
||
longitude: longitude,
|
||
projectSn: this.projectDetail.projectSn,
|
||
latitude: latitude,
|
||
workerId: this.workerId
|
||
},
|
||
method: "POST",
|
||
hideLoading: true,
|
||
success(res) {
|
||
console.log('isInArea', res)
|
||
if (res.result.checkType == 0) {
|
||
console.log('不在考勤范围内')
|
||
that.canClick = false
|
||
} else {
|
||
console.log('在考勤范围内')
|
||
that.canClick = true
|
||
that.electricFence = res.result.electricFence
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 手机打卡
|
||
addPhoneAttendanceFn() {
|
||
// 打卡事件-打卡/识别-后台配置 0-打卡/1-人脸/2-拍照
|
||
var that = this
|
||
var type = 1
|
||
console.log("===============第三步==================");
|
||
if (this.attendenceData.enterTime) {
|
||
type = 2
|
||
}
|
||
this.sendRequest({
|
||
url: 'xmgl/workerAttendance/addPhoneAttendance',
|
||
data: {
|
||
workerId: this.workerId,
|
||
photoUrl: this.photoUrl,
|
||
type: type
|
||
},
|
||
method: "POST",
|
||
success(res) {
|
||
console.log('===========addPhoneAttendanceFn==并且有识别照片==', res)
|
||
that.getAttendenceData()
|
||
}
|
||
})
|
||
},
|
||
clockIn() {
|
||
if (!this.canClick) {
|
||
return
|
||
}
|
||
console.log("===============第一步==================", this.phoneClockImageType);
|
||
if (this.phoneClockImageType == '1') {
|
||
uni.navigateTo({
|
||
url: `./faceRecognition?faceScore=${this.faceScore}&config=${this.url_config}`
|
||
})
|
||
|
||
} else if (this.phoneClockImageType == '2') {
|
||
var that = this
|
||
uni.chooseImage({
|
||
count: 1, //默认9
|
||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||
// sourceType: ['camera','album'], //从相册选择
|
||
sourceType: ['camera'], //从相册选择
|
||
success: function(res) {
|
||
console.log(JSON.stringify(res.tempFilePaths));
|
||
const tempFilePaths = res.tempFilePaths;
|
||
uni.uploadFile({
|
||
url: that.url_config + 'upload/image', //post请求的地址
|
||
filePath: tempFilePaths[0],
|
||
name: 'files',
|
||
// formData: {
|
||
// 'username': this.userInfo.username //formData是指除了图片以外,额外加的字段
|
||
// },
|
||
success: (uploadFileRes) => {
|
||
//这里要注意,uploadFileRes.data是个String类型,要转对象的话需要JSON.parse一下
|
||
var obj = JSON.parse(uploadFileRes.data);
|
||
console.log('obj', obj)
|
||
that.photoUrl = obj.data[0].imageUrl
|
||
that.addPhoneAttendanceFn()
|
||
}
|
||
})
|
||
}
|
||
});
|
||
} else {
|
||
this.addPhoneAttendanceFn()
|
||
console.log("===============第二步==================");
|
||
}
|
||
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.profile_photo {
|
||
width: 45px;
|
||
height: 45px;
|
||
border-radius: 50%;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.box {
|
||
box-shadow: 0 4px 24px 0px rgba(212, 220, 236, 0.69);
|
||
border-radius: 8px;
|
||
margin: 15px;
|
||
padding: 15px;
|
||
}
|
||
|
||
.personInfoBox {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-direction: row;
|
||
|
||
.personName {
|
||
color: rgba(72, 141, 236, 1);
|
||
font-size: 17px;
|
||
}
|
||
|
||
.groupName {
|
||
color: rgba(42, 43, 91, 0.8);
|
||
font-size: 13px;
|
||
}
|
||
}
|
||
|
||
.top {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-direction: row;
|
||
|
||
.item {
|
||
background-color: #f3f4f8;
|
||
border-radius: 4px;
|
||
padding: 8px 12px;
|
||
flex: 1;
|
||
font-size: 15px;
|
||
|
||
// width: calc(50% - 29px);
|
||
// display: inline-flex;
|
||
&:first-child {
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.time {
|
||
font-size: 13px;
|
||
color: rgba(38, 45, 71, 0.7);
|
||
display: flex;
|
||
align-items: center;
|
||
margin-top: 3px;
|
||
flex-direction: row;
|
||
}
|
||
}
|
||
}
|
||
|
||
.backImg {
|
||
margin-right: 3px;
|
||
}
|
||
|
||
.bottom {
|
||
text-align: center;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: calc(100% - 60px);
|
||
|
||
.address {
|
||
font-size: 13px;
|
||
margin-top: 20px;
|
||
color: rgba(38, 45, 71, 0.7);
|
||
flex-direction: row;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
|
||
.circleBox {
|
||
width: 140px;
|
||
height: 140px;
|
||
border-radius: 50%;
|
||
background-image: linear-gradient(#0093f9, #066af8);
|
||
color: white;
|
||
display: inline-block;
|
||
box-shadow: 0 4px 24px 0px rgba(81, 129, 246, 0.5);
|
||
|
||
&.grey {
|
||
background-image: linear-gradient(#f1f1f1, #c3c3c3);
|
||
box-shadow: 0 4px 24px 0px rgba(195, 195, 195, 0.5);
|
||
}
|
||
|
||
.name {
|
||
padding-top: 45px;
|
||
font-size: 20px;
|
||
}
|
||
|
||
.time {
|
||
font-size: 15px;
|
||
|
||
}
|
||
}
|
||
</style> |