项目进度控制

This commit is contained in:
2025-05-08 20:42:58 +08:00
parent a1e2b71141
commit ca3724ff32
42 changed files with 2487 additions and 1 deletions

View File

@@ -63,6 +63,7 @@ public class OaProgressController extends BaseController {
*/
@GetMapping("/one-list")
public TableDataInfo<SysOaProjectVo> oneList(SysOaProjectBo bo, PageQuery pageQuery) {
bo.setTradeType(1L);
return projectService.queryPageList2(bo, pageQuery);
}

View File

@@ -0,0 +1,112 @@
package com.ruoyi.oa.controller;
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.oa.domain.vo.OaProjectScheduleVo;
import com.ruoyi.oa.domain.bo.OaProjectScheduleBo;
import com.ruoyi.oa.service.IOaProjectScheduleService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 项目进度
*
* @author haka
* @date 2025-05-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/oa/projectSchedule")
public class OaProjectScheduleController extends BaseController {
private final IOaProjectScheduleService iOaProjectScheduleService;
/**
* 查询项目进度列表
*/
@GetMapping("/list")
public TableDataInfo<OaProjectScheduleVo> list(OaProjectScheduleBo bo, PageQuery pageQuery) {
return iOaProjectScheduleService.queryPageList(bo, pageQuery);
}
/**
* 导出项目进度列表
*/
@Log(title = "项目进度", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(OaProjectScheduleBo bo, HttpServletResponse response) {
List<OaProjectScheduleVo> list = iOaProjectScheduleService.queryList(bo);
ExcelUtil.exportExcel(list, "项目进度", OaProjectScheduleVo.class, response);
}
/**
* 获取项目进度详细信息
*
* @param scheduleId 主键
*/
@GetMapping("/{scheduleId}")
public R<OaProjectScheduleVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long scheduleId) {
return R.ok(iOaProjectScheduleService.queryById(scheduleId));
}
/**
* 新增项目进度
*/
@Log(title = "项目进度", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody OaProjectScheduleBo bo) {
return toAjax(iOaProjectScheduleService.insertByBo(bo));
}
/**
* 修改项目进度
*/
@Log(title = "项目进度", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody OaProjectScheduleBo bo) {
return toAjax(iOaProjectScheduleService.updateByBo(bo));
}
/**
* 修改项目进度
*/
@Log(title = "项目进度", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/complete")
public R<Void> complete(@RequestBody OaProjectScheduleBo bo) {
return toAjax(iOaProjectScheduleService.complete(bo));
}
/**
* 删除项目进度
*
* @param scheduleIds 主键串
*/
@Log(title = "项目进度", businessType = BusinessType.DELETE)
@DeleteMapping("/{scheduleIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] scheduleIds) {
return toAjax(iOaProjectScheduleService.deleteWithValidByIds(Arrays.asList(scheduleIds), true));
}
}

View File

@@ -0,0 +1,99 @@
package com.ruoyi.oa.controller;
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.oa.service.IOaProjectScheduleStepService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 项目进度步骤跟踪
*
* @author hdka
* @date 2025-05-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/oa/projectScheduleStep")
public class OaProjectScheduleStepController extends BaseController {
private final IOaProjectScheduleStepService iOaProjectScheduleStepService;
/**
* 查询项目进度步骤跟踪列表
*/
@GetMapping("/list")
public TableDataInfo<OaProjectScheduleStepVo> list(OaProjectScheduleStepBo bo, PageQuery pageQuery) {
return iOaProjectScheduleStepService.queryPageList(bo, pageQuery);
}
/**
* 导出项目进度步骤跟踪列表
*/
@Log(title = "项目进度步骤跟踪", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(OaProjectScheduleStepBo bo, HttpServletResponse response) {
List<OaProjectScheduleStepVo> list = iOaProjectScheduleStepService.queryList(bo);
ExcelUtil.exportExcel(list, "项目进度步骤跟踪", OaProjectScheduleStepVo.class, response);
}
/**
* 获取项目进度步骤跟踪详细信息
*
* @param trackId 主键
*/
@GetMapping("/{trackId}")
public R<OaProjectScheduleStepVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long trackId) {
return R.ok(iOaProjectScheduleStepService.queryById(trackId));
}
/**
* 新增项目进度步骤跟踪
*/
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody OaProjectScheduleStepBo bo) {
return toAjax(iOaProjectScheduleStepService.insertByBo(bo));
}
/**
* 修改项目进度步骤跟踪
*/
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody OaProjectScheduleStepBo bo) {
return toAjax(iOaProjectScheduleStepService.updateByBo(bo));
}
/**
* 删除项目进度步骤跟踪
*
* @param trackIds 主键串
*/
@DeleteMapping("/{trackIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] trackIds) {
return toAjax(iOaProjectScheduleStepService.deleteWithValidByIds(Arrays.asList(trackIds), true));
}
}

View File

@@ -0,0 +1,99 @@
package com.ruoyi.oa.controller;
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateVo;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateBo;
import com.ruoyi.oa.service.IOaScheduleTemplateService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 进度模板主
*
* @author hdka
* @date 2025-05-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/oa/scheduleTemplate")
public class OaScheduleTemplateController extends BaseController {
private final IOaScheduleTemplateService iOaScheduleTemplateService;
/**
* 查询进度模板主列表
*/
@GetMapping("/list")
public TableDataInfo<OaScheduleTemplateVo> list(OaScheduleTemplateBo bo, PageQuery pageQuery) {
return iOaScheduleTemplateService.queryPageList(bo, pageQuery);
}
/**
* 导出进度模板主列表
*/
@Log(title = "进度模板主", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(OaScheduleTemplateBo bo, HttpServletResponse response) {
List<OaScheduleTemplateVo> list = iOaScheduleTemplateService.queryList(bo);
ExcelUtil.exportExcel(list, "进度模板主", OaScheduleTemplateVo.class, response);
}
/**
* 获取进度模板主详细信息
*
* @param templateId 主键
*/
@GetMapping("/{templateId}")
public R<OaScheduleTemplateVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long templateId) {
return R.ok(iOaScheduleTemplateService.queryById(templateId));
}
/**
* 新增进度模板主
*/
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody OaScheduleTemplateBo bo) {
return toAjax(iOaScheduleTemplateService.insertByBo(bo));
}
/**
* 修改进度模板主
*/
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody OaScheduleTemplateBo bo) {
return toAjax(iOaScheduleTemplateService.updateByBo(bo));
}
/**
* 删除进度模板主
*
* @param templateIds 主键串
*/
@DeleteMapping("/{templateIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] templateIds) {
return toAjax(iOaScheduleTemplateService.deleteWithValidByIds(Arrays.asList(templateIds), true));
}
}

View File

@@ -0,0 +1,99 @@
package com.ruoyi.oa.controller;
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateStepVo;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateStepBo;
import com.ruoyi.oa.service.IOaScheduleTemplateStepService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 进度模板步骤
*
* @author hdka
* @date 2025-05-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/oa/scheduleTemplateStep")
public class OaScheduleTemplateStepController extends BaseController {
private final IOaScheduleTemplateStepService iOaScheduleTemplateStepService;
/**
* 查询进度模板步骤列表
*/
@GetMapping("/list")
public TableDataInfo<OaScheduleTemplateStepVo> list(OaScheduleTemplateStepBo bo, PageQuery pageQuery) {
return iOaScheduleTemplateStepService.queryPageList(bo, pageQuery);
}
/**
* 导出进度模板步骤列表
*/
@Log(title = "进度模板步骤", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(OaScheduleTemplateStepBo bo, HttpServletResponse response) {
List<OaScheduleTemplateStepVo> list = iOaScheduleTemplateStepService.queryList(bo);
ExcelUtil.exportExcel(list, "进度模板步骤", OaScheduleTemplateStepVo.class, response);
}
/**
* 获取进度模板步骤详细信息
*
* @param stepId 主键
*/
@GetMapping("/{stepId}")
public R<OaScheduleTemplateStepVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long stepId) {
return R.ok(iOaScheduleTemplateStepService.queryById(stepId));
}
/**
* 新增进度模板步骤
*/
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody OaScheduleTemplateStepBo bo) {
return toAjax(iOaScheduleTemplateStepService.insertByBo(bo));
}
/**
* 修改进度模板步骤
*/
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody OaScheduleTemplateStepBo bo) {
return toAjax(iOaScheduleTemplateStepService.updateByBo(bo));
}
/**
* 删除进度模板步骤
*
* @param stepIds 主键串
*/
@DeleteMapping("/{stepIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] stepIds) {
return toAjax(iOaScheduleTemplateStepService.deleteWithValidByIds(Arrays.asList(stepIds), true));
}
}

View File

@@ -11,6 +11,7 @@ import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 进度扩展对象 oa_progress_detail
@@ -41,6 +42,8 @@ public class OaProgressDetail extends BaseEntity {
/**
* 计划开始日期(项目进度)
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date planStartDate;
/**
* 计划结束日期(项目进度)

View File

@@ -0,0 +1,66 @@
package com.ruoyi.oa.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 项目进度对象 oa_project_schedule
*
* @author haka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("oa_project_schedule")
public class OaProjectSchedule extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 项目进度主键
*/
@TableId(value = "schedule_id")
private Long scheduleId;
/**
* 项目ID
*/
private Long projectId;
/**
* 引用的进度模板ID
*/
private Long templateId;
/**
* 当前进行到的步骤序号
*/
private Long currentStep;
/**
* 进度开始时间
*/
private Date startTime;
/**
* 进度完成时间
*/
private Date endTime;
/**
* 状态
*/
private Long status;
/**
*
*/
@TableLogic
private String delFlag;
/**
*
*/
private String remark;
}

View File

@@ -0,0 +1,79 @@
package com.ruoyi.oa.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 项目进度步骤跟踪对象 oa_project_schedule_step
*
* @author hdka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("oa_project_schedule_step")
public class OaProjectScheduleStep extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 跟踪记录主键
*/
@TableId(value = "track_id")
private Long trackId;
/**
* 文件列表
*/
private String accessory;
/**
* 所属项目进度ID
*/
private Long scheduleId;
/**
* 步骤序号
*/
private Long stepOrder;
/**
* 步骤名称(冗余存储模板名称)
*/
private String stepName;
/**
* 计划开始
*/
private Date planStart;
/**
* 计划完成
*/
private Date planEnd;
/**
*
*/
private Date actualStart;
/**
*
*/
private Date actualEnd;
/**
* 0未开始 1进行中 2完成 3暂停
*/
private Long status;
/**
* 进度负责人
*/
private String header;
/**
*
*/
@TableLogic
private String delFlag;
}

View File

@@ -0,0 +1,48 @@
package com.ruoyi.oa.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 进度模板主对象 oa_schedule_template
*
* @author hdka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("oa_schedule_template")
public class OaScheduleTemplate extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 模板主键
*/
@TableId(value = "template_id")
private Long templateId;
/**
* 模板名称
*/
private String templateName;
/**
* 状态(1启用 0停用)
*/
private Long status;
/**
* 删除标识
*/
@TableLogic
private String delFlag;
/**
*
*/
private String remark;
}

View File

@@ -0,0 +1,60 @@
package com.ruoyi.oa.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 进度模板步骤对象 oa_schedule_template_step
*
* @author hdka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("oa_schedule_template_step")
public class OaScheduleTemplateStep extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 步骤主键
*/
@TableId(value = "step_id")
private Long stepId;
/**
* 所属模板ID
*/
private Long templateId;
/**
* 步骤顺序
*/
private Long stepOrder;
/**
* 步骤名称
*/
private String stepName;
/**
* 预期耗时(天)
*/
private Long expectedDays;
/**
* 负责人
*/
private String header;
/**
*
*/
@TableLogic
private String delFlag;
/**
* 详细描述
*/
private String description;
}

View File

@@ -134,4 +134,14 @@ public class SysOaProject extends BaseEntity {
* 项目代表色
*/
private String color;
/**
* 交易类型
*/
private Long tradeType;
/**
* 预付款
*/
private Double prePay;
}

View File

@@ -0,0 +1,75 @@
package com.ruoyi.oa.domain.bo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 项目进度业务对象 oa_project_schedule
*
* @author haka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class OaProjectScheduleBo extends BaseEntity {
/**
* 项目进度主键
*/
@NotNull(message = "项目进度主键不能为空", groups = { EditGroup.class })
private Long scheduleId;
/**
* 项目ID
*/
private Long projectId;
/**
* 引用的进度模板ID
*/
private Long templateId;
/**
* 当前进行到的步骤序号
*/
private Long currentStep;
/**
* 进度开始时间
*/
private Date startTime;
/**
* 进度完成时间
*/
private Date endTime;
/**
* 状态
*/
private Long status;
/**
*
*/
private String remark;
private Double prePay;
private String mode;
private List<OaProjectScheduleStepBo> steps;
}

View File

@@ -0,0 +1,94 @@
package com.ruoyi.oa.domain.bo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 项目进度步骤跟踪业务对象 oa_project_schedule_step
*
* @author hdka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class OaProjectScheduleStepBo extends BaseEntity {
/**
* 跟踪记录主键
*/
private Long trackId;
/**
* 文件列表
*/
private String accessory;
/**
* 所属项目进度ID
*/
private Long scheduleId;
/**
* 步骤序号
*/
private Long stepOrder;
/**
* 步骤名称(冗余存储模板名称)
*/
private String stepName;
/**
* 计划开始
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date planStart;
/**
* 计划完成
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date planEnd;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date actualStart;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date actualEnd;
/**
* 0未开始 1进行中 2完成 3暂停
*/
private Long status;
private String description;
private Long expectedDays;
/**
* 进度负责人
*/
private String header;
}

View File

@@ -0,0 +1,40 @@
package com.ruoyi.oa.domain.bo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 进度模板主业务对象 oa_schedule_template
*
* @author hdka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class OaScheduleTemplateBo extends BaseEntity {
/**
* 模板主键
*/
private Long templateId;
/**
* 模板名称
*/
private String templateName;
/**
* 状态(1启用 0停用)
*/
private Long status;
/**
*
*/
private String remark;
}

View File

@@ -0,0 +1,60 @@
package com.ruoyi.oa.domain.bo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.util.Date;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 进度模板步骤业务对象 oa_schedule_template_step
*
* @author hdka
* @date 2025-05-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class OaScheduleTemplateStepBo extends BaseEntity {
/**
* 步骤主键
*/
private Long stepId;
/**
* 所属模板ID
*/
private Long templateId;
/**
* 步骤顺序
*/
private Long stepOrder;
/**
* 步骤名称
*/
private String stepName;
/**
* 预期耗时(天)
*/
private Long expectedDays;
/**
* 负责人
*/
private String header;
/**
* 详细描述
*/
private String description;
}

View File

@@ -165,4 +165,16 @@ public class SysOaProjectBo extends BaseEntity {
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
/**
* 交易类型
* 0内贸 1外贸
*/
private Long tradeType;
/**
* 预付款
*/
private Double prePay;
}

View File

@@ -0,0 +1,100 @@
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;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import com.ruoyi.system.domain.SysOss;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* 项目进度步骤跟踪视图对象 oa_project_schedule_step
*
* @author hdka
* @date 2025-05-08
*/
@Data
@ExcelIgnoreUnannotated
public class OaProjectScheduleStepVo {
private static final long serialVersionUID = 1L;
/**
* 跟踪记录主键
*/
@ExcelProperty(value = "跟踪记录主键")
private Long trackId;
/**
* 文件列表
*/
@ExcelProperty(value = "文件列表")
private String accessory;
/**
* 所属项目进度ID
*/
@ExcelProperty(value = "所属项目进度ID")
private Long scheduleId;
/**
* 步骤序号
*/
@ExcelProperty(value = "步骤序号")
private Long stepOrder;
/**
* 步骤名称(冗余存储模板名称)
*/
@ExcelProperty(value = "步骤名称(冗余存储模板名称)")
private String stepName;
/**
* 计划开始
*/
@ExcelProperty(value = "计划开始")
private Date planStart;
/**
* 计划完成
*/
@ExcelProperty(value = "计划完成")
private Date planEnd;
/**
*
*/
@ExcelProperty(value = "")
private Date actualStart;
/**
*
*/
@ExcelProperty(value = "")
private Date actualEnd;
/**
* 0未开始 1进行中 2完成 3暂停
*/
@ExcelProperty(value = "0未开始 1进行中 2完成 3暂停")
private Long status;
/**
* 进度负责人
*/
private String header;
private String description;
private Long expectedDays;
/** 附件列表1 步骤可多附件) */
private List<SysOss> fileList; // 建议用 List
}

View File

@@ -0,0 +1,90 @@
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;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* 项目进度视图对象 oa_project_schedule
*
* @author haka
* @date 2025-05-08
*/
@Data
@ExcelIgnoreUnannotated
public class OaProjectScheduleVo {
private static final long serialVersionUID = 1L;
/**
* 项目进度主键
*/
@ExcelProperty(value = "项目进度主键")
private Long scheduleId;
/**
* 项目ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* 引用的进度模板ID
*/
@ExcelProperty(value = "引用的进度模板ID")
private Long templateId;
/**
* 当前进行到的步骤序号
*/
@ExcelProperty(value = "当前进行到的步骤序号")
private Long currentStep;
/**
* 进度开始时间
*/
@ExcelProperty(value = "进度开始时间")
private Date startTime;
/**
* 进度完成时间
*/
@ExcelProperty(value = "进度完成时间")
private Date endTime;
/**
* 状态
*/
@ExcelProperty(value = "状态")
private Long status;
/**
*
*/
@ExcelProperty(value = "")
private String remark;
private String currentStepName;
private String projectName;
private String header;
private Long remainTime;
private Double schedulePercentage;
private String functionary;
private Long expectedDays;
private String description;
}

View File

@@ -0,0 +1,67 @@
package com.ruoyi.oa.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* 进度模板步骤视图对象 oa_schedule_template_step
*
* @author hdka
* @date 2025-05-08
*/
@Data
@ExcelIgnoreUnannotated
public class OaScheduleTemplateStepVo {
private static final long serialVersionUID = 1L;
/**
* 步骤主键
*/
@ExcelProperty(value = "步骤主键")
private Long stepId;
/**
* 所属模板ID
*/
@ExcelProperty(value = "所属模板ID")
private Long templateId;
/**
* 步骤顺序
*/
@ExcelProperty(value = "步骤顺序")
private Long stepOrder;
/**
* 步骤名称
*/
@ExcelProperty(value = "步骤名称")
private String stepName;
/**
* 预期耗时(天)
*/
@ExcelProperty(value = "预期耗时(天)")
private Long expectedDays;
/**
* 负责人
*/
@ExcelProperty(value = "负责人")
private String header;
/**
* 详细描述
*/
@ExcelProperty(value = "详细描述")
private String description;
}

View File

@@ -0,0 +1,49 @@
package com.ruoyi.oa.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* 进度模板主视图对象 oa_schedule_template
*
* @author hdka
* @date 2025-05-08
*/
@Data
@ExcelIgnoreUnannotated
public class OaScheduleTemplateVo {
private static final long serialVersionUID = 1L;
/**
* 模板主键
*/
@ExcelProperty(value = "模板主键")
private Long templateId;
/**
* 模板名称
*/
@ExcelProperty(value = "模板名称")
private String templateName;
/**
* 状态(1启用 0停用)
*/
@ExcelProperty(value = "状态(1启用 0停用)")
private Long status;
/**
*
*/
@ExcelProperty(value = "")
private String remark;
}

View File

@@ -224,4 +224,14 @@ public class SysOaProjectVo {
private Date updateTime;
private List<OaProgressVo> progressList;
/**
* 交易类型
*/
private Long tradeType;
/**
* 预付款
*/
private Double prePay;
}

View File

@@ -0,0 +1,20 @@
package com.ruoyi.oa.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.oa.domain.OaProjectSchedule;
import com.ruoyi.oa.domain.vo.OaProjectScheduleVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
/**
* 项目进度Mapper接口
*
* @author haka
* @date 2025-05-08
*/
public interface OaProjectScheduleMapper extends BaseMapperPlus<OaProjectScheduleMapper, OaProjectSchedule, OaProjectScheduleVo> {
Page<OaProjectScheduleVo> selectVoPagePlus(@Param("page") Page<OaProjectScheduleVo> build,@Param(Constants.WRAPPER) QueryWrapper<OaProjectSchedule> lqw);
}

View File

@@ -0,0 +1,27 @@
package com.ruoyi.oa.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.toolkit.Constants;
/**
* 项目进度步骤跟踪Mapper接口
*
* @author hdka
* @date 2025-05-08
*/
public interface OaProjectScheduleStepMapper extends BaseMapperPlus<OaProjectScheduleStepMapper, OaProjectScheduleStep, OaProjectScheduleStepVo> {
Page<OaProjectScheduleStepVo> selectVoPagePlus(@Param("page")Page<Object> build, @Param(Constants.WRAPPER) QueryWrapper<OaProjectScheduleStep> lqw);
OaProjectScheduleStepVo selectVoPlusById(Long trackId);
OaProjectScheduleStepVo maxStepByScheduleId(Long scheduleId);
void updateByStepAndScheduleId(@Param("currentStep") Long currentStep, @Param("scheduleId") Long scheduleId);
OaProjectScheduleStepVo selectByCurrentStepAndScheduleId(@Param("currentStep") Long currentStep, @Param("scheduleId") Long scheduleId);
}

View File

@@ -0,0 +1,15 @@
package com.ruoyi.oa.mapper;
import com.ruoyi.oa.domain.OaScheduleTemplate;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
/**
* 进度模板主Mapper接口
*
* @author hdka
* @date 2025-05-08
*/
public interface OaScheduleTemplateMapper extends BaseMapperPlus<OaScheduleTemplateMapper, OaScheduleTemplate, OaScheduleTemplateVo> {
}

View File

@@ -0,0 +1,20 @@
package com.ruoyi.oa.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.oa.domain.OaScheduleTemplateStep;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateStepVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
/**
* 进度模板步骤Mapper接口
*
* @author hdka
* @date 2025-05-08
*/
public interface OaScheduleTemplateStepMapper extends BaseMapperPlus<OaScheduleTemplateStepMapper, OaScheduleTemplateStep, OaScheduleTemplateStepVo> {
Page<OaScheduleTemplateStepVo> selectVoPagePlus(@Param("page")Page<OaScheduleTemplateStepVo> build,@Param(Constants.WRAPPER) QueryWrapper<OaScheduleTemplateStep> lqw);
}

View File

@@ -0,0 +1,56 @@
package com.ruoyi.oa.service;
import com.ruoyi.oa.domain.vo.OaProjectScheduleVo;
import com.ruoyi.oa.domain.bo.OaProjectScheduleBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 项目进度Service接口
*
* @author haka
* @date 2025-05-08
*/
public interface IOaProjectScheduleService {
/**
* 查询项目进度
*/
OaProjectScheduleVo queryById(Long scheduleId);
/**
* 查询项目进度列表
*/
TableDataInfo<OaProjectScheduleVo> queryPageList(OaProjectScheduleBo bo, PageQuery pageQuery);
/**
* 查询项目进度列表
*/
List<OaProjectScheduleVo> queryList(OaProjectScheduleBo bo);
/**
* 新增项目进度
*/
Boolean insertByBo(OaProjectScheduleBo bo);
/**
* 修改项目进度
*/
Boolean updateByBo(OaProjectScheduleBo bo);
/**
* 校验并批量删除项目进度信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 完成进度
*
* @param bo
* @return
*/
boolean complete(OaProjectScheduleBo bo);
}

View File

@@ -0,0 +1,58 @@
package com.ruoyi.oa.service;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import org.apache.ibatis.annotations.Param;
import javax.validation.constraints.NotNull;
import java.util.Collection;
import java.util.List;
/**
* 项目进度步骤跟踪Service接口
*
* @author hdka
* @date 2025-05-08
*/
public interface IOaProjectScheduleStepService {
/**
* 查询项目进度步骤跟踪
*/
OaProjectScheduleStepVo queryById(Long trackId);
/**
* 查询项目进度步骤跟踪列表
*/
TableDataInfo<OaProjectScheduleStepVo> queryPageList(OaProjectScheduleStepBo bo, PageQuery pageQuery);
/**
* 查询项目进度步骤跟踪列表
*/
List<OaProjectScheduleStepVo> queryList(OaProjectScheduleStepBo bo);
/**
* 新增项目进度步骤跟踪
*/
Boolean insertByBo(OaProjectScheduleStepBo bo);
/**
* 修改项目进度步骤跟踪
*/
Boolean updateByBo(OaProjectScheduleStepBo bo);
/**
* 校验并批量删除项目进度步骤跟踪信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
OaProjectScheduleStepVo maxStepByScheduleId(Long scheduleId);
void updateByStepAndScheduleId(Long currentStep,Long scheduleId);
OaProjectScheduleStepVo selectByCurrentStepAndScheduleId(Long currentStep, Long scheduleId);
}

View File

@@ -0,0 +1,49 @@
package com.ruoyi.oa.service;
import com.ruoyi.oa.domain.OaScheduleTemplate;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateVo;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 进度模板主Service接口
*
* @author hdka
* @date 2025-05-08
*/
public interface IOaScheduleTemplateService {
/**
* 查询进度模板主
*/
OaScheduleTemplateVo queryById(Long templateId);
/**
* 查询进度模板主列表
*/
TableDataInfo<OaScheduleTemplateVo> queryPageList(OaScheduleTemplateBo bo, PageQuery pageQuery);
/**
* 查询进度模板主列表
*/
List<OaScheduleTemplateVo> queryList(OaScheduleTemplateBo bo);
/**
* 新增进度模板主
*/
Boolean insertByBo(OaScheduleTemplateBo bo);
/**
* 修改进度模板主
*/
Boolean updateByBo(OaScheduleTemplateBo bo);
/**
* 校验并批量删除进度模板主信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,49 @@
package com.ruoyi.oa.service;
import com.ruoyi.oa.domain.OaScheduleTemplateStep;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateStepVo;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateStepBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 进度模板步骤Service接口
*
* @author hdka
* @date 2025-05-08
*/
public interface IOaScheduleTemplateStepService {
/**
* 查询进度模板步骤
*/
OaScheduleTemplateStepVo queryById(Long stepId);
/**
* 查询进度模板步骤列表
*/
TableDataInfo<OaScheduleTemplateStepVo> queryPageList(OaScheduleTemplateStepBo bo, PageQuery pageQuery);
/**
* 查询进度模板步骤列表
*/
List<OaScheduleTemplateStepVo> queryList(OaScheduleTemplateStepBo bo);
/**
* 新增进度模板步骤
*/
Boolean insertByBo(OaScheduleTemplateStepBo bo);
/**
* 修改进度模板步骤
*/
Boolean updateByBo(OaScheduleTemplateStepBo bo);
/**
* 校验并批量删除进度模板步骤信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,197 @@
package com.ruoyi.oa.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import com.ruoyi.oa.domain.OaScheduleTemplate;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateStepBo;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.oa.mapper.OaScheduleTemplateMapper;
import com.ruoyi.oa.service.IOaProjectScheduleStepService;
import com.ruoyi.oa.service.IOaScheduleTemplateStepService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaProjectScheduleBo;
import com.ruoyi.oa.domain.vo.OaProjectScheduleVo;
import com.ruoyi.oa.domain.OaProjectSchedule;
import com.ruoyi.oa.mapper.OaProjectScheduleMapper;
import com.ruoyi.oa.service.IOaProjectScheduleService;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 项目进度Service业务层处理
*
* @author haka
* @date 2025-05-08
*/
@RequiredArgsConstructor
@Service
public class OaProjectScheduleServiceImpl implements IOaProjectScheduleService {
private final OaProjectScheduleMapper baseMapper;
private final OaScheduleTemplateMapper scheduleTemplateMapper;
private final IOaScheduleTemplateStepService scheduleTemplateStepService;
private final IOaProjectScheduleStepService projectScheduleStepService;
/**
* 查询项目进度
*/
@Override
public OaProjectScheduleVo queryById(Long scheduleId){
return baseMapper.selectVoById(scheduleId);
}
/**
* 查询项目进度列表
*/
@Override
public TableDataInfo<OaProjectScheduleVo> queryPageList(OaProjectScheduleBo bo, PageQuery pageQuery) {
QueryWrapper<OaProjectSchedule> lqw = buildQueryWrapper(bo);
Page<OaProjectScheduleVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询项目进度列表
*/
@Override
public List<OaProjectScheduleVo> queryList(OaProjectScheduleBo bo) {
QueryWrapper<OaProjectSchedule> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private QueryWrapper<OaProjectSchedule> buildQueryWrapper(OaProjectScheduleBo bo) {
Map<String, Object> params = bo.getParams();
QueryWrapper<OaProjectSchedule> lqw = Wrappers.query();
lqw.eq("ops.del_flag", 0);
lqw.eq(bo.getProjectId() != null,"ops.project_id", bo.getProjectId());
lqw.eq(bo.getTemplateId() != null, "ops.template_id", bo.getTemplateId());
lqw.eq(bo.getCurrentStep() != null, "ops.current_step", bo.getCurrentStep());
lqw.eq(bo.getStatus() != null, "ops.status", bo.getStatus());
lqw.gt(bo.getPrePay()!=null&&bo.getPrePay()>0, "op.pre_pay", 0);
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
"op.begin_time", params.get("beginCreateTime"), params.get("endCreateTime"));
return lqw;
}
/**
* 新增项目进度
*/
@Override
public Boolean insertByBo(OaProjectScheduleBo bo) {
if (bo.getMode().equals("custom")){
// 生成模板
OaScheduleTemplate oaScheduleTemplate = new OaScheduleTemplate();
oaScheduleTemplate.setTemplateName("自动生成_"+ DateUtils.getTime() +"_"+LoginHelper.getNickName());
oaScheduleTemplate.setStatus(1L);
oaScheduleTemplate.setCreateBy(LoginHelper.getNickName());
scheduleTemplateMapper.insert(oaScheduleTemplate);
// 生成模板对应的步骤
Long templateId = oaScheduleTemplate.getTemplateId();
for (int i = 1; i <= bo.getSteps().size(); i++) {
OaScheduleTemplateStepBo step = getOaScheduleTemplateStepBo(bo, i, templateId);
scheduleTemplateStepService.insertByBo(step);
}
bo.setTemplateId(templateId);
}
bo.setCurrentStep(1L);
OaProjectSchedule add = BeanUtil.toBean(bo, OaProjectSchedule.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setScheduleId(add.getScheduleId());
}
for (int i = 0; i < bo.getSteps().size(); i++) {
OaProjectScheduleStepBo step = bo.getSteps().get(i);
step.setScheduleId(add.getScheduleId());
step.setStepOrder((long) (i+1));
if (i==0){
step.setActualStart(new Date());
}
projectScheduleStepService.insertByBo(step);
}
return flag;
}
private static OaScheduleTemplateStepBo getOaScheduleTemplateStepBo(OaProjectScheduleBo bo, int i, Long templateId) {
OaProjectScheduleStepBo projectScheduleStep = bo.getSteps().get(i-1);
OaScheduleTemplateStepBo step = new OaScheduleTemplateStepBo();
step.setStepName(projectScheduleStep.getStepName());
step.setDescription(projectScheduleStep.getDescription());
step.setTemplateId(templateId);
step.setStepOrder((long) i);
step.setExpectedDays(projectScheduleStep.getExpectedDays());
step.setCreateBy(LoginHelper.getNickName());
return step;
}
/**
* 修改项目进度
*/
@Override
public Boolean updateByBo(OaProjectScheduleBo bo) {
OaProjectSchedule update = BeanUtil.toBean(bo, OaProjectSchedule.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(OaProjectSchedule entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除项目进度
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public boolean complete(OaProjectScheduleBo bo) {
// 0首先判断是否到最后一部
OaProjectScheduleStepVo scheduleStepVo = projectScheduleStepService.maxStepByScheduleId(bo.getScheduleId());
// 此处被分为了两种情况
if (scheduleStepVo.getStepOrder()>bo.getCurrentStep()){
// 1未完成全部进度此时将currentStep更新到下一位 然后将当前的step的完成标志status改为1标志完成
projectScheduleStepService.updateByStepAndScheduleId(bo.getCurrentStep(),bo.getScheduleId());
bo.setCurrentStep(bo.getCurrentStep()+1L);
OaProjectScheduleStepVo stepVo = projectScheduleStepService.selectByCurrentStepAndScheduleId(bo.getCurrentStep()+1L,bo.getScheduleId());
stepVo.setActualStart(new Date());
OaProjectScheduleStepBo update = BeanUtil.toBean(stepVo, OaProjectScheduleStepBo.class);
projectScheduleStepService.updateByBo(update);
}else{
// 2完成了全部进度此时将此对象的status直接改为2代表完成了全部操作
OaProjectScheduleStepVo stepVo = projectScheduleStepService.selectByCurrentStepAndScheduleId(bo.getCurrentStep(),bo.getScheduleId());
OaProjectScheduleStepBo update = BeanUtil.toBean(stepVo, OaProjectScheduleStepBo.class);
update.setActualEnd(new Date());
projectScheduleStepService.updateByBo(update);
bo.setStatus(2L);
}
return updateByBo(bo);
}
}

View File

@@ -0,0 +1,130 @@
package com.ruoyi.oa.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
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 lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import com.ruoyi.oa.mapper.OaProjectScheduleStepMapper;
import com.ruoyi.oa.service.IOaProjectScheduleStepService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 项目进度步骤跟踪Service业务层处理
*
* @author hdka
* @date 2025-05-08
*/
@RequiredArgsConstructor
@Service
public class OaProjectScheduleStepServiceImpl implements IOaProjectScheduleStepService {
private final OaProjectScheduleStepMapper baseMapper;
/**
* 查询项目进度步骤跟踪
*/
@Override
public OaProjectScheduleStepVo queryById(Long trackId){
return baseMapper.selectVoPlusById(trackId);
}
/**
* 查询项目进度步骤跟踪列表
*/
@Override
public TableDataInfo<OaProjectScheduleStepVo> queryPageList(OaProjectScheduleStepBo bo, PageQuery pageQuery) {
QueryWrapper<OaProjectScheduleStep> lqw = buildQueryWrapper(bo);
Page<OaProjectScheduleStepVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询项目进度步骤跟踪列表
*/
@Override
public List<OaProjectScheduleStepVo> queryList(OaProjectScheduleStepBo bo) {
QueryWrapper<OaProjectScheduleStep> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private QueryWrapper<OaProjectScheduleStep> buildQueryWrapper(OaProjectScheduleStepBo bo) {
Map<String, Object> params = bo.getParams();
QueryWrapper<OaProjectScheduleStep> 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());
return lqw;
}
/**
* 新增项目进度步骤跟踪
*/
@Override
public Boolean insertByBo(OaProjectScheduleStepBo bo) {
OaProjectScheduleStep add = BeanUtil.toBean(bo, OaProjectScheduleStep.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setTrackId(add.getTrackId());
}
return flag;
}
/**
* 修改项目进度步骤跟踪
*/
@Override
public Boolean updateByBo(OaProjectScheduleStepBo bo) {
OaProjectScheduleStep update = BeanUtil.toBean(bo, OaProjectScheduleStep.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(OaProjectScheduleStep entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除项目进度步骤跟踪
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public OaProjectScheduleStepVo maxStepByScheduleId(Long scheduleId) {
return baseMapper.maxStepByScheduleId(scheduleId);
}
@Override
public void updateByStepAndScheduleId(Long currentStep, Long scheduleId) {
baseMapper.updateByStepAndScheduleId(currentStep,scheduleId);
}
@Override
public OaProjectScheduleStepVo selectByCurrentStepAndScheduleId(Long currentStep, Long scheduleId) {
return baseMapper.selectByCurrentStepAndScheduleId(currentStep,scheduleId);
}
}

View File

@@ -0,0 +1,110 @@
package com.ruoyi.oa.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
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 lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateBo;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateVo;
import com.ruoyi.oa.domain.OaScheduleTemplate;
import com.ruoyi.oa.mapper.OaScheduleTemplateMapper;
import com.ruoyi.oa.service.IOaScheduleTemplateService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 进度模板主Service业务层处理
*
* @author hdka
* @date 2025-05-08
*/
@RequiredArgsConstructor
@Service
public class OaScheduleTemplateServiceImpl implements IOaScheduleTemplateService {
private final OaScheduleTemplateMapper baseMapper;
/**
* 查询进度模板主
*/
@Override
public OaScheduleTemplateVo queryById(Long templateId){
return baseMapper.selectVoById(templateId);
}
/**
* 查询进度模板主列表
*/
@Override
public TableDataInfo<OaScheduleTemplateVo> queryPageList(OaScheduleTemplateBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<OaScheduleTemplate> lqw = buildQueryWrapper(bo);
Page<OaScheduleTemplateVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询进度模板主列表
*/
@Override
public List<OaScheduleTemplateVo> queryList(OaScheduleTemplateBo bo) {
LambdaQueryWrapper<OaScheduleTemplate> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<OaScheduleTemplate> buildQueryWrapper(OaScheduleTemplateBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<OaScheduleTemplate> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getTemplateName()), OaScheduleTemplate::getTemplateName, bo.getTemplateName());
lqw.eq(bo.getStatus() != null, OaScheduleTemplate::getStatus, bo.getStatus());
return lqw;
}
/**
* 新增进度模板主
*/
@Override
public Boolean insertByBo(OaScheduleTemplateBo bo) {
OaScheduleTemplate add = BeanUtil.toBean(bo, OaScheduleTemplate.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setTemplateId(add.getTemplateId());
}
return flag;
}
/**
* 修改进度模板主
*/
@Override
public Boolean updateByBo(OaScheduleTemplateBo bo) {
OaScheduleTemplate update = BeanUtil.toBean(bo, OaScheduleTemplate.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(OaScheduleTemplate entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除进度模板主
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,118 @@
package com.ruoyi.oa.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
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 lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateStepBo;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateStepVo;
import com.ruoyi.oa.domain.OaScheduleTemplateStep;
import com.ruoyi.oa.mapper.OaScheduleTemplateStepMapper;
import com.ruoyi.oa.service.IOaScheduleTemplateStepService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 进度模板步骤Service业务层处理
*
* @author hdka
* @date 2025-05-08
*/
@RequiredArgsConstructor
@Service
public class OaScheduleTemplateStepServiceImpl implements IOaScheduleTemplateStepService {
private final OaScheduleTemplateStepMapper baseMapper;
/**
* 查询进度模板步骤
*/
@Override
public OaScheduleTemplateStepVo queryById(Long stepId){
return baseMapper.selectVoById(stepId);
}
/**
* 查询进度模板步骤列表
*/
@Override
public TableDataInfo<OaScheduleTemplateStepVo> queryPageList(OaScheduleTemplateStepBo bo, PageQuery pageQuery) {
QueryWrapper<OaScheduleTemplateStep> lqw = buildQueryWrapper(bo);
Page<OaScheduleTemplateStepVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询进度模板步骤列表
*/
@Override
public List<OaScheduleTemplateStepVo> queryList(OaScheduleTemplateStepBo bo) {
QueryWrapper<OaScheduleTemplateStep> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private QueryWrapper<OaScheduleTemplateStep> buildQueryWrapper(OaScheduleTemplateStepBo bo) {
Map<String, Object> params = bo.getParams();
QueryWrapper<OaScheduleTemplateStep> lqw = Wrappers.query();
lqw.eq(bo.getTemplateId() != null, "template_id", bo.getTemplateId());
lqw.eq(bo.getStepOrder() != null, "step_order", bo.getStepOrder());
lqw.like(StringUtils.isNotBlank(bo.getStepName()), "step_name", bo.getStepName());
lqw.eq(bo.getExpectedDays() != null,"expected_days", bo.getExpectedDays());
lqw.eq(StringUtils.isNotBlank(bo.getHeader()), "header", bo.getHeader());
lqw.eq(StringUtils.isNotBlank(bo.getDescription()), "description", bo.getDescription());
lqw.groupBy("step_name","header","step_id");
return lqw;
}
/**
* 新增进度模板步骤
*/
@Override
public Boolean insertByBo(OaScheduleTemplateStepBo bo) {
OaScheduleTemplateStep add = BeanUtil.toBean(bo, OaScheduleTemplateStep.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setStepId(add.getStepId());
}
return flag;
}
/**
* 修改进度模板步骤
*/
@Override
public Boolean updateByBo(OaScheduleTemplateStepBo bo) {
OaScheduleTemplateStep update = BeanUtil.toBean(bo, OaScheduleTemplateStep.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(OaScheduleTemplateStep entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除进度模板步骤
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -67,6 +67,8 @@ public class SysOaProjectServiceImpl implements ISysOaProjectService {
LambdaQueryWrapper<SysOaProject> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getProjectName()), SysOaProject::getProjectName, bo.getProjectName());
lqw.eq(StringUtils.isNotBlank(bo.getProjectNum()), SysOaProject::getProjectNum, bo.getProjectNum());
lqw.eq(bo.getTradeType() != null, SysOaProject::getTradeType, bo.getTradeType());
lqw.gt(bo.getPrePay()!=null&&bo.getPrePay()>0, SysOaProject::getPrePay,0);
lqw.eq(StringUtils.isNotBlank(bo.getProjectType()), SysOaProject::getProjectType, bo.getProjectType());
lqw.eq(StringUtils.isNotBlank(bo.getProjectStatus()), SysOaProject::getProjectStatus, bo.getProjectStatus());
lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), SysOaProject::getCreateBy, bo.getCreateBy());

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.oa.mapper.OaProjectScheduleMapper">
<resultMap type="com.ruoyi.oa.domain.OaProjectSchedule" id="OaProjectScheduleResult">
<result property="scheduleId" column="schedule_id"/>
<result property="projectId" column="project_id"/>
<result property="templateId" column="template_id"/>
<result property="currentStep" column="current_step"/>
<result property="startTime" column="start_time"/>
<result property="endTime" column="end_time"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="remark" column="remark"/>
</resultMap>
<select id="selectVoPagePlus" resultType="com.ruoyi.oa.domain.vo.OaProjectScheduleVo">
SELECT
ops.schedule_id,
ops.project_id,
ops.template_id,
ops.current_step,
opss.step_name AS currentStepName,
ops.start_time,
ops.end_time,
ops.status,
ops.remark,
-- 项目信息
op.project_id AS opProjectId,
op.project_name,
op.project_num,
op.project_type,
op.address,
op.funds,
op.functionary,
op.begin_time,
op.finish_time,
op.introduction,
op.project_grade,
op.project_status,
op.trade_type,
op.pre_pay,
opss.plan_end,
-- 剩余天数
TIMESTAMPDIFF(DAY, NOW(), opss.plan_end) AS remainTime,
-- 进度百分比:当 current_step=1 时强制为0否则按公式计算
CASE
WHEN ops.current_step = 1 THEN 0
ELSE ROUND((ops.current_step / NULLIF(maxs.max_order,0)) * 100, 2)
END AS schedulePercentage -- 添加 NULLIF 防止除以0
FROM oa_project_schedule ops
LEFT JOIN sys_oa_project op ON ops.project_id = op.project_id
LEFT JOIN oa_project_schedule_step opss
ON ops.schedule_id = opss.schedule_id
AND opss.step_order = ops.current_step
LEFT JOIN (
SELECT
schedule_id,
MAX(step_order) AS max_order
FROM oa_project_schedule_step
GROUP BY schedule_id
) maxs ON maxs.schedule_id = ops.schedule_id
${ew.getCustomSqlSegment}
</select>
</mapper>

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.oa.mapper.OaProjectScheduleStepMapper">
<resultMap id="OaProjectScheduleStepResult"
type="com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo" >
<!-- 主键最好用 <id/>,以便 MyBatis 去重 -->
<id property="trackId" column="track_id"/>
<!-- ========== 原有字段 ========= -->
<result property="accessory" column="accessory"/>
<result property="scheduleId" column="schedule_id"/>
<result property="stepOrder" column="step_order"/>
<result property="stepName" column="step_name"/>
<result property="planStart" column="plan_start"/>
<result property="planEnd" column="plan_end"/>
<result property="actualStart" column="actual_start"/>
<result property="actualEnd" column="actual_end"/>
<result property="status" column="status"/>
<result property="expectedDays" column="expected_days"/>
<!-- ========== 附件列表:多对一 折叠 ========= -->
<collection property="fileList"
ofType="com.ruoyi.system.domain.SysOss"
javaType="java.util.ArrayList">
<result property="ossId" column="attach_oss_id"/>
<result property="url" column="attach_url"/>
<result property="fileName" column="attach_file_name"/>
<result property="createBy" column="create_by"/>
</collection>
</resultMap>
<update id="updateByStepAndScheduleId">
UPDATE oa_project_schedule_step
SET
status = 1,
actual_end = NOW()
WHERE
schedule_id = #{scheduleId}
AND step_order = #{currentStep}
AND del_flag = '0'
</update>
<select id="maxStepByScheduleId" resultMap="OaProjectScheduleStepResult">
SELECT opss.track_id,
opss.accessory,
opss.schedule_id,
opss.step_order,
opss.step_name,
opss.plan_start,
opss.plan_end,
opss.actual_start,
opss.actual_end,
opss.status,
opss.del_flag,
opss.header,
osts.expected_days,
osts.description
FROM oa_project_schedule_step opss
LEFT JOIN fad_oa.oa_project_schedule ops ON ops.schedule_id = opss.schedule_id
LEFT JOIN fad_oa.oa_schedule_template_step osts ON osts.template_id = ops.template_id AND osts.step_order = opss.step_order
WHERE opss.schedule_id = #{scheduleId}
AND opss.del_flag = '0'
AND opss.step_order = (
SELECT MAX(step_order)
FROM oa_project_schedule_step
WHERE schedule_id = #{scheduleId}
AND del_flag = '0'
)
</select>
<select id="selectVoPagePlus" resultMap="OaProjectScheduleStepResult">
select opss.track_id,
opss.accessory,
opss.schedule_id,
opss.step_order,
opss.step_name,
opss.plan_start,
opss.plan_end,
opss.actual_start,
opss.actual_end,
opss.status,
opss.del_flag,
opss.header,
osts.expected_days,
osts.description,
so.oss_id AS oss_id,
so.url AS attach_url,
so.original_name AS attach_file_name, -- 如有需要
so.create_by
from oa_project_schedule_step opss
left join fad_oa.oa_project_schedule ops on ops.schedule_id = opss.schedule_id
left join fad_oa.oa_schedule_template_step osts on osts.template_id = ops.template_id and osts.step_order = opss.step_order
LEFT JOIN sys_oss so ON FIND_IN_SET(so.oss_id, opss.accessory)
${ew.getCustomSqlSegment}
</select>
<select id="selectVoPlusById" resultMap="OaProjectScheduleStepResult">
select opss.track_id,
opss.accessory,
opss.schedule_id,
opss.step_order,
opss.step_name,
opss.plan_start,
opss.plan_end,
opss.actual_start,
opss.actual_end,
opss.status,
opss.del_flag,
opss.header,
osts.expected_days,
osts.description,
so.oss_id AS oss_id,
so.url AS attach_url,
so.original_name AS attach_file_name, -- 如有需要
so.create_by
from oa_project_schedule_step opss
left join fad_oa.oa_project_schedule ops on ops.schedule_id = opss.schedule_id
left join fad_oa.oa_schedule_template_step osts on osts.template_id = ops.template_id and osts.step_order = opss.step_order
LEFT JOIN sys_oss so ON FIND_IN_SET(so.oss_id, opss.accessory)
where opss.track_id = #{trackId} and opss.del_flag='0'
</select>
<select id="selectByCurrentStepAndScheduleId" resultType="com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo">
select opss.track_id,
accessory,
schedule_id,
step_order,
step_name,
plan_start,
plan_end,
actual_start,
actual_end,
status,
header
from oa_project_schedule_step opss
WHERE schedule_id = #{scheduleId}
AND step_order = #{currentStep}
AND del_flag = '0'
</select>
</mapper>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.oa.mapper.OaScheduleTemplateMapper">
<resultMap type="com.ruoyi.oa.domain.OaScheduleTemplate" id="OaScheduleTemplateResult">
<result property="templateId" column="template_id"/>
<result property="templateName" column="template_name"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.oa.mapper.OaScheduleTemplateStepMapper">
<resultMap type="com.ruoyi.oa.domain.OaScheduleTemplateStep" id="OaScheduleTemplateStepResult">
<result property="stepId" column="step_id"/>
<result property="templateId" column="template_id"/>
<result property="stepOrder" column="step_order"/>
<result property="stepName" column="step_name"/>
<result property="expectedDays" column="expected_days"/>
<result property="header" column="header"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="description" column="description"/>
</resultMap>
<select id="selectVoPagePlus" resultType="com.ruoyi.oa.domain.vo.OaScheduleTemplateStepVo">
select ANY_VALUE(step_id),
template_id,
step_order,
step_name,
expected_days,
header,
create_by,
create_time,
update_by,
update_time,
del_flag,
description
from oa_schedule_template_step
${ew.getCustomSqlSegment}
</select>
</mapper>

View File

@@ -260,6 +260,8 @@
</select>
<select id="selectVoPlus" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">
SELECT
p.pre_pay,
p.trade_type,
p.project_id,
p.project_name,
p.project_num,

View File

@@ -47,4 +47,6 @@ public class SysOss extends BaseEntity {
*/
private String service;
private String createBy;
}

View File

@@ -377,6 +377,7 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
flowTask.setProcDefId(task.getProcessDefinitionId());
flowTask.setTaskName(task.getName());
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(task.getProcessDefinitionId())
.singleResult();
@@ -396,7 +397,7 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
//获取部门信息(新增于2024年2月29日)
SysUser sysUser = sysUserService.selectUserById(userId);
if (sysUser.getDeptId()!=null){
if (Objects.nonNull(sysUser) && sysUser.getDeptId()!=null){
SysDept sysDept = sysDeptService.selectDeptById(sysUser.getDeptId());
flowTask.setDeptName(sysDept.getDeptName());

View File

@@ -0,0 +1,76 @@
-- 进度模板主表
CREATE TABLE `oa_schedule_template` (
`template_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '模板主键',
`template_name` VARCHAR(64) NOT NULL COMMENT '模板名称',
`status` INT DEFAULT 1 COMMENT '状态(1启用 0停用)',
`create_by` VARCHAR(64) DEFAULT NULL,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_by` VARCHAR(64) DEFAULT NULL,
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`del_flag` CHAR(1) DEFAULT '0' COMMENT '删除标识(0正常 1删除)',
`remark` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`template_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='进度模板主表';
-- 模板步骤明细
CREATE TABLE `oa_schedule_template_step` (
`step_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '步骤主键',
`template_id` BIGINT NOT NULL COMMENT '所属模板ID',
`step_order` INT NOT NULL COMMENT '步骤顺序(从1开始)',
`step_name` VARCHAR(64) NOT NULL COMMENT '步骤名称',
`expected_days` INT DEFAULT NULL COMMENT '预期耗时(天)',
`create_by` VARCHAR(64) DEFAULT NULL,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_by` VARCHAR(64) DEFAULT NULL,
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`del_flag` CHAR(1) DEFAULT '0',
PRIMARY KEY (`step_id`),
UNIQUE KEY `uniq_template_order` (`template_id`,`step_order`),
CONSTRAINT `fk_tpl_step_template` FOREIGN KEY (`template_id`)
REFERENCES `oa_schedule_template` (`template_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='进度模板步骤表';
--------------------------------------------------------------------
-- 项目进度主表
CREATE TABLE `oa_project_schedule` (
`schedule_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '项目进度主键',
`project_id` BIGINT NOT NULL COMMENT '项目ID',
`template_id` BIGINT NOT NULL COMMENT '引用的进度模板ID',
`current_step` INT DEFAULT 0 COMMENT '当前进行到的步骤序号',
`start_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '进度开始时间',
`end_time` DATETIME DEFAULT NULL COMMENT '进度完成时间',
`status` INT DEFAULT 1 COMMENT '状态(1进行中 2已完成 0暂停)',
`create_by` VARCHAR(64) DEFAULT NULL,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_by` VARCHAR(64) DEFAULT NULL,
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`del_flag` CHAR(1) DEFAULT '0',
`remark` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`schedule_id`),
KEY `idx_project` (`project_id`),
CONSTRAINT `fk_project_schedule_tpl` FOREIGN KEY (`template_id`)
REFERENCES `oa_schedule_template` (`template_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目进度主表';
-- 项目进度步骤跟踪表
CREATE TABLE `oa_project_schedule_step` (
`track_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '跟踪记录主键',
`schedule_id` BIGINT NOT NULL COMMENT '所属项目进度ID',
`step_order` INT NOT NULL COMMENT '步骤序号',
`step_name` VARCHAR(64) NOT NULL COMMENT '步骤名称(冗余存储模板名称)',
`plan_start` DATETIME DEFAULT NULL COMMENT '计划开始',
`plan_end` DATETIME DEFAULT NULL COMMENT '计划完成',
`actual_start` DATETIME DEFAULT NULL,
`actual_end` DATETIME DEFAULT NULL,
`status` INT DEFAULT 0 COMMENT '0未开始 1进行中 2完成 3暂停',
`create_by` VARCHAR(64) DEFAULT NULL,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_by` VARCHAR(64) DEFAULT NULL,
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`del_flag` CHAR(1) DEFAULT '0',
PRIMARY KEY (`track_id`),
UNIQUE KEY `uniq_schedule_order` (`schedule_id`,`step_order`),
CONSTRAINT `fk_project_step_main` FOREIGN KEY (`schedule_id`)
REFERENCES `oa_project_schedule` (`schedule_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目进度步骤跟踪表';
``