diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaScheduleController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaScheduleController.java new file mode 100644 index 0000000..59a8c2e --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaScheduleController.java @@ -0,0 +1,64 @@ +package com.ruoyi.oa.controller; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.oa.domain.bo.OaProjectScheduleBo; +import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo; +import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo; +import com.ruoyi.oa.domain.vo.OaProjectScheduleVo; +import com.ruoyi.oa.domain.vo.OaScheduleListVo; +import com.ruoyi.oa.service.IOaProjectScheduleService; +import com.ruoyi.oa.service.IOaProjectScheduleStepService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +/** + * 项目进度(主表 + 子表聚合) + * + * 该控制器用于满足综合看板接口规范: + * - GET /oa/schedule/list?projectId=xx + * + * 复用现有服务: + * - /oa/projectSchedule(主表) + * - /oa/projectScheduleStep(子表) + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/schedule") +public class OaScheduleController extends BaseController { + + private final IOaProjectScheduleService projectScheduleService; + private final IOaProjectScheduleStepService projectScheduleStepService; + + /** + * 获取进度主表 + 子表数据 + * + * @param projectId 项目ID + */ + @GetMapping("/list") + public R> list(@RequestParam("projectId") Long projectId) { + OaProjectScheduleBo scheduleBo = new OaProjectScheduleBo(); + scheduleBo.setProjectId(projectId); + List schedules = projectScheduleService.queryList(scheduleBo); + + List result = new ArrayList<>(); + for (OaProjectScheduleVo schedule : schedules) { + List steps = projectScheduleStepService.selectProjectScheduleStepList(schedule.getScheduleId()); + + OaScheduleListVo vo = new OaScheduleListVo(); + vo.setSchedule(schedule); + vo.setStepList(steps); + result.add(vo); + } + return R.ok(result); + } +} + diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaProjectController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaProjectController.java index f685272..895058b 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaProjectController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaProjectController.java @@ -87,6 +87,17 @@ public class SysOaProjectController extends BaseController { return R.ok(iSysOaProjectService.getMaxCode(prefix)); } + /** + * 项目综合看板聚合数据(项目 + 任务 + 进度主表 + 步骤) + * 必须声明在 /{projectId} 之前,避免部分环境下通配路径优先匹配导致 404。 + * 菜单权限请在 sys_menu 中配置后使用全局路由守卫或接口级注解单独加回。 + */ + @GetMapping("/dashboard/{projectId}") + public R dashboard(@NotNull(message = "主键不能为空") @PathVariable Long projectId) { + OaProjectDashboardVo data = iSysOaProjectService.getProjectDashboard(projectId); + return data == null ? R.fail("项目不存在") : R.ok(data); + } + /** * 获取项目管理详细信息 * diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaProjectBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaProjectBo.java index 872a58d..96a4d06 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaProjectBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaProjectBo.java @@ -201,6 +201,12 @@ public class SysOaProjectBo extends BaseEntity { private Long customerId; //客户名称 private String customerName; + + /** + * 综合模糊查询(名称 / 编号 / 代号 任一匹配),与 projectName、projectNum、projectCode 互斥:有值时优先使用本字段 + */ + private String keyword; + //是否置顶 private Integer isTop; diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaProjectDashboardVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaProjectDashboardVo.java new file mode 100644 index 0000000..1c11c56 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaProjectDashboardVo.java @@ -0,0 +1,23 @@ +package com.ruoyi.oa.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 项目综合看板聚合数据 + */ +@Data +public class OaProjectDashboardVo implements Serializable { + + private static final long serialVersionUID = 1L; + + private SysOaProjectVo project; + + private List tasks; + + private List schedules; + + private List steps; +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaScheduleListVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaScheduleListVo.java new file mode 100644 index 0000000..4151f2e --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaScheduleListVo.java @@ -0,0 +1,26 @@ +package com.ruoyi.oa.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 项目进度列表(主表 + 子表) + * + * 对应表: + * - oa_project_schedule(主表) + * - oa_project_schedule_step(子表) + * + * 该 VO 用于接口:GET /oa/schedule/list + */ +@Data +public class OaScheduleListVo implements Serializable { + + /** 进度主表 */ + private OaProjectScheduleVo schedule; + + /** 进度子表步骤 */ + private List stepList; +} + diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaTaskVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaTaskVo.java index 4ba838f..a13f38e 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaTaskVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaTaskVo.java @@ -1,7 +1,5 @@ package com.ruoyi.oa.domain.vo; -import java.util.Date; - import com.fasterxml.jackson.annotation.JsonFormat; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; @@ -218,11 +216,28 @@ public class SysOaTaskVo { //部门名称 private String deptName; - //关联项目进度id + /** 关联进度子表主键 oa_project_schedule_step.track_id */ private Long trackId; //联查的节点信息 private String tabNode; private String firstLevelNode; private String secondLevelNode; + + /** 进度步骤名称 oa_project_schedule_step.step_name(综合看板联表) */ + private String scheduleStepName; + + /** 进度步骤状态 0未开始 1进行中 2完成 3暂停 */ + private Long scheduleStatus; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date schedulePlanStart; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date schedulePlanEnd; + + /** 进度负责人 oa_project_schedule_step.header */ + private String scheduleHeader; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaProjectScheduleStepMapper.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaProjectScheduleStepMapper.java index 976f64f..afcb3f9 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaProjectScheduleStepMapper.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaProjectScheduleStepMapper.java @@ -31,6 +31,11 @@ public interface OaProjectScheduleStepMapper extends BaseMapperPlus entities); + /** + * 按 schedule_id 查询步骤列表(综合看板使用) + */ + List selectProjectScheduleStepList(@Param("scheduleId") Long scheduleId); + /** * 根据 schedule_id 批量删除步骤记录 * @param scheduleIds 主表的 schedule_id 集合 diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaTaskMapper.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaTaskMapper.java index 74f773e..479ab2e 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaTaskMapper.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaTaskMapper.java @@ -46,6 +46,11 @@ public interface SysOaTaskMapper extends BaseMapperPlus listDocumentProject(Long projectId); + /** + * 综合看板:某项目下任务(一行一条任务) + */ + List selectDashboardTasksByProjectId(@Param("projectId") Long projectId); + /** * 新增:自定义查询任务列表(Plus版) */ diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaProjectScheduleStepService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaProjectScheduleStepService.java index 61bf761..2744e12 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaProjectScheduleStepService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaProjectScheduleStepService.java @@ -38,6 +38,11 @@ public interface IOaProjectScheduleStepService{ */ List queryList(OaProjectScheduleStepBo bo); + /** + * 按 scheduleId 查询进度步骤列表(综合看板聚合接口使用) + */ + List selectProjectScheduleStepList(Long scheduleId); + /** * 新增项目进度步骤跟踪 */ diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaProjectService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaProjectService.java index aff454c..b2a69a9 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaProjectService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaProjectService.java @@ -103,4 +103,9 @@ public interface ISysOaProjectService { Boolean postponeProject(SysOaProject bo); SysOaProjectVo getMaxCode(String prefix); + + /** + * 综合看板:项目详情 + 任务 + 进度主表 + 进度步骤(一次返回) + */ + OaProjectDashboardVo getProjectDashboard(Long projectId); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaTaskService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaTaskService.java index 14e2085..5373691 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaTaskService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaTaskService.java @@ -109,6 +109,11 @@ public interface ISysOaTaskService { * @return */ List listDocumentProject(Long projectId); + + /** + * 综合看板任务列表(完整字段,无 task_item 重复行) + */ + List listDashboardTasks(Long projectId); /** * 新增:自定义查询任务列表(Plus版) */ diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleServiceImpl.java index 8def0ca..d00f90d 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleServiceImpl.java @@ -68,7 +68,8 @@ public class OaProjectScheduleServiceImpl implements IOaProjectScheduleService { */ @Override public TableDataInfo queryPageList(OaProjectScheduleBo bo, PageQuery pageQuery) { - QueryWrapper lqw = buildQueryWrapper(bo); + // 分页列表走自定义 Join SQL(XML 中存在 ops/op 别名) + QueryWrapper lqw = buildQueryWrapperJoin(bo); Page result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw); return TableDataInfo.build(result); } @@ -78,11 +79,17 @@ public class OaProjectScheduleServiceImpl implements IOaProjectScheduleService { */ @Override public List queryList(OaProjectScheduleBo bo) { - QueryWrapper lqw = buildQueryWrapper(bo); + // 非分页列表走 BaseMapper 默认 SQL(无 ops/op 别名),避免出现 ops.del_flag 这类不存在的列引用 + QueryWrapper lqw = buildQueryWrapperBase(bo); return baseMapper.selectVoList(lqw); } - private QueryWrapper buildQueryWrapper(OaProjectScheduleBo bo) { + /** + * Join 场景查询条件(对应 XML: OaProjectScheduleMapper.selectVoPagePlus) + * - 主表别名:ops (oa_project_schedule) + * - 项目表别名:op (sys_oa_project) + */ + private QueryWrapper buildQueryWrapperJoin(OaProjectScheduleBo bo) { Map params = bo.getParams(); QueryWrapper lqw = Wrappers.query(); lqw.eq("ops.del_flag", 0); @@ -112,6 +119,27 @@ public class OaProjectScheduleServiceImpl implements IOaProjectScheduleService { return lqw; } + /** + * Base 表场景查询条件(对应 BaseMapper 默认 SQL:FROM oa_project_schedule) + * 仅使用 oa_project_schedule 表字段,严格对齐表结构: + * - oa_project_schedule(project_id、schedule_id、...、del_flag) + */ + private QueryWrapper buildQueryWrapperBase(OaProjectScheduleBo bo) { + QueryWrapper lqw = Wrappers.query(); + // TableLogic 字段,默认查询只取未删除 + lqw.eq("del_flag", 0); + lqw.eq(bo.getProjectId() != null, "project_id", bo.getProjectId()); + lqw.eq(bo.getTemplateId() != null, "template_id", bo.getTemplateId()); + lqw.eq(bo.getCurrentStep() != null, "current_step", bo.getCurrentStep()); + lqw.eq(bo.getStatus() != null, "status", bo.getStatus()); + lqw.eq(bo.getSteward() != null, "steward", bo.getSteward()); + // 使用 startTime / endTime 进行范围筛选 + lqw.between(bo.getStartTime() != null && bo.getEndTime() != null, "start_time", bo.getStartTime(), bo.getEndTime()); + lqw.ge(bo.getStartTime() != null && bo.getEndTime() == null, "start_time", bo.getStartTime()); + lqw.le(bo.getStartTime() == null && bo.getEndTime() != null, "end_time", bo.getEndTime()); + return lqw; + } + /** * 新增项目进度 */ diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleStepServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleStepServiceImpl.java index e8c3e05..28e0572 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleStepServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaProjectScheduleStepServiceImpl.java @@ -95,13 +95,13 @@ public class OaProjectScheduleStepServiceImpl implements IOaProjectScheduleStepS */ @Override public TableDataInfo queryPageList(OaProjectScheduleStepBo bo, PageQuery pageQuery) { - QueryWrapper lqw = buildQueryWrapper(bo); + QueryWrapper lqw = buildQueryWrapper(bo, true); Page result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw,LoginHelper.getUserId()); return TableDataInfo.build(result); } @Override public TableDataInfo queryPageListPage(OaProjectScheduleStepBo bo, PageQuery pageQuery) { - QueryWrapper lqw = buildQueryWrapper(bo); + QueryWrapper lqw = buildQueryWrapper(bo, true); Page result = baseMapper.selectVoPageNew(pageQuery.build(), lqw); return TableDataInfo.build(result); } @@ -113,22 +113,13 @@ public class OaProjectScheduleStepServiceImpl implements IOaProjectScheduleStepS return TableDataInfo.build(result); } private QueryWrapper buildQueryMyWrapper(OaProjectScheduleStepBo bo) { - Map params = bo.getParams(); QueryWrapper lqw = Wrappers.query(); - lqw.eq(bo.getScheduleId() != null, "opss.schedule_id", bo.getScheduleId()); - lqw.eq("opss.del_flag", 0); - lqw.eq(bo.getStepOrder() != null, "opss.step_order", bo.getStepOrder()); - lqw.like(StringUtils.isNotBlank(bo.getStepName()), "opss.step_name", bo.getStepName()); - lqw.eq(bo.getStatus() != null, "opss.status", bo.getStatus()); + appendCommonStepFilters(lqw, bo, "opss"); // 默认将负责人设置为当前用户 String currentUser = LoginHelper.getNickName(); - lqw.eq(StringUtils.isNotBlank(currentUser), "opss.node_header", currentUser); - lqw.eq(bo.getSupplierId() != null, "opss.supplier_id", bo.getSupplierId()); - //根据开始时间和结束时间作为范围判断planEnd - lqw.ge(bo.getStartTime() != null, "opss.plan_end", bo.getStartTime()); - lqw.le(bo.getEndTime() != null, "opss.plan_end", bo.getEndTime()); + lqw.eq(StringUtils.isNotBlank(currentUser), stepCol("opss", "node_header"), currentUser); // 按时间倒序排列,已完成的排在最后 - lqw.orderByDesc("opss.plan_end"); + lqw.orderByDesc(stepCol("opss", "plan_end")); lqw.orderByAsc("opss.status = 2"); // 状态为2表示已完成,将其排在最后 return lqw; } @@ -137,26 +128,42 @@ public class OaProjectScheduleStepServiceImpl implements IOaProjectScheduleStepS */ @Override public List queryList(OaProjectScheduleStepBo bo) { - QueryWrapper lqw = buildQueryWrapper(bo); + QueryWrapper lqw = buildQueryWrapper(bo, false); return baseMapper.selectVoList(lqw); } - private QueryWrapper buildQueryWrapper(OaProjectScheduleStepBo bo) { - Map params = bo.getParams(); + @Override + public List selectProjectScheduleStepList(Long scheduleId) { + return baseMapper.selectProjectScheduleStepList(scheduleId); + } + + /** + * @param forJoinSql true:XML 中带 opss/schedule 等多表别名,条件须加 opss. 前缀,避免 schedule_id 等列歧义 + */ + private QueryWrapper buildQueryWrapper(OaProjectScheduleStepBo bo, boolean forJoinSql) { QueryWrapper lqw = Wrappers.query(); - lqw.eq(bo.getScheduleId() != null, "opss.schedule_id", bo.getScheduleId()); - lqw.eq("opss.del_flag", 0); - lqw.eq(bo.getStepOrder() != null, "opss.step_order", bo.getStepOrder()); - lqw.like(StringUtils.isNotBlank(bo.getStepName()), "opss.step_name", bo.getStepName()); - lqw.eq(bo.getStatus() != null, "opss.status", bo.getStatus()); - lqw.eq(StringUtils.isNotBlank(bo.getNodeHeader()), "opss.node_header", bo.getNodeHeader()); - lqw.eq(bo.getSupplierId() != null, "opss.supplier_id", bo.getSupplierId()); - //根据开始时间和结束时间作为范围判断planEnd - lqw.ge(bo.getStartTime() != null, "opss.plan_end", bo.getStartTime()); - lqw.le(bo.getEndTime() != null, "opss.plan_end", bo.getEndTime()); + String alias = forJoinSql ? "opss" : null; + appendCommonStepFilters(lqw, bo, alias); + lqw.eq(StringUtils.isNotBlank(bo.getNodeHeader()), stepCol(alias, "node_header"), bo.getNodeHeader()); return lqw; } + private static String stepCol (String tableAlias, String column) { + return StringUtils.isBlank(tableAlias) ? column : tableAlias + "." + column; + } + + /** 步骤表公共筛选(与 oa_project_schedule 联表时须使用别名 opss) */ + private void appendCommonStepFilters (QueryWrapper lqw, OaProjectScheduleStepBo bo, String alias) { + lqw.eq(stepCol(alias, "del_flag"), 0); + lqw.eq(bo.getScheduleId() != null, stepCol(alias, "schedule_id"), bo.getScheduleId()); + lqw.eq(bo.getStepOrder() != null, stepCol(alias, "step_order"), bo.getStepOrder()); + lqw.like(StringUtils.isNotBlank(bo.getStepName()), stepCol(alias, "step_name"), bo.getStepName()); + lqw.eq(bo.getStatus() != null, stepCol(alias, "status"), bo.getStatus()); + lqw.eq(bo.getSupplierId() != null, stepCol(alias, "supplier_id"), bo.getSupplierId()); + lqw.ge(bo.getStartTime() != null, stepCol(alias, "plan_end"), bo.getStartTime()); + lqw.le(bo.getEndTime() != null, stepCol(alias, "plan_end"), bo.getEndTime()); + } + /** * 新增项目进度步骤跟踪 */ diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java index deb1aab..44fb56a 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java @@ -12,12 +12,16 @@ import com.ruoyi.common.core.domain.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.oa.domain.bo.OaProjectScheduleBo; import com.ruoyi.oa.domain.bo.SysOaWarehouseDetailBo; import com.ruoyi.oa.domain.dto.ProjectActivityDTO; import com.ruoyi.oa.domain.dto.ProjectDataDTO; import com.ruoyi.oa.domain.vo.*; import com.ruoyi.oa.service.CodeGeneratorService; import com.ruoyi.oa.service.IExchangeRateService; +import com.ruoyi.oa.service.IOaProjectScheduleService; +import com.ruoyi.oa.service.IOaProjectScheduleStepService; +import com.ruoyi.oa.service.ISysOaTaskService; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -43,6 +47,12 @@ public class SysOaProjectServiceImpl implements ISysOaProjectService { private final SysOaProjectMapper baseMapper; + private final ISysOaTaskService sysOaTaskService; + + private final IOaProjectScheduleService oaProjectScheduleService; + + private final IOaProjectScheduleStepService oaProjectScheduleStepService; + @Autowired private CodeGeneratorService codeGeneratorService; @Autowired @@ -187,9 +197,16 @@ public class SysOaProjectServiceImpl implements ISysOaProjectService { private QueryWrapper buildAliasPQueryWrapper(SysOaProjectBo bo) { Map params = bo.getParams(); QueryWrapper qw = Wrappers.query(); - qw.like(StringUtils.isNotBlank(bo.getProjectName()), "p.project_name", bo.getProjectName()); - qw.like(StringUtils.isNotBlank(bo.getProjectNum()), "p.project_num", bo.getProjectNum()); - qw.like(StringUtils.isNotBlank(bo.getProjectCode()), "p.project_code", bo.getProjectCode()); + if (StringUtils.isNotBlank(bo.getKeyword())) { + String kw = bo.getKeyword().trim(); + qw.and(w -> w.like("p.project_name", kw) + .or().like("p.project_num", kw) + .or().like("p.project_code", kw)); + } else { + qw.like(StringUtils.isNotBlank(bo.getProjectName()), "p.project_name", bo.getProjectName()); + qw.like(StringUtils.isNotBlank(bo.getProjectNum()), "p.project_num", bo.getProjectNum()); + qw.like(StringUtils.isNotBlank(bo.getProjectCode()), "p.project_code", bo.getProjectCode()); + } qw.eq(bo.getProductStatus() != null, "p.product_status", bo.getProductStatus()); qw.eq(bo.getTradeType() != null, "p.trade_type", bo.getTradeType()); if (bo.getPrePay() != null && bo.getPrePay() > 0) { @@ -219,9 +236,16 @@ public class SysOaProjectServiceImpl implements ISysOaProjectService { private LambdaQueryWrapper buildQueryWrapper(SysOaProjectBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.like(StringUtils.isNotBlank(bo.getProjectName()), SysOaProject::getProjectName, bo.getProjectName()); - lqw.like(StringUtils.isNotBlank(bo.getProjectNum()), SysOaProject::getProjectNum, bo.getProjectNum()); - lqw.like(StringUtils.isNotBlank(bo.getProjectCode()), SysOaProject::getProjectCode, bo.getProjectCode()); + if (StringUtils.isNotBlank(bo.getKeyword())) { + String kw = bo.getKeyword().trim(); + lqw.and(w -> w.like(SysOaProject::getProjectName, kw) + .or().like(SysOaProject::getProjectNum, kw) + .or().like(SysOaProject::getProjectCode, kw)); + } else { + lqw.like(StringUtils.isNotBlank(bo.getProjectName()), SysOaProject::getProjectName, bo.getProjectName()); + lqw.like(StringUtils.isNotBlank(bo.getProjectNum()), SysOaProject::getProjectNum, bo.getProjectNum()); + lqw.like(StringUtils.isNotBlank(bo.getProjectCode()), SysOaProject::getProjectCode, bo.getProjectCode()); + } //新增生产结项状态筛选 lqw.eq(bo.getProductStatus() != null, SysOaProject::getProductStatus, bo.getProductStatus()); lqw.eq(bo.getTradeType() != null, SysOaProject::getTradeType, bo.getTradeType()); @@ -587,4 +611,37 @@ public class SysOaProjectServiceImpl implements ISysOaProjectService { return baseMapper.getMaxCodeProject(prefix); } + @Override + public OaProjectDashboardVo getProjectDashboard(Long projectId) { + SysOaProjectVo project = queryById(projectId); + if (project == null) { + return null; + } + List tasks = sysOaTaskService.listDashboardTasks(projectId); + + OaProjectScheduleBo scheduleBo = new OaProjectScheduleBo(); + scheduleBo.setProjectId(projectId); + List schedules = oaProjectScheduleService.queryList(scheduleBo); + + List steps = new ArrayList<>(); + for (OaProjectScheduleVo sch : schedules) { + List part = oaProjectScheduleStepService.selectProjectScheduleStepList(sch.getScheduleId()); + if (part == null) { + continue; + } + for (OaProjectScheduleStepVo st : part) { + st.setProjectId(projectId); + st.setProjectName(project.getProjectName()); + } + steps.addAll(part); + } + + OaProjectDashboardVo vo = new OaProjectDashboardVo(); + vo.setProject(project); + vo.setTasks(tasks); + vo.setSchedules(schedules); + vo.setSteps(steps); + return vo; + } + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaTaskServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaTaskServiceImpl.java index cf9afae..7c56621 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaTaskServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaTaskServiceImpl.java @@ -135,6 +135,11 @@ public class SysOaTaskServiceImpl implements ISysOaTaskService { return baseMapper.listDocumentProject(projectId); } + @Override + public List listDashboardTasks(Long projectId) { + return baseMapper.selectDashboardTasksByProjectId(projectId); + } + /** * 新增:自定义查询任务列表(Plus版) */ diff --git a/ruoyi-oa/src/main/resources/mapper/oa/OaProjectScheduleStepMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/OaProjectScheduleStepMapper.xml index 5346451..de75a8f 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/OaProjectScheduleStepMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/OaProjectScheduleStepMapper.xml @@ -204,8 +204,8 @@ status, header from oa_project_schedule_step opss - WHERE schedule_id = #{scheduleId} - AND step_order = #{currentStep} + WHERE opss.schedule_id = #{scheduleId} + AND opss.step_order = #{currentStep} and use_flag = '1' AND del_flag = '0' @@ -258,5 +258,29 @@ ${ew.customSqlSegment} + + + diff --git a/ruoyi-oa/src/main/resources/mapper/oa/SysOaTaskMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/SysOaTaskMapper.xml index 74620c0..6955f94 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/SysOaTaskMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/SysOaTaskMapper.xml @@ -474,6 +474,41 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + +