修改人天计算方法,避免笛卡尔积问题导致人天错误

This commit is contained in:
2025-04-01 17:22:34 +08:00
parent dbc2515bf0
commit d43f063f6f
2 changed files with 80 additions and 39 deletions

View File

@@ -97,28 +97,58 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectVoListAndTime" resultType="com.ruoyi.oa.domain.vo.SysOaAttendanceVo"> <select id="selectVoListAndTime" resultType="com.ruoyi.oa.domain.vo.SysOaAttendanceVo">
SELECT ANY_VALUE(id), SELECT
user_id, ANY_VALUE(id) AS id,
ANY_VALUE(attendance_day), user_id,
project_id, ANY_VALUE(attendance_day) AS attendance_day,
ANY_VALUE(day_length), project_id,
ANY_VALUE(hour), ANY_VALUE(day_length) AS day_length,
ANY_VALUE(create_time), ANY_VALUE(hour) AS hour,
ANY_VALUE(create_by), ANY_VALUE(create_time) AS create_time,
ANY_VALUE(update_time), ANY_VALUE(create_by) AS create_by,
ANY_VALUE(update_by), ANY_VALUE(update_time) AS update_time,
ANY_VALUE(remark), ANY_VALUE(update_by) AS update_by,
ANY_VALUE(del_flag), ANY_VALUE(remark) AS remark,
count(id) AS count, ANY_VALUE(del_flag) AS del_flag,
SUM(day_length) + CEILING(SUM(hour) / 9) AS work_times, COUNT(id) AS count,
(SUM(day_length) + CEILING(SUM(hour) / 9)) * 9 AS hour_work_times,
FLOOR(SUM(hour) / 9) AS overTime /*
1如果这条记录是按天统计 (day_length>0),就直接用 day_length。
2如果这条记录是按小时统计 (hour>0),那么就算作 1 天。
这样就不会把多日的小时相加再去整除 9。
*/
SUM(
CASE
WHEN day_length > 0 THEN day_length
WHEN hour > 0 THEN 1
ELSE 0
END
) AS work_times,
SUM(
CASE
WHEN day_length > 0 THEN day_length
WHEN hour > 0 THEN 1
ELSE 0
END
) *9 AS hour_work_times,
/*
overTime如果是按小时统计且 hour>9才有加班 = (hour - 9)。
如果是 day_length 统计,则一般不会再去算小时加班(你如果有需要,也可以自己按其它规则)。
*/
SUM(
CASE
WHEN hour > 9 THEN hour - 9
ELSE 0
END
) AS overTime
FROM sys_oa_attendance soa FROM sys_oa_attendance soa
WHERE user_id = #{userId} WHERE user_id = #{userId}
AND #{lastDay} > create_time AND #{lastDay} > create_time
AND create_time > #{firstDay} AND create_time > #{firstDay}
AND del_flag = '0' AND del_flag = '0'
GROUP BY soa.project_id GROUP BY soa.project_id;
</select> </select>

View File

@@ -96,30 +96,41 @@
</select> </select>
<select id="getProjectDataByMonth" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo"> <select id="getProjectDataByMonth" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">
SELECT sop.project_id, SELECT
sop.project_name, p.project_id,
sop.color, p.project_name,
ROUND(SUM(soa.day_length + soa.hour / 9), 2) AS labor_cost, p.color,
-- 子查询里已经聚合完 labor_cost
a.labor_cost,
-- 同理财务部分
f.total_price
FROM sys_oa_project AS p
LEFT JOIN (
SELECT
project_id,
ROUND(SUM(day_length + hour / 9), 2) AS labor_cost
FROM sys_oa_attendance
WHERE create_time BETWEEN #{firstDay} AND #{lastDay}
AND del_flag = '0'
GROUP BY project_id
) AS a ON p.project_id = a.project_id
LEFT JOIN (
SELECT
sof.project_id,
SUM( SUM(
CASE CASE WHEN sof.finance_type = 0 THEN sod.price ELSE 0 END
WHEN sof.finance_type = 0 THEN sod.price
ELSE 0
END
) AS total_price ) AS total_price
FROM sys_oa_project AS sop FROM sys_oa_finance sof
LEFT JOIN sys_oa_attendance AS soa JOIN sys_oa_detail sod ON sof.finance_id = sod.finance_id
ON sop.project_id = soa.project_id AND sod.create_time BETWEEN #{firstDay} AND #{lastDay}
AND soa.create_time BETWEEN #{firstDay} AND #{lastDay} WHERE sof.create_time BETWEEN #{firstDay} AND #{lastDay}
AND soa.del_flag = '0' GROUP BY sof.project_id
LEFT JOIN sys_oa_finance AS sof ) AS f ON p.project_id = f.project_id
ON sop.project_id = sof.project_id
AND sof.create_time BETWEEN #{firstDay} AND #{lastDay} -- 最后只要在这里加一个 WHERE 条件,过滤掉 labor_cost=0 或者为空
LEFT JOIN sys_oa_detail AS sod WHERE a.labor_cost > 0
ON sof.finance_id = sod.finance_id
AND sod.create_time BETWEEN #{firstDay} AND #{lastDay}
GROUP BY sop.project_id,
sop.project_name,
sop.color
</select> </select>
<select id="getProjectDataByMonthAndDate" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo"> <select id="getProjectDataByMonthAndDate" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">