refactor(oa):重构个人报表接口返回结构

- 修改 personalReport 方法返回类型为 PersonalReportDTO
- 新增 PersonalReportDTO 类用于封装用户报表数据
- 调整 controller 层接口返回类型以匹配新的 DTO 结构
-优化 service 层数据组装逻辑,提升代码可读性- 在 VO 对象中补充用户信息、项目列表和进度统计字段
- 统一进度统计字段命名与结构,便于前端处理
This commit is contained in:
2025-10-24 18:07:01 +08:00
parent 4378d12e3e
commit 62629e6f9c
5 changed files with 117 additions and 58 deletions

View File

@@ -7,6 +7,7 @@ import java.util.concurrent.TimeUnit;
import com.ruoyi.common.core.AjaxResult;
import com.ruoyi.oa.domain.bo.BatchBo;
import com.ruoyi.oa.domain.dto.PersonalReportDTO;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
@@ -128,10 +129,10 @@ public class OaProjectScheduleStepController extends BaseController {
* @return 报表数据
*/
@GetMapping("/personal")
public R<Map<String, Object>> getPersonalReport(
public R<PersonalReportDTO> getPersonalReport(
@RequestParam Long poolId,
@RequestParam String nickName
) {
return R.ok(iOaProjectScheduleStepService.personalReport(poolId,nickName));
) {
return R.ok(iOaProjectScheduleStepService.personalReport(poolId, nickName));
}
}

View File

@@ -0,0 +1,38 @@
package com.ruoyi.oa.domain.dto;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import com.ruoyi.oa.domain.SysOaProject;
import lombok.Data;
import java.util.List;
/**
* 个人报表顶层返回结果类
*/
@Data
public class PersonalReportDTO {
/** 用户基本信息 */
private SysUser userInfo;
/** 用户负责的项目列表 */
private List<SysOaProject> responsibleProjects;
/** 进度统计信息 */
private ProgressStats progressStats;
private List<OaProjectScheduleStep> userSteps;
/**
* 进度统计内部类封装total、completed等字段
*/
@Data
public static class ProgressStats {
/** 总进度数 */
private Long total;
/** 已完成进度数 */
private Long completed;
/** 待验收进度数 */
private Long pendingAcceptance;
/** 延期进度数 */
private Long delayed;
}
}

View File

@@ -9,6 +9,8 @@ import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.oa.domain.SysOaProject;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.system.domain.SysOss;
import lombok.Data;
@@ -165,4 +167,21 @@ public class OaProjectScheduleStepVo extends BaseEntity {
//排序字段
private Integer sortNum;
/** 新增:用户基本信息 */
private SysUser userInfo;
/** 新增:用户负责的项目列表 */
private List<SysOaProject> responsibleProjects;
/** 新增:进度统计信息 */
private ProgressStats progressStats;
/** 进度统计内部类封装total、completed等字段 */
@Data
public static class ProgressStats {
private Long total;
private Long completed;
private Long pendingAcceptance;
private Long delayed;
}
}

View File

@@ -1,9 +1,11 @@
package com.ruoyi.oa.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import com.ruoyi.oa.domain.bo.BatchBo;
import com.ruoyi.oa.domain.dto.NodeDTO;
import com.ruoyi.oa.domain.dto.PersonalReportDTO;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -70,5 +72,5 @@ public interface IOaProjectScheduleStepService{
List<Map<String, Object>> queryProgressByHeader();
Map<String, Object> personalReport(Long poolId, String nickName);
PersonalReportDTO personalReport(Long poolId, String nickName);
}

View File

@@ -18,6 +18,7 @@ import com.ruoyi.oa.domain.OaProjectSchedule;
import com.ruoyi.oa.domain.SysOaProject;
import com.ruoyi.oa.domain.bo.BatchBo;
import com.ruoyi.oa.domain.dto.NodeDTO;
import com.ruoyi.oa.domain.dto.PersonalReportDTO;
import com.ruoyi.oa.mapper.OaBonusProjectRelMapper;
import com.ruoyi.oa.mapper.OaProjectScheduleMapper;
import com.ruoyi.oa.mapper.SysOaProjectMapper;
@@ -340,83 +341,81 @@ public class OaProjectScheduleStepServiceImpl implements IOaProjectScheduleStepS
* @return 包含个人信息、负责项目、进度统计的结果
*/
@Override
public Map<String, Object> personalReport(Long poolId,String nickName) {
Map<String, Object> result = new HashMap<>();
//查询用户基本信息sys_user表
public PersonalReportDTO personalReport(Long poolId, String nickName) {
// 1. 查询用户基本信息
SysUser user = sysUserMapper.selectOne(
Wrappers.<SysUser>lambdaQuery()
.eq(SysUser::getNickName, nickName)
.eq(SysUser::getDelFlag, "0") // 未删除
.eq(SysUser::getDelFlag, "0")
);
if (user == null) {
throw new RuntimeException("未找到用户:" + nickName);
}
result.put("userInfo", user); // 个人基本信息(可按需筛选字段)
// 根据奖金池ID查询关联的项目IDoa_bonus_project_rel表
// 2. 查询奖金池关联的项目ID
List<OaBonusProjectRel> rels = bonusProjectRelMapper.selectList(
Wrappers.<OaBonusProjectRel>lambdaQuery()
.eq(OaBonusProjectRel::getPoolId, poolId)
.eq(OaBonusProjectRel::getDelFlag, "0")
);
if (CollUtil.isEmpty(rels)) {
result.put("responsibleProjects", Collections.emptyList());
result.put("progressStats", Collections.emptyMap());
return result;
}
List<Long> projectIds = rels.stream()
.map(OaBonusProjectRel::getProjectId)
.collect(Collectors.toList());
List<Long> projectIds = CollUtil.isEmpty(rels)
? Collections.emptyList()
: rels.stream().map(OaBonusProjectRel::getProjectId).collect(Collectors.toList());
// 筛选用户负责的项目sys_oa_project表functionary = nickName
// 3. 筛选用户负责的项目
List<SysOaProject> responsibleProjects = projectMapper.selectList(
Wrappers.<SysOaProject>lambdaQuery()
.in(SysOaProject::getProjectId, projectIds)
.eq(SysOaProject::getFunctionary, nickName) // 项目负责人匹配
.eq(SysOaProject::getFunctionary, nickName)
);
result.put("responsibleProjects", responsibleProjects); // 负责的项目列表
// 查询用户负责的进度及统计(复用进度统计逻辑,限定关联项目
// 先查询关联项目的进度主表IDoa_project_schedule
List<OaProjectSchedule> schedules = projectScheduleMapper.selectList(
Wrappers.<OaProjectSchedule>lambdaQuery()
.in(OaProjectSchedule::getProjectId, projectIds)
.eq(OaProjectSchedule::getDelFlag, "0")
);
if (CollUtil.isEmpty(schedules)) {
result.put("progressStats", Collections.emptyMap());
return result;
// 4. 查询用户负责的进度步骤(核心数据
List<OaProjectScheduleStep> userSteps = new ArrayList<>();
if (CollUtil.isNotEmpty(projectIds)) {
// 查询关联项目的进度主表
List<OaProjectSchedule> schedules = projectScheduleMapper.selectList(
Wrappers.<OaProjectSchedule>lambdaQuery()
.in(OaProjectSchedule::getProjectId, projectIds)
.eq(OaProjectSchedule::getDelFlag, "0")
);
if (CollUtil.isNotEmpty(schedules)) {
List<Long> scheduleIds = schedules.stream()
.filter(Objects::nonNull)
.map(OaProjectSchedule::getScheduleId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 查询用户负责的进度步骤
userSteps = projectScheduleStepMapper.selectList(
Wrappers.<OaProjectScheduleStep>lambdaQuery()
.in(OaProjectScheduleStep::getScheduleId, scheduleIds)
.eq(OaProjectScheduleStep::getNodeHeader, nickName)
.eq(OaProjectScheduleStep::getDelFlag, "0")
.eq(OaProjectScheduleStep::getUseFlag, 1)
);
}
}
List<Long> scheduleIds = schedules.stream()
.map(OaProjectSchedule::getScheduleId)
.collect(Collectors.toList());
//查询这些进度下的步骤,且负责人是当前用户
LambdaQueryWrapper<OaProjectScheduleStep> stepWrapper = Wrappers.lambdaQuery();
stepWrapper.in(OaProjectScheduleStep::getScheduleId, scheduleIds)
.eq(OaProjectScheduleStep::getHeader, nickName) // 进度负责人匹配
.eq(OaProjectScheduleStep::getDelFlag, "0")
.eq(OaProjectScheduleStep::getUseFlag, 1);
List<OaProjectScheduleStep> userSteps = projectScheduleStepMapper.selectList(stepWrapper);
// 统计进度数据(总数量、完成数、待验收数、延期数)
long total = userSteps.size();
long completed = userSteps.stream()
.filter(step -> step.getStatus() != null && step.getStatus() == 2) // 已完成
.count();
long pendingAcceptance = userSteps.stream()
.filter(step -> step.getStatus() != null && step.getStatus() == 1) // 待验收
.count();
long delayed = userSteps.stream()
// 5. 统计进度数据
PersonalReportDTO.ProgressStats progressStats = new PersonalReportDTO.ProgressStats();
progressStats.setTotal((long) userSteps.size());
progressStats.setCompleted(userSteps.stream()
.filter(step -> step.getStatus() != null && step.getStatus() == 2)
.count());
progressStats.setPendingAcceptance(userSteps.stream()
.filter(step -> step.getStatus() != null && step.getStatus() == 1)
.count());
progressStats.setDelayed(userSteps.stream()
.filter(step -> step.getEndTime() != null && step.getOriginalEndTime() != null)
.filter(step -> step.getEndTime().isAfter(step.getOriginalEndTime())) // 实际结束>原定结束
.count();
.filter(step -> step.getEndTime().isAfter(step.getOriginalEndTime()))
.count());
result.put("total", total);
result.put("completed", completed);
result.put("pendingAcceptance", pendingAcceptance);
result.put("delayed", delayed);
// 6. 封装返回DTO
PersonalReportDTO result = new PersonalReportDTO();
result.setUserInfo(user);
result.setResponsibleProjects(responsibleProjects);
result.setProgressStats(progressStats);
result.setUserSteps(userSteps);
return result;
}