vue打卡考勤如何实现
实现 Vue 打卡考勤功能
前端实现(Vue.js)
使用 Vue 3 的 Composition API 结合 Element Plus 或 Ant Design Vue 组件库构建打卡界面。创建一个打卡按钮组件,绑定点击事件触发打卡操作。
<template>
<div class="attendance-container">
<el-button type="primary" @click="handleClockIn" :disabled="isClockedIn">
{{ isClockedIn ? '已打卡' : '上班打卡' }}
</el-button>
<el-button type="success" @click="handleClockOut" :disabled="!isClockedIn">
下班打卡
</el-button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { clockIn, clockOut } from '@/api/attendance'
const isClockedIn = ref(false)
const handleClockIn = async () => {
try {
await clockIn({ timestamp: new Date() })
isClockedIn.value = true
ElMessage.success('打卡成功')
} catch (error) {
ElMessage.error(error.message)
}
}
const handleClockOut = async () => {
try {
await clockOut({ timestamp: new Date() })
isClockedIn.value = false
ElMessage.success('签退成功')
} catch (error) {
ElMessage.error(error.message)
}
}
</script>
后端接口设计
需要提供两个核心 API 端点:
- POST
/api/attendance/clock-in处理上班打卡 - POST
/api/attendance/clock-out处理下班打卡
建议后端验证:

- 防止重复打卡(同一用户同一天只能打卡一次)
- 检查打卡时间是否在合理范围内(如上班时间9:00-10:00有效)
- 记录地理位置信息(如需)
数据库设计
MySQL 示例表结构:
CREATE TABLE `attendance_records` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '用户ID',
`clock_in_time` datetime DEFAULT NULL COMMENT '上班打卡时间',
`clock_out_time` datetime DEFAULT NULL COMMENT '下班打卡时间',
`location` varchar(255) DEFAULT NULL COMMENT 'GPS坐标',
`ip_address` varchar(50) DEFAULT NULL COMMENT '打卡IP',
`device_info` varchar(255) DEFAULT NULL COMMENT '设备信息',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_user_date` (`user_id`, `date(clock_in_time)`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
高级功能实现
地理位置验证 使用浏览器 Geolocation API 获取用户坐标:

const getLocation = () => {
return new Promise((resolve, reject) => {
if (!navigator.geolocation) {
reject(new Error('浏览器不支持地理位置功能'))
}
navigator.geolocation.getCurrentPosition(
position => resolve({
lat: position.coords.latitude,
lng: position.coords.longitude
}),
error => reject(error)
)
})
}
人脸识别集成 通过 WebRTC 调用摄像头拍照后调用人脸识别 API:
const openCamera = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ video: true })
videoElement.srcObject = stream
}
const captureFace = () => {
const canvas = document.createElement('canvas')
canvas.width = videoElement.videoWidth
canvas.height = videoElement.videoHeight
canvas.getContext('2d').drawImage(videoElement, 0, 0)
return canvas.toDataURL('image/jpeg')
}
数据统计展示
使用 ECharts 实现打卡数据可视化:
<template>
<div ref="chart" style="width: 600px; height: 400px;"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
const chart = ref(null)
onMounted(() => {
const myChart = echarts.init(chart.value)
myChart.setOption({
title: { text: '月度考勤统计' },
tooltip: {},
xAxis: { data: ['1日', '2日', '3日'] },
yAxis: {},
series: [{
name: '迟到次数',
type: 'bar',
data: [5, 20, 36]
}]
})
})
</script>
注意事项
- 时区处理:所有时间建议使用 UTC 存储,显示时转换本地时区
- 数据安全:敏感操作需要增加二次验证(短信/邮箱验证码)
- 离线模式:考虑使用 Service Worker 实现离线打卡数据暂存
- 考勤规则:需要支持灵活配置工作日、节假日和特殊考勤规则
以上方案可根据实际需求进行组合或删减,建议先实现核心打卡功能再逐步扩展高级特性。






