|
@@ -2303,6 +2303,160 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<IotRhDailyReportSummaryYearRespVO> reportSummary(IotRhDailyReportPageReqVO pageReqVO) {
|
|
|
|
|
+ // 查询选择部门下面所有子部门
|
|
|
|
|
+ Set<Long> ids = new HashSet<>();
|
|
|
|
|
+ if (Objects.nonNull(pageReqVO.getDeptId())) {
|
|
|
|
|
+ ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
|
|
|
|
|
+ ids.add(pageReqVO.getDeptId());
|
|
|
|
|
+ pageReqVO.setDeptIds(ids);
|
|
|
|
|
+ }
|
|
|
|
|
+ // searchKey 兼容移动端查询的情况
|
|
|
|
|
+ if (StrUtil.isNotBlank(pageReqVO.getSearchKey())) {
|
|
|
|
|
+ if (CollUtil.isEmpty(pageReqVO.getProjectIds()) && CollUtil.isEmpty(pageReqVO.getTaskIds())) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // PC 端 AND 检查:各自条件必须匹配到对应 ID
|
|
|
|
|
+ if (StrUtil.isNotBlank(pageReqVO.getContractName()) && CollUtil.isEmpty(pageReqVO.getProjectIds())) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StrUtil.isNotBlank(pageReqVO.getTaskName()) && CollUtil.isEmpty(pageReqVO.getTaskIds())) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
+ PageResult<IotRhDailyReportDO> pageReports = iotRhDailyReportMapper.selectPage(pageReqVO);
|
|
|
|
|
+ List<IotRhDailyReportDO> dailyReports = pageReports.getList();
|
|
|
|
|
+ if (CollUtil.isEmpty(dailyReports)) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查询每个日报关联的部门名称
|
|
|
|
|
+ Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(dailyReports, IotRhDailyReportDO::getDeptId));
|
|
|
|
|
+
|
|
|
|
|
+ // 按照 年 月 日 汇总统计 日报数据
|
|
|
|
|
+ List<IotRhDailyReportSummaryYearRespVO> result = new ArrayList<>();
|
|
|
|
|
+ // 1. 按年 -> 月 -> 日 分组,过滤 createTime 为空的数据
|
|
|
|
|
+ Map<String, Map<String, Map<String, List<IotRhDailyReportDO>>>> grouped = dailyReports.stream()
|
|
|
|
|
+ .filter(r -> r.getCreateTime() != null)
|
|
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
|
|
+ r -> String.valueOf(r.getCreateTime().getYear()),
|
|
|
|
|
+ Collectors.groupingBy(
|
|
|
|
|
+ r -> String.valueOf(r.getCreateTime().getMonthValue()),
|
|
|
|
|
+ Collectors.groupingBy(
|
|
|
|
|
+ r -> String.valueOf(r.getCreateTime().getDayOfMonth())
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ ));
|
|
|
|
|
+ // 2. 遍历年份
|
|
|
|
|
+ for (Map.Entry<String, Map<String, Map<String, List<IotRhDailyReportDO>>>> yearEntry : grouped.entrySet()) {
|
|
|
|
|
+ String year = yearEntry.getKey();
|
|
|
|
|
+ Map<String, Map<String, List<IotRhDailyReportDO>>> monthMap = yearEntry.getValue();
|
|
|
|
|
+
|
|
|
|
|
+ IotRhDailyReportSummaryYearRespVO yearVO = new IotRhDailyReportSummaryYearRespVO();
|
|
|
|
|
+ yearVO.setYear(year);
|
|
|
|
|
+ yearVO.setLevel("year");
|
|
|
|
|
+ List<IotRhDailyReportSummaryMonthRespVO> monthVOList = new ArrayList<>();
|
|
|
|
|
+ int yearReportCount = 0;
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 遍历月份
|
|
|
|
|
+ for (Map.Entry<String, Map<String, List<IotRhDailyReportDO>>> monthEntry : monthMap.entrySet()) {
|
|
|
|
|
+ String month = monthEntry.getKey();
|
|
|
|
|
+ Map<String, List<IotRhDailyReportDO>> dayMap = monthEntry.getValue();
|
|
|
|
|
+
|
|
|
|
|
+ IotRhDailyReportSummaryMonthRespVO monthVO = new IotRhDailyReportSummaryMonthRespVO();
|
|
|
|
|
+ monthVO.setMonth(month);
|
|
|
|
|
+ monthVO.setLevel("month");
|
|
|
|
|
+ List<IotRhDailyReportSummaryDayRespVO> dayVOList = new ArrayList<>();
|
|
|
|
|
+ int monthReportCount = 0;
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 遍历日
|
|
|
|
|
+ for (Map.Entry<String, List<IotRhDailyReportDO>> dayEntry : dayMap.entrySet()) {
|
|
|
|
|
+ String day = dayEntry.getKey();
|
|
|
|
|
+ List<IotRhDailyReportDO> dayReports = dayEntry.getValue();
|
|
|
|
|
+
|
|
|
|
|
+ IotRhDailyReportSummaryDayRespVO dayVO = new IotRhDailyReportSummaryDayRespVO();
|
|
|
|
|
+ dayVO.setDay(day);
|
|
|
|
|
+ dayVO.setLevel("day");
|
|
|
|
|
+
|
|
|
|
|
+ // 统计已填报(status=1)和未填报(status=0)数量
|
|
|
|
|
+ long filled = dayReports.stream()
|
|
|
|
|
+ .filter(r -> r.getStatus() != null && r.getStatus() == 1)
|
|
|
|
|
+ .count();
|
|
|
|
|
+ long unfilled = dayReports.stream()
|
|
|
|
|
+ .filter(r -> r.getStatus() != null && r.getStatus() == 0)
|
|
|
|
|
+ .count();
|
|
|
|
|
+ dayVO.setFilledCount(String.valueOf(filled));
|
|
|
|
|
+ dayVO.setUnfilledCount(String.valueOf(unfilled));
|
|
|
|
|
+ dayVO.setReportCount(dayReports.size());
|
|
|
|
|
+
|
|
|
|
|
+ // 计算星期几(基于该天第一个日报的 createTime)
|
|
|
|
|
+ if (!dayReports.isEmpty()) {
|
|
|
|
|
+ LocalDateTime dateTime = dayReports.get(0).getCreateTime();
|
|
|
|
|
+ // 转换为中文星期几,如 "星期一"
|
|
|
|
|
+ String weekDay = dateTime.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, java.util.Locale.CHINESE);
|
|
|
|
|
+ dayVO.setWeekDay(weekDay);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建日报简要列表(仅 id 和 reportName)
|
|
|
|
|
+ List<IotRhDailyReportShortRespVO> reportVOList = dayReports.stream()
|
|
|
|
|
+ .map(r -> {
|
|
|
|
|
+ IotRhDailyReportShortRespVO respVO = new IotRhDailyReportShortRespVO();
|
|
|
|
|
+ respVO.setId(r.getId());
|
|
|
|
|
+ // 根据 createTime deptId 设置日报名称
|
|
|
|
|
+ LocalDateTime createTime = r.getCreateTime();
|
|
|
|
|
+ Long deptId = r.getDeptId();
|
|
|
|
|
+ if (ObjUtil.isNotEmpty(deptId) && deptMap.containsKey(deptId) && ObjUtil.isNotEmpty(createTime)) {
|
|
|
|
|
+ DeptDO dept = deptMap.get(deptId);
|
|
|
|
|
+ if (ObjUtil.isNotEmpty(dept)) {
|
|
|
|
|
+ String deptName = dept.getName();
|
|
|
|
|
+ String createTimeStr = LocalDateTimeUtil.format(createTime, DatePattern.NORM_DATE_PATTERN);
|
|
|
|
|
+ String reportTitle = StrUtil.join(" ", deptName, createTimeStr, "日报");
|
|
|
|
|
+ respVO.setReportName(reportTitle);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ respVO.setProjectId(r.getProjectId());
|
|
|
|
|
+ respVO.setTaskId(r.getTaskId());
|
|
|
|
|
+ respVO.setAuditStatus(r.getAuditStatus());
|
|
|
|
|
+ return respVO;
|
|
|
|
|
+ })
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ dayVO.setReports(reportVOList);
|
|
|
|
|
+
|
|
|
|
|
+ dayVOList.add(dayVO);
|
|
|
|
|
+ monthReportCount += dayReports.size();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ monthVO.setDays(dayVOList);
|
|
|
|
|
+ monthVO.setDayCount(dayVOList.size()); // 该月下有日报的天数
|
|
|
|
|
+ monthVO.setReportCount(monthReportCount); // 该月日报总数
|
|
|
|
|
+ monthVOList.add(monthVO);
|
|
|
|
|
+ yearReportCount += monthReportCount;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ yearVO.setMonths(monthVOList);
|
|
|
|
|
+ yearVO.setMonthCount(monthVOList.size()); // 该年下有日报的月份数
|
|
|
|
|
+ yearVO.setReportCount(yearReportCount); // 该年日报总数
|
|
|
|
|
+ result.add(yearVO);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 排序:年份降序、月份降序、日降序(最新在前)—— 使用数字比较
|
|
|
|
|
+ result.sort((y1, y2) -> Integer.compare(Integer.parseInt(y2.getYear()), Integer.parseInt(y1.getYear())));
|
|
|
|
|
+ for (IotRhDailyReportSummaryYearRespVO yearVO : result) {
|
|
|
|
|
+ if (CollUtil.isNotEmpty(yearVO.getMonths())) {
|
|
|
|
|
+ yearVO.getMonths().sort((m1, m2) -> Integer.compare(Integer.parseInt(m2.getMonth()), Integer.parseInt(m1.getMonth())));
|
|
|
|
|
+ for (IotRhDailyReportSummaryMonthRespVO monthVO : yearVO.getMonths()) {
|
|
|
|
|
+ if (CollUtil.isNotEmpty(monthVO.getDays())) {
|
|
|
|
|
+ // 日排序:降序,数字比较
|
|
|
|
|
+ monthVO.getDays().sort((d1, d2) -> Integer.compare(Integer.parseInt(d2.getDay()), Integer.parseInt(d1.getDay())));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private void adjustMonthStatisticsTime(IotRhDailyReportPageReqVO pageReqVO) {
|
|
private void adjustMonthStatisticsTime(IotRhDailyReportPageReqVO pageReqVO) {
|
|
|
LocalDateTime[] times = pageReqVO.getCreateTime();
|
|
LocalDateTime[] times = pageReqVO.getCreateTime();
|
|
|
if (times == null || times.length < 2 || times[0] == null || times[1] == null) {
|
|
if (times == null || times.length < 2 || times[0] == null || times[1] == null) {
|