diff --git a/yuthon_hr_attendance/controllers/applet_attendance.py b/yuthon_hr_attendance/controllers/applet_attendance.py index 5cbffa596..c807bcdd1 100644 --- a/yuthon_hr_attendance/controllers/applet_attendance.py +++ b/yuthon_hr_attendance/controllers/applet_attendance.py @@ -161,39 +161,64 @@ class AppletAttendance(Controller): @route('/yuthon/app/att', methods=['POST'], type='json', auth='none', csrf=False) def yuthon_app_att(self, **kw): """ - 打卡接口 :param kw: :return: { - "code": "200", // 状态码 - "message": "OK", // 状态消息 + "code": "200", // 状态码,200表示成功 + "message": "OK", // 状态描述 "data": { - # 当月的打卡信息 - "current_month": { - "abnormal_stats": { // 异常统计信息 - "is_no_card": 1, // 缺卡次数 - "is_early_card": 2, // 早退次数 - "is_late_card": 0, // 迟到次数 - "is_abnormal": 3 // 异常总次数 - }, - "records": [ // 每日考勤记录列表 - { - "date": "2023-06-01", // 考勤日期(YYYY-MM-DD格式) - "class": ["早班", "09:00-18:00"], // 班次信息:[班次名称, "标准上班时间-标准下班时间"] - "user_id": 123, // 用户ID - "check_in": ["08:55:00", "正常"], // 上班打卡信息:[实际打卡时间, 打卡状态] - "check_out": ["17:30:00", "早退"], // 下班打卡信息:[实际打卡时间, 打卡状态] - "is_no_card": false, // 是否缺卡(布尔值) - "is_early_card": true, // 是否早退(布尔值) - "is_late_card": false, // 是否迟到(布尔值) - "is_abnormal": false // 是否异常(布尔值) + "current_month": { // 当月考勤数据 + "holiday_data": { // 假期数据 + "holiday_list": ["2025-01-01", "2025-01-02"], // 法定节假日,调休休息日列表(日期字符串) + "shift_days_list": ["2025-02-10", "2025-02-11"] // 调休补班日列表(日期字符串) }, - // 其他日期记录... - ] - }, + "banner_rote": { // 异常统计 + "is_no_card": 2, // 未打卡次数 + "is_early_card": 1, // 早退次数 + "is_late_card": 3, // 迟到次数 + "is_abnormal": 5 // 异常总次数 + }, + "attendance_data": [ // 每日考勤记录列表 + { + "date": "2025-06-15", // 日期 + "class": ["早班", "08:30-17:30"], // 班次信息 [班次名称, 标准时间范围] + "user_id": 1001, // 用户ID + "check_in": ["08:45:20", "迟到"], // 签到信息 [时间, 状态] + "check_out": ["17:20:15", "正常"] // 签退信息 [时间, 状态] + }, + { + "date": "2025-06-16", + "class": ["晚班", "14:00-22:00"], + "user_id": 1001, + "check_in": ["未打卡", "未打卡"], + "check_out": ["未打卡", "未打卡"] + } + ] + }, + "previous_month": { // 上月考勤数据(结构同current_month) + "holiday_data": { ... }, + "banner_rote": { ... }, + "attendance_data": [ ... ] + } + } + } """ user_id = int(kw['user_id']) now = datetime.now() + calendar_leaves = self.env['resource.calendar.leaves'].search([("calendar_id", "=", "行政考勤工作日")]) + holidays_list = [] # 假期 + shift_days_list = [] # 调休 + for leaves in calendar_leaves: + if leaves.holidays: + holidays_list.extend(leaves.holidays.split(',')) # 法定节假日 + if leaves.shift_replacement_day: + shift_days_list.extend(leaves.shift_replacement_day.split(',')) # 调班补班 + if leaves.alternate_rest_day: + holidays_list.extend(leaves.alternate_rest_day.split(',')) # 调休日 + holiday_data = { + "holiday_list": holidays_list, + "shift_days_list": shift_days_list, + } # 当月日期范围 current_month_first = datetime(now.year, now.month, 1) if now.month == 12: @@ -212,6 +237,7 @@ class AppletAttendance(Controller): ('employee_id.user_id', '=', user_id), ('current_data', '>=', current_month_first.date()), ('current_data', '<=', current_month_last.date()), + ('week', 'not in', ['seven', 'six']) ]) # 本月异常次数 current_stats = { @@ -225,6 +251,7 @@ class AppletAttendance(Controller): ('employee_id.user_id', '=', user_id), ('current_data', '>=', prev_month_first.date()), ('current_data', '<=', prev_month_last.date()), + ('week', 'not in', ['seven', 'six']) ]) # 上月异常次数 prev_stats = { @@ -242,13 +269,15 @@ class AppletAttendance(Controller): 'data': { # 本月打卡 'current_month': { - 'abnormal_stats': current_stats, - 'records': current_records, + 'holiday_data': holiday_data, + 'banner_rote': current_stats, + 'attendance_data': current_records, }, # 上月打卡 'previous_month': { - 'abnormal_stats': prev_stats, - 'records': prev_records, + 'holiday_data': holiday_data, + 'banner_rote': prev_stats, + 'attendance_data': prev_records, } } } @@ -287,51 +316,17 @@ class AppletAttendance(Controller): # 格式化实际打卡时间 check_in_str = check_in.strftime('%H:%M:%S') if check_in else '未打卡' check_out_str = check_out.strftime('%H:%M:%S') if check_out else '未打卡' + def get_status_color(status): + return 'red' if status in ['迟到', '早退', '未打卡'] else 'green' + check_in_html = f'

{check_in_str} {check_in_status}

' + check_out_html = f'

{check_out_str} {check_out_status}

' # 添加到记录列表 records.append({ 'date': att.current_data.strftime('%Y-%m-%d'), 'class': [shift_name, f"{standard_check_in_str}-{standard_check_out_str}"], 'user_id': user_id, - 'check_in': [check_in_str, check_in_status], - 'check_out': [check_out_str, check_out_status], + 'check_in': check_in_html, + 'check_out': check_out_html, }) - return records - - @route('/attendance/banner/route', type='json', auth='user') - def employee_banner_route(self): - now = datetime.now() - first_day_of_month = datetime(now.year, now.month, 1) - if now.month == 12: - next_month_first_day = datetime(now.year + 1, 1, 1) - else: - next_month_first_day = datetime(now.year, now.month + 1, 1) - last_day_of_month = next_month_first_day - timedelta(days=1) - domain = [ - ('employee_id.user_id', '=', request.env.user.id), - ('current_data', '>=', first_day_of_month.date()), - ('current_data', '<=', last_day_of_month.date()), - ('week', 'not in', ['seven', 'six']) - ] - attendance = request.env['hr.attendance'].sudo().search(domain) - is_no_card = 0 - is_early_card = 0 - is_late_card = 0 - all_card = 0 - normal_card = 0 - absenteeism_card = 0 - leave_card = 0 - out_card = 0 - travel_card = 0 - field_card = 0 - home_card = 0 - for rec in attendance: - if rec.is_no_card: - is_no_card += 1 - if rec.is_no_card: - is_early_card += 1 - if rec.is_no_card: - is_late_card += 1 - return { - - } \ No newline at end of file + return records \ No newline at end of file