#ifndef ATTENDANCE_SYSTEM_APP_HPP #define ATTENDANCE_SYSTEM_APP_HPP #include #include #include #include #include #include #include #include #include #include #include // ============================================================ // 常量与枚举 // ============================================================ /// 打卡类型 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 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 getRecords(const std::string& employeeId) const; // ---- 考勤核算 ---- DailyAttendance calculateDaily(const std::string& employeeId, const std::string& dateStr); std::vector generateReport(const std::string& deptId, const std::string& dateBegin, const std::string& dateEnd); // ---- 异常预警 ---- AlertLog createAlert(const std::string& employeeId, AbnormalFlag type); std::vector 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 employees_; std::map shifts_; std::vector records_; std::vector alerts_; std::vector 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