Browse Source

app 学生考勤打卡

黑艺新账号
yxq 1 year ago
parent
commit
8e180fe6e7
3 changed files with 556 additions and 0 deletions
  1. +13
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json
  2. +381
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/list.vue
  3. +162
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/single.vue

+ 13
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json View File

@@ -413,6 +413,19 @@
"navigationBarTitleText": "外勤打卡"
}
},
// 学生考勤打卡
{
"path": "pages/AttendanceCardStudent/list",
"style": {
"navigationBarTitleText": "学生考勤打卡"
}
},
{
"path": "pages/AttendanceCardStudent/single",
"style": {
"navigationBarTitleText": "学生考勤打卡"
}
},
//班级自诊打卡
{
"path": "pages/EducationalAdministration/Thermography/list",


+ 381
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/list.vue View File

@@ -0,0 +1,381 @@
<template>
<view class="">
<view v-if="ready" class="contentBox">
<view class="rules">
<view class="">
<view class="">
上课 {{info.WorkTime}}
</view>
<view class="">
{{info.UserWorkTime?info.UserWorkTime.split(' ')[1]+' 打卡':'未打卡'}}
</view>
</view>
<view class="">
<view class="">
下课 {{info.CloseTime}}
</view>
<view class="">
{{info.UserCloseTime?info.UserCloseTime.split(' ')[1]+' 打卡':'未打卡'}}
</view>
</view>
</view>
<view class="content" id="attendContent">
<view id="show">{{now}}</view>
<view class="pen" @click="action('dk')">
<img :class="{gray:info.AttendanceType != 1}" id="attimg" :src="imgsrc" alt="" width="100%">
</view>
<view class="title">
<text>{{resInfo.AttendanceTypeString}}</text>
<text>{{postData.AIsOut== 1 ? ' | ' + info.AttendanceTypeString:''}}</text>
<view style="color: #666;">
{{postData.ClockPlace}}
</view>
</view>
</view>
<view class="footer">
<img src="../../common/images/2.png" alt="" width="100%">
</view>
</view>
<view id='container'></view>
</view>

</template>


<script>
/*
* 版 本 Learun-ADMS V7.0.3 力软敏捷开发框架(http://www.learun.cn)
* Copyright (c) 2013-2020 上海力软信息技术有限公司
* 创建人:超级管理员
* 日 期:2022-03-10 15:30
* 描 述:考勤打卡
*/

/**
* 本段代码由移动端代码生成器输出,移动端须 2.2.0 版本及以上可以使用
* 请在移动端 /pages.json 中的 pages 字段中添加一条记录:
* { "path": "pages/AttendanceCard/list", "style": { "navigationBarTitleText": "考勤打卡" } }
*
* (navigationBarTitleText 字段为本页面的标题文本,可以修改)
* (必须自行操作该步骤,力软代码生成器不会自动帮您修改 /pages.json 文件)
*/

import get from 'lodash/get'
import set from 'lodash/set'
import moment from 'moment'
import customPageMixins from '@/common/custompage.js'
import wxFn from '@/common/wxFn.js'
//导入图片
import dk from '../../common/images/dk.png'
import dkred from '../../common/images/dkred.png'
import dkyellow from '../../common/images/dkyellow.png'

export default {
mixins: [customPageMixins, wxFn],

data() {
return {
// 页面相关参数
info: {},
resInfo:{},
now: null,
imgsrc: dk,
ready: false,
timer: '',
timer1:'',
map: null,
postData: {},
isGetingLocal:false,
}
},

async onLoad() {
await this.init()
},

methods: {
// 页面初始化
async init() {
this.LOADING('加载数据中...')

this.now = this.getCurrentTime()
this.timer = setInterval(this.getCurrentTime, 1000)
let res = await this.judgeIsDK()

this.ready = res ? true : false
this.HIDE_LOADING()
},

// 点击 「打卡」按钮
async action(type) {
switch (type) {
case 'dk':
if ([5].includes(this.info.AttendanceType)) {
return
}
if ([4].includes(this.info.AttendanceType)) {
this.NAV_TO(`./single`, this.postData,true)
return
}
this.LOADING()
this.HTTP_POST('learun/adms/attendance/clockinStudent', {}, '打卡失败').then(success => {
this.HIDE_LOADING()
if (!success) {
this.TOAST('打卡失败')
return
}
this.TOAST('打卡成功', 'success')
setTimeout(this.back, 500)

})
return

default:
break
}
},
//获取打卡信息
async judgeIsDK() {
let success = await this.HTTP_GET('learun/adms/attendance/IsAttendanceStudent', {}, '判断当前时间是否可以打卡失败')
if (!success) {
return false
}
this.info = success.data
this.imgsrc = dk;
// if ([1].includes(this.info.AttendanceType)) {
// this.imgsrc=dk;
// } else if ([2,3].includes(this.info.AttendanceType)) {
// this.imgsrc=dkyellow;
// }else {
// this.imgsrc=dkred;
// }
if (![5].includes(this.info.AttendanceType)) {
// 保存原打卡状态,改为外勤
this.resInfo = {
AttendanceType:this.info.AttendanceType,
AttendanceTypeString:this.info.AttendanceTypeString,
}
this.$set(this.info, 'AttendanceType', 4)
this.$set(this.info, 'AttendanceTypeString', '外勤打卡')
this.$set(this.postData, 'AIsOut', 1)
// 获取定位,不是外勤时候改变状态
if (!window.BMapGL) await this.loadJScript()
this.map = new BMapGL.Map('container');
await this.isFieldPersonnel()
this.timer1 = setInterval(async ()=>{
if(this.isGetingLocal)return
this.isGetingLocal = true
await this.isFieldPersonnel()
// console.log(this.postData)
this.isGetingLocal = false
},3000)
}
return true
},
//返回
back() {
this.NAV_BACK()
},
//获取当前时间
getCurrentTime() {
let nowDate = new Date();
let hh = nowDate.getHours();
let mf = nowDate.getMinutes() < 10 ? '0' + nowDate.getMinutes() : nowDate.getMinutes();
let ss = nowDate.getSeconds() < 10 ? '0' + nowDate.getSeconds() : nowDate.getSeconds();
this.now = hh + ':' + mf + ':' + ss;
},
// 判断是否外勤打卡
async isFieldPersonnel() {
let point = new BMapGL.Point(this.info.GPSLon, this.info.GPSLat)
await this.getDistance(point)
},
//异步加载地图
loadJScript() {
return new Promise((resolve, reject) => {
window.initMap = function() {
resolve(BMapGL)
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.src =
'https://api.map.baidu.com/api?v=1.0&type=webgl&ak=j1TvNK854LRvVuxuAhNNxdhKVB0KbEZD' +
'&callback=' + 'initMap';
script.onerror = reject
document.head.appendChild(script);
})
},
// 计算距离打卡点的距离
// 签到状态(1正常打卡,2迟到打卡,3早退打卡,4外勤打卡,5不在考勤时间范围)
async getDistance(myP1) {
// new BMapGL.Point(116.404, 39.915)
let myP2 = await this.local();
if (!myP2) {
// this.TOAST('获取定位失败!')
this.$set(this.info, 'AttendanceType', 4)
this.$set(this.info, 'AttendanceTypeString', '外勤打卡')
this.$set(this.postData, 'AIsOut', 1)
return
}
let distance = this.map.getDistance(myP1, myP2).toFixed(2)
// alert('距离'+ distance)
// console.log('距离', distance, '打卡坐标:', myP1, '当前坐标:', myP2)
if (Number(distance) > Number(this.info.GPSRange)) {
this.$set(this.info, 'AttendanceType', 4)
this.$set(this.info, 'AttendanceTypeString', '外勤打卡')
this.$set(this.postData, 'AIsOut', 1)
} else {
this.$set(this.info, 'AttendanceType', this.resInfo.AttendanceType)
this.$set(this.info, 'AttendanceTypeString', this.resInfo.AttendanceTypeString)
this.$set(this.postData, 'AIsOut', 0)
}
},
// 获取当前位置
local() {
return new Promise(async (resolve) => {
// let res = await this.getLocation()
let res = {
lng: 112.57205562051,
lat: 37.742374280962
}
if (!res) {
this.$set(this.postData, 'ALon', '')
this.$set(this.postData, 'ALat', '')
this.$set(this.postData, 'ClockPlace', '')
resolve(false)
}
new BMapGL.Convertor().translate([res], 3, 5, data => {
if (data.status == 0) {
// alert(data.points[0].lng + '' + data.points[0].lat)
this.$set(this.postData, 'ALon', data.points[0].lng)
this.$set(this.postData, 'ALat', data.points[0].lat)
let geoc = new BMapGL.Geocoder();
geoc.getLocation(data.points[0], (rs) => {
let addComp = rs.addressComponents;
let address =
addComp.province +
addComp.city +
addComp.district +
addComp.street +
addComp.streetNumber
this.$set(this.postData, 'ClockPlace', address)
resolve(data.points[0])
});
} else {
this.$set(this.postData, 'ALon', '')
this.$set(this.postData, 'ALat', '')
this.$set(this.postData, 'ClockPlace', '')
this.TOAST('获取定位失败!')
resolve(false)
}

})
});
}
},
destroyed() {
clearInterval(this.timer)
clearInterval(this.timer1)
}
}
</script>

<style lang="less">
uni-page-body {
height: 100%;
width: 100%;
background-color: #fff;
}

.content {
width: 48%;
height: 50%;
position: absolute;
top: 15%;
left: 50%;
transform: translate(-50%, 10%);
}

.title {
font-size: 14px;
text-align: center;
color: #333;
margin-top: 8px;
}

.rules {
display: flex;
justify-content: space-between;
color: #666;
padding: 15px;
line-height: 24px;
}

.rules>* {
width: 49%;
background-color: #BDE4FF;
padding: 8px;
border-radius: 8px 12px;
}

.rules>*>*:first-child {
color: #333;
}

#show {
text-align: center;
height: 200rpx;
font-size: 56rpx;
}

.pen {
// height: 48%;
border-radius: 50%;
background-color: #e7f5ff;
display: flex;
align-items: center;
justify-content: center;
}

.pen2 {
width: 91%;
height: 91%;
border-radius: 50%;
background-color: #bde4ff;
display: flex;
align-items: center;
justify-content: center;
}

.pen3 {
width: 84%;
height: 84%;
border-radius: 50%;
background-color: #0c86d8;
text-align: center;
font-size: 68rpx;
display: flex;
align-items: center;
justify-content: center;
color: #ffff;
}

.footer {
width: 100%;
position: fixed;
left: 0;
bottom: 0;
overflow: hidden;
}

.gray {
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
filter: gray;
}
</style>

+ 162
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/single.vue View File

@@ -0,0 +1,162 @@
<template>
<view class="page">
<view v-if="ready">
<uploadImage @input="setValue('AttendanceCard.ADPhoto', $event)" :accept="['camera']" :value="getValue('AttendanceCard.ADPhoto')"
:readonly="!edit" :number="1" title="照片上传" required/>
<l-textarea @input="setValue('AttendanceCard.ARemark', $event)" :value="getValue('AttendanceCard.ARemark')"
:readonly="!edit" title="备注" />
</view>

<view v-if="ready" class="bg-white margin-tb padding" style="padding-top: 0; overflow: hidden;">
<l-button v-if="edit" @click="action('save')" size="lg" color="green" class="block margin-top" block>
外勤打卡
</l-button>
</view>
</view>
</template>


<script>
/*
* 版 本 Learun-ADMS V7.0.3 力软敏捷开发框架(http://www.learun.cn)
* Copyright (c) 2013-2020 上海力软信息技术有限公司
* 创建人:超级管理员
* 日 期:2020-10-21 10:28
* 描 述:听课记录
*/

/**
* 本段代码由移动端代码生成器输出,移动端须 2.2.0 版本及以上可以使用
* 请在移动端 /pages.json 中的 pages 字段中添加一条记录:
* { "path": "pages/LogisticsManagement/AttendanceCard/single", "style": { "navigationBarTitleText": "表单详情页" } }
*
* (navigationBarTitleText 字段为本页面的标题文本,可以修改)
* (必须自行操作该步骤,力软代码生成器不会自动帮您修改 /pages.json 文件)
*/

import get from 'lodash/get'
import set from 'lodash/set'
import moment from 'moment'
import customPageMixins from '@/common/custompage.js'
import uploadImage from '@/components/uploadImage.vue'

export default {
mixins: [customPageMixins],
components:{
uploadImage
},

data() {
return {
// 页面相关参数
edit:true,
mode:null,
ready: false,
id:null,
params:{},

// 表单数据
current: {},
origin: {},

// 表单项数据结构
scheme: {
AttendanceCard: {
ADPhoto: {
type: 'upload_old',
title: '图片',
verify:'NotNull'
},
ARemark: {
type: 'textarea',
title: '备注'
},
},

},

// 数据源
dataSource: {
AttendanceCard: {},
}
}
},

async onLoad({
type,
id
}) {
await this.init(type, id)
},

methods: {
// 页面初始化
async init(type, id) {
this.LOADING('加载数据中...')
this.params = this.GET_PARAM()

// 拉取表单数据,同时拉取所有来自数据源的选单数据
await Promise.all([
() => {}
])
await this.fetchForm()

this.ready = true
this.HIDE_LOADING()
},

// 加载表单数据
async fetchForm() {
this.origin = await this.getDefaultForm()
this.current = this.COPY(this.origin)
},

// 点击 「编辑」、「重置」、「保存」、「删除」 按钮
async action(type) {
switch (type) {
case 'save':
const verifyResult = this.verifyForm()
if (verifyResult.length > 0) {
this.CONFIRM('表单验证失败', verifyResult.join('\n'))
return
}

if (!(await this.CONFIRM('提交确认', '确定要提交本页表单内容吗?', true))) {
return
}

this.LOADING('正在提交...')
const postData = await this.getPostData(this.id)
console.log(postData)
let strEntity = JSON.parse(postData.strEntity)
let strEntity_ = {...strEntity,...this.params}
this.HTTP_POST('learun/adms/attendance/clockinStudent', {strEntity:JSON.stringify(strEntity_)}, '打卡失败').then(success => {
this.HIDE_LOADING()
if (!success) {
this.TOAST('打卡失败')
return
}
this.TOAST('打卡成功', 'success')
setTimeout(()=>{
this.NAV_BACK(2)
}, 500)
})
break

default:
break
}
},

// 获取表单值
getValue(path) {
return get(this.current, path)
},

// 设置表单值
setValue(path, val) {
set(this.current, path, val)
},
}
}
</script>

Loading…
Cancel
Save