vue实现刷卡考勤
Vue 实现刷卡考勤系统
系统架构设计
刷卡考勤系统通常需要前后端配合实现。Vue作为前端框架负责界面交互,后端处理数据存储和逻辑验证。
前端实现步骤
安装必要依赖
npm install axios vue-router vuex
创建考勤页面组件
<template>
<div class="attendance-container">
<h3>刷卡考勤系统</h3>
<div class="card-reader">
<input
type="text"
v-model="cardId"
placeholder="请刷卡或输入卡号"
@keyup.enter="handleAttendance"
/>
</div>
<div class="result-message" :class="{'success': isSuccess, 'error': isError}">
{{ message }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
cardId: '',
message: '',
isSuccess: false,
isError: false
}
},
methods: {
async handleAttendance() {
try {
const response = await axios.post('/api/attendance', {
cardId: this.cardId,
timestamp: new Date().toISOString()
});
this.message = response.data.message;
this.isSuccess = true;
this.isError = false;
// 3秒后清空输入框
setTimeout(() => {
this.cardId = '';
}, 3000);
} catch (error) {
this.message = error.response.data.error || '考勤失败';
this.isError = true;
this.isSuccess = false;
}
}
}
}
</script>
配置路由
// router/index.js
import Attendance from '../views/Attendance.vue'
const routes = [
{
path: '/attendance',
name: 'Attendance',
component: Attendance
}
]
后端接口设计
基本考勤接口

// Node.js示例
router.post('/api/attendance', async (req, res) => {
const { cardId, timestamp } = req.body;
try {
// 验证卡号有效性
const employee = await Employee.findOne({ cardId });
if (!employee) {
return res.status(400).json({ error: '无效卡号' });
}
// 记录考勤
const record = new AttendanceRecord({
employeeId: employee._id,
checkInTime: new Date(timestamp),
status: '正常'
});
await record.save();
res.json({ message: `考勤成功,欢迎${employee.name}` });
} catch (err) {
res.status(500).json({ error: '服务器错误' });
}
});
硬件集成方案
串口通信方案
// 使用serialport库与读卡器通信
const SerialPort = require('serialport');
const Readline = require('@serialport/parser-readline');
const port = new SerialPort('/dev/ttyUSB0', { baudRate: 9600 });
const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
parser.on('data', (cardId) => {
// 将卡号发送到前端
io.emit('card-read', cardId.trim());
});
前端接收硬件信号
// 使用Socket.io接收实时卡号
import io from 'socket.io-client';
export default {
created() {
this.socket = io('http://localhost:3000');
this.socket.on('card-read', (cardId) => {
this.cardId = cardId;
this.handleAttendance();
});
}
}
数据可视化
考勤记录展示

<template>
<div class="records-container">
<h3>考勤记录</h3>
<table>
<thead>
<tr>
<th>员工姓名</th>
<th>刷卡时间</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr v-for="record in records" :key="record._id">
<td>{{ record.employee.name }}</td>
<td>{{ formatDate(record.checkInTime) }}</td>
<td>{{ record.status }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
records: []
}
},
async created() {
const response = await axios.get('/api/attendance/records');
this.records = response.data;
},
methods: {
formatDate(dateString) {
return new Date(dateString).toLocaleString();
}
}
}
</script>
安全增强措施
防止重复刷卡
// 后端验证逻辑
const existingRecord = await AttendanceRecord.findOne({
employeeId: employee._id,
checkInTime: {
$gte: new Date().setHours(0, 0, 0, 0),
$lt: new Date().setHours(23, 59, 59, 999)
}
});
if (existingRecord) {
return res.status(400).json({ error: '今日已打卡' });
}
数据加密传输
// 前端axios配置
axios.defaults.baseURL = 'https://your-domain.com/api';
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
扩展功能
考勤统计报表
// 后端统计接口
router.get('/api/attendance/stats', async (req, res) => {
const stats = await AttendanceRecord.aggregate([
{
$match: {
checkInTime: {
$gte: new Date(req.query.startDate),
$lt: new Date(req.query.endDate)
}
}
},
{
$group: {
_id: "$employeeId",
count: { $sum: 1 },
lateCount: {
$sum: {
$cond: [{ $eq: ["$status", "迟到"] }, 1, 0]
}
}
}
}
]);
res.json(stats);
});
移动端适配
/* 响应式设计 */
@media (max-width: 768px) {
.attendance-container {
padding: 10px;
}
input[type="text"] {
width: 90%;
font-size: 16px;
}
}
该系统实现方案涵盖了从硬件集成到前后端开发的完整流程,可根据实际需求进行扩展和调整。






