const API = require("../../lib/API"); const { BaseStdResponse } = require("../../BaseStdResponse"); const db = require("../../plugin/DataBase/db"); const AccessControl = require("../../lib/AccessControl"); class AddAttendanceRecord extends API { constructor() { super(); this.setPath('/AddAttendanceRecord'); this.setMethod('GET'); } async onRequest(req, res) { let { uuid, session, project_id } = req.query; // 检查必需的参数是否缺失 if ([uuid, session, project_id].some(value => value === '' || value === null || value === undefined)) { res.json({ ...BaseStdResponse.MISSING_PARAMETER, endpoint: 1513123 }); return; } // 检查 session 是否有效 if (!await AccessControl.checkSession(uuid, session)) { res.json({ ...BaseStdResponse.ACCESS_DENIED, endpoint: 48153145 }); return; } // 获取考勤项目 const sqlGetProject = 'SELECT user, day_of_week, loopy, begintime, endtime FROM kq_items WHERE id = ?'; let projectResult = await db.query(sqlGetProject, [project_id]); if (!projectResult || projectResult.length === 0) { res.json({ ...BaseStdResponse.DATABASE_ERR, endpoint: 154754511 }); return; } let projectData = projectResult[0]; let users = projectData.user; if (!users.includes(uuid)) { res.json({ ...BaseStdResponse.ERR, endpoint: 481454, msg: '用户不在考勤名单中' }); return; } const isWithinTime = this.isWithinAttendanceTime(projectData); if (!isWithinTime) { return res.json({ ...BaseStdResponse.ERR, endpoint: 513513, msg: '未在打卡时间段内' }); } // 检查是否已存在考勤记录 const sqlCheckRecord = 'SELECT id, uuid, time FROM kq_records WHERE project_id = ? AND uuid = ?'; let recordsResult = await db.query(sqlCheckRecord, [project_id, uuid]); if (!recordsResult) { return res.json({ ...BaseStdResponse.DATABASE_ERR, endpoint: 513513 }); } if (recordsResult.length !== 0 && this.hasRecord(projectData, recordsResult, uuid)) { return res.json({ ...BaseStdResponse.ERR, endpoint: 513513, msg: '用户在本考勤周期已有考勤记录!' }); } // 插入考勤记录 const sqlInsertRecord = 'INSERT INTO kq_records (project_id, uuid, time) VALUES (?, ?, ?)'; let insertResult = await db.query(sqlInsertRecord, [project_id, uuid, new Date().getTime()]); if (insertResult.affectedRows !== 1) { return res.json({ ...BaseStdResponse.DATABASE_ERR, endpoint: 513513 }); } res.json({ ...BaseStdResponse.OK }); } isWithinAttendanceTime(attendanceTimes) { const now = new Date(); const dayOfWeek = now.getDay(); const nowTime = now.getTime(); function timeToTodayTimestamp(timeStr) { const [hours, minutes, seconds] = timeStr.split(':').map(Number); const todayWithTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes, seconds); return todayWithTime.getTime(); } const { createTime, day_of_week, begintime, endtime, loopy } = attendanceTimes if (dayOfWeek === day_of_week && (loopy || (Number(createTime) + 604800000 - nowTime > 0)) && timeToTodayTimestamp(begintime) <= nowTime && timeToTodayTimestamp(endtime) >= nowTime) { return true; } return false } hasRecord(attendanceData, records, uuid) { const { day_of_week, begintime, endtime, loopy } = attendanceData; if (!loopy) { return records.some(record => record.uuid === uuid); } const now = new Date(); const dayOfWeek = now.getDay(); const nowTime = now.getTime(); function getTimestamp(time) { const daysUntilTarget = (day_of_week - dayOfWeek + 7) % 7; const targetDate = new Date(now); targetDate.setDate(now.getDate() + daysUntilTarget); const [hours, minutes, seconds] = time.split(':').map(Number); targetDate.setHours(hours, minutes, seconds, 0); return targetDate.getTime(); } const begin = getTimestamp(begintime); const end = getTimestamp(endtime); if (nowTime >= begin) { return records.some(record => record.time >= begin && record.time <= end && record.uuid === uuid); } } } module.exports.AddAttendanceRecord = AddAttendanceRecord;