feat(hrm): 添加请假统计功能
- 在控制器中新增 /stats 接口用于获取请假统计数据 - 新增 HrmLeaveStatsVo 数据传输对象定义统计结构 - 在数据访问层添加多个统计查询方法,包括按类型、部门、月份统计 - 实现服务层统计业务逻辑,包括请假汇总、分类统计、员工状态统计 - 配置 MyBatis 映射文件实现各维度统计 SQL 查询 - 添加员工总数和请假中员工数的统计功能
This commit is contained in:
@@ -9,6 +9,7 @@ import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.hrm.domain.HrmLeaveReq;
|
||||
import com.ruoyi.hrm.domain.bo.HrmLeaveReqBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveReqVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveStatsVo;
|
||||
import com.ruoyi.hrm.service.IHrmLeaveReqService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -59,4 +60,9 @@ public class HrmLeaveReqController extends BaseController {
|
||||
public R<List<HrmLeaveReqVo>> all(HrmLeaveReqBo bo) {
|
||||
return R.ok(service.queryList(bo));
|
||||
}
|
||||
|
||||
@GetMapping("/stats")
|
||||
public R<HrmLeaveStatsVo> stats() {
|
||||
return R.ok(service.getLeaveStats());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.ruoyi.hrm.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class HrmLeaveStatsVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 总请假申请数
|
||||
*/
|
||||
private Integer totalLeaveRequests;
|
||||
|
||||
/**
|
||||
* 总请假时长(小时)
|
||||
*/
|
||||
private BigDecimal totalLeaveHours;
|
||||
|
||||
/**
|
||||
* 按请假类型统计
|
||||
*/
|
||||
private List<LeaveTypeStats> leaveByType;
|
||||
|
||||
/**
|
||||
* 按部门统计
|
||||
*/
|
||||
private List<DeptStats> leaveByDept;
|
||||
|
||||
/**
|
||||
* 按月份统计(本年)
|
||||
*/
|
||||
private List<MonthStats> leaveByMonth;
|
||||
|
||||
/**
|
||||
* 总员工数
|
||||
*/
|
||||
private Integer totalEmployees;
|
||||
|
||||
/**
|
||||
* 请假中员工数
|
||||
*/
|
||||
private Integer leavingEmployees;
|
||||
|
||||
@Data
|
||||
public static class LeaveTypeStats {
|
||||
private String leaveType;
|
||||
private Integer count;
|
||||
private BigDecimal totalHours;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class DeptStats {
|
||||
private Long deptId;
|
||||
private String deptName;
|
||||
private Integer count;
|
||||
private BigDecimal totalHours;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class MonthStats {
|
||||
private String month; // YYYY-MM
|
||||
private Integer count;
|
||||
private BigDecimal totalHours;
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,13 @@ import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import com.ruoyi.hrm.domain.HrmLeaveReq;
|
||||
import com.ruoyi.hrm.domain.bo.HrmLeaveReqBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveReqVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveStatsVo;
|
||||
import org.apache.ibatis.annotations.MapKey;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface HrmLeaveReqMapper extends BaseMapperPlus<HrmLeaveReqMapper, HrmLeaveReq, HrmLeaveReqVo> {
|
||||
|
||||
@@ -17,4 +20,17 @@ public interface HrmLeaveReqMapper extends BaseMapperPlus<HrmLeaveReqMapper, Hrm
|
||||
List<HrmLeaveReqVo> selectVoWithProjectByPage(IPage<HrmLeaveReqVo> page, @Param("bo") HrmLeaveReqBo bo);
|
||||
|
||||
List<HrmLeaveReqVo> selectVoWithProjectList(@Param("bo") HrmLeaveReqBo bo);
|
||||
|
||||
// 统计相关方法
|
||||
Map<String, Object> selectLeaveSummary();
|
||||
|
||||
List<Map<String, Object>> selectLeaveByType();
|
||||
|
||||
List<Map<String, Object>> selectLeaveByDept();
|
||||
|
||||
List<Map<String, Object>> selectLeaveByMonth(@Param("year") Integer year);
|
||||
|
||||
Integer selectTotalEmployees();
|
||||
|
||||
Integer selectLeavingEmployees();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.hrm.domain.HrmLeaveReq;
|
||||
import com.ruoyi.hrm.domain.bo.HrmLeaveReqBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveReqVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveStatsVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -24,4 +25,7 @@ public interface IHrmLeaveReqService {
|
||||
Boolean updateByBo(HrmLeaveReqBo bo);
|
||||
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
// 统计方法
|
||||
HrmLeaveStatsVo getLeaveStats();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,13 @@ import com.ruoyi.hrm.domain.HrmLeaveReq;
|
||||
import com.ruoyi.hrm.domain.bo.HrmFlowStartBo;
|
||||
import com.ruoyi.hrm.domain.bo.HrmLeaveReqBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveReqVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmLeaveStatsVo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import com.ruoyi.hrm.mapper.HrmFlowTemplateMapper;
|
||||
import com.ruoyi.hrm.mapper.HrmLeaveReqMapper;
|
||||
import com.ruoyi.hrm.service.IHrmFlowInstanceService;
|
||||
@@ -117,6 +124,55 @@ public class HrmLeaveReqServiceImpl implements IHrmLeaveReqService {
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HrmLeaveStatsVo getLeaveStats() {
|
||||
HrmLeaveStatsVo stats = new HrmLeaveStatsVo();
|
||||
|
||||
// 获取汇总数据
|
||||
Map<String, Object> summary = baseMapper.selectLeaveSummary();
|
||||
stats.setTotalLeaveRequests(((Long) summary.get("totalRequests")).intValue());
|
||||
stats.setTotalLeaveHours((BigDecimal) summary.get("totalHours"));
|
||||
|
||||
// 按类型统计
|
||||
List<Map<String, Object>> leaveByType = baseMapper.selectLeaveByType();
|
||||
stats.setLeaveByType(leaveByType.stream().map(map -> {
|
||||
HrmLeaveStatsVo.LeaveTypeStats s = new HrmLeaveStatsVo.LeaveTypeStats();
|
||||
s.setLeaveType((String) map.get("leaveType"));
|
||||
s.setCount(((Long) map.get("count")).intValue());
|
||||
s.setTotalHours((BigDecimal) map.get("totalHours"));
|
||||
return s;
|
||||
}).collect(Collectors.toList()));
|
||||
|
||||
// 按部门统计
|
||||
List<Map<String, Object>> leaveByDept = baseMapper.selectLeaveByDept();
|
||||
stats.setLeaveByDept(leaveByDept.stream().map(map -> {
|
||||
HrmLeaveStatsVo.DeptStats s = new HrmLeaveStatsVo.DeptStats();
|
||||
s.setDeptName((String) map.get("deptName"));
|
||||
s.setCount(((Long) map.get("count")).intValue());
|
||||
s.setTotalHours((BigDecimal) map.get("totalHours"));
|
||||
return s;
|
||||
}).collect(Collectors.toList()));
|
||||
|
||||
// 按月份统计(当前年)
|
||||
int currentYear = LocalDate.now().getYear();
|
||||
List<Map<String, Object>> leaveByMonth = baseMapper.selectLeaveByMonth(currentYear);
|
||||
stats.setLeaveByMonth(leaveByMonth.stream().map(map -> {
|
||||
HrmLeaveStatsVo.MonthStats s = new HrmLeaveStatsVo.MonthStats();
|
||||
s.setMonth((String) map.get("month"));
|
||||
s.setCount(((Long) map.get("count")).intValue());
|
||||
s.setTotalHours((BigDecimal) map.get("totalHours"));
|
||||
return s;
|
||||
}).collect(Collectors.toList()));
|
||||
|
||||
// 总员工数
|
||||
stats.setTotalEmployees(baseMapper.selectTotalEmployees());
|
||||
|
||||
// 请假中员工数
|
||||
stats.setLeavingEmployees(baseMapper.selectLeavingEmployees());
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HrmLeaveReq> buildQueryWrapper(HrmLeaveReqBo bo) {
|
||||
LambdaQueryWrapper<HrmLeaveReq> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getBizId() != null, HrmLeaveReq::getBizId, bo.getBizId());
|
||||
|
||||
@@ -149,4 +149,64 @@
|
||||
</if>
|
||||
ORDER BY l.create_time DESC
|
||||
</select>
|
||||
<!-- 统计查询 -->
|
||||
<select id="selectLeaveSummary" resultType="java.util.Map">
|
||||
SELECT
|
||||
COUNT(*) as totalRequests,
|
||||
SUM(hours) as totalHours
|
||||
FROM hrm_leave_req
|
||||
WHERE del_flag = 0
|
||||
AND status = 'approved'
|
||||
</select>
|
||||
|
||||
<select id="selectLeaveByType" resultType="java.util.Map">
|
||||
SELECT
|
||||
leave_type as leaveType,
|
||||
COUNT(*) as count,
|
||||
SUM(hours) as totalHours
|
||||
FROM hrm_leave_req
|
||||
WHERE del_flag = 0
|
||||
AND status = 'approved'
|
||||
GROUP BY leave_type
|
||||
ORDER BY totalHours DESC
|
||||
</select>
|
||||
|
||||
<select id="selectLeaveByDept" resultType="java.util.Map">
|
||||
SELECT
|
||||
d.dept_name as deptName,
|
||||
COUNT(l.biz_id) as count,
|
||||
SUM(l.hours) as totalHours
|
||||
FROM hrm_leave_req l
|
||||
JOIN hrm_employee e ON l.emp_id = e.emp_id AND e.del_flag = 0
|
||||
LEFT JOIN sys_dept d ON e.dept_id = d.dept_id AND d.del_flag = '0'
|
||||
WHERE l.del_flag = 0
|
||||
AND l.status = 'approved'
|
||||
GROUP BY d.dept_id, d.dept_name
|
||||
ORDER BY totalHours DESC
|
||||
</select>
|
||||
|
||||
<select id="selectLeaveByMonth" resultType="java.util.Map">
|
||||
SELECT
|
||||
DATE_FORMAT(start_time, '%Y-%m') as month,
|
||||
COUNT(*) as count,
|
||||
SUM(hours) as totalHours
|
||||
FROM hrm_leave_req
|
||||
WHERE del_flag = 0
|
||||
AND status = 'approved'
|
||||
AND YEAR(start_time) = #{year}
|
||||
GROUP BY DATE_FORMAT(start_time, '%Y-%m')
|
||||
ORDER BY month
|
||||
</select>
|
||||
|
||||
<select id="selectTotalEmployees" resultType="java.lang.Integer">
|
||||
SELECT COUNT(*) FROM hrm_employee WHERE del_flag = 0 AND status = 'onboard'
|
||||
</select>
|
||||
|
||||
<select id="selectLeavingEmployees" resultType="java.lang.Integer">
|
||||
SELECT COUNT(DISTINCT l.emp_id)
|
||||
FROM hrm_leave_req l
|
||||
WHERE l.del_flag = 0
|
||||
AND l.status = 'approved'
|
||||
AND NOW() BETWEEN l.start_time AND l.end_time
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user