Browse Source

调整打卡细节

master
song 4 years ago
parent
commit
84f543d6c9
  1. 4
      rest/project.http
  2. 10
      src/App.vue
  3. 296
      src/components/List/List.vue
  4. 2
      src/components/MemberPicker/MemberPicker.vue
  5. 59
      src/components/TimePicker/TimePicker.vue
  6. 2
      src/plugins/ant-design-vue.js

4
rest/project.http

@ -7,8 +7,8 @@ content-type: application/json;charset=utf-8
{ {
"client": 1, "client": 1,
"data": { "data": {
"credential": "123456", "credential": "999999",
"identifier": "zb" "identifier": "song"
}, },
"scene": 0, "scene": 0,
"type": 3 "type": 3

10
src/App.vue

@ -1,8 +1,10 @@
<template> <template>
<div id="app"> <a-locale-provider :locale="zh_CN">
<head-nav class="head-nav" /> <div id="app">
<router-view></router-view> <head-nav class="head-nav" />
</div> <router-view></router-view>
</div>
</a-locale-provider>
</template> </template>
<script> <script>

296
src/components/List/List.vue

@ -6,141 +6,145 @@
<div class="table-head-item"></div> <div class="table-head-item"></div>
<div class="table-head-item" style="width: 30%">审核人</div> <div class="table-head-item" style="width: 30%">审核人</div>
</div> </div>
<div v-if="clockInfos && clockInfos.length"> <div id="scrollTo">
<div v-for="(list, listIndex) in clockInfos" :key="listIndex" class="teble-box"> <div v-if="clockInfos && clockInfos.length">
<div class="table-time px-2">{{ list.dateTime }}</div> <div v-for="(list, listIndex) in clockInfos" :key="listIndex" class="teble-box">
<a-table :pagination="false" :show-header="false" :columns="columns" :data-source="list.recordList"> <div class="table-time px-2">{{ list.dateTime }}</div>
<!-- --> <a-table :pagination="false" :show-header="false" :columns="columns" :data-source="list.recordList">
<template slot="morning" slot-scope="text, record, index"> <!-- -->
<div v-if="!record.isMine && !record.isChecker"> <template slot="morning" slot-scope="text, record, index">
<span v-if="record.morningStatus">{{ $moment(record.morning - 0).format('HH:mm') }}</span> <div v-if="!record.isMine && !record.isChecker">
<span v-else>未打卡</span> <span v-if="record.morningStatus">{{ $moment(record.morning - 0).format('HH:mm') }}</span>
</div> <span v-else>未打卡</span>
<div v-else>
<div v-if="record.isMine">
<span v-if="record.morningStatus" class="baseColor font-bold">
{{ $moment(record.morning - 0).format('HH:mm') }}
</span>
<a-button
v-else
type="primary"
size="small"
@click="checkTime(listIndex, index, 0, record.id, record.memberId, record.checkerId)"
>
打卡
</a-button>
</div> </div>
<div v-if="record.isChecker"> <div v-else>
<div v-if="record.morningStatus && !showMorningTime"> <div v-if="record.isMine">
<a-popconfirm <span v-if="record.morningStatus" class="baseColor font-bold">
ok-text="取消" {{ $moment(record.morning - 0).format('HH:mm') }}
cancel-text="修改" </span>
ok-type="" <a-button
@confirm="cancel" v-else
:visible="morningVisible" type="primary"
@cancel="changeStatus(record.id, 0, 'morning')" size="small"
:loading="morningLoading"
@click="checkTime(listIndex, index, 0, record.id, record.memberId, record.checkerId, list.dateTime)"
> >
<a-icon slot="icon" type="" /> 打卡
<a-button slot="title" size="small" @click="rejectStatus(record.id, 1, 'morning', record.morning)">驳回</a-button> </a-button>
<span </div>
class="font-bold"
:class="record.morningStatus === 2 ? 'line-through red--text' : 'green--text'" <div v-if="record.isChecker">
@click="changeVisible(record.morningStatus, 'morningVisible')" <div v-if="record.morningStatus && !showMorningTime">
<a-popconfirm
ok-text="取消"
cancel-text="修改"
ok-type=""
@confirm="cancel"
:visible="morningVisible"
@cancel="changeStatus(record.id, 0, 'morning')"
> >
{{ $moment(record.morning - 0).format('HH:mm') }} <a-icon slot="icon" type="" />
</span> <a-button slot="title" size="small" @click="rejectStatus(record.id, 1, 'morning', record.morning)">驳回</a-button>
</a-popconfirm> <span
class="font-bold"
:class="record.morningStatus === 2 ? 'line-through red--text' : 'green--text'"
@click="changeVisible(record.morningStatus, 'morningVisible')"
>
{{ $moment(record.morning - 0).format('HH:mm') }}
</span>
</a-popconfirm>
</div>
<div v-if="!record.morningStatus && !showMorningTime">未打卡</div>
<!-- 修改时间 -->
<a-time-picker
placeholder="请选择"
style="width: 100%"
v-if="showMorningTime"
format="HH:mm"
class="px-2"
@change="timeChange"
@openChange="openChange($event, 'morning')"
/>
</div> </div>
<div v-if="!record.morningStatus && !showMorningTime">未打卡</div>
<!-- 修改时间 -->
<a-time-picker
placeholder="请选择"
style="width: 100%"
v-if="showMorningTime"
format="HH:mm"
class="px-2"
@change="timeChange"
@openChange="openChange($event, 'morning')"
/>
</div> </div>
</div> </template>
</template> <!-- -->
<!-- --> <template slot="night" slot-scope="text, record, index">
<template slot="night" slot-scope="text, record, index"> <div v-if="!record.isMine && !record.isChecker">
<div v-if="!record.isMine && !record.isChecker"> <span v-if="record.nightStatus">{{ $moment(record.night - 0).format('HH:mm') }}</span>
<span v-if="record.nightStatus">{{ $moment(record.night - 0).format('HH:mm') }}</span> <span v-else>未打卡</span>
<span v-else>未打卡</span>
</div>
<div v-else>
<div v-if="record.isMine">
<span v-if="record.nightStatus" class="baseColor font-bold">
{{ $moment(record.night - 0).format('HH:mm') }}
</span>
<a-button
v-else
type="primary"
size="small"
@click="checkTime(listIndex, index, 1, record.id, record.memberId, record.checkerId)"
>
打卡
</a-button>
</div> </div>
<div v-if="record.isChecker"> <div v-else>
<div v-if="record.nightStatus && !showNightTime"> <div v-if="record.isMine">
<a-popconfirm <span v-if="record.nightStatus" class="baseColor font-bold">
ok-text="取消" {{ $moment(record.night - 0).format('HH:mm') }}
cancel-text="修改" </span>
ok-type="" <a-button
@confirm="cancel" v-else
:visible="visible" type="primary"
@cancel="changeStatus(record.id, 0, 'night')" size="small"
:loading="nightLoading"
@click="checkTime(listIndex, index, 1, record.id, record.memberId, record.checkerId, list.dateTime)"
> >
<a-icon slot="icon" type="" /> 打卡
<a-button slot="title" size="small" @click="rejectStatus(record.id, 1, 'night', record.night)">驳回</a-button> </a-button>
<span </div>
class="font-bold"
:class="record.nightStatus === 2 ? 'line-through red--text' : 'green--text'" <div v-if="record.isChecker">
@click="changeVisible(record.nightStatus, 'visible')" <div v-if="record.nightStatus && !showNightTime">
<a-popconfirm
ok-text="取消"
cancel-text="修改"
ok-type=""
@confirm="cancel"
:visible="visible"
@cancel="changeStatus(record.id, 0, 'night')"
> >
{{ $moment(record.night - 0).format('HH:mm') }} <a-icon slot="icon" type="" />
</span> <a-button slot="title" size="small" @click="rejectStatus(record.id, 1, 'night', record.night)">驳回</a-button>
</a-popconfirm> <span
class="font-bold"
:class="record.nightStatus === 2 ? 'line-through red--text' : 'green--text'"
@click="changeVisible(record.nightStatus, 'visible')"
>
{{ $moment(record.night - 0).format('HH:mm') }}
</span>
</a-popconfirm>
</div>
<div v-if="!record.nightStatus && !showNightTime">未打卡</div>
<!-- 修改时间 -->
<a-time-picker
placeholder="请选择"
style="width: 100%"
v-if="showNightTime"
format="HH:mm"
class="px-2"
@change="timeChange"
@openChange="openChange($event, 'night')"
/>
</div> </div>
<div v-if="!record.nightStatus && !showNightTime">未打卡</div>
<!-- 修改时间 -->
<a-time-picker
placeholder="请选择"
style="width: 100%"
v-if="showNightTime"
format="HH:mm"
class="px-2"
@change="timeChange"
@openChange="openChange($event, 'night')"
/>
</div> </div>
</div> </template>
</template> <!-- 审核人 -->
<!-- 审核人 --> <template slot="checkerName" slot-scope="text, record">
<template slot="checkerName" slot-scope="text, record"> <div class="px-2">
<div class="px-2"> <div v-if="!record.isMine || (record.isMine && record.morningStatus && record.nightStatus)">
<div v-if="!record.isMine || (record.isMine && record.morningStatus && record.nightStatus)"> {{ record.checkerName || members[0].name }}
{{ record.checkerName || members[0].name }} </div>
<a-select v-else :default-value="record.checkerId || members[0].memberId" style="width: 100%" @change="chooseChecker">
<a-select-option :value="member.memberId" v-for="member in members" :key="member.memberId">
{{ member.name }}
</a-select-option>
</a-select>
</div> </div>
<a-select v-else :default-value="record.checkerId || members[0].memberId" style="width: 100%" @change="chooseChecker"> </template>
<a-select-option :value="member.memberId" v-for="member in members" :key="member.memberId"> </a-table>
{{ member.name }} </div>
</a-select-option>
</a-select>
</div>
</template>
</a-table>
</div> </div>
<a-empty class="mt-8 mb-8" description="暂无打卡信息" v-else />
</div> </div>
<a-empty class="mt-8 mb-8" description="暂无打卡信息" v-else />
</div> </div>
</template> </template>
@ -178,16 +182,26 @@ export default {
showMorningTime: false, showMorningTime: false,
chooseTime: '', chooseTime: '',
auditOptions: null, auditOptions: null,
morningLoading: false,
nightLoading: false,
startTime: '',
endTime: '',
}; };
}, },
computed: mapState('home', ['projectId', 'members']), computed: mapState('home', ['projectId', 'members']),
mounted() { mounted() {
this.timer = setInterval(() => { this.timer = setInterval(async () => {
if (this.projectId) { if (this.projectId) {
clearInterval(this.timer); clearInterval(this.timer);
this.setParams(); await this.setParams();
//
document.querySelector('#scrollTo').scrollIntoView({
behavior: 'smooth', //
block: 'start', //
});
} }
}, 300); }, 300);
}, },
@ -196,10 +210,10 @@ export default {
async setParams(options) { async setParams(options) {
const { projectId } = this; const { projectId } = this;
const time = this.$moment(Date.now()).format('YYYY-MM-DD'); const time = this.$moment(Date.now()).format('YYYY-MM-DD');
const startTime = (options && options.startTime) || this.$moment(`${time} 00:00`).format('x') - 0; this.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; this.endTime = (options && options.endTime) || this.$moment(`${time} 23:59`).format('x') - 0;
const memberIdList = (options && options.memberIdList) || this.memberIdList; this.memberIdList = (options && options.memberIdList) || [];
const params = { param: { projectId, memberIdList, startTime, endTime } }; const params = { param: { projectId, memberIdList: this.memberIdList, startTime: this.startTime, endTime: this.endTime } };
await this.getClockQuery(params); await this.getClockQuery(params);
}, },
@ -231,7 +245,7 @@ export default {
}, },
// //
checkTime(listIndex, index, clockType, id, memberId, checkerId) { checkTime(listIndex, index, clockType, id, memberId, checkerId, clockTime) {
const time = Date.now(); const time = Date.now();
const selectTime = this.$moment(time).format('HH:mm'); const selectTime = this.$moment(time).format('HH:mm');
if (clockType === 0) { if (clockType === 0) {
@ -239,7 +253,7 @@ export default {
} else { } else {
this.clockInfos[listIndex].recordList[index].night = selectTime; this.clockInfos[listIndex].recordList[index].night = selectTime;
} }
const dateTime = this.$moment(time).format('x') - 0; const dateTime = this.$moment(`${clockTime} ${selectTime}`).format('x') - 0;
const params = { param: { checkerId: this.checkerId || checkerId || this.members[0].memberId, clockType, dateTime, id, memberId } }; const params = { param: { checkerId: this.checkerId || checkerId || this.members[0].memberId, clockType, dateTime, id, memberId } };
this.handleClockPunch(params); this.handleClockPunch(params);
}, },
@ -254,16 +268,32 @@ export default {
*/ */
async handleClockPunch(params) { async handleClockPunch(params) {
try { try {
if (params.param.clockType === 0) {
this.morningLoading = true;
} else {
this.nightLoading = true;
}
const res = await clockPunch(params); const res = await clockPunch(params);
const { code, msg } = res.data; const { code, msg } = res.data;
if (code === 200) { if (code === 200) {
this.$message.success('打卡成功'); this.$message.success('打卡成功');
this.setParams(); const options = { startTime: this.startTime, endTime: this.endTime, memberIdList: this.memberIdList };
this.setParams(options);
} else { } else {
this.$message.error(msg || '打卡失败'); this.$message.error(msg || '打卡失败');
throw msg; throw msg;
} }
if (params.param.clockType === 0) {
this.morningLoading = false;
} else {
this.nightLoading = false;
}
} catch (error) { } catch (error) {
if (params.param.clockType === 0) {
this.morningLoading = false;
} else {
this.nightLoading = false;
}
throw error || '打卡失败'; throw error || '打卡失败';
} }
}, },
@ -336,7 +366,8 @@ export default {
this.showNightTime = false; this.showNightTime = false;
this.showMorningTime = false; this.showMorningTime = false;
this.auditOptions = null; this.auditOptions = null;
this.setParams(); const options = { startTime: this.startTime, endTime: this.endTime, memberIdList: this.memberIdList };
this.setParams(options);
} else { } else {
this.$message.error(msg || '审核失败'); this.$message.error(msg || '审核失败');
throw msg; throw msg;
@ -359,9 +390,10 @@ export default {
} }
.table-time { .table-time {
height: 36px; height: 30px;
line-height: 36px; line-height: 30px;
border-bottom: 1px solid #e8e8e8; border-bottom: 1px solid #e8e8e8;
background: #fafafa;
} }
.table-head-item { .table-head-item {

2
src/components/MemberPicker/MemberPicker.vue

@ -22,7 +22,7 @@ export default {
setTimeout(() => { setTimeout(() => {
const options = { memberIdList: value }; const options = { memberIdList: value };
this.$emit('changeTime', options); this.$emit('changeTime', options);
}, 800); }, 1000);
}, },
}, },
}; };

59
src/components/TimePicker/TimePicker.vue

@ -3,24 +3,36 @@
<a-date-picker <a-date-picker
v-model="startValue" v-model="startValue"
:disabled-date="disabledStartDate" :disabled-date="disabledStartDate"
show-time
allow-clear allow-clear
locale="zh-cn" locale="zh-cn"
:format="monthFormat" :format="monthFormat"
placeholder="起始时间" placeholder="起始时间"
class="box box1" class="box box1"
:show-today="false"
:open="startOpen"
@openChange="handleStartOpenChange" @openChange="handleStartOpenChange"
/> >
<template slot="renderExtraFooter">
<a-button size="small" type="primary" ghost @click="setYesterday('startValue', 'startOpen')">昨天</a-button>
<a-button class="ml-3" size="small" type="primary" ghost @click="setToday('startValue', 'startOpen')">今天</a-button>
</template>
</a-date-picker>
<a-date-picker <a-date-picker
v-model="endValue" v-model="endValue"
:disabled-date="disabledEndDate" :disabled-date="disabledEndDate"
allow-clear allow-clear
:format="monthFormat" :format="monthFormat"
class="box box2" class="box box2"
:show-today="false"
placeholder="截止时间" placeholder="截止时间"
:open="endOpen" :open="endOpen"
@openChange="handleEndOpenChange" @openChange="handleEndOpenChange"
/> >
<template slot="renderExtraFooter">
<a-button size="small" type="primary" ghost @click="setYesterday('endValue', 'endOpen')">昨天</a-button>
<a-button class="ml-3" size="small" type="primary" ghost @click="setToday('endValue', 'endOpen')">今天</a-button>
</template>
</a-date-picker>
</div> </div>
</template> </template>
@ -31,18 +43,42 @@ export default {
monthFormat: 'YYYY-MM-DD', monthFormat: 'YYYY-MM-DD',
startValue: null, startValue: null,
endValue: null, endValue: null,
startOpen: false,
endOpen: false, endOpen: false,
}; };
}, },
watch: { watch: {
startValue(val) {
console.log('startValue', val);
},
endValue(val) { endValue(val) {
console.log('endValue', val); if (!this.startValue) {
this.$message.error('请选择起始时间');
return;
}
if (this.startValue && val) {
const startTime = this.$moment(this.startValue).format('x');
const endTime = this.$moment(this.endValue).format('x');
const options = { startTime, endTime };
this.$emit('changeTime', options);
}
}, },
}, },
methods: { methods: {
//
setYesterday(value, open) {
this[value] = this.$moment(new Date().getTime() - 24 * 60 * 60 * 1000).format('YYYY-MM-DD');
this[open] = false;
if (open === 'startOpen' && !this.startOpen) {
this.endOpen = true;
}
},
setToday(value, open) {
this[value] = this.$moment(new Date()).format('YYYY-MM-DD');
this[open] = false;
if (open === 'startOpen' && !this.startOpen) {
this.endOpen = true;
}
},
disabledStartDate(startValue) { disabledStartDate(startValue) {
const endValue = this.endValue; const endValue = this.endValue;
if (!startValue || !endValue) { if (!startValue || !endValue) {
@ -58,20 +94,13 @@ export default {
return startValue.valueOf() >= endValue.valueOf(); return startValue.valueOf() >= endValue.valueOf();
}, },
handleStartOpenChange(open) { handleStartOpenChange(open) {
this.startOpen = open;
if (!open) { if (!open) {
this.endOpen = true; this.endOpen = true;
} }
}, },
handleEndOpenChange(open) { handleEndOpenChange(open) {
this.endOpen = open; this.endOpen = open;
if (!this.startValue) {
this.$message.error('请选择起始时间');
} else {
const startTime = this.$moment(this.startValue).format('x');
const endTime = this.$moment(this.endValue).format('x');
const options = { startTime, endTime };
this.$emit('changeTime', options);
}
}, },
}, },
}; };

2
src/plugins/ant-design-vue.js

@ -44,6 +44,7 @@ import {
Skeleton, Skeleton,
Drawer, Drawer,
TimePicker, TimePicker,
LocaleProvider,
} from 'ant-design-vue'; } from 'ant-design-vue';
import { ConfigProvider } from 'ant-design-vue'; import { ConfigProvider } from 'ant-design-vue';
Vue.component(ConfigProvider.name, ConfigProvider); Vue.component(ConfigProvider.name, ConfigProvider);
@ -82,6 +83,7 @@ Vue.use(Card);
Vue.use(Skeleton); Vue.use(Skeleton);
Vue.use(Drawer); Vue.use(Drawer);
Vue.use(TimePicker); Vue.use(TimePicker);
Vue.use(LocaleProvider);
Vue.prototype.$message = message; Vue.prototype.$message = message;
Vue.prototype.$notification = notification; Vue.prototype.$notification = notification;

Loading…
Cancel
Save