AttendanceRecordMapper.xml 8.09 KB
<?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="AttendanceRecordV1ServiceDaoImpl">

    <insert id="saveAttendanceRecord" parameterType="com.java110.po.property.AttendanceRecordPo">
        INSERT INTO attendance_record(id, user_id, user_name, work_type, punch_type, punch_time, punch_address, longitude, latitude, store_id, photo_url, create_time)
        VALUES(#{id}, #{userId}, #{userName}, #{workType}, #{punchType}, #{punchTime}, #{punchAddress}, #{longitude}, #{latitude}, #{storeId}, #{photoUrl}, NOW())
    </insert>

    <select id="queryAttendanceRecords" parameterType="map" resultType="map">
        SELECT * FROM attendance_record WHERE 1=1
        <if test="userId != null and userId != ''">AND user_id = #{userId}</if>
        <if test="workType != null and workType != ''">AND work_type = #{workType}</if>
        <if test="punchType != null and punchType != ''">AND punch_type = #{punchType}</if>
        <if test="startTime != null and startTime != ''">AND punch_time &gt;= #{startTime}</if>
        <if test="endTime != null and endTime != ''">AND punch_time &lt;= #{endTime}</if>
        <if test="storeId != null and storeId != ''">AND store_id = #{storeId}</if>
        ORDER BY punch_time DESC
        <if test="page != null and page != '' and row != null and row != ''">
            LIMIT #{page}, #{row}
        </if>
    </select>

    <select id="queryAttendanceRecordsCount" parameterType="map" resultType="map">
        SELECT COUNT(1) count FROM attendance_record WHERE 1=1
        <if test="userId != null and userId != ''">AND user_id = #{userId}</if>
        <if test="workType != null and workType != ''">AND work_type = #{workType}</if>
        <if test="punchType != null and punchType != ''">AND punch_type = #{punchType}</if>
        <if test="startTime != null and startTime != ''">AND punch_time &gt;= #{startTime}</if>
        <if test="endTime != null and endTime != ''">AND punch_time &lt;= #{endTime}</if>
        <if test="storeId != null and storeId != ''">AND store_id = #{storeId}</if>
    </select>

    <select id="queryTodayAttendanceByType" parameterType="map" resultType="map">
        SELECT * FROM attendance_record
        WHERE user_id = #{userId} AND punch_type = #{punchType}
        AND DATE(punch_time) = CURDATE()
        LIMIT 1
    </select>

    <select id="countTodayByType" parameterType="map" resultType="int">
        SELECT COUNT(1) FROM attendance_record
        WHERE user_id = #{userId} AND punch_type = #{punchType}
        AND DATE(punch_time) = CURDATE()
    </select>

    <select id="getLastPunch" parameterType="map" resultType="map">
        SELECT * FROM attendance_record
        WHERE user_id = #{userId}
        ORDER BY punch_time DESC
        LIMIT 1
    </select>

    <select id="queryAllAttendanceUsers" parameterType="map" resultType="map">
        SELECT u.user_id, u.name AS user_name, u.address, '' AS work_type, '' AS store_name
        FROM u_user u
        WHERE u.status_cd = '0'
        AND (u.level_cd = '00' OR u.level_cd = '01')
        ORDER BY u.name
    </select>

    <!-- 打卡统计:按用户聚合(u_user 为主表,LEFT JOIN 打卡记录) -->
    <select id="queryAttendanceStats" parameterType="map" resultType="map">
        SELECT
            u.user_id,
            u.name AS user_name,
            u.address,
            COUNT(ar.id) AS total_punches,
            IFNULL(SUM(CASE ar.punch_type WHEN 'ON' THEN 1 ELSE 0 END), 0) AS on_punches,
            IFNULL(SUM(CASE ar.punch_type WHEN 'OFF' THEN 1 ELSE 0 END), 0) AS off_punches,
            COUNT(DISTINCT DATE(ar.punch_time)) AS actual_days
        FROM u_user u
        <if test="storeId != null and storeId != ''">
            INNER JOIN staff_community sc ON u.user_id = sc.staff_id AND sc.store_id = #{storeId} AND sc.status_cd = '0'
        </if>
        LEFT JOIN attendance_record ar
            ON u.user_id = ar.user_id
            AND ar.punch_time &gt;= #{startTime}
            AND ar.punch_time &lt;= #{endTime}
        WHERE u.status_cd != '1'
        <if test="userId != null and userId != ''">AND u.user_id = #{userId}</if>
        GROUP BY u.user_id, u.name, u.address
        ORDER BY u.name
    </select>

    <!-- 打卡统计:用户数 -->
    <select id="queryAttendanceStatsCount" parameterType="map" resultType="map">
        SELECT COUNT(1) AS count
        FROM u_user u
        <if test="storeId != null and storeId != ''">
            INNER JOIN staff_community sc ON u.user_id = sc.staff_id AND sc.store_id = #{storeId} AND sc.status_cd = '0'
        </if>
        WHERE u.status_cd != '1'
        <if test="userId != null and userId != ''">AND u.user_id = #{userId}</if>
    </select>

    <!-- 打卡统计:每日出勤人数(图表用) -->
    <select id="queryDailyAttendanceStats" parameterType="map" resultType="map">
        SELECT
            DATE(ar.punch_time) AS punch_date,
            COUNT(DISTINCT ar.user_id) AS user_count,
            COUNT(*) AS total_punches
        FROM attendance_record ar
        WHERE ar.punch_time &gt;= #{startTime} AND ar.punch_time &lt;= #{endTime}
        <if test="storeId != null and storeId != ''">
            AND ar.user_id IN (SELECT DISTINCT staff_id FROM staff_community WHERE store_id = #{storeId} AND status_cd = '0')
        </if>
        GROUP BY DATE(ar.punch_time)
        ORDER BY punch_date
    </select>

    <!-- 打卡统计:异常检测(有上班无下班 或 有下班无上班) -->
    <select id="queryAttendanceRecordsForStats" parameterType="map" resultType="map">
        SELECT
            t1.user_id,
            t1.punch_date,
            CASE
                WHEN t1.has_on = 1 AND t1.has_off = 0 THEN '有上班无下班'
                WHEN t1.has_on = 0 AND t1.has_off = 1 THEN '有下班无上班'
            END AS lack_desc
        FROM (
            SELECT
                user_id,
                DATE(punch_time) AS punch_date,
                MAX(CASE punch_type WHEN 'ON' THEN 1 ELSE 0 END) AS has_on,
                MAX(CASE punch_type WHEN 'OFF' THEN 1 ELSE 0 END) AS has_off
            FROM attendance_record
            WHERE punch_time &gt;= #{startTime} AND punch_time &lt;= #{endTime}
            <if test="storeId != null and storeId != ''">
                AND user_id IN (SELECT DISTINCT staff_id FROM staff_community WHERE store_id = #{storeId} AND status_cd = '0')
            </if>
            <if test="userId != null and userId != ''">AND user_id = #{userId}</if>
            GROUP BY user_id, DATE(punch_time)
        ) t1
        HAVING lack_desc IS NOT NULL
        ORDER BY t1.user_id, t1.punch_date
    </select>

    <!-- 打卡统计:项目维度聚合(物业端) -->
    <select id="queryProjectAttendanceStats" parameterType="map" resultType="map">
        SELECT
            sc.community_id,
            sc.community_name,
            COUNT(DISTINCT ar.user_id) AS user_count,
            COUNT(*) AS total_punches,
            SUM(CASE WHEN ar.punch_type = 'ON' THEN 1 ELSE 0 END) AS on_punches,
            SUM(CASE WHEN ar.punch_type = 'OFF' THEN 1 ELSE 0 END) AS off_punches,
            COUNT(DISTINCT DATE(ar.punch_time)) AS total_actual_days
        FROM staff_community sc
        INNER JOIN attendance_record ar ON sc.staff_id = ar.user_id AND sc.status_cd = '0'
        WHERE ar.punch_time &gt;= #{startTime} AND ar.punch_time &lt;= #{endTime}
        <if test="storeId != null and storeId != ''">AND sc.store_id = #{storeId}</if>
        GROUP BY sc.community_id, sc.community_name
        ORDER BY sc.community_name
    </select>

    <!-- 打卡统计:查询员工排班工作日数 -->
    <select id="queryScheduleWorkdays" parameterType="map" resultType="map">
        SELECT
            scs.staff_id,
            COUNT(DISTINCT CONCAT(scd.day, '_', scd.week_flag)) AS schedule_days
        FROM schedule_classes_staff scs
        INNER JOIN schedule_classes_day scd ON scs.schedule_id = scd.schedule_id AND scd.status_cd = '0'
        WHERE scs.status_cd = '0'
        <if test="staffId != null and staffId != ''">AND scs.staff_id = #{staffId}</if>
        GROUP BY scs.staff_id
    </select>

</mapper>