<template>
|
<b-modal ref="modalRef" centered hide-footer @hide="hiddenFn" size="lg">
|
<div class="row">
|
<div class="col-10">
|
<div class>
|
<h4 class="float-left">人员:{{attendanceInfo.employeeName?attendanceInfo.employeeName:''}}</h4>
|
<div class="pb-4 flex-center">
|
<el-date-picker
|
v-model="yearValue"
|
type="month"
|
format="yyyy年MM月"
|
value-format="yyyy-MM"
|
:clearable="false"
|
style="width:140px"
|
placeholder="选择年月"
|
></el-date-picker>
|
</div>
|
</div>
|
<vueCalendar
|
ref="calendar"
|
:events="calendarEvent"
|
:lunar="false"
|
:value="calendarDate"
|
@select="calendarSelect"
|
:isShowHeader="false"
|
tdHeight="100px"
|
@recordFn="recordFn"
|
@leaveFn="leaveFn"
|
@repairFn="repairFn"
|
/>
|
</div>
|
<!-- 统计数据 -->
|
<div class="col-2">
|
<div class="pt-4 pb-3 text-center">
|
<b-button @click="setToday" size="sm" variant="primary" class="border-radius-25">返回今天</b-button>
|
<fButton
|
size="sm"
|
type="primary"
|
class="ml30 border-radius-25"
|
@click.native="exportFile"
|
authority="sys:attendance:export"
|
>导出报表</fButton>
|
</div>
|
<!-- <b-list-group>
|
<b-list-group-item href="javascript:void(0)" class="media ">
|
<div class="media-body line-height-condenced text-center ">
|
<h5 class="">签到天数<small class="text-secondary">(含补签)</small></h5>
|
<div class="bg-primary text-white font-weight-bold attendance-count-num">
|
18
|
</div>
|
</div>
|
</b-list-group-item>
|
<b-list-group-item href="javascript:void(0)" class="media ">
|
<div class="media-body line-height-condenced text-center">
|
<div class="text-dark">未签到</div>
|
<div class="bg-warning text-white font-weight-bold attendance-count-num">
|
2
|
</div>
|
</div>
|
</b-list-group-item>
|
<b-list-group-item href="javascript:void(0)" class="media ">
|
<div class="media-body line-height-condenced text-center">
|
<div class="text-dark">补签天数</div>
|
<div class="bg-success text-white font-weight-bold attendance-count-num">
|
2
|
</div>
|
</div>
|
</b-list-group-item>
|
</b-list-group>-->
|
<div class="ml-4 mr-4" style="margin-top:150px">
|
<div class="bg-primary text-white text-center pt-3 mt-4 mr-4 ml-4">
|
<h5 class>
|
签到天数
|
<small class>(含补签)</small>
|
</h5>
|
<div
|
class="text-white font-weight-bold attendance-count-num"
|
>{{attendanceInfo.attendValue}}</div>
|
</div>
|
<div class="bg-warning text-white text-center pt-3 mt-4 mr-4 ml-4">
|
<h5 class>未签到</h5>
|
<div class="text-white font-weight-bold attendance-count-num">{{attendanceInfo.isLeave}}</div>
|
</div>
|
<!-- <div class="bg-success text-white text-center pt-3 mt-4 mr-4 ml-4">
|
<h5 class="">补签天数</h5>
|
<div class="text-white font-weight-bold attendance-count-num">
|
{{attendanceInfo.isRepair}}
|
</div>
|
</div>-->
|
</div>
|
</div>
|
</div>
|
<el-dialog
|
title="签到流水"
|
:modal="false"
|
width="80%"
|
:show-close="false"
|
:visible.sync="recordInfoModal"
|
>
|
<div slot="title" class="flex-row-between">
|
<div class="flex-center">
|
<h4 class="m-0">人员:{{attendanceInfo.employeeName}}</h4>
|
<small class="pt-2 pl-4">{{yearValue + '-' + calendarValue}}</small>
|
</div>
|
<div>
|
<!-- <b-button variant="primary" class="border-radius-25 pl20 pr20 mr10" @click="exportFileDay">导出报表</b-button> -->
|
<fButton
|
type="primary"
|
@click.native="exportFileDay"
|
authority="sys:attendance:export"
|
class="border-radius-25 pl20 pr20 mr10"
|
>导出报表</fButton>
|
<b-button
|
variant="outline-primary"
|
class="border-radius-25 pl30 pr30"
|
@click="recordInfoModal = false"
|
>返回</b-button>
|
</div>
|
</div>
|
<div style="height:58vh" class="overflow-auto px-2 pb-4">
|
<Table :data="tableList" :border="true">
|
<TableColumn type="index" prop="index" label="序号" :index="snMethod" width="50"/>
|
<TableColumn label="抓拍图像" prop="deviceName" width="120">
|
<template slot-scope="scope">
|
<httpImgCopy :src="scope.row.Snapshotpath" height="80px" size="80px" alt/>
|
</template>
|
</TableColumn>
|
<TableColumn label="进出入位置" prop="indevicename"/>
|
<TableColumn label="时间" prop="onlinetime"/>
|
<!-- <TableColumn
|
label="是否补签"
|
prop="updateTime"
|
:span="3"
|
/>-->
|
</Table>
|
</div>
|
</el-dialog>
|
<el-dialog
|
title="补签到"
|
:modal="false"
|
width="500px"
|
@close="repairModalFn"
|
:modal-append-to-body="false"
|
:visible.sync="repairModal"
|
>
|
<div class="pl-5">
|
<el-form :model="repairForm" :rules="rules" ref="repairForm" label-width="100px">
|
<el-form-item label="活动区域" prop="inTime">
|
<el-time-picker
|
value-format="HH:mm:ss"
|
v-model="repairForm.inTime"
|
placeholder="选择首次时间"
|
></el-time-picker>
|
</el-form-item>
|
<el-form-item label="首次位置" prop="inDeviceName">
|
<el-select v-model="repairForm.inDeviceName" placeholder="首次位置" style="width: 220px;">
|
<el-option label="区域一" value="shanghai"></el-option>
|
<el-option label="区域二" value="beijing"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="末次时间" prop="outTime">
|
<el-time-picker
|
value-format="HH:mm:ss"
|
v-model="repairForm.outTime"
|
placeholder="选择末次时间"
|
></el-time-picker>
|
</el-form-item>
|
<el-form-item label="末次位置" prop="outDeviceName">
|
<el-select
|
v-model="repairForm.outDeviceName"
|
placeholder="请选择末次位置"
|
style="width: 220px;"
|
>
|
<el-option label="区域一" value="shanghai"></el-option>
|
<el-option label="区域二" value="beijing"></el-option>
|
</el-select>
|
</el-form-item>
|
</el-form>
|
</div>
|
<hr class="p-0 m-0">
|
<div slot="footer" class="dialog-footer">
|
<b-button variant="primary" @click="submitForm('repairForm')">确 定</b-button>
|
<b-button variant="default" @click="repairModal = false">取 消</b-button>
|
</div>
|
</el-dialog>
|
</b-modal>
|
</template>
|
|
<script>
|
import {
|
DatePicker,
|
Dialog,
|
Button,
|
Form,
|
FormItem,
|
TimePicker,
|
Select,
|
Option,
|
Table,
|
TableColumn
|
} from 'element-ui'
|
import vueCalendar from '@/components/vueCalendar'
|
import httpImgCopy from '@/components/common/httpImgCopy'
|
import { getPersonMouthData, getPersonById } from '@/server/attend.js'
|
export default {
|
name: 'CalendarAttendanceModal',
|
components: {
|
vueCalendar,
|
elDatePicker: DatePicker,
|
elDialog: Dialog,
|
elButton: Button,
|
elForm: Form,
|
elFormItem: FormItem,
|
elSelect: Select,
|
elOption: Option,
|
elTimePicker: TimePicker,
|
Table,
|
TableColumn,
|
httpImgCopy
|
},
|
// props: {
|
// modalData: {
|
// default: null,
|
// type: Object
|
// }
|
// },
|
data() {
|
return {
|
modalData: {},
|
attendanceInfo: {},
|
yearValue: this.$moment().format('YYYY-MM'),
|
calendarValue: this.$moment().format('DD'),
|
|
dataLsit: [],
|
dayTime: '',
|
recordInfoModal: false,
|
tableList: [],
|
repairModal: false,
|
repairForm: {
|
inTime: '',
|
inDeviceName: '',
|
outTime: '',
|
outDeviceName: ''
|
},
|
rules: {
|
inTime: [
|
{ required: true, message: '请选择末次时间', trigger: 'blur' }
|
],
|
inDeviceName: [
|
{ required: true, message: '请选择首次位置', trigger: 'blur' }
|
],
|
outTime: [
|
{ required: true, message: '请选择末次时间', trigger: 'blur' }
|
],
|
outDeviceName: [
|
{ required: true, message: '请选择末次位置', trigger: 'blur' }
|
]
|
}
|
}
|
},
|
computed: {
|
calendarDate() {
|
// 用于控制日历
|
// console.log(this.dateValue(), 'this.dateValue')
|
return this.dateValue().split('-')
|
},
|
calendarEvent() {
|
let json = {}
|
this.dataLsit.map(iteam => {
|
json[iteam.signDate] = iteam
|
})
|
console.log(json, 'json')
|
return json
|
}
|
},
|
methods: {
|
snMethod(index) {
|
return this.activePage > 1
|
? this.pageSize * (this.activePage - 1) + index + 1
|
: index + 1
|
},
|
// 计算日历中心val
|
dateValue() {
|
if (this.yearValue) {
|
// console.log(this.calendarValue, 'this.calendarValue')
|
const day = this.calendarValue
|
? this.calendarValue
|
: this.$moment().format('DD')
|
const dayNum = this.$moment(this.yearValue, 'YYYY-MM')
|
.endOf('month')
|
.format('DD') // 这个月最后一天
|
if (dayNum < day) {
|
this.calendarValue = dayNum
|
return `${this.yearValue}-${dayNum}`
|
}
|
return `${this.yearValue}-${day}`
|
}
|
return this.$moment().format('YYYY-MM-DD')
|
},
|
showModal(data) {
|
this.modalData = data
|
this.queryperson({
|
personId: data.pid ? data.pid : '',
|
mouthDate: this.$moment().format('YYYY-MM')
|
})
|
this.$refs.modalRef.show()
|
},
|
hideModal() {
|
this.$refs.modalRef.hide()
|
},
|
hiddenFn() {
|
// console.log('关闭主要弹窗')
|
this.recordInfoModal = false
|
this.repairModal = false
|
},
|
calendarSelect(value) {
|
this.calendarValue = this.$moment(value.join('-'), 'YYYY-M-D').format(
|
'DD'
|
)
|
// console.log(this.calendarValue, 'value')
|
},
|
setToday() {
|
this.yearValue = this.$moment().format('YYYY-MM')
|
this.calendarValue = this.$moment().format('DD')
|
},
|
recordFn({ data, day }) {
|
// console.log(data, '记录回调')
|
let endTime = this.$moment(data.signDate).format('YYYY-MM-DD')
|
let beginTime = this.$moment(data.signDate).format('YYYY-MM-DD')
|
this.dayTime = endTime
|
// console.log(endTime, 'endTime')
|
let json = {
|
id: data.employeeId,
|
endTime: endTime,
|
beginTime: beginTime
|
}
|
this.queryPersonById(json)
|
},
|
async queryPersonById(json) {
|
let res = await getPersonById(json)
|
if (res && res.data) {
|
console.log(res.data, ' dayList ')
|
this.tableList = res.data.dayList
|
this.recordInfoModal = true
|
} else {
|
this.$toast({
|
message: res.msg ? res.msg : '报错了',
|
type: 'error'
|
})
|
}
|
},
|
async queryperson(json) {
|
let res = await getPersonMouthData(json)
|
if (res && res.data) {
|
console.log(res.data, 'res.data---数据')
|
this.attendanceInfo = res.data
|
this.dataLsit = res.data.dayList ? res.data.dayList : []
|
console.log(this.dataLsit, 'this.dataLsit')
|
} else {
|
this.$toast({
|
message: res.msg ? res.msg : '报错了',
|
type: 'error'
|
})
|
}
|
},
|
exportFile() {
|
let access = JSON.parse(
|
sessionStorage.getItem('loginedInfo')
|
).access_token.replace('bearer ', '')
|
/* 创建form对象 */
|
let oA = document.createElement('A')
|
// oA.setAttribute('method', 'get')
|
oA.setAttribute(
|
'href',
|
'data/api-a/att/poiPersonMouuthDataExcel?access_token=' +
|
access +
|
'&mouthDate=' +
|
this.yearValue +
|
'&personId=' +
|
this.modalData.pid
|
)
|
// console.log(oA, 'oA')
|
document.body.append(oA)
|
oA.click()
|
// window.location.href = 'data/api-a/att/poiPersonMouuthDataExcel?access_token=' + access + '&mouthDate=' + this.yearValue + '&personId=' + this.modalData.pid
|
// window.open('data/api-a/att/excel?access_token=' + access, '_blank')
|
},
|
exportFileDay() {
|
// console.log(this.dayTime, 'dayTime')
|
let access = JSON.parse(
|
sessionStorage.getItem('loginedInfo')
|
).access_token.replace('bearer ', '')
|
/* 创建form对象 */
|
let oA = document.createElement('A')
|
// oA.setAttribute('method', 'get')
|
oA.setAttribute(
|
'href',
|
'data/api-a/att/poiPersonDayDataExcel?access_token=' +
|
access +
|
'&id=' +
|
this.modalData.pid +
|
'&dayTime=' +
|
this.dayTime
|
)
|
console.log(oA, 'oA')
|
document.body.append(oA)
|
oA.click()
|
// window.location.href = 'data/api-a/att/poiPersonMouuthDataExcel?access_token=' + access + '&mouthDate=' + this.yearValue + '&personId=' + this.modalData.pid
|
// window.open('data/api-a/att/excel?access_token=' + access, '_blank')
|
},
|
leaveFn({ data, day }) {
|
console.log(data, '请假回调')
|
alert('请假回调')
|
},
|
|
/* 补签开始 */
|
repairFn({ data, day }) {
|
console.log(data, '补签回到')
|
console.log(data, 'data')
|
this.repairModal = true
|
if (data) {
|
this.repairForm = data
|
} else {
|
this.repairForm = {
|
inTime: '',
|
inDeviceName: '',
|
outTime: '',
|
outDeviceName: ''
|
}
|
}
|
},
|
submitForm(formName) {
|
this.$refs[formName].validate(valid => {
|
if (valid) {
|
alert('submit!')
|
this.repairModal = false
|
this.resetForm('repairForm')
|
} else {
|
return false
|
}
|
})
|
},
|
/* 补签重置 */
|
resetForm(formName) {
|
this.$refs[formName].resetFields()
|
},
|
repairModalFn() {
|
this.resetForm('repairForm')
|
}
|
},
|
watch: {
|
yearValue(newVal, oldVal) {
|
console.log(newVal, oldVal, 'newVal,oldVal')
|
this.queryperson({
|
personId: this.modalData.pid,
|
mouthDate: newVal
|
})
|
}
|
}
|
}
|
</script>
|
<style>
|
@media (min-width: 992px) {
|
.modal-lg {
|
max-width: 100rem;
|
}
|
}
|
.attendance-count-num {
|
border-radius: 5px;
|
margin-top: 10px;
|
font-size: 30px;
|
line-height: 50px;
|
height: 60px;
|
}
|
.border-radius-25 {
|
border-radius: 25px;
|
}
|
</style>
|