|
@@ -207,9 +207,9 @@ public class ReportServiceImpl implements ReportService {
|
|
|
queryWrapper.eq("REPORT.IS_TEMP", 0);
|
|
|
queryWrapper.eq("RECEIVE.DELETED", 0);
|
|
|
queryWrapper.eq("RECEIVE.RECEIVE_USER_ID", SecurityFrameworkUtils.getLoginUserId());
|
|
|
- queryWrapper.eq(StrUtil.isNotBlank(reqVO.getReportType()),"REPORT.REPORT_TYPE", reqVO.getReportType());
|
|
|
+ queryWrapper.eq(StrUtil.isNotBlank(reqVO.getReportType()), "REPORT.REPORT_TYPE", reqVO.getReportType());
|
|
|
queryWrapper.orderByDesc("REPORT.UPDATE_TIME");
|
|
|
- if(CollectionUtil.isNotEmpty(reqVO.getUserIds())){
|
|
|
+ if (CollectionUtil.isNotEmpty(reqVO.getUserIds())) {
|
|
|
queryWrapper.in("REPORT.USER_ID", reqVO.getUserIds());
|
|
|
}
|
|
|
if (reqVO.getReportYear() != null) {
|
|
@@ -505,7 +505,7 @@ public class ReportServiceImpl implements ReportService {
|
|
|
Long leaveCount = weekLeaveMap.get(date).stream().collect(Collectors.counting());
|
|
|
List<WorkdayDO> workdayList = workDayCount.get(date) == null ? new ArrayList<>() : workDayCount.get(date);
|
|
|
//如果该周请假的次数 >= 该周工作日 * 2 (上下午),则说明该周都请假
|
|
|
- if (leaveCount >= workdayList.size() * 2 && workdayList.size()>0) {
|
|
|
+ if (leaveCount >= workdayList.size() * 2 && workdayList.size() > 0) {
|
|
|
allLeaveWeekSet.add(date);
|
|
|
}
|
|
|
}
|
|
@@ -636,7 +636,7 @@ public class ReportServiceImpl implements ReportService {
|
|
|
// 如果入职时间在本月 ,需要重新计算应填
|
|
|
LocalDateTime rgssj;
|
|
|
StaffRecordSDO staffRecords = userMap.get(staff.getId());
|
|
|
- if(staffRecords != null) {
|
|
|
+ if (staffRecords != null) {
|
|
|
rgssj = staffRecords.getRgssj();
|
|
|
|
|
|
if (rgssj != null && rgssj.getYear() == year && rgssj.getMonthValue() == month) {
|
|
@@ -671,7 +671,6 @@ public class ReportServiceImpl implements ReportService {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* 过滤掉在指定年月时尚未入职的用户
|
|
|
*
|
|
@@ -702,6 +701,7 @@ public class ReportServiceImpl implements ReportService {
|
|
|
})
|
|
|
.collect(Collectors.toList());
|
|
|
}
|
|
|
+
|
|
|
public String sendFillRemind(Short year, Short month) {
|
|
|
ReportStatisticReqDTO reportStatisticReqDTO = new ReportStatisticReqDTO();
|
|
|
reportStatisticReqDTO.setYear(year);
|
|
@@ -766,12 +766,14 @@ public class ReportServiceImpl implements ReportService {
|
|
|
//获取每个用户周报统计结果
|
|
|
List<ReportStatisticRespVO> userWeekReportStatistics = this.getReportStatisticsList(reportStatisticReqDTO.setReportType("weekly"));
|
|
|
//获取每个部门周报统计结果
|
|
|
- Map<String, DeptReportStatisticRespVO> weekReportStatisticsGroup = this.aggregateDeptReportStatistics(userWeekReportStatistics, deptList, year, month, dailyReportDeptIdList);
|
|
|
+ Map<String, DeptReportStatisticRespVO> weekReportStatisticsGroup = this.aggregateDeptReportStatistics(userWeekReportStatistics, deptList, year, month);
|
|
|
|
|
|
//获取每个用户日报统计结果
|
|
|
List<ReportStatisticRespVO> userDailyReportStatistics = this.getReportStatisticsList(reportStatisticReqDTO.setReportType("daily"));
|
|
|
//获取每个部门日报统计结果
|
|
|
- Map<String, DeptReportStatisticRespVO> dailyReportStatisticsGroup = this.aggregateDeptReportStatistics(userDailyReportStatistics, deptList, year, month, dailyReportDeptIdList);
|
|
|
+ Map<String, DeptReportStatisticRespVO> dailyReportStatisticsGroup = this.aggregateDeptReportStatistics(userDailyReportStatistics, deptList, year, month);
|
|
|
+
|
|
|
+ Map<String, Set<String>> deptIdMap = this.collectSubtreeIds(deptList);
|
|
|
|
|
|
//统计每个部门的周日报完成率
|
|
|
List<DeptReportStatisticRespVO> voList = new ArrayList<>();
|
|
@@ -784,23 +786,58 @@ public class ReportServiceImpl implements ReportService {
|
|
|
vo.setParentId(dept.getParentId());
|
|
|
|
|
|
DeptReportStatisticRespVO reportStatistic = null;
|
|
|
- if (dailyReportDeptIdList.contains(dept.getId())) {
|
|
|
- reportStatistic = dailyReportStatisticsGroup.get(dept.getId());
|
|
|
- vo.setReportType("daily");
|
|
|
+
|
|
|
+ String currentDeptId = dept.getId();
|
|
|
+ Set<String> childDeptIdList = deptIdMap.get(currentDeptId);
|
|
|
+
|
|
|
+ if (childDeptIdList.size() <= 1) {
|
|
|
+ //如果没有子部门或子部门列表中只有自己 直接使用结果
|
|
|
+ if (dailyReportDeptIdList.contains(currentDeptId)) {
|
|
|
+ reportStatistic = dailyReportStatisticsGroup.get(currentDeptId);
|
|
|
+ vo.setReportType("daily");
|
|
|
+ } else {
|
|
|
+ reportStatistic = weekReportStatisticsGroup.get(currentDeptId);
|
|
|
+ vo.setReportType("weekly");
|
|
|
+ }
|
|
|
+ if (reportStatistic != null) {
|
|
|
+ vo.setShouldFilledCount(reportStatistic.getShouldFilledCount());
|
|
|
+ vo.setFilledCount(reportStatistic.getFilledCount());
|
|
|
+ vo.setNotFilledCount(reportStatistic.getNotFilledCount());
|
|
|
+ vo.setFillRate(reportStatistic.getFillRate());
|
|
|
+ vo.setPeopleCount(reportStatistic.getPeopleCount());
|
|
|
+ }
|
|
|
} else {
|
|
|
- reportStatistic = weekReportStatisticsGroup.get(dept.getId());
|
|
|
- vo.setReportType("weekly");
|
|
|
- }
|
|
|
+ //如果包含子集部门,则使用按人头加权平均法 部门完成率 = (部门1人数*部门1完成率 + 部门2人数*部门2完成率 +…………)/ 各部门人数总和
|
|
|
+ Integer deptPeopleTotal = 0;
|
|
|
+ Double fz = 0.0;
|
|
|
+ for (String childDeptId : childDeptIdList) {
|
|
|
+ if (currentDeptId.equals(childDeptId)) continue;
|
|
|
+
|
|
|
+ if (dailyReportDeptIdList.contains(childDeptId)) {
|
|
|
+ reportStatistic = dailyReportStatisticsGroup.get(childDeptId);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ reportStatistic = weekReportStatisticsGroup.get(childDeptId);
|
|
|
+ }
|
|
|
+ if (reportStatistic != null) {
|
|
|
+ Integer childPeopleCount = reportStatistic.getPeopleCount();
|
|
|
+
|
|
|
+ Double childFz = reportStatistic.getFillRate() * childPeopleCount;
|
|
|
+ deptPeopleTotal += childPeopleCount;
|
|
|
+ fz += childFz;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (reportStatistic != null) {
|
|
|
+ Double fillRate = fz / (deptPeopleTotal * 1.0);
|
|
|
+ vo.setFillRate(fillRate);
|
|
|
+ vo.setPeopleCount(deptPeopleTotal);
|
|
|
+ }
|
|
|
|
|
|
- if (reportStatistic != null) {
|
|
|
- vo.setShouldFilledCount(reportStatistic.getShouldFilledCount());
|
|
|
- vo.setFilledCount(reportStatistic.getFilledCount());
|
|
|
- vo.setNotFilledCount(reportStatistic.getNotFilledCount());
|
|
|
- vo.setFillRate(reportStatistic.getFillRate());
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
voList.add(vo);
|
|
|
}
|
|
|
-
|
|
|
return voList;
|
|
|
}
|
|
|
|
|
@@ -812,10 +849,9 @@ public class ReportServiceImpl implements ReportService {
|
|
|
* @param deptList 部门列表
|
|
|
* @param year 年份
|
|
|
* @param month 月份
|
|
|
- * @param dailyReportDeptIdList 填写日报的部门列表
|
|
|
* @return
|
|
|
*/
|
|
|
- public Map<String, DeptReportStatisticRespVO> aggregateDeptReportStatistics(List<ReportStatisticRespVO> userReportStatistics, List<DeptRespDTO> deptList, Short year, Short month, List<String> dailyReportDeptIdList) {
|
|
|
+ public Map<String, DeptReportStatisticRespVO> aggregateDeptReportStatistics(List<ReportStatisticRespVO> userReportStatistics, List<DeptRespDTO> deptList, Short year, Short month) {
|
|
|
//第一步:合并用户统计到部门统计(只能统计到直属部门)
|
|
|
Map<String, DeptReportStatisticRespVO> deptStatisticMap = new HashMap<>();
|
|
|
for (ReportStatisticRespVO vo : userReportStatistics) {
|
|
@@ -830,85 +866,63 @@ public class ReportServiceImpl implements ReportService {
|
|
|
deptStat.setFilledCount(deptStat.getFilledCount() + vo.getFilledCount());
|
|
|
deptStat.setFillRate(deptStat.getShouldFilledCount() == 0 ? null
|
|
|
: deptStat.getFilledCount() * 1.0 / deptStat.getShouldFilledCount() > 1 ? 1 : deptStat.getFilledCount() * 1.0 / deptStat.getShouldFilledCount());
|
|
|
- }
|
|
|
- List<DeptReportStatisticRespVO> deptStatisticValue = deptStatisticMap.values().stream().collect(Collectors.toList());
|
|
|
-
|
|
|
- //第二步:合并部门统计到部门统计(可以统计到子部门)
|
|
|
- //获取每个部门的子部门id(包含自己)列表
|
|
|
- Map<String, List<String>> deptIdMap = this.collectSubtreeIds(deptList);
|
|
|
- //遍历部门id,找到有子节点的部门,并计算其子节点的统计值
|
|
|
- for (String deptId : deptIdMap.keySet()) {
|
|
|
- List<String> childDeptIdList = deptIdMap.get(deptId);
|
|
|
- if (childDeptIdList.size() <= 1) {
|
|
|
- //如果没有子部门或子部门列表中只有自己,不再重新计算,直接使用第一步结果
|
|
|
- continue;
|
|
|
- }
|
|
|
- //TODO 需求 板块统计去除市场部门,如“空间信息研究院”完成率中要去掉“空间信息浙江市场部”
|
|
|
- //子级去除市场部门
|
|
|
- List<String> removeMarketChildDeptIdList = childDeptIdList.stream().filter(item -> !dailyReportDeptIdList.contains(item)).collect(Collectors.toList());
|
|
|
-
|
|
|
- List<DeptReportStatisticRespVO> childDeptList = deptStatisticValue.stream().filter(c -> removeMarketChildDeptIdList.contains(c.getDeptId())).collect(Collectors.toList());
|
|
|
- // 使用Stream进行统计 应填和已填
|
|
|
- int shouldFilledCount = (int) childDeptList.stream().mapToLong(DeptReportStatisticRespVO::getShouldFilledCount).sum();
|
|
|
- int filledCount = (int) childDeptList.stream().mapToLong(DeptReportStatisticRespVO::getFilledCount).sum();
|
|
|
- DeptReportStatisticRespVO vo = new DeptReportStatisticRespVO(deptId, shouldFilledCount, filledCount);
|
|
|
- deptStatisticMap.put(deptId, vo);
|
|
|
+
|
|
|
+ // 累加部门人数
|
|
|
+ deptStat.setPeopleCount(deptStat.getPeopleCount() + 1); // 每个用户统计结果代表一个人
|
|
|
}
|
|
|
return deptStatisticMap;
|
|
|
}
|
|
|
|
|
|
|
|
|
- /**
|
|
|
- * 获取部门及子部门id
|
|
|
- *
|
|
|
- * @param deptList 部门列表
|
|
|
- * @return key是部门id,value是所有子集节点id(包含自己)列表
|
|
|
- */
|
|
|
- public static Map<String, List<String>> collectSubtreeIds(List<DeptRespDTO> deptList) {
|
|
|
+ public static Map<String, Set<String>> collectSubtreeIds(List<DeptRespDTO> deptList) {
|
|
|
// 创建一个部门id和部门的映射,用于快速查找部门对象
|
|
|
Map<String, DeptRespDTO> idToDeptMap = new HashMap<>();
|
|
|
for (DeptRespDTO dept : deptList) {
|
|
|
idToDeptMap.put(dept.getId(), dept);
|
|
|
}
|
|
|
|
|
|
- // 结果集,key是部门id,value是所有子集节点id列表
|
|
|
- Map<String, List<String>> result = new HashMap<>();
|
|
|
-
|
|
|
- // 遍历每个部门,并递归地收集子集节点
|
|
|
+ // 构建父子关系图
|
|
|
+ Map<String, List<String>> childrenMap = new HashMap<>();
|
|
|
+ String rootId = null;
|
|
|
for (DeptRespDTO dept : deptList) {
|
|
|
- collectSubtreeIdsRecursive(dept, idToDeptMap, result);
|
|
|
+ if (dept.getParentId() == null) { // 找到根节点
|
|
|
+ rootId = dept.getId();
|
|
|
+ }
|
|
|
+ childrenMap.computeIfAbsent(dept.getParentId(), k -> new ArrayList<>()).add(dept.getId());
|
|
|
}
|
|
|
- return result;
|
|
|
- }
|
|
|
|
|
|
- /**
|
|
|
- * 递归地收集子集节点
|
|
|
- *
|
|
|
- * @param dept 部门
|
|
|
- * @param idToDeptMap 部门id和部门映射Map
|
|
|
- * @param result 结果集
|
|
|
- */
|
|
|
- private static void collectSubtreeIdsRecursive(DeptRespDTO dept, Map<String, DeptRespDTO> idToDeptMap, Map<String, List<String>> result) {
|
|
|
- // 获取当前部门的ID,并添加到结果映射中(如果尚未添加)
|
|
|
- String deptId = dept.getId();
|
|
|
- result.computeIfAbsent(deptId, k -> new ArrayList<>()).add(deptId);
|
|
|
+ // 结果集,key是部门id,value是所有子集节点id(包含自己)列表
|
|
|
+ Map<String, Set<String>> result = new HashMap<>();
|
|
|
|
|
|
- // 递归地处理子部门
|
|
|
- String parentId = dept.getParentId();
|
|
|
- if (parentId != null) { // 确保parentId不是null,避免无限循环(理论上应该是这样,但最好检查)
|
|
|
- DeptRespDTO parentDept = idToDeptMap.get(parentId);
|
|
|
- if (parentDept != null) { // 确保找到了父部门
|
|
|
- // 如果父部门的子集列表尚未初始化,则初始化它
|
|
|
- result.computeIfAbsent(parentId, k -> new ArrayList<>());
|
|
|
- // 将当前部门添加到父部门的子集列表中
|
|
|
- result.get(parentId).add(deptId);
|
|
|
- // 递归地处理父部门的所有其他子部门
|
|
|
- collectSubtreeIdsRecursive(parentDept, idToDeptMap, result);
|
|
|
+ // 如果有根节点,则从根节点开始收集子树
|
|
|
+ if (rootId != null) {
|
|
|
+ dfsCollect(rootId, idToDeptMap, childrenMap, result);
|
|
|
+ } else {
|
|
|
+ // 如果没有明确的根节点,则对每一个节点作为根节点进行处理
|
|
|
+ for (String deptId : idToDeptMap.keySet()) {
|
|
|
+ if (!result.containsKey(deptId)) {
|
|
|
+ dfsCollect(deptId, idToDeptMap, childrenMap, result);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
+ private static void dfsCollect(String deptId, Map<String, DeptRespDTO> idToDeptMap,
|
|
|
+ Map<String, List<String>> childrenMap, Map<String, Set<String>> result) {
|
|
|
+ // 初始化当前部门的结果集
|
|
|
+ Set<String> currentSet = result.computeIfAbsent(deptId, k -> new HashSet<>());
|
|
|
+ currentSet.add(deptId); // 添加自己
|
|
|
|
|
|
+ // 递归地处理子部门
|
|
|
+ List<String> children = childrenMap.getOrDefault(deptId, Collections.emptyList());
|
|
|
+ for (String childId : children) {
|
|
|
+ dfsCollect(childId, idToDeptMap, childrenMap, result);
|
|
|
+ // 将子部门及其所有子部门合并到当前部门的结果集中
|
|
|
+ currentSet.addAll(result.get(childId));
|
|
|
+ }
|
|
|
+ }
|
|
|
/**
|
|
|
* 获取报告工作量统计信息
|
|
|
*
|