|
|
@ -7,42 +7,59 @@ |
|
|
|
<div class="table-head-item">晚</div> |
|
|
|
<div class="table-head-item">审核人</div> |
|
|
|
</div> |
|
|
|
<div v-for="(list, listIndex) in lists" :key="listIndex"> |
|
|
|
<div class="my-2 table-time px-2">{{ list.dateTime }}</div> |
|
|
|
<a-table :pagination="false" :showHeader="false" :columns="columns" :data-source="list.clockList"> |
|
|
|
<div v-if="clockInfos && clockInfos.length"> |
|
|
|
<div v-for="(list, listIndex) in clockInfos" :key="listIndex" class="teble-box"> |
|
|
|
<div class="table-time px-2">{{ list.dateTime }}</div> |
|
|
|
<a-table :pagination="false" :show-header="false" :columns="columns" :data-source="list.recordList"> |
|
|
|
<template slot="actions" slot-scope="text, record, index"> |
|
|
|
<img src="https://www.tall.wiki/staticrec/drag.svg" /> |
|
|
|
<img @click="showMenu(index)" src="https://www.tall.wiki/staticrec/drag.svg" /> |
|
|
|
</template> |
|
|
|
<template slot="morning" slot-scope="text, record, index"> |
|
|
|
<div class="clock-in"> |
|
|
|
<div v-if="record.morningStatus"> |
|
|
|
{{ $moment(record.morning - 0).format('HH:mm') }} |
|
|
|
</div> |
|
|
|
<div v-else> |
|
|
|
<a-button type="primary" size="small" class="clock-btn"> 打卡 </a-button> |
|
|
|
<a-date-picker show-time @change="onChange($event, listIndex, index, 1)" class="clock-select" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<a-button |
|
|
|
v-else |
|
|
|
type="primary" |
|
|
|
size="small" |
|
|
|
@click="checkTime(listIndex, index, 0, record.id, record.memberId, record.checkerId)" |
|
|
|
> |
|
|
|
打卡 |
|
|
|
</a-button> |
|
|
|
</template> |
|
|
|
<template slot="night" slot-scope="text, record, index"> |
|
|
|
<div class="clock-in"> |
|
|
|
<div v-if="record.nightStatus"> |
|
|
|
{{ $moment(record.night - 0).format('HH:mm') }} |
|
|
|
</div> |
|
|
|
<div v-else> |
|
|
|
<a-button type="primary" size="small" class="clock-btn"> 打卡 </a-button> |
|
|
|
<a-date-picker show-time @change="onChange($event, listIndex, index, 2)" class="clock-select" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<a-button |
|
|
|
v-else |
|
|
|
type="primary" |
|
|
|
size="small" |
|
|
|
@click="checkTime(listIndex, index, 1, record.id, record.memberId, record.checkerId)" |
|
|
|
> |
|
|
|
打卡 |
|
|
|
</a-button> |
|
|
|
</template> |
|
|
|
<template slot="checkerName" slot-scope="text, record"> |
|
|
|
<a-select :default-value="record.checkerId || checkerId" style="width: 80px" placeholder="选择" @change="chooseChecker"> |
|
|
|
<a-select-option :value="member.memberId" v-for="member in members" :key="member.memberId"> |
|
|
|
{{ member.name }} |
|
|
|
</a-select-option> |
|
|
|
</a-select> |
|
|
|
</template> |
|
|
|
</a-table> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<a-empty class="mt-8 mb-8" description="暂无打卡信息" v-else /> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import { mapState } from 'vuex'; |
|
|
|
import { clockQuery, clockPunch } from '@/config/api'; |
|
|
|
|
|
|
|
const columns = [ |
|
|
|
{ title: ' ', dataIndex: 'actions', key: 'actions', scopedSlots: { customRender: 'actions' }, width: '10%' }, |
|
|
|
{ title: ' ', dataIndex: 'actions', key: 'actions', scopedSlots: { customRender: 'actions' }, align: 'center', width: '10%' }, |
|
|
|
{ title: '姓名', dataIndex: 'memberName', key: 'memberName', align: 'center', width: '22.5%' }, |
|
|
|
{ title: '早', dataIndex: 'morning', key: 'morning', scopedSlots: { customRender: 'morning' }, align: 'center', width: '22.5%' }, |
|
|
|
{ title: '晚', dataIndex: 'night', key: 'night', scopedSlots: { customRender: 'night' }, align: 'center', width: '22.5%' }, |
|
|
@ -56,91 +73,103 @@ const columns = [ |
|
|
|
}, |
|
|
|
]; |
|
|
|
|
|
|
|
const lists = [ |
|
|
|
{ |
|
|
|
dateTime: '2021-08-27', |
|
|
|
clockList: [ |
|
|
|
{ |
|
|
|
id: 1, |
|
|
|
morning: '1630283371000', |
|
|
|
morningStatus: true, |
|
|
|
night: '1630319371000', |
|
|
|
nightStatus: true, |
|
|
|
memberName: '赵同学', |
|
|
|
checkerName: '周勇', |
|
|
|
}, |
|
|
|
{ |
|
|
|
key: 2, |
|
|
|
morning: '1630283371000', |
|
|
|
morningStatus: true, |
|
|
|
night: '1630319371000', |
|
|
|
nightStatus: false, |
|
|
|
memberName: '张野', |
|
|
|
checkerName: '武慧娟', |
|
|
|
}, |
|
|
|
{ |
|
|
|
key: 3, |
|
|
|
morning: '1630283371000', |
|
|
|
morningStatus: false, |
|
|
|
night: '1630319371000', |
|
|
|
nightStatus: true, |
|
|
|
memberName: '李亚男', |
|
|
|
checkerName: '姚工', |
|
|
|
}, |
|
|
|
], |
|
|
|
}, |
|
|
|
{ |
|
|
|
dateTime: '2021-08-27', |
|
|
|
clockList: [ |
|
|
|
{ |
|
|
|
id: 4, |
|
|
|
morning: '1630283371000', |
|
|
|
morningStatus: true, |
|
|
|
night: '1630319371000', |
|
|
|
nightStatus: true, |
|
|
|
memberName: '赵同学', |
|
|
|
checkerName: '周勇', |
|
|
|
}, |
|
|
|
{ |
|
|
|
key: 5, |
|
|
|
morning: '1630283371000', |
|
|
|
morningStatus: true, |
|
|
|
night: '1630319371000', |
|
|
|
nightStatus: false, |
|
|
|
memberName: '张野', |
|
|
|
checkerName: '武慧娟', |
|
|
|
}, |
|
|
|
{ |
|
|
|
key: 6, |
|
|
|
morning: '1630283371000', |
|
|
|
morningStatus: false, |
|
|
|
night: '1630319371000', |
|
|
|
nightStatus: true, |
|
|
|
memberName: '李亚男', |
|
|
|
checkerName: '姚工', |
|
|
|
}, |
|
|
|
], |
|
|
|
}, |
|
|
|
]; |
|
|
|
|
|
|
|
export default { |
|
|
|
data() { |
|
|
|
return { |
|
|
|
columns, |
|
|
|
lists, |
|
|
|
clockInfos: [], |
|
|
|
memberIdList: [], |
|
|
|
options: null, |
|
|
|
checkerId: undefined, |
|
|
|
}; |
|
|
|
}, |
|
|
|
|
|
|
|
computed: mapState('home', ['projectId', 'members']), |
|
|
|
|
|
|
|
mounted() { |
|
|
|
this.setParams(); |
|
|
|
}, |
|
|
|
|
|
|
|
methods: { |
|
|
|
onChange(dateString, listIndex, index, type) { |
|
|
|
const selectTime = this.$moment(dateString).format('x'); |
|
|
|
console.log('selectTime: ', selectTime); |
|
|
|
if (type === 1) { |
|
|
|
this.lists[listIndex].clockList[index].morning = selectTime; |
|
|
|
async setParams(options) { |
|
|
|
const { projectId } = this; |
|
|
|
const time = this.$moment(Date.now()).format('YYYY-MM-DD'); |
|
|
|
const startTime = (options && options.startTime) || this.$moment(`${time} 00:00`).format('x') - 0; |
|
|
|
const endTime = (options && options.endTime) || this.$moment(`${time} 23:59`).format('x') - 0; |
|
|
|
const memberIdList = (options && options.memberIdList) || this.memberIdList; |
|
|
|
const params = { param: { projectId, memberIdList, startTime, endTime } }; |
|
|
|
await this.getClockQuery(params); |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
* 查询考勤信息 |
|
|
|
* @param {string} projectId |
|
|
|
* @param {array} memberIdList |
|
|
|
* @param {string} startTime |
|
|
|
* @param {string} endTime |
|
|
|
*/ |
|
|
|
async getClockQuery(params) { |
|
|
|
try { |
|
|
|
const res = await clockQuery(params); |
|
|
|
const { code, msg, data } = res.data; |
|
|
|
if (code === 200) { |
|
|
|
this.clockInfos = data; |
|
|
|
} else { |
|
|
|
this.$message.error(msg || '获取失败'); |
|
|
|
throw msg; |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
throw error || '获取失败'; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 选择审核人 |
|
|
|
chooseChecker(value) { |
|
|
|
this.checkerId = value; |
|
|
|
}, |
|
|
|
|
|
|
|
// 打卡 |
|
|
|
checkTime(listIndex, index, clockType, id, memberId, checkerId) { |
|
|
|
const time = Date.now(); |
|
|
|
const selectTime = this.$moment(time).format('HH:mm'); |
|
|
|
if (clockType === 0) { |
|
|
|
this.clockInfos[listIndex].recordList[index].morning = selectTime; |
|
|
|
} else { |
|
|
|
this.clockInfos[listIndex].recordList[index].night = selectTime; |
|
|
|
} |
|
|
|
const dateTime = this.$moment(time).format('x') - 0; |
|
|
|
// TODO: |
|
|
|
const params = { param: { checkerId: this.checkerId || checkerId, clockType, dateTime, id, memberId } }; |
|
|
|
this.handleClockPunch(params); |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
* 打卡 |
|
|
|
* @param {string} checkerId 审核员id |
|
|
|
* @param {array} clockType 打卡类型(0-早,1-晚) |
|
|
|
* @param {string} dateTime 打卡时间 |
|
|
|
* @param {string} id 记录id(没有则不传) |
|
|
|
* @param {string} memberId 考勤信息中的成员id |
|
|
|
*/ |
|
|
|
async handleClockPunch(params) { |
|
|
|
try { |
|
|
|
const res = await clockPunch(params); |
|
|
|
const { code, msg } = res.data; |
|
|
|
if (code === 200) { |
|
|
|
this.$message.success('打卡成功'); |
|
|
|
this.setParams(); |
|
|
|
} else { |
|
|
|
this.lists[listIndex].clockList[index].night = selectTime; |
|
|
|
this.$message.error(msg || '获取失败'); |
|
|
|
throw msg; |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
throw error || '获取失败'; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
showMenu(index) { |
|
|
|
console.log('展开菜单', index); |
|
|
|
}, |
|
|
|
}, |
|
|
|
}; |
|
|
|
</script> |
|
|
@ -149,14 +178,14 @@ export default { |
|
|
|
.table-head { |
|
|
|
border-bottom: 1px solid #e8e8e8; |
|
|
|
background: #fafafa; |
|
|
|
height: 54px; |
|
|
|
line-height: 54px; |
|
|
|
height: 40px; |
|
|
|
line-height: 40px; |
|
|
|
font-weight: bold; |
|
|
|
} |
|
|
|
|
|
|
|
.table-time { |
|
|
|
height: 54px; |
|
|
|
line-height: 54px; |
|
|
|
height: 40px; |
|
|
|
line-height: 40px; |
|
|
|
border-bottom: 1px solid #e8e8e8; |
|
|
|
} |
|
|
|
|
|
|
@ -170,21 +199,7 @@ img { |
|
|
|
max-width: auto !important; |
|
|
|
} |
|
|
|
|
|
|
|
.clock-in { |
|
|
|
position: relative; |
|
|
|
} |
|
|
|
|
|
|
|
.clock-btn { |
|
|
|
position: absolute; |
|
|
|
} |
|
|
|
|
|
|
|
.clock-select { |
|
|
|
position: relative; |
|
|
|
min-width: auto !important; |
|
|
|
width: 47px; |
|
|
|
height: 20px; |
|
|
|
overflow: hidden; |
|
|
|
z-index: 9; |
|
|
|
opacity: 0; |
|
|
|
.teble-box >>> .ant-table-row-cell-break-word { |
|
|
|
padding: 8px 0 !important; |
|
|
|
} |
|
|
|
</style> |
|
|
|