新增车间计算记录与数据看板

This commit is contained in:
2025-05-15 21:35:16 +08:00
parent a63afc6bfb
commit a0bc26ef3a
31 changed files with 1127 additions and 78 deletions

View File

@@ -1,7 +1,7 @@
<?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">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.oa.mapper.SysOaAttendanceMapper">
<resultMap type="com.ruoyi.oa.domain.vo.SysOaAttendanceVo" id="SysOaAttendanceResult">
@@ -110,16 +110,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ANY_VALUE(remark) AS remark,
ANY_VALUE(del_flag) AS del_flag,
COUNT(id) AS count,
/*
1如果这条记录是按天统计 (day_length>0),就直接用 day_length。
2如果这条记录是按小时统计 (hour>0),那么就算作 1 天。
这样就不会把多日的小时相加再去整除 8。
*/
SUM(
CASE
WHEN day_length > 0 THEN day_length
WHEN hour > 0 THEN ROUND(hour / 8, 1)
WHEN day_length > 0 THEN 1
WHEN hour > 0 THEN 1
ELSE 0
END
) AS work_times,
@@ -130,20 +124,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ELSE 0
END
) AS hour_work_times,
/*
overTime如果是按小时统计且 hour>8才有加班 = (hour - 8)。
如果是 day_length 统计,则一般不会再去算小时加班(你如果有需要,也可以自己按其它规则)。
*/
SUM(
IF(hour > 8, hour - 8, 0)
) AS overTime,
/* ---------- 出差天数 (project_id = 0) ---------- */
SUM(
IF(project_id = 0, 1, 0)
) AS tripDays,
/* ---------- 请假天数 (project_id = 1) ---------- */
SUM(
IF(project_id = 1, 1, 0)
) AS absenceDays
@@ -166,10 +153,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
soa.id,soa.attendance_day,soa.project_id,soa.day_length,soa.hour,
color,
sop.project_name, sop.project_num, sop.project_type, sop.address, sop.funds, sop.functionary, sop.begin_time,
sop.finish_time, sop.delivery, sop.guarantee, sop.introduction, sop.project_grade, sop.project_status, sop.contract_id, sop.invoice_name,
sop.invoice_number, sop.invoice_address, sop.invoice_bank, sop.accessory, sop.bail,sop.is_postpone, sop.postpone_reason,sop.postpone_time
sop.finish_time, sop.delivery, sop.guarantee, sop.introduction, sop.project_grade, sop.project_status,
sop.contract_id, sop.invoice_name,
sop.invoice_number, sop.invoice_address, sop.invoice_bank, sop.accessory, sop.bail,sop.is_postpone,
sop.postpone_reason,sop.postpone_time
FROM sys_user su
left join sys_oa_attendance soa on (su.user_id = soa.user_id and (soa.create_time BETWEEN #{firstDay} AND #{lastDay}))
left join sys_oa_attendance soa on (su.user_id = soa.user_id and (soa.create_time BETWEEN #{firstDay} AND
#{lastDay}))
left join sys_oa_project sop on soa.project_id = sop.project_id
WHERE su.user_id IN
<foreach item="userId" index="index" collection="userIds"
@@ -181,7 +171,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="queryListByTime" resultMap="SysOaAttendanceResult">
SELECT id, user_id, attendance_day, project_id, day_length, hour, create_time, create_by, update_time, update_by, remark, del_flag
SELECT id,
user_id,
attendance_day,
project_id,
day_length,
hour,
create_time,
create_by,
update_time,
update_by,
remark,
del_flag
FROM sys_oa_attendance
WHERE create_time BETWEEN #{startTime} AND #{endTime}
AND user_id = #{userId}
@@ -190,18 +191,143 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<delete id="delOaAttendanceAll">
delete from sys_oa_attendance where
attendance_day = #{day}
and #{lastDay} > create_time
and create_time > #{firstDay}
delete
from sys_oa_attendance
where attendance_day = #{day}
and #{lastDay} > create_time
and create_time > #{firstDay}
</delete>
<select id="getAttendanceDay" resultType="java.lang.Double">
select sum(day_length)
from sys_oa_attendance
where user_id = #{userId} and project_id = #{projectId} and del_flag = '0'
select sum(day_length)
from sys_oa_attendance
where user_id = #{userId}
and project_id = #{projectId}
and del_flag = '0'
</select>
<select id="selectNowMonthUserId" resultType="java.lang.Long">
select distinct user_id
from sys_oa_attendance
where YEAR(create_time) = YEAR(#{firstDay})
and MONTH(create_time) = MONTH(#{firstDay})
</select>
<!-- 结果映射 -->
<resultMap id="AttendanceMonthlyCountMap" type="com.ruoyi.oa.domain.vo.AttendanceMonthlyCount">
<result column="month" property="month"/>
<result column="attendance_count" property="attendanceCount"/>
<result column="leave_count" property="leaveCount"/>
</resultMap>
<select id="selectLastSixMonthsByMonth"
resultMap="AttendanceMonthlyCountMap">
SELECT DATE_FORMAT(create_time, '%Y-%m') AS month,
SUM(CASE WHEN project_id != 1 THEN 1 ELSE 0 END) AS attendance_count,
SUM(CASE WHEN project_id = 1 THEN 1 ELSE 0 END) AS leave_count
FROM sys_oa_attendance
WHERE create_time >= DATE_FORMAT(DATE_SUB(#{refDate}, INTERVAL 6 MONTH), '%Y-%m-01')
AND IF(DATE_FORMAT(#{refDate}, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m'), NOW(),
TIMESTAMP(LAST_DAY(DATE_SUB(#{refDate}, INTERVAL 1 MONTH)), '23:59:59'))
>= create_time
AND del_flag = 0
GROUP BY month
ORDER BY month;
</select>
<select id="selectAttendanceMonthlyCountByMonth"
resultType="com.ruoyi.oa.domain.vo.AttendanceMonthlyCount">
SELECT
-- 1) project_id = 0 : 出勤 / 出差工时(天长 * 8 + 小时)
SUM(
IF(project_id != 1 and project_id != 0, IFNULL(day_length, 0) * 8 -- day_length换算成小时
+ IFNULL(hour, 0), 0)
) AS workHours,
SUM(
IF(project_id = 0,8,0)
) AS tripHours,
-- 2) project_id = 1 : 请假工时(每条记录按 8 小时计)
SUM(
IF(project_id = 1, 8, 0)
) AS leaveHours,
-- 3) 加班工时project_id = 0 情况下hour 字段超出 8 小时的部分求和
SUM(
IF(project_id != 1, GREATEST(IFNULL(hour, 0) - 8, 0), 0)
) AS overtimeHours
FROM sys_oa_attendance
WHERE del_flag = 0
AND YEAR(create_time) = YEAR(#{refDate})
and MONTH(create_time) = MONTH(#{refDate})
</select>
<select id="selectMonthlyCounts" resultType="com.ruoyi.oa.domain.vo.AttendanceMonthlyCount">
SELECT m.month,
ROUND(
COUNT(
DISTINCT CASE
WHEN a.project_id NOT IN (0, 1)
THEN CONCAT(a.user_id, '_', DATE(a.create_time))
END
)
/
NULLIF(
COUNT(
DISTINCT CASE
WHEN a.project_id != 0
THEN a.user_id
END
)
*
COUNT(
DISTINCT CASE
WHEN a.project_id != 0
THEN DATE(a.create_time)
END
),
0
),
4
) AS attendanceRate,
SUM(CASE WHEN a.project_id = 0 THEN 1 ELSE 0 END) AS tripCount,
COUNT(CASE WHEN a.project_id = 1 THEN 1 END) AS leavePeople,
SUM(CASE
WHEN a.project_id NOT IN (0, 1)
AND IFNULL(a.hour, 0) > 8
THEN IFNULL(a.hour, 0) - 8
ELSE 0
END) AS overtimeHours
FROM (SELECT DATE_FORMAT(#{refDate}, '%Y-%m') AS month,
LAST_DAY(#{refDate}) AS last_day,
CASE
WHEN DATE_FORMAT(#{refDate}, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
THEN DAY(#{refDate}) -- 本月:已过天数
ELSE DAY(LAST_DAY(#{refDate})) -- 历史月:整月天数
END AS days_so_far
UNION ALL
SELECT DATE_FORMAT(DATE_SUB(#{refDate}, INTERVAL 1 MONTH), '%Y-%m'),
LAST_DAY(DATE_SUB(#{refDate}, INTERVAL 1 MONTH)),
DAY(LAST_DAY(DATE_SUB(#{refDate}, INTERVAL 1 MONTH)))) m
LEFT JOIN sys_oa_attendance a
ON a.del_flag = 0
AND DATE_FORMAT(a.create_time, '%Y-%m') = m.month
AND a.create_time &lt;=
CASE
WHEN m.month = DATE_FORMAT(CURDATE(), '%Y-%m')
THEN #{refDate}
ELSE TIMESTAMP(m.last_day, '23:59:59')
END
GROUP BY m.month
ORDER BY m.month DESC; -- 本月在前,上月在后
</select>
</mapper>