<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="jnpf.attendance.mapper.AttendanceDayStatisticsMapper">

    <!-- 日统计返回Vo-->
    <resultMap type="jnpf.model.attendance.vo.attendance.DayStatisticsQueryVo" id="attendanceDayStatisticsMap">
        <id property="id" column="F_Id"/>
        <result property="userId" column="F_UserId"/>
        <result property="groupId" column="F_GroupId"/>
        <result property="date" column="F_Date"/>
        <result property="shouldAttendHours" column="F_ShouldAttendHours"/>
        <result property="effectiveAttendHours" column="F_EffectiveAttendHours"/>
        <result property="actualAttendHours" column="F_ActualAttendHours"/>
        <result property="lateTimes" column="F_LateTimes"/>
        <result property="lateMinutes" column="F_LateMinutes"/>
        <result property="makeUpCardTimes" column="F_MakeUpCardTimes"/>
        <result property="outworkTimes" column="F_OutworkTimes"/>
        <result property="earlyLeaveTimes" column="F_EarlyLeaveTimes"/>
        <result property="earlyLeaveMinutes" column="F_EarlyLeaveMinutes"/>
        <result property="absenceCardTimes" column="F_AbsenceCardTimes"/>
        <result property="absenceCardHours" column="F_AbsenceCardHours"/>
        <result property="outworkTimes" column="F_OutworkTimes"/>
        <result property="overtimeTimes" column="F_OvertimeTimes"/>
        <result property="selfGroup" column="F_SelfGroup"/>
        <result property="restTimes" column="F_RestTimes"/>
        <result property="outHours" column="F_OutHours"/>
        <result property="leaveBatchNumber" column="F_LeaveBatchNumber"/>
        <result property="absenceTimes" column="F_AbsenceTimes"/>
        <result property="absenceHours" column="F_AbsenceHours"/>
        <result property="holidaysOvertimeHours" column="F_HolidaysOvertimeHours"/>
        <result property="publicHolidaysOvertimeHours" column="F_PublicHolidaysOvertimeHours"/>
        <result property="weekdayOvertimeHours" column="F_WeekdayOvertimeHours"/>
        <result property="compensationHours" column="F_CompensationHours"/>
        <result property="customLeaveList" column="customLeaveList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
        <result property="busDays" column="F_BusDays"/>
        <result property="outDays" column="F_OutDays"/>
        <result property="leaveHours" column="F_LeaveHours"/>
        <result property="shiftsJson" column="F_ShiftsJson"/>
    </resultMap>
    <!-- 计薪日统计返回Vo-->
    <resultMap type="jnpf.model.attendance.vo.attendance.DayPayrollStatisticsQueryVo" id="attendanceDayPayrollStatisticsMap">
        <id property="id" column="F_Id"/>
        <result property="userId" column="F_UserId"/>
        <result property="groupId" column="F_GroupId"/>
        <result property="date" column="F_Date"/>
        <result property="shouldAttendPayrollHours" column="F_ShouldAttendPayrollHours"/>
        <result property="effectiveAttendPayrollHours" column="F_EffectiveAttendPayrollHours"/>
        <result property="absenceCardPayrollHours" column="F_ActualAttendPayrollHours"/>
        <result property="absenceCardPayrollHours" column="F_AbsenceCardPayrollHours"/>
        <result property="absencePayrollHours" column="F_AbsencePayrollHours"/>
        <result property="leavePayrollHours" column="F_LeavePayrollHours"/>
        <result property="compensationPayrollHours" column="F_CompensationPayrollHours"/>
        <result property="customLeaveList" column="customLeaveList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
        <result property="shiftsJson" column="F_ShiftsJson"/>
    </resultMap>

    <!-- 月统计返回Vo-->
    <resultMap type="jnpf.model.attendance.vo.attendance.MonthStatisticsQueryVo" id="attendanceMonthStatisticsMap">
        <id property="id" column="F_Id"/>
        <result property="userId" column="F_UserId"/>
        <result property="groupId" column="F_GroupId"/>
        <result property="attendanceRatio" column="F_AttendanceRatio"/>
        <result property="shouldAttendDays" column="F_ShouldAttendDays"/>
        <result property="shouldAttendHours" column="F_ShouldAttendHours"/>
        <result property="effectiveAttendDays" column="F_EffectiveAttendDays"/>
        <result property="effectiveAttendHours" column="F_EffectiveAttendHours"/>
        <result property="actualAttendDays" column="F_ActualAttendDays"/>
        <result property="actualAttendHours" column="F_ActualAttendHours"/>
        <result property="lateTimes" column="F_LateTimes"/>
        <result property="lateMinutes" column="F_LateMinutes"/>
        <result property="earlyLeaveTimes" column="F_EarlyLeaveTimes"/>
        <result property="earlyLeaveMinutes" column="F_EarlyLeaveMinutes"/>
        <result property="absenceCardTimes" column="F_AbsenceCardTimes"/>
        <result property="absenceCardDays" column="F_AbsenceCardDays"/>
        <result property="makeUpCardTimes" column="F_MakeUpCardTimes"/>
        <result property="outworkTimes" column="F_OutworkTimes"/>
        <result property="absenceTimes" column="F_AbsenceTimes"/>
        <result property="absenceDays" column="F_AbsenceDays"/>
        <result property="busTimes" column="F_BusTimes"/>
        <result property="busDays" column="F_BusDays"/>
        <result property="outTimes" column="F_OutTimes" typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
        <result property="outDays" column="F_OutDays"/>
        <result property="overtimeTimes" column="F_OvertimeTimes"/>
        <result property="holidaysOvertimeHours" column="F_HolidaysOvertimeHours"/>
        <result property="publicHolidaysOvertimeHours" column="F_PublicHolidaysOvertimeHours"/>
        <result property="weekdayOvertimeHours" column="F_WeekdayOvertimeHours"/>
        <result property="leaveTimes" column="F_LeaveTimes"/>
        <result property="leaveDays" column="F_LeaveDays"/>
        <result property="leaveHours" column="F_LeaveHours"/>
        <result property="selfGroupTimes" column="F_SelfGroupTimes"/>
        <result property="restTimes" column="F_RestTimes"/>
        <result property="compensationDays" column="F_CompensationDays"/>
        <result property="customLeaveList" column="customLeaveList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
    </resultMap>

    <!-- 计薪月统计返回Vo-->
    <resultMap type="jnpf.model.attendance.vo.attendance.MonthPayrollStatisticsQueryVo" id="attendanceMonthPayrollStatisticsMap">
        <id property="id" column="F_Id"/>
        <result property="userId" column="F_UserId"/>
        <result property="groupId" column="F_GroupId"/>
        <result property="shouldAttendPayrollHours" column="F_ShouldAttendPayrollHours"/>
        <result property="effectiveAttendPayrollHours" column="F_EffectiveAttendPayrollHours"/>
        <result property="absenceCardPayrollHours" column="F_ActualAttendPayrollHours"/>
        <result property="absenceCardPayrollHours" column="F_AbsenceCardPayrollHours"/>
        <result property="absencePayrollHours" column="F_AbsencePayrollHours"/>
        <result property="leavePayrollHours" column="F_LeavePayrollHours"/>
        <result property="compensationPayrollHours" column="F_CompensationPayrollHours"/>
        <result property="customLeaveList" column="customLeaveList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
    </resultMap>

    <resultMap type="jnpf.model.attendance.vo.attendance.SalaryAttendanceSupportQuery" id="salaryStatisticsListMap">
        <result property="userId" column="F_UserId"/>
        <result property="groupId" column="F_GroupId"/>
        <result property="attendanceRatio" column="F_AttendanceRatio"/>
        <result property="shouldAttendDays" column="F_ShouldAttendDays"/>
        <result property="shouldAttendPayrollHours" column="F_ShouldAttendPayrollHours"/>
        <result property="effectiveAttendDays" column="F_EffectiveAttendDays"/>
        <result property="effectiveAttendPayrollHours" column="F_EffectiveAttendPayrollHours"/>
        <result property="effectiveAttendDayList" column="F_EffectiveAttendDayList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
        <result property="actualAttendDays" column="F_ActualAttendDays"/>
        <result property="actualAttendPayrollHours" column="F_ActualAttendPayrollHours"/>
        <result property="lateTimes" column="F_LateTimes"/>
        <result property="lateMinutes" column="F_LateMinutes"/>
        <result property="lateDayMinutesList" column="F_LateDayMinutesList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
        <result property="earlyLeaveTimes" column="F_EarlyLeaveTimes"/>
        <result property="earlyLeaveMinutes" column="F_EarlyLeaveMinutes"/>
        <result property="earlyLeaveDayMinutesList" column="F_EarlyLeaveMinutesList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
        <result property="absenceCardTimes" column="F_AbsenceCardTimes"/>
        <result property="absenceTimes" column="F_AbsenceTimes"/>
        <result property="absenceDays" column="F_AbsenceDays"/>
        <result property="absencePayrollHours" column="F_AbsencePayrollHours"/>
        <result property="makeUpCardTimes" column="F_MakeUpCardTimes"/>
        <result property="outworkTimes" column="F_OutworkTimes"/>
        <result property="outworkDays" column="F_OutworkDays"/>
        <result property="outworkPayrollHours" column="F_OutworkPayrollHours"/>
        <result property="overtimeTimes" column="F_OvertimeTimes"/>
        <result property="overtimeDays" column="F_OvertimeDays"/>
        <result property="overtimeHours" column="F_OvertimeHours"/>
        <result property="busDays" column="F_BusDays"/>
        <result property="busHours" column="F_BusHours"/>
        <result property="outDays" column="F_OutDays"/>
        <result property="outHours" column="F_OutHours"/>
        <result property="weekdayOvertimeDays" column="F_WeekdayOvertimeDays"/>
        <result property="weekdayOvertimeHours" column="F_WeekdayOvertimeHours"/>
        <result property="holidaysOvertimeDays" column="F_HolidaysOvertimeDays"/>
        <result property="holidaysOvertimeHours" column="F_HolidaysOvertimeHours"/>
        <result property="publicHolidaysOvertimeDays" column="F_PublicHolidaysOvertimeDays"/>
        <result property="publicHolidaysOvertimeHours" column="F_PublicHolidaysOvertimeHours"/>
        <result property="publicHolidaysDays" column="F_PublicHolidaysDays"/>
        <result property="publicHolidaysPayrollHours" column="F_PublicHolidaysPayrollHours"/>
        <result property="actualPublicHolidays" column="F_ActualPublicHolidaysDays"/>
        <result property="actualPublicHolidaysHours" column="F_ActualPublicHolidaysHours"/>
        <result property="leaveDays" column="F_LeaveDays"/>
        <result property="leavePayrollHours" column="F_LeavePayrollHours"/>
        <result property="compensationDays" column="F_CompensationDays"/>
        <result property="compensationPayrollHours" column="F_CompensationPayrollHours"/>
        <result property="customLeaveList" column="customLeaveList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
        <result property="leaveBatchNumber" column="F_LeaveBatchNumber"/>
    </resultMap>

    <resultMap type="jnpf.model.attendance.vo.attendance.DayStatisticsQueryDbVo" id="userMonthListMap">
        <result property="lateTimes" column="F_LateTimes"/>
        <result property="earlyLeaveTimes" column="F_EarlyLeaveTimes"/>
        <result property="absenceCardTimes" column="F_AbsenceCardTimes"/>
        <result property="absenceTimes" column="F_AbsenceTimes"/>
        <result property="leaveTimes" column="F_LeaveTimes"/>
        <result property="customLeaveList" column="customLeaveList"
                typeHandler="jnpf.attendance.handler.JsonToListTypeHandler"/>
    </resultMap>

    <sql id="dayStaticsField">
        COUNT(*) totalCount,
         SUM(IF(fads.F_IsClocked = 0 or
               fads.F_IsScheduling = 0 or
               fads.F_LateTimes > 0 or
               fads.F_EarlyLeaveTimes > 0 or
               fads.F_AbsenceCardTimes > 0 or
               fads.F_AbsenceTimes > 0 or
               fads.F_ShiftsJson->'$[*].clockInResultList' is null, 0, 1)) normalCount,
        SUM(IF(fads.F_LateTimes > 0, 1, 0)) lateCount,
        SUM(IF(fads.F_EarlyLeaveTimes > 0, 1, 0)) earlyLeaveCount,
        SUM(IF(fads.F_IsScheduling = 0 , 1, 0)) notSchedulingCount,
        SUM(IF(fads.F_AbsenceCardTimes > 0, 1, 0)) absenceCardCount,
        SUM(IF(fads.F_AbsenceTimes > 0, 1, 0)) absenceCount,
        SUM(IF(fads.F_LeaveHours > 0, 1, 0)) leaveCount,
        SUM(IF(fads.F_BusBatchNumber IS NOT NULL, 1, 0)) busCount,
        SUM(IF(fads.F_OutBatchNumber IS NOT NULL, 1, 0)) outCount,
        SUM(IF(fads.F_SelfGroup = 1 , 1, 0)) selfCount,
        SUM(IF(fads.F_OvertimeTimes > 0 , 1, 0)) overtimeCount
    </sql>
    <sql id="monthStaticsNormalField">
        COUNT(*) totalCount,
        SUM(IF(fads.F_IsScheduling != 0 and (fads.F_IsClocked = 0 or
               fads.F_IsScheduling = 0 or
               fads.F_LateTimes > 0 or
               fads.F_EarlyLeaveTimes > 0 or
               fads.F_AbsenceCardTimes > 0 or
               fads.F_AbsenceTimes > 0 or
               fads.F_ShiftsJson->'$[*].clockInResultList' is null)
               , 1, 0)) normalCount,
        SUM(IF(fads.F_LateTimes > 0, 1, 0)) lateCount,
        SUM(IF(fads.F_EarlyLeaveTimes > 0, 1, 0)) earlyLeaveCount,
        SUM(IF(fads.F_IsScheduling = 0 , 1, 0)) notSchedulingCount,
        SUM(IF(fads.F_AbsenceCardTimes > 0, 1, 0)) absenceCardCount,
        SUM(IF(fads.F_AbsenceTimes > 0, 1, 0)) absenceCount,
        SUM(IF(fads.F_LeaveHours > 0, 1, 0)) leaveCount,
        SUM(IF(fads.F_BusBatchNumber IS NOT NULL, 1, 0)) busCount,
        SUM(IF(fads.F_OutBatchNumber IS NOT NULL, 1, 0)) outCount,
        SUM(IF(fads.F_SelfGroup = 1 , 1, 0)) selfCount,
        SUM(IF(fads.F_OvertimeTimes > 0 , 1, 0)) overtimeCount
    </sql>
    <sql id="dayPageListField">
        fads.F_Id,
        fads.F_UserId,
        fads.F_GroupId,
        fads.F_Date,
        fads.F_JoinTime,
        fads.F_ShouldAttendHours,
        fads.F_EffectiveAttendHours,
        fads.F_ActualAttendHours,
        fads.F_LateTimes,
        fads.F_LateMinutes,
        fads.F_MakeUpCardTimes,
        fads.F_OutworkTimes,
        fads.F_EarlyLeaveTimes,
        fads.F_EarlyLeaveMinutes,
        fads.F_AbsenceCardTimes,
        fads.F_AbsenceCardHours,
        fads.F_AbsenceTimes,
        fads.F_AbsenceHours,
        fads.F_OutworkTimes,
        fads.F_OvertimeTimes,
        fads.F_SelfGroup,
        fads.F_LeaveBatchNumber,
        fads.F_OutHours,
        fads.F_RestTimes,
        fads.F_HolidaysOvertimeHours,
        fads.F_PublicHolidaysOvertimeHours,
        fads.F_WeekdayOvertimeHours,
        fads.F_CompensationHours,
        fads.F_CustomLeaveJson as customLeaveList,
        fads.F_BusDays,
        fads.F_OutDays,
        fads.F_LeaveHours,
        fads.F_ShiftsJson
    </sql>
    <sql id="dayPayrollPageListField">
        fads.F_Id,
        fads.F_UserId,
        fads.F_GroupId,
        fads.F_Date,
        fads.F_ShouldAttendPayrollHours,
        fads.F_EffectiveAttendPayrollHours,
        fads.F_ActualAttendPayrollHours,
        fads.F_AbsenceCardPayrollHours,
        fads.F_AbsencePayrollHours,
        fads.F_LeavePayrollHours,
        fads.F_CompensationPayrollHours,
        fads.F_CustomLeaveJson as customLeaveList,
        fads.F_ShiftsJson
    </sql>

    <sql id="monthStaticsField">
        COALESCE(COUNT(*),0) totalCount,
        COALESCE(SUM(IF(t.normalCount > 0 OR t.notSchedulingCount > 0 , 0, 1)),0) normalCount,
        COALESCE(SUM(IF(t.lateCount > 0, 1, 0)),0) lateCount,
        COALESCE(SUM(IF(t.earlyLeaveCount > 0, 1, 0)),0) earlyLeaveCount,
        COALESCE(SUM(IF(t.notSchedulingCount > 0, 1, 0)),0) notSchedulingCount,
        COALESCE(SUM(IF(t.absenceCardCount > 0, 1, 0)),0) absenceCardCount,
        COALESCE(SUM(IF(t.absenceCount > 0, 1, 0)),0) absenceCount,
        COALESCE(SUM(IF(t.leaveCount > 0, 1, 0)),0) leaveCount,
        COALESCE(SUM(IF(t.busCount > 0, 1, 0)),0) busCount,
        COALESCE(SUM(IF(t.outCount > 0, 1, 0)),0) outCount,
        COALESCE(SUM(IF(t.selfCount > 0 , 1, 0)),0) selfCount,
        COALESCE(SUM(IF(t.overtimeCount > 0 , 1, 0)),0) overtimeCount
    </sql>

    <sql id="monthPageListQueryField">
        fads.F_Id,
        fads.F_UserId,
        fads.F_GroupId,
        fads.F_SelfGroup,
        fads.F_JoinTime,
        fads.F_Date,
        fads.F_AttendanceRatio,
        fads.F_ShouldAttendDays,
        fads.F_ShouldAttendHours,
        fads.F_EffectiveAttendDays,
        fads.F_EffectiveAttendHours,
        fads.F_ActualAttendDays,
        fads.F_ActualAttendHours,
        fads.F_LateTimes,
        fads.F_LateMinutes,
        fads.F_EarlyLeaveTimes,
        fads.F_EarlyLeaveMinutes,
        fads.F_AbsenceCardTimes,
        fads.F_AbsenceCardDays,
        fads.F_MakeUpCardTimes,
        fads.F_OutworkTimes,
        fads.F_OutworkDays,
        fads.F_OutworkHours,
        fads.F_AbsenceTimes,
        fads.F_AbsenceDays,
        fads.F_AbsenceHours,
        fads.F_BusBatchNumber,
        fads.F_BusDays,
        fads.F_BusHours,
        fads.F_OutBatchNumber,
        fads.F_OutDays,
        fads.F_OutHours,
        fads.F_OvertimeTimes,
        fads.F_OvertimeDays,
        fads.F_OvertimeHours,
        fads.F_WeekdayOvertimeDays,
        fads.F_WeekdayOvertimeHours,
        fads.F_HolidaysOvertimeDays,
        fads.F_HolidaysOvertimeHours,
        fads.F_PublicHolidaysOvertimeDays,
        fads.F_PublicHolidaysOvertimeHours,
        fads.F_PublicHolidaysDays,
        fads.F_PublicHolidaysHours,
        fads.F_LeaveBatchNumber,
        fads.F_LeaveDays,
        fads.F_LeaveHours,
        fads.F_RestTimes,
        fads.F_IsScheduling,
        fads.F_IsClocked,
        fads.F_ShiftsJson,
        fads.F_CompensationDays,
        fads.F_CompensationHours,
        fads.F_CustomLeaveJson
    </sql>

    <sql id="salaryListQueryField">
        fads.F_Id,
        fads.F_UserId,
        fads.F_GroupId,
        fads.F_SelfGroup,
        fads.F_JoinTime,
        fads.F_Date,
        fads.F_AttendanceRatio,
        fads.F_ShouldAttendDays,
        fads.F_ShouldAttendPayrollHours,
        fads.F_EffectiveAttendDays,
        fads.F_EffectiveAttendPayrollHours,
        fads.F_ActualAttendDays,
        fads.F_ActualAttendPayrollHours,
        fads.F_LateTimes,
        fads.F_LateMinutes,
        fads.F_EarlyLeaveTimes,
        fads.F_EarlyLeaveMinutes,
        fads.F_AbsenceCardTimes,
        fads.F_AbsenceCardDays,
        fads.F_MakeUpCardTimes,
        fads.F_OutworkTimes,
        fads.F_OutworkDays,
        fads.F_OutworkPayrollHours,
        fads.F_AbsenceTimes,
        fads.F_AbsenceDays,
        fads.F_AbsencePayrollHours,
        fads.F_BusBatchNumber,
        fads.F_BusDays,
        fads.F_BusHours,
        fads.F_OutBatchNumber,
        fads.F_OutDays,
        fads.F_OutHours,
        fads.F_OvertimeTimes,
        fads.F_OvertimeDays,
        fads.F_OvertimeHours,
        fads.F_WeekdayOvertimeDays,
        fads.F_WeekdayOvertimeHours,
        fads.F_HolidaysOvertimeDays,
        fads.F_HolidaysOvertimeHours,
        fads.F_PublicHolidaysOvertimeDays,
        fads.F_PublicHolidaysOvertimeHours,
        fads.F_PublicHolidaysDays,
        fads.F_PublicHolidaysPayrollHours,
        fads.F_LeaveBatchNumber,
        fads.F_LeaveDays,
        fads.F_LeavePayrollHours,
        fads.F_RestTimes,
        fads.F_IsScheduling,
        fads.F_IsClocked,
        fads.F_ShiftsJson,
        fads.F_CompensationDays,
        fads.F_CompensationPayrollHours,
        fads.F_CustomLeaveJson
    </sql>

    <sql id="monthPayrollPageListQueryField">
        fads.F_Id,
        fads.F_UserId,
        fads.F_GroupId,
        fads.F_JoinTime,
        fads.F_ShouldAttendPayrollHours,
        fads.F_EffectiveAttendPayrollHours,
        fads.F_ActualAttendPayrollHours,
        fads.F_AbsenceCardPayrollHours,
        fads.F_AbsencePayrollHours,
        fads.F_LeavePayrollHours,
        fads.F_CompensationPayrollHours,
        fads.F_CustomLeaveJson
    </sql>

    <sql id="salaryListField">
        t.F_Id,
        t.F_UserId,
        t.F_GroupId,
        t.F_AttendanceRatio,
        SUM(t.F_ShouldAttendDays) F_ShouldAttendDays,
        SUM(t.F_ShouldAttendPayrollHours) F_ShouldAttendPayrollHours,
        SUM(t.F_EffectiveAttendDays) F_EffectiveAttendDays,
        SUM(t.F_EffectiveAttendPayrollHours) F_EffectiveAttendPayrollHours,
         JSON_ARRAYAGG(CASE WHEN t.F_EffectiveAttendPayrollHours > 0 THEN
                JSON_OBJECT(
                    'day', t.F_Date,
                    'hours', t.F_EffectiveAttendPayrollHours,
                    'days', t.F_EffectiveAttendDays
                ) ELSE NULL END ) AS F_EffectiveAttendDayList,
        SUM(t.F_ActualAttendDays) F_ActualAttendDays,
        SUM(t.F_ActualAttendPayrollHours) F_ActualAttendPayrollHours,
        SUM(t.F_LateTimes) F_LateTimes,
        SUM(t.F_LateMinutes) F_LateMinutes,
        JSON_ARRAYAGG(CASE WHEN t.F_LateMinutes > 0 THEN
                JSON_OBJECT(
                    'day', t.F_Date,
                    'minutes', t.F_LateMinutes
                ) ELSE NULL END ) AS F_LateDayMinutesList,
        SUM(t.F_EarlyLeaveTimes) F_EarlyLeaveTimes,
        SUM(t.F_EarlyLeaveMinutes) F_EarlyLeaveMinutes,
        JSON_ARRAYAGG(CASE WHEN t.F_EarlyLeaveMinutes > 0 THEN
                JSON_OBJECT(
                    'day', t.F_Date,
                    'minutes', t.F_EarlyLeaveMinutes
                ) ELSE NULL END ) AS F_EarlyLeaveMinutesList,
        SUM(t.F_AbsenceCardTimes) F_AbsenceCardTimes,
        SUM(t.F_AbsenceTimes) F_AbsenceTimes,
        SUM(t.F_AbsenceDays) F_AbsenceDays,
        SUM(t.F_AbsencePayrollHours) F_AbsencePayrollHours,
        SUM(t.F_MakeUpCardTimes) F_MakeUpCardTimes,
        SUM(t.F_OutworkTimes) F_OutworkTimes,
        SUM(t.F_OutworkDays) F_OutworkDays,
        SUM(t.F_OutworkPayrollHours) F_OutworkPayrollHours,
        SUM(t.F_OvertimeTimes) F_OvertimeTimes,
        SUM(t.F_OvertimeDays) F_OvertimeDays,
        SUM(t.F_OvertimeHours) F_OvertimeHours,
        SUM(t.F_WeekdayOvertimeDays) F_WeekdayOvertimeDays,
        SUM(t.F_WeekdayOvertimeHours) F_WeekdayOvertimeHours,
        SUM(t.F_HolidaysOvertimeDays) F_HolidaysOvertimeDays,
        SUM(t.F_HolidaysOvertimeHours) F_HolidaysOvertimeHours,
        SUM(t.F_PublicHolidaysOvertimeDays) F_PublicHolidaysOvertimeDays,
        SUM(t.F_PublicHolidaysOvertimeHours) F_PublicHolidaysOvertimeHours,
        SUM(t.F_PublicHolidaysDays) F_PublicHolidaysDays,
        SUM(t.F_PublicHolidaysPayrollHours) F_PublicHolidaysPayrollHours,
        SUM(t.F_LeaveDays) F_LeaveDays,
        SUM(t.F_LeavePayrollHours) F_LeavePayrollHours,
        SUM(t.F_BusDays) F_BusDays,
        SUM(t.F_BusHours) F_BusHours,
        SUM(t.F_OutDays) F_OutDays,
        SUM(t.F_OutHours) F_OutHours,
        SUM(t.F_CompensationDays) F_CompensationDays,
        SUM(t.F_CompensationPayrollHours) F_CompensationPayrollHours,
        JSON_ARRAYAGG(t.F_CustomLeaveJson) as customLeaveList,
	    GROUP_CONCAT(t.F_LeaveBatchNumber) F_LeaveBatchNumber
    </sql>
    <sql id="monthPageListField">
        t.F_Id,
        t.F_UserId,
        t.F_GroupId,
        t.F_AttendanceRatio,
        SUM(IF(t.F_IsScheduling != 0 and (t.F_IsClocked = 0 or
        t.F_LateTimes > 0 or
        t.F_EarlyLeaveTimes > 0 or
        t.F_AbsenceCardTimes > 0 or
        t.F_AbsenceTimes > 0 or
        t.F_ShiftsJson->'$[*].clockInResultList' is null)
        , 1, 0)) F_NormalCount,
        SUM(IF(t.F_IsScheduling = 0 , 1, 0)) F_IsSchedulingCount,
        DATE_FORMAT(t.F_Date, '%Y年%m月') AS `month`,
        SUM(IF(t.F_SelfGroup = 1, 1, 0)) F_SelfGroupTimes,
        SUM(t.F_ShouldAttendDays) F_ShouldAttendDays,
        SUM(t.F_ShouldAttendHours) F_ShouldAttendHours,
        SUM(t.F_EffectiveAttendDays) F_EffectiveAttendDays,
        SUM(t.F_EffectiveAttendHours) F_EffectiveAttendHours,
        SUM(t.F_ActualAttendDays) F_ActualAttendDays,
        SUM(t.F_ActualAttendHours) F_ActualAttendHours,
        SUM(t.F_LateTimes) F_LateTimes,
        SUM(t.F_LateMinutes) F_LateMinutes,
        SUM(t.F_EarlyLeaveTimes) F_EarlyLeaveTimes,
        SUM(t.F_EarlyLeaveMinutes) F_EarlyLeaveMinutes,
        SUM(t.F_AbsenceCardTimes) F_AbsenceCardTimes,
        SUM(t.F_AbsenceCardDays) F_AbsenceCardDays,
        SUM(t.F_MakeUpCardTimes) F_MakeUpCardTimes,
        SUM(t.F_OutworkTimes) F_OutworkTimes,
        SUM(t.F_AbsenceTimes) F_AbsenceTimes,
        SUM(t.F_AbsenceDays) F_AbsenceDays,
        SUM(t.F_AbsenceHours) F_AbsenceHours,
        SUM(t.F_OvertimeTimes) F_OvertimeTimes,
        SUM(t.F_OvertimeDays) F_OvertimeDays,
        SUM(t.F_OvertimeHours) F_OvertimeHours,
        GROUP_CONCAT(DISTINCT CASE WHEN t.F_BusBatchNumber IS NOT NULL AND t.F_BusBatchNumber != '' THEN t.F_BusBatchNumber END) F_BusTimes,
        SUM(t.F_BusDays) F_BusDays,
        JSON_ARRAYAGG(t.F_OutBatchNumber) as F_OutTimes,
        SUM(t.F_OutDays) F_OutDays,
        SUM(t.F_HolidaysOvertimeHours) F_HolidaysOvertimeHours,
        SUM(t.F_PublicHolidaysOvertimeHours) F_PublicHolidaysOvertimeHours,
        SUM(t.F_WeekdayOvertimeHours) F_WeekdayOvertimeHours,
        GROUP_CONCAT(DISTINCT CASE WHEN t.F_LeaveBatchNumber IS NOT NULL AND t.F_LeaveBatchNumber != '' THEN t.F_LeaveBatchNumber END) F_LeaveTimes,
        SUM(t.F_LeaveDays) F_LeaveDays,
        SUM(t.F_LeaveHours) F_LeaveHours,
        SUM(t.F_RestTimes) F_RestTimes,
        SUM(t.F_CompensationDays) F_CompensationDays,
        JSON_ARRAYAGG(t.F_CustomLeaveJson) as customLeaveList
    </sql>

    <sql id="userDayListField">
        fads.F_LateTimes,
        fads.F_EarlyLeaveTimes,
        fads.F_AbsenceCardTimes,
        fads.F_AbsenceTimes,
        fads.F_LeaveBatchNumber,
        fads.F_CustomLeaveJson
    </sql>
    <sql id="userMonthListField">
        COALESCE(SUM(t.F_LateTimes),0) F_LateTimes,
        COALESCE(SUM(t.F_EarlyLeaveTimes),0) F_EarlyLeaveTimes,
        COALESCE(SUM(t.F_AbsenceCardTimes),0) F_AbsenceCardTimes,
        COALESCE(SUM(t.F_AbsenceTimes),0) F_AbsenceTimes,
        GROUP_CONCAT(DISTINCT CASE WHEN t.F_LeaveBatchNumber IS NOT NULL AND t.F_LeaveBatchNumber != '' THEN t.F_LeaveBatchNumber END) F_LeaveTimes,
        JSON_ARRAYAGG(t.F_CustomLeaveJson) as customLeaveList
    </sql>
    <sql id="monthPayrollPageListField">
        t.F_Id,
        t.F_UserId,
        t.F_GroupId,
        SUM(t.F_ShouldAttendPayrollHours) F_ShouldAttendPayrollHours,
        SUM(t.F_EffectiveAttendPayrollHours) F_EffectiveAttendPayrollHours,
        SUM(t.F_ActualAttendPayrollHours) F_ActualAttendPayrollHours,
        SUM(t.F_AbsenceCardPayrollHours) F_AbsenceCardPayrollHours,
        SUM(t.F_AbsencePayrollHours) F_AbsencePayrollHours,
        SUM(t.F_LeavePayrollHours) F_LeavePayrollHours,
        SUM(t.F_CompensationPayrollHours) F_CompensationPayrollHours,
        JSON_ARRAYAGG(t.F_CustomLeaveJson) as customLeaveList
    </sql>
    <!-- 定义一个用于构建动态查询条件的SQL片段 -->
    <sql id="staticsWhere">
        <where>
            <!-- 判断是否需要根据分组ID列表添加查询条件 -->
            <if test="req.groupIds!= null and req.groupIds.size()>0">
                and fads.F_GroupId in
                <foreach collection="req.groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <!-- 判断是否需要根据日期范围添加查询条件 -->
            <if test="req.startDate != null and req.endDate != ''">
                AND fads.F_Date BETWEEN #{req.startDate} AND #{req.endDate}
            </if>
            <!-- 判断是否需要根据用户ID列表添加查询条件 -->
            <if test="req.userIds!= null and req.userIds.size()>0">
                and fads.F_UserId in
                <foreach collection="req.userIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </sql>
    <sql id="staticsConfirmWhere">
        <where>
            <if test="startDate != null and startDate != null">
                AND fads.F_Date BETWEEN #{startDate} AND #{endDate}
            </if>
            <if test="userIds!= null and userIds.size()>0">
                and fads.F_UserId in
                <foreach collection="userIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </sql>
    <sql id="staticsSalaryWhere">
        <where>
            <!-- 判断是否需要根据日期范围添加查询条件 -->
            <if test="req.startDate != null and req.endDate != ''">
                AND fads.F_Date BETWEEN #{req.startDate} AND #{req.endDate}
            </if>
            <!-- 判断是否需要根据用户ID列表添加查询条件 -->
            <if test="req.userIds!= null and req.userIds.size()>0">
                and fads.F_UserId in
                <foreach collection="req.userIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </sql>
    <sql id="shouldAttendDaysWhere">
        <where>
            fads.F_IsShouldAttend = 1
            <!-- 判断是否需要根据分组ID列表添加查询条件 -->
            <if test="req.groupIds!= null and req.groupIds.size()>0">
                and fads.F_GroupId in
                <foreach collection="req.groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <!-- 判断是否需要根据日期范围添加查询条件 -->
            <if test="req.startDate != null and req.endDate != ''">
                AND fads.F_Date BETWEEN #{req.startDate} AND #{req.endDate}
            </if>
            <!-- 判断是否需要根据用户ID列表添加查询条件 -->
            <if test="req.userIds!= null and req.userIds.size()>0">
                and fads.F_UserId in
                <foreach collection="req.userIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </sql>

    <!-- 定义一个名为 dayPageListWhere 的 SQL 片段 -->
    <sql id="dayPageListWhere">
        <!-- where 子句的开头 -->
        <where>
            <!-- 如果 groupIds 非空且不为空，则生成相应的 SQL 条件 -->
            <if test="req.groupIds!= null and req.groupIds.size()>0">
                and fads.F_GroupId in
                <!-- 遍历 groupIds 列表，生成 IN 子句中的参数列表 -->
                <foreach collection="req.groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <!-- 如果 startDate 和 endDate 都非空，则生成日期范围的 SQL 条件 -->
            <if test="req.startDate != null and req.endDate != ''">
                AND fads.F_Date BETWEEN #{req.startDate} AND #{req.endDate}
            </if>
            <!-- 如果 userIds 非空且不为空，则生成相应的 SQL 条件 -->
            <if test="req.userIds!= null and req.userIds.size()>0">
                and fads.F_UserId in
                <!-- 遍历 userIds 列表，生成 IN 子句中的参数列表 -->
                <foreach collection="req.userIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <!-- 根据 queryType 的不同值，生成不同的 SQL 条件 -->
            <choose>
                <!-- 如果 queryType 为 2，则生成特定的考勤情况 SQL 条件 -->
                <when test="req.queryType == 2">
                    and fads.F_IsClocked = 1
                    and fads.F_IsScheduling = 1
                    and fads.F_LateTimes = 0 and fads.F_EarlyLeaveTimes = 0
                    and fads.F_AbsenceCardTimes = 0 and fads.F_AbsenceTimes = 0
                    and fads.F_ShiftsJson->'$[*].clockInResultList' is not null
                </when>
                <!-- 如果 queryType 为 3，则根据 fieldName 的不同生成 SQL 条件 -->
                <when test="req.queryType == 3">
                    <choose>
                        <!-- 如果 fieldName 为 F_IsScheduling，则生成相应的 SQL 条件 -->
                        <when test="req.fieldName == 'F_IsScheduling'">
                            and fads.${req.fieldName} = 0
                        </when>
                        <!-- 否则，根据 fieldName 生成其它的 SQL 条件 -->
                        <otherwise>
                            and fads.${req.fieldName} > 0
                        </otherwise>
                    </choose>
                </when>
                <otherwise>
                    and 1=1
                </otherwise>
            </choose>
        </where>
    </sql>

    <select id="getDayStatisticsDataQuery" resultType="jnpf.model.attendance.vo.attendance.StatisticsDataQueryVo">
        SELECT
        <!-- 包含每日考勤统计的字段定义 -->
        <include refid="dayStaticsField"/>
        <!-- 指定数据来源表 -->
        FROM ftb_attendance_day_statistics fads
        <!-- 包含考勤统计查询的条件部分 -->
        <include refid="staticsWhere"/>
    </select>


    <!-- 获取日统计数据的分页列表 -->
    <select id="getDayPageList" resultMap="attendanceDayStatisticsMap">
        SELECT
        <include refid="dayPageListField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="dayPageListWhere"/>
        order by fads.F_GroupId,fads.F_JoinTime,fads.F_UserId,fads.F_Date
    </select>

    <!-- 获取月统计数据的查询结果，包括各种统计字段 -->
    <select id="getMonthStatisticsDataQuery" resultType="jnpf.model.attendance.vo.attendance.StatisticsDataQueryVo">
        SELECT
        <include refid="monthStaticsField"/>
        from (SELECT
        <include refid="monthStaticsNormalField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="staticsWhere"/>
        <choose>
            <when test="isGroupBy">
                group BY fads.F_GroupId,fads.F_UserId
            </when>
            <otherwise>
                group BY fads.F_UserId
            </otherwise>
        </choose>
        ) t
    </select>
    <!-- 获取月统计数据的分页列表，包括分组和用户级别的统计 -->
    <select id="getMonthPageList" resultMap="attendanceMonthStatisticsMap">
        SELECT
        <include refid="monthPageListField"/>
        from (SELECT
        <include refid="monthPageListQueryField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="staticsWhere"/>
        ) t
        group BY t.F_GroupId,t.F_UserId
        <choose>
            <when test="req.queryType == 3">
                <choose>
                    <when test="req.fieldName == 'F_LeaveTimes' or req.fieldName == 'F_BusTimes'">
                        HAVING ${req.fieldName} is not null
                    </when>
                    <when test="req.fieldName == 'F_OutTimes'">
                        HAVING ${req.fieldName} is not null
                        AND JSON_SEARCH(${req.fieldName}, 'one', '%', NULL, '$[*]') IS NOT NULL
                    </when>
                    <otherwise>
                        HAVING ${req.fieldName} > 0
                    </otherwise>
                </choose>
            </when>
            <when test="req.queryType == 2">
                having ${req.fieldName} = 0 and F_IsSchedulingCount = 0
            </when>
        </choose>
        order by t.F_GroupId,t.F_JoinTime desc,t.F_UserId
    </select>
    <resultMap type="jnpf.model.attendance.vo.attendance.DayStatisticsNoticeQueryVo" id="dayStatisticsNoticeMap">
        <result property="id" column="F_Id"/>
        <result property="userId" column="F_UserId"/>
        <result property="groupId" column="F_GroupId"/>
        <result property="date" column="F_Date"/>
        <result property="shouldAttendHours" column="F_ShouldAttendHours"/>
        <result property="actualAttendHours" column="F_ActualAttendHours"/>
        <result property="effectiveAttendHours" column="F_EffectiveAttendHours"/>
        <result property="lateTimes" column="F_LateTimes"/>
        <result property="lateMinutes" column="F_LateMinutes"/>
        <result property="earlyLeaveTimes" column="F_EarlyLeaveTimes"/>
        <result property="earlyLeaveMinutes" column="F_EarlyLeaveMinutes"/>
        <result property="absenceCardTimes" column="F_AbsenceCardTimes"/>
        <result property="absenceCardHours" column="F_AbsenceCardHours"/>
        <result property="absenceTimes" column="F_AbsenceTimes"/>
        <result property="absenceHours" column="F_AbsenceHours"/>
        <result property="leaveHours" column="F_LeaveHours"/>
        <result property="leaveDays" column="F_LeaveDays"/>
        <result property="busBatchNumber" column="F_BusBatchNumber"/>
        <result property="outDays" column="F_OutDays"/>
        <result property="outHours" column="F_OutHours"/>
        <result property="overtimeHours" column="F_OvertimeHours"/>
        <result property="shiftsJson" column="F_ShiftsJson"/>
    </resultMap>
    <sql id="dayStatisticsNoticeField">
        fads.F_Id,
        fads.F_UserId,
        fads.F_GroupId,
        fads.F_Date,
        fads.F_ShouldAttendHours,
        fads.F_ActualAttendHours,
        fads.F_LateTimes,
        fads.F_LateMinutes,
        fads.F_EarlyLeaveTimes,
        fads.F_EarlyLeaveMinutes,
        fads.F_AbsenceCardTimes,
        fads.F_AbsenceCardHours,
        fads.F_AbsenceTimes,
        fads.F_AbsenceHours,
        fads.F_LeaveHours,
        fads.F_LeaveDays,
        fads.F_BusBatchNumber,
        fads.F_OutHours,
        fads.F_OutDays,
        fads.F_OvertimeHours,
        fads.F_ShiftsJson
    </sql>
    <resultMap type="jnpf.model.attendance.vo.attendance.MonthStatisticsNoticeQueryVo" id="monthStatisticsNoticeMap">
        <id property="id" column="F_Id"/>
        <result property="userId" column="F_UserId"/>
        <result property="groupId" column="F_GroupId"/>
        <result property="effectiveAttendDays" column="F_EffectiveAttendDays"/>
        <result property="lateTimes" column="F_LateTimes"/>
        <result property="earlyLeaveTimes" column="F_EarlyLeaveTimes"/>
        <result property="absenceCardTimes" column="F_AbsenceCardTimes"/>
        <result property="absenceTimes" column="F_AbsenceTimes"/>
        <result property="busTimes" column="F_BusTimes"/>
        <result property="outTimes" column="F_OutTimes"/>
        <result property="overtimeTimes" column="F_OvertimeTimes"/>
        <result property="leaveDays" column="F_LeaveDays"/>
        <result property="remindTime" column="F_RemindTime"/>
    </resultMap>
    <sql id="monthStatisticsNoticeQueryField">
        fads.F_Id,
        fads.F_UserId,
        fads.F_GroupId,
        fads.F_AttendanceRatio,
        fads.F_LateTimes,
        fads.F_EarlyLeaveTimes,
        fads.F_AbsenceCardTimes,
        fads.F_AbsenceTimes,
        fads.F_BusBatchNumber,
        fads.F_OutBatchNumber,
        fads.F_OvertimeTimes,
        fads.F_LeaveDays,
        fads.F_LeaveHours,
        fads.F_RemindTime
    </sql>
    <sql id="monthStatisticsNoticeField">
        t.F_Id,
        t.F_UserId,
        t.F_GroupId,
        SUM(ROUND(t.F_EffectiveAttendHours / t.F_AttendanceRatio, 2)) F_EffectiveAttendDays,
        SUM(t.F_LateTimes) F_LateTimes,
        SUM(t.F_EarlyLeaveTimes) F_EarlyLeaveTimes,
        SUM(t.F_AbsenceCardTimes) F_AbsenceCardTimes,
        SUM(t.F_AbsenceTimes) F_AbsenceTimes,
        GROUP_CONCAT(DISTINCT t.F_BusBatchNumber) F_BusTimes,
        GROUP_CONCAT(DISTINCT t.F_OutBatchNumber) F_OutTimes,
        SUM(t.F_LeaveDays) F_LeaveDays,
        SUM(t.F_LeaveHours) F_LeaveHours,
        SUM(t.F_OvertimeTimes) F_OvertimeTimes,
        MAX(t.F_RemindTime) F_RemindTime
    </sql>

    <!-- 定义一个用于查询当天考勤提醒的SQL片段 -->
    <sql id="dayNoticeWhere">
        <where>
            <!-- 设置查询条件：考勤安排存在且已打卡 -->
            AND fads.F_IsScheduling = 1
            and fads.F_IsClocked = 1
            <!-- 确保考勤班次的打卡结果列表不为空 -->
            and fads.F_ShiftsJson->'$[*].clockInResultList' is not null
            <!-- 根据开始日期和结束日期筛选提醒时间 -->
            <if test="startDate != null and endDate != null">
                AND fads.F_RemindTime BETWEEN #{startDate} AND #{endDate}
            </if>
        </where>
    </sql>

    <!-- 定义一个用于查询月度或团队月度考勤提醒的SQL片段 -->
    <sql id="monthOrTeamMonthNoticeWhere">
        <where>
            <!-- 设置查询条件：考勤安排存在且已打卡 -->
            AND fads.F_IsScheduling = 1
            and fads.F_IsClocked = 1
            <!-- 确保考勤班次的打卡结果列表不为空 -->
            and fads.F_ShiftsJson->'$[*].clockInResultList' is not null
            <!-- 根据开始日期和结束日期筛选日期 -->
            <if test="startDate != null and endDate != null">
                AND fads.F_Date BETWEEN #{startDate} AND #{endDate}
            </if>
        </where>
    </sql>
    <!-- 定义一个用于团队月度统计的字段列表SQL片段 -->
    <sql id="getAvgHoursWhere">
        <where>
            <if test="groupIds!= null and groupIds.size()>0">
                and fads.F_GroupId in
                <foreach collection="groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <if test="startDate != null and startDate != null">
                AND fads.F_Date BETWEEN #{startDate} AND #{endDate}
            </if>
        </where>
    </sql>

    <sql id="teamMonthStaticsNormalField">
        <!-- 选择团队ID和其他相关统计字段 -->
        fads.F_GroupId,
        <!-- 计算不正常的打卡次数 -->
        SUM(IF(fads.F_IsScheduling != 0 and (fads.F_IsClocked = 0 or
        fads.F_IsScheduling = 0 or
        fads.F_LateTimes > 0 or
        fads.F_EarlyLeaveTimes > 0 or
        fads.F_AbsenceCardTimes > 0 or
        fads.F_AbsenceTimes > 0 or
        fads.F_ShiftsJson->'$[*].clockInResultList' is null)
        , 1, 0)) normalCount,
        <!-- 计算未安排考勤的次数 -->
        SUM(IF(fads.F_IsScheduling = 0 , 1, 0)) notSchedulingCount,
        <!-- 计算请假次数 -->
        SUM(IF(fads.F_LeaveHours > 0, 1, 0)) leaveCount,
        <!-- 计算迟到次数 -->
        SUM(IF(fads.F_LateTimes > 0, 1, 0)) lateCount,
        <!-- 计算早退次数 -->
        SUM(IF(fads.F_EarlyLeaveTimes > 0, 1, 0)) earlyLeaveCount,
        <!-- 计算缺卡次数 -->
        SUM(IF(fads.F_AbsenceCardTimes > 0, 1, 0)) absenceCardCount,
        <!-- 计算缺勤次数 -->
        SUM(IF(fads.F_AbsenceTimes > 0, 1, 0)) absenceCount,
        <!-- 计算出差次数 -->
        SUM(IF(fads.F_BusBatchNumber IS NOT NULL, 1, 0)) busCount,
        <!-- 计算外出次数 -->
        SUM(IF(fads.F_OutBatchNumber IS NOT NULL, 1, 0)) outCount,
        <!-- 计算加班次数 -->
        SUM(IF(fads.F_OvertimeTimes > 0 , 1, 0)) overtimeCount,
        <!-- 选择最新的提醒时间 -->
        MAX(fads.F_RemindTime) F_RemindTime
    </sql>
    <!-- 定义一个用于团队月度统计的字段列表SQL片段 -->
    <sql id="teamMonthStaticsField">
        <!-- 选择团队ID和其他相关统计字段 -->
        t.F_GroupId groupId,
        <!-- 计算正常打卡次数 -->
        SUM(IF(t.normalCount > 0 OR t.notSchedulingCount > 0 , 0, 1)) normalCount,
        <!-- 计算请假次数 -->
        SUM(IF(t.leaveCount > 0, 1, 0)) leaveCount,
        <!-- 计算迟到次数 -->
        SUM(IF(t.lateCount > 0, 1, 0)) lateCount,
        <!-- 计算早退次数 -->
        SUM(IF(t.earlyLeaveCount > 0, 1, 0)) earlyLeaveCount,
        <!-- 计算缺卡次数 -->
        SUM(IF(t.absenceCardCount > 0, 1, 0)) absenceCardCount,
        <!-- 计算缺勤次数 -->
        SUM(IF(t.absenceCount > 0, 1, 0)) absenceCount,
        <!-- 计算出差次数 -->
        SUM(IF(t.busCount > 0, 1, 0)) busCount,
        <!-- 计算外出次数 -->
        SUM(IF(t.outCount > 0, 1, 0)) outCount,
        <!-- 计算加班次数 -->
        SUM(IF(t.overtimeCount > 0 , 1, 0)) overtimeCount,
        <!-- 选择最新的提醒时间 -->
        MAX(t.F_RemindTime) remindTime
    </sql>

    <!-- 获取每日统计通知 -->
    <select id="getDayStatisticsNotice" resultMap="dayStatisticsNoticeMap">
        SELECT
        <include refid="dayStatisticsNoticeField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="dayNoticeWhere"/>
        order by fads.F_GroupId,fads.F_JoinTime,fads.F_UserId,fads.F_Date
    </select>

    <!-- 获取月度统计通知 -->
    <select id="getMonthStatisticsNotice" resultMap="monthStatisticsNoticeMap">
        SELECT
        <include refid="monthStatisticsNoticeField"/>
        from (SELECT
        <include refid="monthStatisticsNoticeQueryField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="monthOrTeamMonthNoticeWhere"/>
        ) t
        group BY t.F_GroupId,t.F_UserId
        order by t.F_GroupId,t.F_UserId
    </select>

    <!-- 获取部门月度统计通知 -->
    <select id="getStemMonthStatisticsNotice"
            resultType="jnpf.model.attendance.vo.attendance.TeamMonthStatisticsNoticeQueryVo">
        SELECT
        <include refid="teamMonthStaticsField"/>
        from (SELECT
        <include refid="teamMonthStaticsNormalField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="monthOrTeamMonthNoticeWhere"/>
        group BY fads.F_GroupId,fads.F_UserId
        ) t GROUP BY t.F_GroupId
    </select>

    <!--获取考勤组每月的平均工时-->
    <select id="getAvgHours" resultType="jnpf.attendance.dto.AttendanceCountAvgHoursVo">
        SELECT
        DATE_FORMAT(fads.F_Date, '%Y-%m') AS month,
        ROUND(SUM(fads.F_ActualAttendHours) / COUNT(DISTINCT fads.F_UserId), 2) avgHours
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY month
        ORDER BY month;
    </select>

    <!--获取多考勤组月度统计数据-->
    <select id="getAttendanceAvgHoursDetails"
            resultType="jnpf.model.attendance.vo.attendance.MonthStatsDetailsQueryVo">
        SELECT
        COALESCE(ROUND(SUM(fads.F_ActualAttendHours)/COUNT(DISTINCT fads.F_UserId),2),0) avgHours,
        COALESCE(ROUND(SUM(fads.F_OvertimeHours)/COUNT(DISTINCT IF(fads.F_OvertimeTimes > 0, fads.F_UserId, NULL)),2),0)
        avgOverTimeHours,
        COALESCE(ROUND(SUM(fads.F_LeaveDays)/COUNT(DISTINCT IF(fads.F_LeaveBatchNumber is not null, fads.F_UserId,
        NULL)),2),0) avgLeaveDays,
        COALESCE(ROUND(SUM(fads.F_AbsenceDays)/COUNT(DISTINCT IF(fads.F_AbsenceTimes > 0, fads.F_UserId, NULL)),2),0) AS
        avgAbsentDays,
        COUNT(DISTINCT IF(fads.F_LateTimes > 0, fads.F_UserId, NULL)) lateCount,
        COUNT(DISTINCT IF(fads.F_EarlyLeaveTimes > 0, fads.F_UserId, NULL)) earlyCount
        FROM
        ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
    </select>
    <!--获取多考勤组月度人均工时折线图-->
    <select id="getAttendanceMonthPerCapita"
            resultType="jnpf.model.attendance.vo.attendance.MonthStatsPerCapitaQueryVo">
        SELECT
        fads.F_Date day,
        ROUND(COALESCE(SUM(fads.F_ActualAttendHours),0) / COUNT(DISTINCT fads.F_UserId), 2) avgHours
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_Date
        ORDER BY fads.F_Date;
    </select>
    <select id="getAttendanceDailySituation"
            resultType="jnpf.model.attendance.vo.attendance.MonthStatsDailySituationQueryVo">
        SELECT
        COALESCE(SUM(t.normalCount),0) normalDays,
        COALESCE(SUM(t.lateCount),0) lateDays,
        COALESCE(SUM(t.earlyLeaveCount),0) earlyLeaveDays,
        COALESCE(SUM(t.notSchedulingCount),0) notSchedulingDays,
        COALESCE(SUM(t.absenceCardCount),0) absenceCardDays,
        COALESCE(SUM(t.absenceCount),0) absenceDays,
        COALESCE(SUM(t.leaveCount),0) leaveDays,
        COALESCE(SUM(t.busCount),0) busDays,
        COALESCE(SUM(t.outCount),0) outDays,
        COALESCE(SUM(t.selfCount),0) selfDays,
        COALESCE(SUM(t.overtimeCount),0) overtimeDays
        from (
        SELECT
        SUM(IF(fads.F_IsScheduling = 1 and
        fads.F_IsClocked = 1 and
        fads.F_LateTimes = 0 and
        fads.F_EarlyLeaveTimes = 0 and
        fads.F_AbsenceCardTimes = 0 and
        fads.F_AbsenceTimes = 0 and
        fads.F_ShiftsJson->'$[*].clockInResultList' is not null, 1, 0)) normalCount,
        SUM(IF(fads.F_IsScheduling = 0 , 1, 0)) notSchedulingCount,
        SUM(IF(fads.F_LeaveHours > 0, 1, 0)) leaveCount,
        SUM(IF(fads.F_LateTimes > 0, 1, 0)) lateCount,
        SUM(IF(fads.F_EarlyLeaveTimes > 0, 1, 0)) earlyLeaveCount,
        SUM(IF(fads.F_AbsenceCardTimes > 0, 1, 0)) absenceCardCount,
        SUM(IF(fads.F_AbsenceTimes > 0, 1, 0)) absenceCount,
        SUM(IF(fads.F_BusBatchNumber IS NOT NULL, 1, 0)) busCount,
        SUM(IF(fads.F_OutBatchNumber IS NOT NULL, 1, 0)) outCount,
        SUM(IF(fads.F_SelfGroup = 1 , 1, 0)) selfCount,
        SUM(IF(fads.F_OvertimeTimes > 0 , 1, 0)) overtimeCount
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_Date
        ORDER BY fads.F_Date
        ) t
    </select>
    <select id="getAttendanceHoursRanking"
            resultType="jnpf.model.attendance.vo.attendance.MonthStatsHoursRankingQueryVo">
        SELECT
        fads.F_UserId userId,
        COALESCE(SUM(fads.F_ActualAttendHours),0) hours
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_UserId
        having hours > 0
        ORDER BY hours DESC;
    </select>
    <select id="getAttendanceFullSituation"
            resultType="jnpf.model.attendance.vo.attendance.MonthStatsFullSituationQueryVo">
        SELECT
        fads.F_Date day,
        COUNT(DISTINCT fads.F_UserId) groupUserCount,
        COUNT(DISTINCT IF(fads.F_IsScheduling = 1 and
        fads.F_IsClocked = 1 and
        fads.F_LateTimes = 0 and
        fads.F_EarlyLeaveTimes = 0 and
        fads.F_AbsenceCardTimes = 0 and
        fads.F_AbsenceTimes = 0 and
        fads.F_ShiftsJson->'$[*].clockInResultList' is not null, fads.F_UserId, NULL)) fullCount
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_Date
        ORDER BY fads.F_Date
    </select>
    <select id="getAttendanceAbnormalCondition"
            resultType="jnpf.model.attendance.vo.attendance.MonthStatsAbnormalConditionQueryVo">
        SELECT
        COALESCE(SUM(IF(fads.F_IsScheduling = 1 and
        fads.F_IsClocked = 1 and
        fads.F_LateTimes = 0 and
        fads.F_EarlyLeaveTimes = 0 and
        fads.F_AbsenceCardTimes = 0 and
        fads.F_AbsenceTimes = 0 and
        fads.F_ShiftsJson->'$[*].clockInResultList' is not null, 1, 0)),0) normalCount,
        COALESCE(SUM(fads.F_LateTimes),0) lateCount,
        COALESCE(SUM(fads.F_EarlyLeaveTimes),0) earlyCount,
        COALESCE(SUM(fads.F_AbsenceCardTimes),0) absenceCardCount,
        COALESCE(SUM(fads.F_AbsenceTimes),0) absenceCount
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
    </select>
    <select id="getAttendanceOvertimeSituation"
            resultType="jnpf.model.attendance.vo.attendance.MonthStatsOvertimeSituationQueryVo">
        SELECT
        fads.F_Date day,
        COALESCE(ROUND(SUM(fads.F_OvertimeHours)/COUNT(DISTINCT IF(fads.F_OvertimeTimes > 0, fads.F_UserId, NULL)),2),0)
        overtimeHours
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_Date
        ORDER BY fads.F_Date
    </select>

    <select id="getConfirmDetailsInfoByMonth" resultMap="attendanceMonthStatisticsMap">
        SELECT
        <include refid="monthPageListField"/>
        from (SELECT
        <include refid="monthPageListQueryField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="staticsConfirmWhere"/>
        ) t
        group BY t.F_UserId
        order by t.F_GroupId,t.F_JoinTime desc,t.F_UserId
    </select>
    <select id="selectUserIsSeal" resultType="jnpf.model.attendance.vo.attendance.SealUserInfoDataVo">
        SELECT
        fads.F_UserId AS userId,
        MAX(IF(fads.F_Seal = 1, 1, 0)) AS seal
        FROM ftb_attendance_day_statistics fads
        <where>
            <!-- 判断是否需要根据日期范围添加查询条件 -->
            <if test="startDate != null and endDate != ''">
                AND fads.F_Date BETWEEN #{startDate} AND #{endDate}
            </if>
            <!-- 判断是否需要根据用户ID列表添加查询条件 -->
            <if test="userIdList!= null and userIdList.size()>0">
                and fads.F_UserId in
                <foreach collection="userIdList" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
        GROUP BY fads.F_UserId
    </select>
    <!-- 按天查询用户在日期范围内已封存(F_Seal=1)的具体日期，用于跨月场景按天判断锁定状态 -->
    <select id="selectUserDailySeal" resultType="jnpf.model.attendance.vo.attendance.UserDailySealVo">
        SELECT
        fads.F_UserId AS userId,
        DATE_FORMAT(fads.F_Date, '%Y-%m-%d') AS date
        FROM ftb_attendance_day_statistics fads
        <where>
            AND fads.F_Seal = 1
            <if test="startDate != null and startDate != '' and endDate != null and endDate != ''">
                AND fads.F_Date BETWEEN #{startDate} AND #{endDate}
            </if>
            <if test="userIdList != null and userIdList.size() > 0">
                AND fads.F_UserId IN
                <foreach collection="userIdList" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </select>
    <select id="sealPageList" resultType="jnpf.model.attendance.vo.attendance.MonthSealPageListVo">
        SELECT
        fads.F_UserId AS userId,
        MAX(IF(fads.F_Seal = 1, 1, 0)) AS seal
        FROM ftb_attendance_day_statistics fads
        <where>
            <!-- 判断是否需要根据分组ID列表添加查询条件 -->
            <if test="req.groupIds!= null and req.groupIds.size()>0">
                and fads.F_GroupId in
                <foreach collection="req.groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <!-- 判断是否需要根据日期范围添加查询条件 -->
            <if test="req.startDate != null and req.endDate != ''">
                AND fads.F_Date BETWEEN #{req.startDate} AND #{req.endDate}
            </if>
            <!-- 判断是否需要根据用户ID列表添加查询条件 -->
            <if test="req.userIds!= null and req.userIds.size()>0">
                and fads.F_UserId in
                <foreach collection="req.userIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <if test="seal != null">
                and fads.F_Seal = #{seal}
            </if>
        </where>
        GROUP BY fads.F_UserId
    </select>
    <select id="salaryAttendanceSupport" resultMap="salaryStatisticsListMap">
        SELECT
        <include refid="salaryListField"/>
        from (SELECT
        <include refid="salaryListQueryField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="staticsSalaryWhere"/>
        ) t
        group BY t.F_GroupId,t.F_UserId
        order by t.F_GroupId,t.F_JoinTime desc,t.F_UserId
    </select>

    <!-- 结果映射 -->
    <resultMap id="AttendanceDimensionResult" type="jnpf.model.attendance.vo.attendance.AttendanceDimensionVo">
        <result column="dimensionType" property="dimensionType"/>
        <result column="groupId" property="groupId"/>
        <result column="personCount" property="personCount"/>
    </resultMap>

    <select id="getDimensionsAttendanceCountList" resultMap="AttendanceDimensionResult">
        <foreach collection="dimensions" item="dimension" index="index" separator=" UNION ALL ">
            SELECT
            #{dimension.typeEnums.value} as dimensionType,
            F_GroupId as groupId,
            COUNT(DISTINCT CONCAT(F_UserId, '-', F_Date)) as personCount
            FROM ftb_attendance_day_statistics
            WHERE F_GroupId IN
            <foreach collection="groupIds" item="groupId" open="(" separator="," close=")">
                #{groupId}
            </foreach>
            AND F_Date BETWEEN #{dimension.startDate} AND #{dimension.endDate}
            AND F_EffectiveAttendHours > 0
            GROUP BY F_GroupId
        </foreach>
        ORDER BY groupId,CASE dimensionType
        WHEN 'CURRENT' THEN 1
        WHEN 'YOY' THEN 2
        WHEN 'MOM' THEN 3
        ELSE 4
        END
    </select>

    <select id="getDimensionsAttendanceDayCountList" resultType="jnpf.model.attendance.vo.attendance.AttendanceDimensionDayVo">
        SELECT
        F_GroupId as groupId,
        F_Date as day,
        COUNT(DISTINCT CONCAT(F_UserId, '-', F_Date)) as personCount
        FROM ftb_attendance_day_statistics
        WHERE F_GroupId IN
        <foreach collection="groupIds" item="groupId" open="(" separator="," close=")">
            #{groupId}
        </foreach>
        AND F_Date BETWEEN #{startDate} AND #{endDate}
        AND F_EffectiveAttendHours > 0
        GROUP BY F_GroupId,F_Date
    </select>

    <!-- 获取计薪日统计数据的分页列表 -->
    <select id="getDayPayrollPageList" resultMap="attendanceDayPayrollStatisticsMap">
        SELECT
        <include refid="dayPayrollPageListField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="staticsWhere"/>
        order by fads.F_GroupId,fads.F_JoinTime,fads.F_UserId,fads.F_Date
    </select>

    <!-- 获取计薪月统计数据的分页列表 -->
    <select id="getMonthPayrollPageList" resultMap="attendanceMonthPayrollStatisticsMap">
        SELECT
        <include refid="monthPayrollPageListField"/>
        from (SELECT
        <include refid="monthPayrollPageListQueryField"/>
        FROM ftb_attendance_day_statistics fads
        <include refid="staticsWhere"/>
        ) t
        group BY t.F_GroupId,t.F_UserId
        order by t.F_GroupId,t.F_JoinTime DESC,t.F_UserId
    </select>
    <select id="averageWorkHoursTrendPageList" resultType="jnpf.model.attendance.vo.attendance.AverageTrendPageListVo">
        SELECT
        fads.F_GroupId AS groupName,
        DATE_FORMAT(fads.F_Date, '%Y-%m') AS month,
        ROUND(SUM(fads.F_ActualAttendHours) / COUNT(DISTINCT fads.F_UserId), 2) avgHours
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY groupName,month
        having avgHours > 0
        ORDER BY groupName,month
    </select>
    <select id="personWorkHoursTrendPageList" resultType="jnpf.model.attendance.vo.attendance.PersonnelTrendPageListVo">
        SELECT
        fads.F_GroupId AS groupName,
        DATE_FORMAT(fads.F_Date, '%Y-%m-%d') AS day,
        ROUND(COALESCE(SUM(fads.F_ActualAttendHours),0) / COUNT(DISTINCT fads.F_UserId), 2) personHours
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY groupName,day
        having personHours > 0
        ORDER BY groupName,day
    </select>
    <select id="dailySituationPageList" resultType="jnpf.model.attendance.vo.attendance.DailySituationPageListVo">
        SELECT
        groupName,
        userName,
        COALESCE(SUM(t.normalCount),0) normalDays,
        COALESCE(SUM(t.lateCount),0) lateDays,
        COALESCE(SUM(t.earlyLeaveCount),0) earlyLeaveDays,
        COALESCE(SUM(t.notSchedulingCount),0) notSchedulingDays,
        COALESCE(SUM(t.absenceCardCount),0) absenceCardDays,
        COALESCE(SUM(t.absenceCount),0) absenceDays,
        COALESCE(SUM(t.leaveCount),0) leaveDays,
        COALESCE(SUM(t.busCount),0) busDays,
        COALESCE(SUM(t.outCount),0) outDays,
        COALESCE(SUM(t.selfCount),0) selfDays,
        COALESCE(SUM(t.overtimeCount),0) overtimeDays
        from (
        SELECT
        fads.F_GroupId AS groupName,
        fads.F_UserId AS userName,
        SUM(IF(fads.F_IsScheduling = 1 and
        fads.F_IsClocked = 1 and
        fads.F_LateTimes = 0 and
        fads.F_EarlyLeaveTimes = 0 and
        fads.F_AbsenceCardTimes = 0 and
        fads.F_AbsenceTimes = 0 and
        fads.F_ShiftsJson->'$[*].clockInResultList' is not null, 1, 0)) normalCount,
        SUM(IF(fads.F_IsScheduling = 0 , 1, 0)) notSchedulingCount,
        SUM(IF(fads.F_LeaveBatchNumber IS NOT NULL, 1, 0)) leaveCount,
        SUM(IF(fads.F_LateTimes > 0, 1, 0)) lateCount,
        SUM(IF(fads.F_EarlyLeaveTimes > 0, 1, 0)) earlyLeaveCount,
        SUM(IF(fads.F_AbsenceCardTimes > 0, 1, 0)) absenceCardCount,
        SUM(IF(fads.F_AbsenceTimes > 0, 1, 0)) absenceCount,
        SUM(IF(fads.F_BusBatchNumber IS NOT NULL, 1, 0)) busCount,
        SUM(IF(fads.F_OutBatchNumber IS NOT NULL, 1, 0)) outCount,
        SUM(IF(fads.F_SelfGroup = 1 , 1, 0)) selfCount,
        SUM(IF(fads.F_OvertimeTimes > 0 , 1, 0)) overtimeCount
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_GroupId,fads.F_UserId,fads.F_Date
        ORDER BY fads.F_Date
        ) t
        GROUP BY t.groupName,t.userName
        ORDER BY t.groupName,t.userName
    </select>
    <select id="workHoursRankingPageList" resultType="jnpf.model.attendance.vo.attendance.WorkHoursRankingPageListVo">
        SELECT
        fads.F_GroupId AS groupName,
        fads.F_UserId AS userName,
        COALESCE(SUM(fads.F_ActualAttendHours),0) attendanceHours
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_GroupId,fads.F_UserId
        having attendanceHours > 0
        ORDER BY attendanceHours DESC
    </select>
    <select id="fullAttendanceStatusPageList" resultType="jnpf.model.attendance.vo.attendance.FullAttendanceStatusPageListVo">
        SELECT
        fads.F_GroupId AS groupName,
        DATE_FORMAT(fads.F_Date, '%Y-%m-%d') AS day,
        COUNT(DISTINCT fads.F_UserId) groupCount,
        COUNT(DISTINCT IF(fads.F_IsScheduling = 1 and
        fads.F_IsClocked = 1 and
        fads.F_LateTimes = 0 and
        fads.F_EarlyLeaveTimes = 0 and
        fads.F_AbsenceCardTimes = 0 and
        fads.F_AbsenceTimes = 0 and
        fads.F_ShiftsJson->'$[*].clockInResultList' is not null, fads.F_UserId, NULL)) fullAttendCount
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_GroupId,fads.F_Date
        having groupCount > 0
        ORDER BY fads.F_Date ,fads.F_GroupId
    </select>
    <select id="exceptionSituationPageList" resultType="jnpf.model.attendance.vo.attendance.ExceptionSituationPageListVo">
        SELECT
        fads.F_GroupId AS groupName,
        fads.F_UserId AS userName,
        COALESCE(SUM(IF(fads.F_IsScheduling = 1 and
        fads.F_IsClocked = 1 and
        fads.F_LateTimes = 0 and
        fads.F_EarlyLeaveTimes = 0 and
        fads.F_AbsenceCardTimes = 0 and
        fads.F_AbsenceTimes = 0 and
        fads.F_ShiftsJson->'$[*].clockInResultList' is not null, 1, 0)),0) normalCount,
        COALESCE(SUM(fads.F_LateTimes),0) lateCount,
        COALESCE(SUM(fads.F_EarlyLeaveTimes),0) earlyCount,
        COALESCE(SUM(fads.F_AbsenceCardTimes),0) absenceCardCount,
        COALESCE(SUM(fads.F_AbsenceTimes),0) absenceCount
        FROM ftb_attendance_day_statistics fads
        <include refid="getAvgHoursWhere"/>
        GROUP BY fads.F_GroupId,fads.F_UserId
        ORDER BY fads.F_GroupId,fads.F_UserId
    </select>
    <select id="overtimeSituationPageList" resultType="jnpf.model.attendance.vo.attendance.OvertimeSituationPageListVo">
        SELECT
        DATE_FORMAT(curr.F_Date, '%Y-%m-%d') AS day,
        curr.F_GroupId AS groupName,
        curr.avgOvertimeHours,
        -- 同比计算：本期和去年同期都必须有有效数据才计算
        IF(curr.avgOvertimeHours IS NULL OR curr.avgOvertimeHours = 0 OR ly.avgOvertimeHours IS NULL OR ly.avgOvertimeHours = 0, NULL,
        ROUND((curr.avgOvertimeHours - ly.avgOvertimeHours) / ly.avgOvertimeHours * 100, 2)) AS yearOnYear,
        -- 环比计算：本期和前一天都必须有有效数据才计算
        IF(curr.avgOvertimeHours IS NULL OR curr.avgOvertimeHours = 0 OR prev.avgOvertimeHours IS NULL OR prev.avgOvertimeHours = 0, NULL,
        ROUND((curr.avgOvertimeHours - prev.avgOvertimeHours) / prev.avgOvertimeHours * 100, 2)) AS annulus
        FROM (
        -- 当前查询期间的统计数据
        SELECT
        fads.F_Date,
        fads.F_GroupId,
        COALESCE(ROUND(SUM(fads.F_OvertimeHours) / COUNT(DISTINCT IF(fads.F_OvertimeTimes > 0, fads.F_UserId, NULL)),2), 0) AS avgOvertimeHours
        FROM ftb_attendance_day_statistics fads
        <where>
            fads.F_OvertimeHours > 0
            <if test="groupIds!= null and groupIds.size()>0">
                AND fads.F_GroupId IN
                <foreach collection="groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <if test="startDate != null and endDate != null">
                AND fads.F_Date BETWEEN DATE_SUB(#{startDate}, INTERVAL 1 DAY) AND #{endDate}
            </if>
        </where>
        GROUP BY fads.F_Date, fads.F_GroupId
        ) curr
        -- 关联去年同一天的数据（同比）
        LEFT JOIN (
        SELECT
        fads.F_Date,
        fads.F_GroupId,
        COALESCE(ROUND(SUM(fads.F_OvertimeHours) / COUNT(DISTINCT IF(fads.F_OvertimeTimes > 0, fads.F_UserId, NULL)),2), 0) AS avgOvertimeHours
        FROM ftb_attendance_day_statistics fads
        <where>
            fads.F_OvertimeHours > 0
            <if test="groupIds!= null and groupIds.size()>0">
                AND fads.F_GroupId IN
                <foreach collection="groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <if test="startDate != null and endDate != null">
                AND fads.F_Date BETWEEN DATE_SUB(#{startDate}, INTERVAL 1 YEAR) AND DATE_SUB(#{endDate}, INTERVAL 1 YEAR)
            </if>
        </where>
        GROUP BY fads.F_Date, fads.F_GroupId
        ) ly ON curr.F_GroupId = ly.F_GroupId
        AND ly.F_Date = DATE_SUB(curr.F_Date, INTERVAL 1 YEAR)
        -- 关联上个月的数据（环比）
        LEFT JOIN (
        SELECT
        fads.F_Date,
        fads.F_GroupId,
        COALESCE(ROUND(SUM(fads.F_OvertimeHours) / COUNT(DISTINCT IF(fads.F_OvertimeTimes > 0, fads.F_UserId, NULL)),2), 0) AS avgOvertimeHours
        FROM ftb_attendance_day_statistics fads
        <where>
            fads.F_OvertimeHours > 0
            <if test="groupIds!= null and groupIds.size()>0">
                AND fads.F_GroupId IN
                <foreach collection="groupIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <if test="startDate != null and endDate != null">
                AND fads.F_Date BETWEEN DATE_SUB(#{startDate}, INTERVAL 1 MONTH) AND DATE_SUB(#{endDate}, INTERVAL 1 MONTH)
            </if>
        </where>
        GROUP BY fads.F_Date, fads.F_GroupId
        ) prev ON curr.F_GroupId = prev.F_GroupId
        AND prev.F_Date = DATE_SUB(curr.F_Date, INTERVAL 1 MONTH)
        <where>
            <if test="startDate != null and endDate != null">
                AND curr.F_Date BETWEEN #{startDate} AND #{endDate}
            </if>
        </where>
        ORDER BY curr.F_Date, curr.F_GroupId
    </select>

    <select id="queryUserStatisticsInfo" resultMap="userMonthListMap">
        SELECT
        <include refid="userMonthListField"/>
        from (SELECT
        <include refid="userDayListField"/>
        FROM ftb_attendance_day_statistics fads
        <where>
            <!-- 判断是否需要根据日期范围添加查询条件 -->
            <if test="dateRangeDto.startDate != null and dateRangeDto.endDate != ''">
                AND fads.F_Date BETWEEN #{dateRangeDto.startDate} AND #{dateRangeDto.endDate}
            </if>
            <!-- 判断是否需要根据用户ID列表添加查询条件 -->
            <if test="userId != null and userId != ''">
                and fads.F_UserId = #{userId}
            </if>
        </where>
        ) t
    </select>
    <select id="queryUserOvertime" resultType="jnpf.model.attendance.vo.attendance.QueryUserOvertimeDetailsDbVo">
        SELECT
        fads.F_Date AS `day`,
        fads.F_OvertimeHours AS hours,
        fads.F_ShiftsJson AS shiftsJson
        FROM ftb_attendance_day_statistics fads
        <where>
            fads.F_OvertimeHours > 0
            <!-- 判断是否需要根据日期范围添加查询条件 -->
            <if test="dateRangeDto.startDate != null and dateRangeDto.endDate != ''">
                AND fads.F_Date BETWEEN #{dateRangeDto.startDate} AND #{dateRangeDto.endDate}
            </if>
            <!-- 判断是否需要根据用户ID列表添加查询条件 -->
            <if test="userId != null and userId != ''">
                and fads.F_UserId = #{userId}
            </if>
        </where>
    </select>

    <!-- 查询用户工作状况统计信息 -->
    <select id="queryUserWorkSituation" resultType="jnpf.model.attendance.vo.attendance.UserWorkSituationDbVo">
        SELECT
            fads.F_UserId AS userId,
            fads.F_Date AS date,
            ROUND(SUM(fads.F_ShouldAttendHours), 2) AS attendanceHours,
            IF(fads.F_IsScheduling = 1, 1, 0) AS isScheduling
        FROM ftb_attendance_day_statistics fads
        <where>
            fads.F_UserId IN
            <foreach collection="userIds" item="userId" open="(" separator="," close=")">
                #{userId}
            </foreach>
            <if test="startDate != null and endDate != null">
                AND fads.F_Date BETWEEN #{startDate} AND #{endDate}
            </if>
            AND fads.F_ShouldAttendHours > 0
        </where>
        GROUP BY fads.F_UserId, fads.F_Date
        ORDER BY fads.F_UserId, fads.F_Date ASC
    </select>
</mapper>