feat(oa): 实现项目进度延期申请与审批功能
- 新增申请延期接口,自动填充申请人与申请时间 - 新增审批延期接口,自动填充审批人与审批时间 - 完善延期记录查询逻辑,支持多字段筛选 - 补充延期记录列表展示字段,关联步骤信息 - 优化延期申请逻辑,自动补全原计划结束时间 - 更新Mapper XML,完善延期记录联合查询SQL - VO类新增步骤相关字段,用于前端展示 - Controller层增加申请与审批接口路由 - Service层实现申请与审批核心业务逻辑 - BO类新增申请与审批方法签名定义
This commit is contained in:
@@ -98,4 +98,26 @@ public class OaProjectScheduleDelayController extends BaseController {
|
||||
@PathVariable Long[] delayIds) {
|
||||
return toAjax(iOaProjectScheduleDelayService.deleteWithValidByIds(Arrays.asList(delayIds), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请延期:申请人取当前登录昵称
|
||||
* 前端需传:trackId, expectEndTime, applyReason, originalEndTime(可选)
|
||||
*/
|
||||
@Log(title = "项目进度步骤延期记录-申请延期", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/apply")
|
||||
public R<Void> apply(@Validated(AddGroup.class) @RequestBody OaProjectScheduleDelayBo bo) {
|
||||
return toAjax(iOaProjectScheduleDelayService.applyDelay(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 审批延期:审批人取当前登录昵称
|
||||
* 前端需传:delayId, approveResult(1通过/2驳回), approveRemark(可选)
|
||||
*/
|
||||
@Log(title = "项目进度步骤延期记录-审批", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/approve")
|
||||
public R<Void> approve(@Validated(EditGroup.class) @RequestBody OaProjectScheduleDelayBo bo) {
|
||||
return toAjax(iOaProjectScheduleDelayService.approveDelay(bo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,4 +103,28 @@ public class OaProjectScheduleDelayVo {
|
||||
private String remark;
|
||||
|
||||
|
||||
/**
|
||||
* 步骤名称(来自步骤表)
|
||||
*/
|
||||
@ExcelProperty(value = "步骤名称")
|
||||
private String stepName;
|
||||
|
||||
/**
|
||||
* 节点负责人(来自步骤表)
|
||||
*/
|
||||
@ExcelProperty(value = "节点负责人")
|
||||
private String nodeHeader;
|
||||
|
||||
/**
|
||||
* 步骤状态(来自步骤表)
|
||||
*/
|
||||
@ExcelProperty(value = "步骤状态")
|
||||
private Long stepStatus;
|
||||
|
||||
/**
|
||||
* 所属进度ID(来自步骤表)
|
||||
*/
|
||||
@ExcelProperty(value = "所属进度ID")
|
||||
private Long scheduleId;
|
||||
|
||||
}
|
||||
|
||||
@@ -46,4 +46,14 @@ public interface IOaProjectScheduleDelayService {
|
||||
* 校验并批量删除项目进度步骤延期记录信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 申请延期:自动填充申请人与申请时间
|
||||
*/
|
||||
Boolean applyDelay(OaProjectScheduleDelayBo bo);
|
||||
|
||||
/**
|
||||
* 审批延期:自动填充审批人与审批时间,并更新状态
|
||||
*/
|
||||
Boolean approveDelay(OaProjectScheduleDelayBo bo);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,16 @@ import com.ruoyi.oa.domain.vo.OaProjectScheduleDelayVo;
|
||||
import com.ruoyi.oa.domain.OaProjectScheduleDelay;
|
||||
import com.ruoyi.oa.mapper.OaProjectScheduleDelayMapper;
|
||||
import com.ruoyi.oa.service.IOaProjectScheduleDelayService;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.oa.mapper.OaProjectScheduleStepMapper;
|
||||
import com.ruoyi.oa.domain.OaProjectScheduleStep;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* 项目进度步骤延期记录Service业务层处理
|
||||
@@ -31,6 +37,7 @@ import java.util.Collection;
|
||||
public class OaProjectScheduleDelayServiceImpl implements IOaProjectScheduleDelayService {
|
||||
|
||||
private final OaProjectScheduleDelayMapper baseMapper;
|
||||
private final OaProjectScheduleStepMapper stepMapper;
|
||||
|
||||
/**
|
||||
* 查询项目进度步骤延期记录
|
||||
@@ -51,7 +58,22 @@ public class OaProjectScheduleDelayServiceImpl implements IOaProjectScheduleDela
|
||||
}
|
||||
|
||||
private QueryWrapper<OaProjectScheduleDelay> buildQueryWrapperPlus(OaProjectScheduleDelayBo bo) {
|
||||
return null;
|
||||
QueryWrapper<OaProjectScheduleDelay> lqw = Wrappers.query();
|
||||
// 使用别名与XML中保持一致
|
||||
lqw.eq("opsd.del_flag", 0);
|
||||
lqw.eq(bo.getTrackId() != null, "opsd.track_id", bo.getTrackId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getApplyUserName()), "opsd.apply_user_name", bo.getApplyUserName());
|
||||
lqw.eq(bo.getApplyTime() != null, "opsd.apply_time", bo.getApplyTime());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getApplyReason()), "opsd.apply_reason", bo.getApplyReason());
|
||||
lqw.eq(bo.getOriginalEndTime() != null, "opsd.original_end_time", bo.getOriginalEndTime());
|
||||
lqw.eq(bo.getExpectEndTime() != null, "opsd.expect_end_time", bo.getExpectEndTime());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getApproveUserName()), "opsd.approve_user_name", bo.getApproveUserName());
|
||||
lqw.eq(bo.getApproveTime() != null, "opsd.approve_time", bo.getApproveTime());
|
||||
lqw.eq(bo.getApproveResult() != null, "opsd.approve_result", bo.getApproveResult());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getApproveRemark()), "opsd.approve_remark", bo.getApproveRemark());
|
||||
lqw.eq(bo.getDelayStatus() != null, "opsd.delay_status", bo.getDelayStatus());
|
||||
lqw.orderByDesc("opsd.create_time");
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,4 +144,51 @@ public class OaProjectScheduleDelayServiceImpl implements IOaProjectScheduleDela
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean applyDelay(OaProjectScheduleDelayBo bo) {
|
||||
// 自动填充申请人和时间,初始化状态
|
||||
bo.setApplyUserName(LoginHelper.getNickName());
|
||||
bo.setApplyTime(new Date());
|
||||
if (bo.getDelayStatus() == null) {
|
||||
bo.setDelayStatus(0L);
|
||||
}
|
||||
if (bo.getApproveResult() == null) {
|
||||
bo.setApproveResult(0L);
|
||||
}
|
||||
// 如果未传原计划结束时间,则从步骤表补齐
|
||||
if (bo.getOriginalEndTime() == null && bo.getTrackId() != null) {
|
||||
OaProjectScheduleStep step = stepMapper.selectById(bo.getTrackId());
|
||||
if (step != null && step.getOriginalEndTime() != null) {
|
||||
LocalDateTime ldt = step.getOriginalEndTime();
|
||||
bo.setOriginalEndTime(Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()));
|
||||
}
|
||||
}
|
||||
return insertByBo(bo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean approveDelay(OaProjectScheduleDelayBo bo) {
|
||||
// 审批人与时间
|
||||
bo.setApproveUserName(LoginHelper.getNickName());
|
||||
bo.setApproveTime(new Date());
|
||||
// 状态联动:1 通过,2 驳回
|
||||
if (bo.getApproveResult() != null) {
|
||||
bo.setDelayStatus(bo.getApproveResult() == 1L ? 1L : 2L);
|
||||
}
|
||||
boolean ok = updateByBo(bo);
|
||||
// // 审批通过后,同步更新步骤的结束时间为申请的预计结束时间
|
||||
// if (ok && bo.getApproveResult() != null && bo.getApproveResult() == 1L) {
|
||||
// OaProjectScheduleDelay current = baseMapper.selectById(bo.getDelayId());
|
||||
// if (current != null && current.getTrackId() != null && current.getExpectEndTime() != null) {
|
||||
// OaProjectScheduleStep step = stepMapper.selectById(current.getTrackId());
|
||||
// if (step != null) {
|
||||
// LocalDateTime newEnd = LocalDateTime.ofInstant(current.getExpectEndTime().toInstant(), ZoneId.systemDefault());
|
||||
// step.setEndTime(newEnd);
|
||||
// stepMapper.updateById(step);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,33 @@
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="remark" column="remark"/>
|
||||
</resultMap>
|
||||
<select id="selectVoPagePlus" resultType="com.ruoyi.oa.domain.vo.OaProjectScheduleDelayVo"></select>
|
||||
<select id="selectVoPagePlus" resultType="com.ruoyi.oa.domain.vo.OaProjectScheduleDelayVo">
|
||||
SELECT opsd.delay_id AS delayId,
|
||||
opsd.track_id AS trackId,
|
||||
opsd.apply_user_name AS applyUserName,
|
||||
opsd.apply_time AS applyTime,
|
||||
opsd.apply_reason AS applyReason,
|
||||
opsd.original_end_time AS originalEndTime,
|
||||
opsd.expect_end_time AS expectEndTime,
|
||||
opsd.approve_user_name AS approveUserName,
|
||||
opsd.approve_time AS approveTime,
|
||||
opsd.approve_result AS approveResult,
|
||||
opsd.approve_remark AS approveRemark,
|
||||
opsd.delay_status AS delayStatus,
|
||||
opsd.remark AS remark,
|
||||
opss.step_name AS stepName,
|
||||
opss.node_header AS nodeHeader,
|
||||
opss.status AS stepStatus,
|
||||
opss.schedule_id AS scheduleId,
|
||||
opss.tab_node AS tabNode,
|
||||
opss.first_level_node AS firstLevelNode,
|
||||
opss.second_level_node AS secondLevelNode,
|
||||
opss.start_time AS startTime,
|
||||
opss.specification AS specification
|
||||
FROM oa_project_schedule_delay opsd
|
||||
LEFT JOIN oa_project_schedule_step opss ON opss.track_id = opsd.track_id
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user