|
@@ -0,0 +1,154 @@
|
|
|
|
+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(data, res) {
|
|
|
|
+ this.setAllowCORS(res);
|
|
|
|
+ let {
|
|
|
|
+ uuid,
|
|
|
|
+ session,
|
|
|
|
+ project_id
|
|
|
|
+ } = data;
|
|
|
|
+
|
|
|
|
+ // 检查必需的参数是否缺失
|
|
|
|
+ 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 = JSON.parse(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);
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+module.exports.AddAttendanceRecord = AddAttendanceRecord;
|