diff --git a/src/main/java/cn/yinlihupo/controller/analysis/DailyReportAnalysisController.java b/src/main/java/cn/yinlihupo/controller/analysis/DailyReportAnalysisController.java index 2bd2bb4..77cca37 100644 --- a/src/main/java/cn/yinlihupo/controller/analysis/DailyReportAnalysisController.java +++ b/src/main/java/cn/yinlihupo/controller/analysis/DailyReportAnalysisController.java @@ -8,6 +8,7 @@ import cn.yinlihupo.common.util.SecurityUtils; import cn.yinlihupo.domain.dto.ApplyDailyReportSuggestionsRequest; import cn.yinlihupo.domain.entity.DailyReportUpdateSuggestion; import cn.yinlihupo.domain.vo.DailyReportAnalysisSuggestionsVO; +import cn.yinlihupo.domain.vo.DailyReportUpdateSuggestionVO; import cn.yinlihupo.mapper.DailyReportUpdateSuggestionMapper; import cn.yinlihupo.service.analysis.DailyReportSuggestionService; import jakarta.validation.Valid; @@ -34,26 +35,25 @@ public class DailyReportAnalysisController { private final DailyReportUpdateSuggestionMapper dailyReportUpdateSuggestionMapper; /** - * 获取日报进度更新建议 - * - * @param projectId 项目ID - * @param reportId 日报ID - * @param reportDate 日报日期 - * @param submitterUsername 日报提交人用户名 + * 根据项目ID获取日报进度更新建议(项目维度) */ @GetMapping("/suggestions") - public BaseResponse getSuggestions( + public BaseResponse> getSuggestions( @RequestParam Long projectId, - @RequestParam(required = false) Long reportId, @RequestParam(required = false) LocalDate reportDate, - @RequestParam(required = false) String submitterUsername) { + @RequestParam(required = false) String status) { + List list = dailyReportSuggestionService.listSuggestionsByProjectId(projectId, reportDate, status); + return ResultUtils.success("查询成功", list); + } - DailyReportAnalysisSuggestionsVO vo; - if (reportId != null) { - vo = dailyReportSuggestionService.getLatestSuggestionsByReportId(projectId, reportId); - } else { - vo = dailyReportSuggestionService.getLatestSuggestionsByUniqueKey(projectId, reportDate, submitterUsername); - } + /** + * 获取指定日报的进度更新建议(日报维度) + */ + @GetMapping("/suggestions/report") + public BaseResponse getReportSuggestions( + @RequestParam Long projectId, + @RequestParam Long reportId) { + DailyReportAnalysisSuggestionsVO vo = dailyReportSuggestionService.getLatestSuggestionsByReportId(projectId, reportId); return ResultUtils.success("查询成功", vo); } @@ -94,4 +94,3 @@ public class DailyReportAnalysisController { return ResultUtils.success("应用成功", applied); } } - diff --git a/src/main/java/cn/yinlihupo/domain/vo/DailyReportUpdateSuggestionVO.java b/src/main/java/cn/yinlihupo/domain/vo/DailyReportUpdateSuggestionVO.java index 28e3d16..dbe7386 100644 --- a/src/main/java/cn/yinlihupo/domain/vo/DailyReportUpdateSuggestionVO.java +++ b/src/main/java/cn/yinlihupo/domain/vo/DailyReportUpdateSuggestionVO.java @@ -3,12 +3,21 @@ package cn.yinlihupo.domain.vo; import lombok.Data; import java.math.BigDecimal; +import java.time.LocalDate; @Data public class DailyReportUpdateSuggestionVO { private Long suggestionId; + private Long analysisId; + + private Long reportId; + + private LocalDate reportDate; + + private String submitterUsername; + private String targetType; private Long targetId; @@ -29,4 +38,3 @@ public class DailyReportUpdateSuggestionVO { private String status; } - diff --git a/src/main/java/cn/yinlihupo/service/analysis/DailyReportSuggestionService.java b/src/main/java/cn/yinlihupo/service/analysis/DailyReportSuggestionService.java index ac31664..202155f 100644 --- a/src/main/java/cn/yinlihupo/service/analysis/DailyReportSuggestionService.java +++ b/src/main/java/cn/yinlihupo/service/analysis/DailyReportSuggestionService.java @@ -1,6 +1,7 @@ package cn.yinlihupo.service.analysis; import cn.yinlihupo.domain.vo.DailyReportAnalysisSuggestionsVO; +import cn.yinlihupo.domain.vo.DailyReportUpdateSuggestionVO; import java.time.LocalDate; import java.util.List; @@ -11,6 +12,7 @@ public interface DailyReportSuggestionService { DailyReportAnalysisSuggestionsVO getLatestSuggestionsByUniqueKey(Long projectId, LocalDate reportDate, String submitterUsername); + List listSuggestionsByProjectId(Long projectId, LocalDate reportDate, String status); + int applySuggestions(Long projectId, List suggestionIds, Long appliedBy); } - diff --git a/src/main/java/cn/yinlihupo/service/analysis/impl/DailyReportSuggestionServiceImpl.java b/src/main/java/cn/yinlihupo/service/analysis/impl/DailyReportSuggestionServiceImpl.java index 8334f54..69e238a 100644 --- a/src/main/java/cn/yinlihupo/service/analysis/impl/DailyReportSuggestionServiceImpl.java +++ b/src/main/java/cn/yinlihupo/service/analysis/impl/DailyReportSuggestionServiceImpl.java @@ -86,6 +86,49 @@ public class DailyReportSuggestionServiceImpl implements DailyReportSuggestionSe return getLatestSuggestionsByReportId(projectId, report.getId()); } + @Override + public List listSuggestionsByProjectId(Long projectId, LocalDate reportDate, String status) { + if (projectId == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "projectId不能为空"); + } + + String actualStatus = StringUtils.hasText(status) ? status : "pending"; + + List suggestions; + if (reportDate != null) { + List records = dailyReportAnalysisRecordMapper.selectList( + new LambdaQueryWrapper() + .eq(DailyReportAnalysisRecord::getProjectId, projectId) + .eq(DailyReportAnalysisRecord::getReportDate, reportDate) + .eq(DailyReportAnalysisRecord::getDeleted, 0) + .orderByDesc(DailyReportAnalysisRecord::getCreateTime) + .last("LIMIT 200") + ); + if (records == null || records.isEmpty()) { + return List.of(); + } + List analysisIds = records.stream().map(DailyReportAnalysisRecord::getId).toList(); + suggestions = dailyReportUpdateSuggestionMapper.selectList( + new LambdaQueryWrapper() + .eq(DailyReportUpdateSuggestion::getProjectId, projectId) + .eq(DailyReportUpdateSuggestion::getDeleted, 0) + .eq(DailyReportUpdateSuggestion::getStatus, actualStatus) + .in(DailyReportUpdateSuggestion::getAnalysisId, analysisIds) + .orderByDesc(DailyReportUpdateSuggestion::getCreateTime) + ); + } else { + suggestions = dailyReportUpdateSuggestionMapper.selectList( + new LambdaQueryWrapper() + .eq(DailyReportUpdateSuggestion::getProjectId, projectId) + .eq(DailyReportUpdateSuggestion::getDeleted, 0) + .eq(DailyReportUpdateSuggestion::getStatus, actualStatus) + .orderByDesc(DailyReportUpdateSuggestion::getCreateTime) + ); + } + + return buildSuggestionVOList(projectId, suggestions); + } + @Override @Transactional(rollbackFor = Exception.class) public int applySuggestions(Long projectId, List suggestionIds, Long appliedBy) { @@ -305,4 +348,98 @@ public class DailyReportSuggestionServiceImpl implements DailyReportSuggestionSe vo.setSuggestions(voList); return vo; } + + private List buildSuggestionVOList(Long projectId, List suggestions) { + if (suggestions == null || suggestions.isEmpty()) { + return List.of(); + } + + List analysisIds = suggestions.stream() + .filter(Objects::nonNull) + .map(DailyReportUpdateSuggestion::getAnalysisId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + Map recordMap = analysisIds.isEmpty() + ? Collections.emptyMap() + : dailyReportAnalysisRecordMapper.selectBatchIds(analysisIds).stream() + .filter(r -> r != null && r.getDeleted() != null && r.getDeleted() == 0) + .collect(Collectors.toMap(DailyReportAnalysisRecord::getId, Function.identity(), (a, b) -> a)); + + List taskIds = new ArrayList<>(); + List milestoneIds = new ArrayList<>(); + for (DailyReportUpdateSuggestion suggestion : suggestions) { + if (suggestion == null || suggestion.getTargetId() == null) { + continue; + } + if ("task".equalsIgnoreCase(suggestion.getTargetType())) { + taskIds.add(suggestion.getTargetId()); + } else if ("milestone".equalsIgnoreCase(suggestion.getTargetType())) { + milestoneIds.add(suggestion.getTargetId()); + } + } + + Map taskMap = taskIds.isEmpty() + ? Collections.emptyMap() + : taskMapper.selectBatchIds(taskIds).stream() + .filter(Objects::nonNull) + .filter(t -> t.getDeleted() != null && t.getDeleted() == 0) + .collect(Collectors.toMap(Task::getId, Function.identity(), (a, b) -> a)); + + Map milestoneMap = milestoneIds.isEmpty() + ? Collections.emptyMap() + : projectMilestoneMapper.selectBatchIds(milestoneIds).stream() + .filter(Objects::nonNull) + .filter(m -> m.getDeleted() != null && m.getDeleted() == 0) + .collect(Collectors.toMap(ProjectMilestone::getId, Function.identity(), (a, b) -> a)); + + List voList = new ArrayList<>(); + for (DailyReportUpdateSuggestion suggestion : suggestions) { + if (suggestion == null) { + continue; + } + if (!Objects.equals(projectId, suggestion.getProjectId())) { + continue; + } + + DailyReportUpdateSuggestionVO vo = new DailyReportUpdateSuggestionVO(); + vo.setSuggestionId(suggestion.getId()); + vo.setAnalysisId(suggestion.getAnalysisId()); + vo.setReportId(suggestion.getReportId()); + vo.setTargetType(suggestion.getTargetType()); + vo.setTargetId(suggestion.getTargetId()); + vo.setSuggestedStatus(suggestion.getSuggestedStatus()); + vo.setSuggestedProgress(suggestion.getSuggestedProgress()); + vo.setReason(suggestion.getReason()); + vo.setConfidence(suggestion.getConfidence()); + vo.setStatus(suggestion.getStatus()); + + DailyReportAnalysisRecord record = suggestion.getAnalysisId() != null ? recordMap.get(suggestion.getAnalysisId()) : null; + if (record != null) { + vo.setReportDate(record.getReportDate()); + vo.setSubmitterUsername(record.getSubmitterUsername()); + } + + if ("task".equalsIgnoreCase(suggestion.getTargetType())) { + Task task = taskMap.get(suggestion.getTargetId()); + if (task != null) { + vo.setTargetName(task.getTaskName()); + vo.setCurrentStatus(task.getStatus()); + vo.setCurrentProgress(task.getProgress()); + } + } else if ("milestone".equalsIgnoreCase(suggestion.getTargetType())) { + ProjectMilestone milestone = milestoneMap.get(suggestion.getTargetId()); + if (milestone != null) { + vo.setTargetName(milestone.getMilestoneName()); + vo.setCurrentStatus(milestone.getStatus()); + vo.setCurrentProgress(milestone.getProgress()); + } + } + + voList.add(vo); + } + + return voList; + } }