yusm 1 месяц назад
Родитель
Сommit
6c442d8d79

+ 173 - 74
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -16133,7 +16133,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 .groupBy("dept_id")
                 .orderByDesc("sum(working_time)"));
         Map<Integer, Department> departmentMap = getDepartmentMap(companyId);
-        List<HashMap> resultList = buildDeptReportResult(deptReportList, departmentMap, false);
+        List<HashMap> resultList = buildDeptReportResult(rollupDeptReportRows(deptReportList, departmentMap), departmentMap, false);
         msg.data = resultList;
         return msg;
     }
@@ -16150,7 +16150,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 .groupBy("dept_id")
                 .orderByDesc("sum(working_time)"));
         Map<Integer, Department> departmentMap = getDepartmentMap(companyId);
-        List<HashMap> resultList = buildDeptReportResult(deptReportList, departmentMap, true);
+        List<HashMap> resultList = buildDeptReportResult(rollupDeptReportRows(deptReportList, departmentMap), departmentMap, true);
         msg.data = resultList;
         return msg;
     }
@@ -16160,22 +16160,17 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         HttpRespMsg msg = new HttpRespMsg();
         String month = normalizeYearMonth(ymonth);
         List<Map<String, Object>> deptReportList = reportMapper.selectMaps(new QueryWrapper<Report>()
-                .select("dept_id as deptId", "count(distinct project_id) as projectCount", "count(distinct if(ifnull(overtime_hours, 0) > 0, project_id, null)) as overtimeProjectCount", "count(distinct creator_id) as memberCount")
+                .select("dept_id as deptId", "project_id as projectId", "creator_id as userId", "sum(ifnull(overtime_hours, 0)) as overtimeHours")
                 .eq("company_id", companyId)
                 .eq("state", 1)
                 .apply("date_format(create_date, '%Y-%m') = {0}", month)
-                .groupBy("dept_id")
-                .orderByDesc("count(distinct project_id)"));
+                .groupBy("dept_id", "project_id", "creator_id"));
         Map<Integer, Department> departmentMap = getDepartmentMap(companyId);
         List<HashMap> resultList = new ArrayList<>();
-        deptReportList.forEach(row -> {
+        rollupDeptProjectCountRows(deptReportList, departmentMap).forEach(row -> {
             Integer deptId = toInteger(row.get("deptId"));
-            Department department = departmentMap.get(deptId);
             HashMap<String, Object> map = new HashMap<>();
-            map.put("departmentId", deptId);
-            map.put("departmentName", department == null ? "未分配部门" : department.getDepartmentName());
-            map.put("corpwxDeptid", department == null ? null : department.getCorpwxDeptid());
-            map.put("departmentOpenId", department == null ? null : department.getCorpwxDeptid());
+            fillDepartmentInfo(map, deptId, departmentMap);
             double projectCount = toDouble(row.get("projectCount"));
             double memberCount = Math.max(toDouble(row.get("memberCount")), 1D);
             map.put("projectCount", projectCount);
@@ -16197,13 +16192,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         result.put("projectSituation", getProjectSituation(companyId, month));
         result.put("projectOvertimeTop5", getProjectRank(companyId, month, "sum(ifnull(overtime_hours, 0))", 5, true));
         result.put("top3OvertimeProjectDept", getTopProjectDeptReport(companyId, month, "sum(ifnull(overtime_hours, 0))", true));
-        result.put("deptOvertimeSummary", buildDeptReportResult(reportMapper.selectMaps(new QueryWrapper<Report>()
+        List<Map<String, Object>> deptOvertimeSummaryList = reportMapper.selectMaps(new QueryWrapper<Report>()
                 .select("dept_id as deptId", "sum(working_time) as workingTime", "count(distinct creator_id) as memberCount", "sum(ifnull(overtime_hours, 0)) as overtimeHours", "max(ifnull(overtime_hours, 0)) as maxOvertimeHours")
                 .eq("company_id", companyId)
                 .eq("state", 1)
                 .apply("date_format(create_date, '%Y-%m') = {0}", month)
                 .groupBy("dept_id")
-                .orderByDesc("sum(ifnull(overtime_hours, 0))")), departmentMap, true));
+                .orderByDesc("sum(ifnull(overtime_hours, 0))"));
+        result.put("deptOvertimeSummary", buildDeptReportResult(rollupDeptReportRows(deptOvertimeSummaryList, departmentMap), departmentMap, true));
         result.put("deptProjectTop3", getDeptProjectTopN(companyId, month, departmentMap, false));
         result.put("deptOvertimeProjectTop3", getDeptProjectTopN(companyId, month, departmentMap, true));
         result.put("deptUserOvertimeTop3", getDeptUserOvertimeTopN(companyId, month, departmentMap));
@@ -16255,12 +16251,101 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     private Map<Integer, Department> getDepartmentMap(Integer companyId) {
         return departmentMapper.selectList(new QueryWrapper<Department>()
-                .select("department_id, department_name, corpwx_deptid")
+                .select("department_id, department_name, superior_id, corpwx_deptid")
                 .eq("company_id", companyId))
                 .stream()
                 .collect(Collectors.toMap(Department::getDepartmentId, Function.identity(), (left, right) -> left));
     }
 
+    private Integer getTopDepartmentId(Integer deptId, Map<Integer, Department> departmentMap) {
+        if (deptId == null) {
+            return null;
+        }
+        if (!departmentMap.containsKey(deptId)) {
+            return deptId;
+        }
+        Set<Integer> visited = new HashSet<>();
+        Integer currentDeptId = deptId;
+        while (currentDeptId != null && departmentMap.containsKey(currentDeptId) && visited.add(currentDeptId)) {
+            Department current = departmentMap.get(currentDeptId);
+            Integer superiorId = current.getSuperiorId();
+            if (superiorId == null || superiorId == 0 || !departmentMap.containsKey(superiorId)) {
+                return currentDeptId;
+            }
+            currentDeptId = superiorId;
+        }
+        return deptId;
+    }
+
+    private void fillDepartmentInfo(HashMap<String, Object> map, Integer deptId, Map<Integer, Department> departmentMap) {
+        Department department = departmentMap.get(deptId);
+        map.put("departmentId", deptId);
+        map.put("departmentName", department == null ? "未分配部门" : department.getDepartmentName());
+        map.put("corpwxDeptid", department == null ? null : department.getCorpwxDeptid());
+        map.put("departmentOpenId", department == null ? null : department.getCorpwxDeptid());
+    }
+
+    private List<Map<String, Object>> rollupDeptReportRows(List<Map<String, Object>> rows, Map<Integer, Department> departmentMap) {
+        Map<Integer, HashMap<String, Object>> grouped = new LinkedHashMap<>();
+        rows.forEach(row -> {
+            Integer deptId = toInteger(row.get("deptId"));
+            Integer topDeptId = getTopDepartmentId(deptId, departmentMap);
+            Integer groupKey = topDeptId == null ? -1 : topDeptId;
+            HashMap<String, Object> target = grouped.computeIfAbsent(groupKey, key -> {
+                HashMap<String, Object> map = new HashMap<>();
+                map.put("deptId", topDeptId);
+                map.put("workingTime", 0D);
+                map.put("overtimeHours", 0D);
+                map.put("memberCount", 0D);
+                map.put("projectCount", 0D);
+                map.put("overtimeProjectCount", 0D);
+                map.put("maxOvertimeHours", 0D);
+                return map;
+            });
+            target.put("workingTime", toDouble(target.get("workingTime")) + toDouble(row.get("workingTime")));
+            target.put("overtimeHours", toDouble(target.get("overtimeHours")) + toDouble(row.get("overtimeHours")));
+            target.put("memberCount", toDouble(target.get("memberCount")) + toDouble(row.get("memberCount")));
+            target.put("projectCount", toDouble(target.get("projectCount")) + toDouble(row.get("projectCount")));
+            target.put("overtimeProjectCount", toDouble(target.get("overtimeProjectCount")) + toDouble(row.get("overtimeProjectCount")));
+            if (row.containsKey("maxOvertimeHours")) {
+                target.put("maxOvertimeHours", Math.max(toDouble(target.get("maxOvertimeHours")), toDouble(row.get("maxOvertimeHours"))));
+            }
+        });
+        return new ArrayList<>(grouped.values());
+    }
+
+    private List<Map<String, Object>> rollupDeptProjectCountRows(List<Map<String, Object>> rows, Map<Integer, Department> departmentMap) {
+        Map<Integer, Set<Integer>> projectMap = new LinkedHashMap<>();
+        Map<Integer, Set<Integer>> overtimeProjectMap = new LinkedHashMap<>();
+        Map<Integer, Set<String>> memberMap = new LinkedHashMap<>();
+        rows.forEach(row -> {
+            Integer deptId = toInteger(row.get("deptId"));
+            Integer topDeptId = getTopDepartmentId(deptId, departmentMap);
+            Integer groupKey = topDeptId == null ? -1 : topDeptId;
+            Integer projectId = toInteger(row.get("projectId"));
+            String userId = row.get("userId") == null ? null : String.valueOf(row.get("userId"));
+            if (projectId != null) {
+                projectMap.computeIfAbsent(groupKey, key -> new HashSet<>()).add(projectId);
+                if (toDouble(row.get("overtimeHours")) > 0) {
+                    overtimeProjectMap.computeIfAbsent(groupKey, key -> new HashSet<>()).add(projectId);
+                }
+            }
+            if (!StringUtils.isEmpty(userId)) {
+                memberMap.computeIfAbsent(groupKey, key -> new HashSet<>()).add(userId);
+            }
+        });
+        List<Map<String, Object>> result = new ArrayList<>();
+        projectMap.forEach((deptId, projectIds) -> {
+            HashMap<String, Object> map = new HashMap<>();
+            map.put("deptId", deptId == -1 ? null : deptId);
+            map.put("projectCount", projectIds.size());
+            map.put("overtimeProjectCount", overtimeProjectMap.getOrDefault(deptId, new HashSet<>()).size());
+            map.put("memberCount", memberMap.getOrDefault(deptId, new HashSet<>()).size());
+            result.add(map);
+        });
+        return result;
+    }
+
     private HashMap<String, Object> getProjectSituation(Integer companyId, String month) {
         long projectCount = projectMapper.selectCount(new QueryWrapper<Project>().eq("company_id", companyId));
         long executingProjectCount = projectMapper.selectCount(new QueryWrapper<Project>().eq("company_id", companyId).eq("status", 1));
@@ -16323,7 +16408,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 .in("project_id", projectIds)
                 .groupBy("dept_id")
                 .orderByDesc(orderByOvertime ? "sum(ifnull(overtime_hours, 0))" : "sum(working_time)"));
-        return buildDeptReportResult(deptReportList, getDepartmentMap(companyId), false);
+        Map<Integer, Department> departmentMap = getDepartmentMap(companyId);
+        return buildDeptReportResult(rollupDeptReportRows(deptReportList, departmentMap), departmentMap, false);
     }
 
     private List<HashMap> getDeptProjectTopN(Integer companyId, String month, Map<Integer, Department> departmentMap, boolean overtimeOnly) {
@@ -16333,29 +16419,38 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 .eq("state", 1)
                 .apply("date_format(create_date, '%Y-%m') = {0}", month)
                 .groupBy("dept_id", "project_id")
-                .having(overtimeOnly, "sum(ifnull(overtime_hours, 0)) > 0")
-                .orderByAsc("dept_id")
-                .orderByDesc(overtimeOnly ? "sum(ifnull(overtime_hours, 0))" : "sum(working_time)"));
-        Map<Integer, List<HashMap>> grouped = new LinkedHashMap<>();
+                .having(overtimeOnly, "sum(ifnull(overtime_hours, 0)) > 0"));
+        Map<String, HashMap<String, Object>> projectGroupMap = new LinkedHashMap<>();
         fillProjectInfo(companyId, reportList).forEach(item -> {
             Integer deptId = toInteger(item.get("deptId"));
-            Department department = departmentMap.get(deptId);
-            item.put("departmentName", department == null ? "未分配部门" : department.getDepartmentName());
-            item.put("corpwxDeptid", department == null ? null : department.getCorpwxDeptid());
-            item.put("departmentOpenId", department == null ? null : department.getCorpwxDeptid());
-            List<HashMap> list = grouped.computeIfAbsent(deptId == null ? -1 : deptId, key -> new ArrayList<>());
-            if (list.size() < 3) {
-                list.add(item);
-            }
+            Integer topDeptId = getTopDepartmentId(deptId, departmentMap);
+            String key = (topDeptId == null ? -1 : topDeptId) + "_" + item.get("projectId");
+            HashMap<String, Object> target = projectGroupMap.computeIfAbsent(key, groupKey -> {
+                HashMap<String, Object> map = new HashMap<>();
+                map.putAll(item);
+                map.put("deptId", topDeptId);
+                fillDepartmentInfo(map, topDeptId, departmentMap);
+                map.put("workingTime", 0D);
+                map.put("overtimeHours", 0D);
+                return map;
+            });
+            target.put("workingTime", roundHours(toDouble(target.get("workingTime")) + toDouble(item.get("workingTime"))));
+            target.put("overtimeHours", roundHours(toDouble(target.get("overtimeHours")) + toDouble(item.get("overtimeHours"))));
         });
+        Map<Integer, List<HashMap>> grouped = new LinkedHashMap<>();
+        projectGroupMap.values().stream()
+                .sorted((left, right) -> Double.compare(toDouble(right.get(overtimeOnly ? "overtimeHours" : "workingTime")), toDouble(left.get(overtimeOnly ? "overtimeHours" : "workingTime"))))
+                .forEach(item -> {
+                    Integer deptId = toInteger(item.get("departmentId"));
+                    List<HashMap> list = grouped.computeIfAbsent(deptId == null ? -1 : deptId, key -> new ArrayList<>());
+                    if (list.size() < 3) {
+                        list.add(item);
+                    }
+                });
         List<HashMap> resultList = new ArrayList<>();
         grouped.forEach((deptId, items) -> {
             HashMap<String, Object> deptMap = new HashMap<>();
-            Department department = departmentMap.get(deptId);
-            deptMap.put("departmentId", deptId == -1 ? null : deptId);
-            deptMap.put("departmentName", department == null ? "未分配部门" : department.getDepartmentName());
-            deptMap.put("corpwxDeptid", department == null ? null : department.getCorpwxDeptid());
-            deptMap.put("departmentOpenId", department == null ? null : department.getCorpwxDeptid());
+            fillDepartmentInfo(deptMap, deptId == -1 ? null : deptId, departmentMap);
             deptMap.put("items", items);
             resultList.add(deptMap);
         });
@@ -16369,41 +16464,42 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 .eq("state", 1)
                 .apply("date_format(create_date, '%Y-%m') = {0}", month)
                 .groupBy("dept_id", "creator_id")
-                .having("sum(ifnull(overtime_hours, 0)) > 0")
-                .orderByAsc("dept_id")
-                .orderByDesc("sum(ifnull(overtime_hours, 0))"));
+                .having("sum(ifnull(overtime_hours, 0)) > 0"));
         List<String> userIds = reportList.stream().map(row -> String.valueOf(row.get("userId"))).filter(id -> !StringUtils.isEmpty(id)).collect(Collectors.toList());
         Map<String, User> userMap = userIds.isEmpty() ? new HashMap<>() : userMapper.selectList(new QueryWrapper<User>().select("id, name, corpwx_userid").in("id", userIds))
                 .stream().collect(Collectors.toMap(User::getId, Function.identity(), (left, right) -> left));
-        Map<Integer, List<HashMap>> grouped = new LinkedHashMap<>();
+        Map<String, HashMap<String, Object>> userGroupMap = new LinkedHashMap<>();
         reportList.forEach(row -> {
             Integer deptId = toInteger(row.get("deptId"));
-            List<HashMap> list = grouped.computeIfAbsent(deptId == null ? -1 : deptId, key -> new ArrayList<>());
-            if (list.size() >= 3) {
-                return;
-            }
+            Integer topDeptId = getTopDepartmentId(deptId, departmentMap);
             String userId = String.valueOf(row.get("userId"));
-            User user = userMap.get(userId);
-            HashMap<String, Object> map = new HashMap<>();
-            map.put("departmentId", deptId);
-            Department department = departmentMap.get(deptId);
-            map.put("departmentName", department == null ? "未分配部门" : department.getDepartmentName());
-            map.put("corpwxDeptid", department == null ? null : department.getCorpwxDeptid());
-            map.put("departmentOpenId", department == null ? null : department.getCorpwxDeptid());
-            map.put("userId", userId);
-            map.put("userName", user == null ? userId : user.getName());
-            map.put("corpwxUserid", user == null ? null : user.getCorpwxUserid());
-            map.put("overtimeHours", roundHours(row.get("overtimeHours")));
-            list.add(map);
+            String key = (topDeptId == null ? -1 : topDeptId) + "_" + userId;
+            HashMap<String, Object> map = userGroupMap.computeIfAbsent(key, groupKey -> {
+                User user = userMap.get(userId);
+                HashMap<String, Object> item = new HashMap<>();
+                fillDepartmentInfo(item, topDeptId, departmentMap);
+                item.put("userId", userId);
+                item.put("userName", user == null ? userId : user.getName());
+                item.put("corpwxUserid", user == null ? null : user.getCorpwxUserid());
+                item.put("overtimeHours", 0D);
+                return item;
+            });
+            map.put("overtimeHours", roundHours(toDouble(map.get("overtimeHours")) + toDouble(row.get("overtimeHours"))));
         });
+        Map<Integer, List<HashMap>> grouped = new LinkedHashMap<>();
+        userGroupMap.values().stream()
+                .sorted((left, right) -> Double.compare(toDouble(right.get("overtimeHours")), toDouble(left.get("overtimeHours"))))
+                .forEach(item -> {
+                    Integer deptId = toInteger(item.get("departmentId"));
+                    List<HashMap> list = grouped.computeIfAbsent(deptId == null ? -1 : deptId, key -> new ArrayList<>());
+                    if (list.size() < 3) {
+                        list.add(item);
+                    }
+                });
         List<HashMap> resultList = new ArrayList<>();
         grouped.forEach((deptId, items) -> {
             HashMap<String, Object> deptMap = new HashMap<>();
-            Department department = departmentMap.get(deptId);
-            deptMap.put("departmentId", deptId == -1 ? null : deptId);
-            deptMap.put("departmentName", department == null ? "未分配部门" : department.getDepartmentName());
-            deptMap.put("corpwxDeptid", department == null ? null : department.getCorpwxDeptid());
-            deptMap.put("departmentOpenId", department == null ? null : department.getCorpwxDeptid());
+            fillDepartmentInfo(deptMap, deptId == -1 ? null : deptId, departmentMap);
             deptMap.put("items", items);
             resultList.add(deptMap);
         });
@@ -16417,9 +16513,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 .eq("state", 1)
                 .apply("date_format(create_date, '%Y-%m') = {0}", month)
                 .groupBy("creator_id", "dept_id")
-                .having("sum(ifnull(overtime_hours, 0)) > 0")
-                .orderByDesc("sum(ifnull(overtime_hours, 0))")
-                .last("limit 10"));
+                .having("sum(ifnull(overtime_hours, 0)) > 0"));
         List<String> userIds = reportList.stream()
                 .map(row -> String.valueOf(row.get("userId")))
                 .filter(id -> !StringUtils.isEmpty(id))
@@ -16429,24 +16523,29 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 .in("id", userIds))
                 .stream()
                 .collect(Collectors.toMap(User::getId, Function.identity(), (left, right) -> left));
-        List<HashMap> resultList = new ArrayList<>();
+        Map<String, HashMap<String, Object>> grouped = new LinkedHashMap<>();
         reportList.forEach(row -> {
             Integer deptId = toInteger(row.get("deptId"));
-            Department department = departmentMap.get(deptId);
+            Integer topDeptId = getTopDepartmentId(deptId, departmentMap);
             String userId = String.valueOf(row.get("userId"));
-            User user = userMap.get(userId);
-            HashMap<String, Object> map = new HashMap<>();
-            map.put("departmentId", deptId);
-            map.put("departmentName", department == null ? "未分配部门" : department.getDepartmentName());
-            map.put("corpwxDeptid", department == null ? null : department.getCorpwxDeptid());
-            map.put("departmentOpenId", department == null ? null : department.getCorpwxDeptid());
-            map.put("userId", userId);
-            map.put("userName", user == null ? userId : user.getName());
-            map.put("corpwxUserid", user == null ? null : user.getCorpwxUserid());
-            map.put("overtimeHours", roundHours(row.get("overtimeHours")));
-            resultList.add(map);
+            String key = userId + "_" + (topDeptId == null ? -1 : topDeptId);
+            HashMap<String, Object> map = grouped.computeIfAbsent(key, groupKey -> {
+                User user = userMap.get(userId);
+                HashMap<String, Object> item = new HashMap<>();
+                fillDepartmentInfo(item, topDeptId, departmentMap);
+                item.put("userId", userId);
+                item.put("userName", user == null ? userId : user.getName());
+                item.put("corpwxUserid", user == null ? null : user.getCorpwxUserid());
+                item.put("overtimeHours", 0D);
+                return item;
+            });
+            map.put("overtimeHours", roundHours(toDouble(map.get("overtimeHours")) + toDouble(row.get("overtimeHours"))));
         });
-        return resultList;
+        return grouped.values().stream()
+                .sorted((left, right) -> Double.compare(toDouble(right.get("overtimeHours")), toDouble(left.get("overtimeHours"))))
+                .limit(10)
+                .map(item -> (HashMap) item)
+                .collect(Collectors.toList());
     }
 
     private List<HashMap> fillProjectInfo(Integer companyId, List<Map<String, Object>> reportList) {