task_auto_plan/include/app.hpp

241 lines
6.9 KiB
C++
Raw Permalink Normal View History

2026-04-25 03:15:03 +00:00
#ifndef ATTENDANCE_SYSTEM_APP_HPP
#define ATTENDANCE_SYSTEM_APP_HPP
#include <string>
#include <vector>
#include <map>
#include <ctime>
#include <memory>
#include <functional>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <stdexcept>
#include <cassert>
// ============================================================
// 常量与枚举
// ============================================================
/// 打卡类型
enum class CheckType {
Unknown,
ClockIn, // 上班打卡
ClockOut // 下班打卡
};
/// 异常标记
enum class AbnormalFlag {
None,
Late, // 迟到
EarlyLeave, // 早退
Absenteeism // 旷工
};
/// 报表输出格式
enum class ReportFormat {
Excel,
PDF
};
/// 预警发送状态
enum class AlertStatus {
Pending,
Sent,
Failed,
Read
};
/// 角色类型RBAC
enum class RoleType {
Employee,
DeptManager,
HRAdmin,
SystemAdmin
};
// ============================================================
// 数据结构定义
// ============================================================
/// 员工信息
struct Employee {
std::string employeeId;
std::string name;
std::string department;
std::string position;
std::string shiftId;
std::string phone;
RoleType role{RoleType::Employee};
// 脱敏手机号显示后4位明文
std::string maskedPhone() const {
if (phone.length() != 11) return "***";
return "*******" + phone.substr(7);
}
};
/// 排班规则
struct ShiftRule {
std::string shiftId;
std::string shiftName;
int startHour{9}; // 上班小时
int startMin{0}; // 上班分钟
int endHour{18}; // 下班小时
int endMin{0}; // 下班分钟
int flexWindow{30}; // 弹性时间窗口(分钟)
int graceLate{15}; // 迟到宽限分钟
/// 获取上班时间(分钟偏移量)
int workStartMinutes() const { return startHour * 60 + startMin; }
/// 获取下班时间(分钟偏移量)
int workEndMinutes() const { return endHour * 60 + endMin; }
};
/// 打卡流水记录
struct CheckInRecord {
std::string recordId;
std::string employeeId;
std::time_t timestamp{0};
CheckType type{CheckType::Unknown};
std::string deviceId;
std::string latitude;
std::string longitude;
bool verified{false};
};
/// 考勤核算结果(按天)
struct DailyAttendance {
std::string dateStr;
std::string employeeId;
int expectedMinutes{0}; // 应出勤分钟
int actualMinutes{0}; // 实际出勤分钟
int overtimeMinutes{0}; // 加班分钟
int leaveDeduction{0}; // 调休抵扣分钟
AbnormalFlag abnormal{AbnormalFlag::None};
/// 有效出勤率(%
double attendanceRate() const {
if (expectedMinutes == 0) return 100.0;
return 100.0 * actualMinutes / expectedMinutes;
}
/// 是否异常
bool hasAbnormal() const { return abnormal != AbnormalFlag::None; }
std::string abnormalStr() const {
switch (abnormal) {
case AbnormalFlag::Late: return "迟到";
case AbnormalFlag::EarlyLeave: return "早退";
case AbnormalFlag::Absenteeism: return "旷工";
default: return "正常";
}
}
};
/// 异常预警日志
struct AlertLog {
std::string alertId;
std::string employeeId;
AbnormalFlag type{AbnormalFlag::None};
std::time_t occurTime{0};
std::string channel; // 通知渠道:站内信/短信/企业微信
AlertStatus status{AlertStatus::Pending};
int retryCount{0};
};
/// 报表任务
struct ReportTask {
std::string taskId;
std::string requester;
std::string deptId;
std::string dateRangeBegin;
std::string dateRangeEnd;
ReportFormat format{ReportFormat::Excel};
std::string status{"Pending"}; // Pending / Running / Done / Failed
std::string downloadUrl;
std::time_t createTime{0};
};
/// 权限配置RBAC
struct Permission {
std::string resource; // 资源路径,如 "/api/v1/reports"
std::string action; // 操作READ / WRITE / DELETE
};
// ============================================================
// 业务逻辑类
// ============================================================
class AttendanceService {
public:
AttendanceService();
// ---- 员工管理 ----
void addEmployee(const Employee& emp);
const Employee* findEmployee(const std::string& id) const;
std::vector<Employee> getEmployeesByDept(const std::string& dept) const;
// ---- 排班管理 ----
void addShiftRule(const ShiftRule& rule);
const ShiftRule* findShift(const std::string& shiftId) const;
// ---- 打卡处理 ----
CheckInRecord processCheckIn(const std::string& employeeId,
CheckType type,
const std::string& deviceId,
std::time_t timestamp);
std::vector<CheckInRecord> getRecords(const std::string& employeeId) const;
// ---- 考勤核算 ----
DailyAttendance calculateDaily(const std::string& employeeId,
const std::string& dateStr);
std::vector<DailyAttendance> generateReport(const std::string& deptId,
const std::string& dateBegin,
const std::string& dateEnd);
// ---- 异常预警 ----
AlertLog createAlert(const std::string& employeeId, AbnormalFlag type);
std::vector<AlertLog> getAlerts(const std::string& employeeId) const;
// ---- 报表任务 ----
ReportTask createReportTask(const std::string& requester,
const std::string& deptId,
const std::string& dateBegin,
const std::string& dateEnd,
ReportFormat fmt);
void completeTask(const std::string& taskId, const std::string& url);
// ---- 工具 ----
static std::string timeToString(std::time_t t);
static std::string currentDateStr();
static std::time_t parseDate(const std::string& dateStr);
private:
std::map<std::string, Employee> employees_;
std::map<std::string, ShiftRule> shifts_;
std::vector<CheckInRecord> records_;
std::vector<AlertLog> alerts_;
std::vector<ReportTask> tasks_;
int idCounter_{0};
std::string nextId();
int minutesFromMidnight(std::time_t t) const;
bool isSameDate(std::time_t t, const std::string& dateStr) const;
};
// ============================================================
// 工具函数声明
// ============================================================
/// 脱敏工具:将敏感字符串中间部分替换为 '*'
std::string maskSensitive(const std::string& input, size_t visibleHead = 2, size_t visibleTail = 2);
/// 格式化输出一行分隔线
void printSeparator(char ch = '=', size_t count = 60);
#endif // ATTENDANCE_SYSTEM_APP_HPP