流程管理

liweidong
张乾翔 3 days ago
parent a0a9772963
commit a2f4d59e79
  1. 18
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalServiceImpl.java
  2. 83
      blade-service/blade-desk/src/main/java/org/springblade/desk/process/controller/FmProjectApplicationController.java
  3. 5
      blade-service/blade-desk/src/main/java/org/springblade/desk/process/controller/FmProjectMilestoneController.java
  4. 97
      blade-service/blade-desk/src/main/java/org/springblade/desk/process/pojo/entity/FmProjectApplicationEntity.java
  5. 22
      blade-service/blade-desk/src/main/java/org/springblade/desk/process/pojo/entity/FmProjectMilestoneEntity.java
  6. 26
      blade-service/blade-desk/src/main/java/org/springblade/desk/process/service/IFmProjectApplicationService.java
  7. 269
      blade-service/blade-desk/src/main/java/org/springblade/desk/process/service/impl/FmProjectApplicationServiceImpl.java
  8. 478
      blade-service/blade-desk/src/main/java/org/springblade/desk/process/service/impl/FmProjectMilestoneServiceImpl.java

@ -340,15 +340,15 @@ public class OemSettlementApprovalServiceImpl extends BaseServiceImpl<OemSettlem
/** /**
* 发送通知给外协结算审核领导 * 发送通知给外协结算审核领导
*/ */
private void sendNotificationToAuditLeader(OemSettlementApprovalEntity approval) { private void sendNotificationToAuditLeader(OemSettlementApprovalEntity approval) {
try { try {
Long auditLeaderRoleId = 2054852195869057026L; Long auditLeaderRoleId = 2054852195869057026L;
String roleName = "外协结算审核领导"; String roleName = "外协结算审核领导";
// 构建通知消息 // 构建通知消息
String title = String.format("外协结算审批提醒 - %s", String title = String.format("外协结算审批提醒 - %s",
approval.getApprovalNo()); approval.getApprovalNo());
String content = String.format( String content = String.format(
"外协结算审批详情:\n" + "外协结算审批详情:\n" +
"- 审批单号:%s\n" + "- 审批单号:%s\n" +
@ -363,7 +363,7 @@ public class OemSettlementApprovalServiceImpl extends BaseServiceImpl<OemSettlem
approval.getTotalAmount() != null ? approval.getTotalAmount() : BigDecimal.ZERO, approval.getTotalAmount() != null ? approval.getTotalAmount() : BigDecimal.ZERO,
approval.getSubmitTime() approval.getSubmitTime()
); );
// 创建通知消息实体 // 创建通知消息实体
MesNotifyMessageEntity notifyMessage = MesNotifyMessageEntity.builder() MesNotifyMessageEntity notifyMessage = MesNotifyMessageEntity.builder()
.title(title) .title(title)
@ -375,15 +375,15 @@ public class OemSettlementApprovalServiceImpl extends BaseServiceImpl<OemSettlem
// 通知失败不影响主流程 // 通知失败不影响主流程
// 调用Feign客户端保存通知消息 // 调用Feign客户端保存通知消息
R result = mesNotifyMessageClient.save(notifyMessage); R result = mesNotifyMessageClient.save(notifyMessage);
if (result != null && result.isSuccess()) { if (result != null && result.isSuccess()) {
log.info("成功发送外协结算审批提醒,审批单号: {}, 校对人: {}", log.info("成功发送外协结算审批提醒,审批单号: {}, 校对人: {}",
approval.getApprovalNo(), AuthUtil.getUserName()); approval.getApprovalNo(), AuthUtil.getUserName());
} else { } else {
log.error("发送外协结算审批提醒失败,审批单号: {}, 错误信息: {}", log.error("发送外协结算审批提醒失败,审批单号: {}, 错误信息: {}",
approval.getApprovalNo(), result != null ? result.getMsg() : "返回结果为空"); approval.getApprovalNo(), result != null ? result.getMsg() : "返回结果为空");
} }
} catch (Exception e) { } catch (Exception e) {
log.error("发送外协结算审批提醒时发生异常,审批单号: {}", approval.getApprovalNo(), e); log.error("发送外协结算审批提醒时发生异常,审批单号: {}", approval.getApprovalNo(), e);
} }

@ -56,12 +56,14 @@ import org.springblade.desk.process.service.IFmProjectMilestoneService;
import org.springblade.desk.process.wrapper.FmProjectApplicationWrapper; import org.springblade.desk.process.wrapper.FmProjectApplicationWrapper;
import org.springblade.system.feign.IUserClient; import org.springblade.system.feign.IUserClient;
import org.springblade.system.pojo.entity.User; import org.springblade.system.pojo.entity.User;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -139,21 +141,7 @@ public class FmProjectApplicationController extends BladeController {
@ApiOperationSupport(order = 5) @ApiOperationSupport(order = 5)
@Operation(summary = "修改", description = "传入fmProjectApplication") @Operation(summary = "修改", description = "传入fmProjectApplication")
public R update(@Valid @RequestBody FmProjectApplicationEntity fmProjectApplication) { public R update(@Valid @RequestBody FmProjectApplicationEntity fmProjectApplication) {
List<FmProjectMilestoneEntity> stoneList = fmProjectApplication.getStoneList(); return fmProjectApplicationService.updateOrSave(fmProjectApplication);
if(CollectionUtils.isNotEmpty(stoneList)){
//子项全删全增
List<FmProjectMilestoneEntity> oldStoneList = fmProjectMilestoneService.list(Wrappers.<FmProjectMilestoneEntity>lambdaQuery().eq(FmProjectMilestoneEntity::getPaId,fmProjectApplication.getId()));
List<Long> stoneIdList = oldStoneList.stream().map(BaseEntity::getId).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(stoneIdList)){
fmProjectMilestoneService.deleteLogic(stoneIdList);
}
stoneList.forEach(item -> {
item.setId(null);
item.setPaId(fmProjectApplication.getId());
});
fmProjectMilestoneService.saveBatch(stoneList);
}
return R.status(fmProjectApplicationService.updateById(fmProjectApplication));
} }
/** /**
@ -163,8 +151,9 @@ public class FmProjectApplicationController extends BladeController {
@ApiOperationSupport(order = 6) @ApiOperationSupport(order = 6)
@Operation(summary = "新增或修改", description = "传入fmProjectApplication") @Operation(summary = "新增或修改", description = "传入fmProjectApplication")
public R submit(@Valid @RequestBody FmProjectApplicationEntity fmProjectApplication) { public R submit(@Valid @RequestBody FmProjectApplicationEntity fmProjectApplication) {
if(fmProjectApplication.getId()==null||0==fmProjectApplication.getId()) if(fmProjectApplication.getId()==null||0==fmProjectApplication.getId()) {
fmProjectApplication.setPaCode(nextCode()); fmProjectApplication.setPaCode(fmProjectApplicationService.nextCode());
}
if(fmProjectApplication.getTouchingTime()==null){ if(fmProjectApplication.getTouchingTime()==null){
fmProjectApplication.setTouchingTime(new Date()); fmProjectApplication.setTouchingTime(new Date());
} }
@ -213,33 +202,43 @@ public class FmProjectApplicationController extends BladeController {
List<FmProjectApplicationExcel> list = fmProjectApplicationService.exportFmProjectApplication(queryWrapper); List<FmProjectApplicationExcel> list = fmProjectApplicationService.exportFmProjectApplication(queryWrapper);
ExcelUtil.export(response, "项目管理数据" + DateUtil.time(), "项目管理数据表", list, FmProjectApplicationExcel.class); ExcelUtil.export(response, "项目管理数据" + DateUtil.time(), "项目管理数据表", list, FmProjectApplicationExcel.class);
} }
public String nextCode() {
// 自增总长度 /**
int len = 3; * 项目管理 立项新增
// 自增值 * 立项后状态设置为待审批不立即进入审批环节
int num = 0; */
// 编码模式 @PostMapping("/createApplication")
String codePattern = new SimpleDateFormat("yyyyMMdd").format(new Date()); @ApiOperationSupport(order = 10)
// 当前模式下最大编码 @Operation(summary = "立项", description = "传入fmProjectApplication,立项后状态为待审批")
List<FmProjectApplicationEntity> pgrList = fmProjectApplicationService.list( public R createApplication(@Valid @RequestBody FmProjectApplicationEntity fmProjectApplication) {
new QueryWrapper<FmProjectApplicationEntity>().lambda() return R.status(fmProjectApplicationService.createApplication(fmProjectApplication));
.likeRight(FmProjectApplicationEntity::getPaCode, codePattern)
.orderByDesc(FmProjectApplicationEntity::getPaCode));
FmProjectApplicationEntity pgr = pgrList.size() > 0 ? pgrList.get(0) : null;
if (pgr != null) {
num = Integer.parseInt(pgr.getPaCode().substring(codePattern.length(), codePattern.length() + len));
}
num++;
// 下个编码
return codePattern + prefix(String.valueOf(num), "0", len);
} }
public static final String prefix(String StringToFix, String fixChar, int targetLen) {
int len = StringToFix.length();
for(int i = 0; i < targetLen - len; i += fixChar.length()) { /**
StringToFix = fixChar + StringToFix; * 项目管理 提交审批
} * 仅对待审批状态的项目生效提交后进入审批环节
return StringToFix; */
@GetMapping("/submitApproval")
@ApiOperationSupport(order = 11)
@Operation(summary = "提交审批", description = "传入项目ID,仅对待审批状态的项目生效")
public R submitApproval(@Parameter(description = "项目ID", required = true) @RequestParam Long id,
@Parameter(description = "审批人", required = true) @RequestParam Long approverId,
@Parameter(description = "审批人名称", required = true) @RequestParam String approverName) {
fmProjectApplicationService.submitApproval(id,approverId,approverName);
return R.success("提交审批成功");
}
/**
* 项目管理 审批
*/
@PostMapping("/approval")
@ApiOperationSupport(order = 5)
@Operation(summary = "修改", description = "传入fmProjectApplication")
public R approval(@Valid @RequestBody FmProjectApplicationEntity fmProjectApplication) {
fmProjectApplicationService.approval(fmProjectApplication);
return R.success("审批成功");
} }
} }

@ -25,6 +25,7 @@
*/ */
package org.springblade.desk.process.controller; package org.springblade.desk.process.controller;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
@ -52,6 +53,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* 项目里程碑 控制器 * 项目里程碑 控制器
@ -164,6 +166,9 @@ public class FmProjectMilestoneController extends BladeController {
@ApiOperationSupport(order = 10) @ApiOperationSupport(order = 10)
@Operation(summary = "执行", description = "传入fmProjectMilestone") @Operation(summary = "执行", description = "传入fmProjectMilestone")
public R projectExecute(@Valid @RequestBody FmProjectMilestoneEntity fmProjectMilestone) { public R projectExecute(@Valid @RequestBody FmProjectMilestoneEntity fmProjectMilestone) {
if (BeanUtil.isEmpty(fmProjectMilestone) || Objects.isNull(fmProjectMilestone.getId())) {
throw new RuntimeException("参数异常");
}
return R.status(fmProjectMilestoneService.projectExecute(fmProjectMilestone)); return R.status(fmProjectMilestoneService.projectExecute(fmProjectMilestone));
} }
/** /**

@ -159,12 +159,109 @@ public class FmProjectApplicationEntity extends BaseEntity {
*/ */
@Schema(description = "成员名称") @Schema(description = "成员名称")
private String memberName; private String memberName;
/**APPROVAL_MAN
* 审批人
* */
@Schema(description = "审批人")
private Long approvalMan;
/**
* APPROVAL_MAN_NAME
* 审批人名称
*/
@Schema(description = "审批人名称")
private String approvalManName;
/** /**
* 审批状态 * 审批状态
*/ */
@Schema(description = "审批状态") @Schema(description = "审批状态")
private Long approvalStatus; private Long approvalStatus;
public enum ApprovalStatusEnum {
/**
* 立项待提交
*/
STATUS_DRAFT(0L, "立项待提交"),
/**
* 立项待审
*/
STATUS_PENDING(1L, "立项待审"),
/**
* 立项审批不通过
*/
STATUS_REJECTED(2L, "立项审批不通过"),
/**
* 项目进行中
*/
STATUS_IN_PROGRESS(3L, "项目进行中"),
/**
* 项目待核查
*/
STATUS_PENDING_CHECK(4L, "项目待核查"),
/**
* 项目核查不通过
*/
STATUS_CHECK_REJECTED(5L, "项目核查不通过"),
/**
* 项目待核准
*/
STATUS_PENDING_APPROVAL(6L, "项目待核准"),
/**
* 项目核准不通过
*/
STATUS_APPROVAL_REJECTED(7L, "项目核准不通过"),
/**
* 项目已核准
*/
STATUS_APPROVED(8L, "项目已核准");
private final Long code;
private final String desc;
ApprovalStatusEnum(Long code, String desc) {
this.code = code;
this.desc = desc;
}
public Long getCode() {
return code;
}
public String getDesc() {
return desc;
}
/**
* 根据 code 获取描述
*/
public static String getDescByCode(Long code) {
if (code == null) {
return "";
}
for (ApprovalStatusEnum status : values()) {
if (status.getCode().equals(code)) {
return status.getDesc();
}
}
return "";
}
/**
* 根据 code 获取枚举
*/
public static ApprovalStatusEnum getByCode(Long code) {
if (code == null) {
return null;
}
for (ApprovalStatusEnum status : values()) {
if (status.getCode().equals(code)) {
return status;
}
}
return null;
}
}
@TableField(exist = false) @TableField(exist = false)
private List<FmProjectMilestoneEntity> stoneList; private List<FmProjectMilestoneEntity> stoneList;

@ -157,8 +157,14 @@ public class FmProjectMilestoneEntity extends BaseEntity {
/** /**
* 评价人 * 评价人
*/ */
@Schema(description = "评价人") @Schema(description = "评价人名称")
private String gradeMan; private String gradeMan;
/**
* 评价人
*/
@Schema(description = "评价人Id")
private Long gradeManId;
/** /**
* 业务领导评价 * 业务领导评价
*/ */
@ -182,6 +188,18 @@ public class FmProjectMilestoneEntity extends BaseEntity {
@Schema(description = "附件ID") @Schema(description = "附件ID")
private String fileId; private String fileId;
/**
* 下一节点审批人ID用于存储用户选择的审批人
*/
@Schema(description = "下一节点审批人ID")
private Long nextApproverId;
/**
* 下一节点审批人姓名冗余字段便于展示
*/
@Schema(description = "下一节点审批人姓名")
private String nextApproverName;
/** /**
* 评价等级 未评价 * 评价等级 未评价
*/ */
@ -270,7 +288,7 @@ public class FmProjectMilestoneEntity extends BaseEntity {
*/ */
public static Short CHECK_RESULT_NO = 3; public static Short CHECK_RESULT_NO = 3;
public static Map<Short, String> checkResultMap = new HashMap<>(3); public static Map<Short, String> checkResultMap = new HashMap<>(4);
static { static {
checkResultMap.put(CHECK_RESULT_NULL, "未核查"); checkResultMap.put(CHECK_RESULT_NULL, "未核查");

@ -28,6 +28,7 @@ package org.springblade.desk.process.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService; import org.springblade.core.mp.base.BaseService;
import org.springblade.core.tool.api.R;
import org.springblade.desk.process.excel.FmProjectApplicationExcel; import org.springblade.desk.process.excel.FmProjectApplicationExcel;
import org.springblade.desk.process.pojo.entity.FmProjectApplicationEntity; import org.springblade.desk.process.pojo.entity.FmProjectApplicationEntity;
import org.springblade.desk.process.pojo.vo.FmProjectApplicationVO; import org.springblade.desk.process.pojo.vo.FmProjectApplicationVO;
@ -59,4 +60,29 @@ public interface IFmProjectApplicationService extends BaseService<FmProjectAppli
*/ */
List<FmProjectApplicationExcel> exportFmProjectApplication(Wrapper<FmProjectApplicationEntity> queryWrapper); List<FmProjectApplicationExcel> exportFmProjectApplication(Wrapper<FmProjectApplicationEntity> queryWrapper);
/**
* 项目立项新增
* 立项后状态设置为待审批不立即进入审批环节
*
* @param fmProjectApplication 项目申请实体
* @return 是否成功
*/
boolean createApplication(FmProjectApplicationEntity fmProjectApplication);
/**
* 提交审批
* 仅对待审批状态的项目生效提交后进入审批环节
*
* @param id 项目ID
* @return 是否成功
*/
void submitApproval(Long id,Long approverId,String approverName);
String nextCode();
R updateOrSave(FmProjectApplicationEntity fmProjectApplication);
void approval(FmProjectApplicationEntity fmProjectApplication);
} }

@ -25,17 +25,43 @@
*/ */
package org.springblade.desk.process.service.impl; package org.springblade.desk.process.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.desk.common.feign.MesNotifyMessageClient;
import org.springblade.desk.common.pojo.entity.MesNotifyMessageEntity;
import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalEntity;
import org.springblade.desk.process.excel.FmProjectApplicationExcel; import org.springblade.desk.process.excel.FmProjectApplicationExcel;
import org.springblade.desk.process.mapper.FmProjectApplicationMapper; import org.springblade.desk.process.mapper.FmProjectApplicationMapper;
import org.springblade.desk.process.pojo.entity.FmProjectApplicationEntity; import org.springblade.desk.process.pojo.entity.FmProjectApplicationEntity;
import org.springblade.desk.process.pojo.entity.FmProjectMilestoneEntity;
import org.springblade.desk.process.pojo.vo.FmProjectApplicationVO; import org.springblade.desk.process.pojo.vo.FmProjectApplicationVO;
import org.springblade.desk.process.service.IFmProjectApplicationService; import org.springblade.desk.process.service.IFmProjectApplicationService;
import org.springblade.desk.process.service.IFmProjectMilestoneService;
import org.springblade.system.feign.IUserClient;
import org.springblade.system.pojo.entity.User;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/** /**
* 项目管理 服务实现类 * 项目管理 服务实现类
@ -43,21 +69,242 @@ import java.util.List;
* @author BladeX * @author BladeX
* @since 2026-01-07 * @since 2026-01-07
*/ */
@Slf4j
@Service @Service
@AllArgsConstructor
public class FmProjectApplicationServiceImpl extends BaseServiceImpl<FmProjectApplicationMapper, FmProjectApplicationEntity> implements IFmProjectApplicationService { public class FmProjectApplicationServiceImpl extends BaseServiceImpl<FmProjectApplicationMapper, FmProjectApplicationEntity> implements IFmProjectApplicationService {
@Override private final IFmProjectMilestoneService fmProjectMilestoneService;
public IPage<FmProjectApplicationVO> selectFmProjectApplicationPage(IPage<FmProjectApplicationVO> page, FmProjectApplicationVO fmProjectApplication) { private final IUserClient userClient;
return page.setRecords(baseMapper.selectFmProjectApplicationPage(page, fmProjectApplication)); private final MesNotifyMessageClient mesNotifyMessageClient;
}
@Override
public IPage<FmProjectApplicationVO> selectFmProjectApplicationPage(IPage<FmProjectApplicationVO> page, FmProjectApplicationVO fmProjectApplication) {
return page.setRecords(baseMapper.selectFmProjectApplicationPage(page, fmProjectApplication));
}
@Override
public List<FmProjectApplicationExcel> exportFmProjectApplication(Wrapper<FmProjectApplicationEntity> queryWrapper) {
List<FmProjectApplicationExcel> fmProjectApplicationList = baseMapper.exportFmProjectApplication(queryWrapper);
//fmProjectApplicationList.forEach(fmProjectApplication -> {
// fmProjectApplication.setTypeName(DictCache.getValue(DictEnum.YES_NO, FmProjectApplication.getType()));
//});
return fmProjectApplicationList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean createApplication(FmProjectApplicationEntity fmProjectApplication) {
if (fmProjectApplication == null) {
return false;
}
// 新增时生成单据号
if (fmProjectApplication.getId() == null || fmProjectApplication.getId() == 0) {
fmProjectApplication.setPaCode(nextCode());
}
// 设置制单时间
if (fmProjectApplication.getTouchingTime() == null) {
fmProjectApplication.setTouchingTime(new Date());
}
// 获取当前用户信息
BladeUser bladeUser = AuthUtil.getUser();
if (bladeUser != null) {
User user = userClient.userInfoById(bladeUser.getUserId()).getData();
if (user != null) {
fmProjectApplication.setTouchingMan(user.getRealName());
fmProjectApplication.setTouchingManId(String.valueOf(bladeUser.getUserId()));
}
}
// 设置状态为待审批(0)
fmProjectApplication.setApprovalStatus(FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_DRAFT.getCode());
// 保存主表
boolean flag = this.saveOrUpdate(fmProjectApplication);
if (flag) {
// 处理子表(里程碑)
List<FmProjectMilestoneEntity> stoneList = fmProjectApplication.getStoneList();
if (CollectionUtils.isNotEmpty(stoneList)) {
// 先删除旧的子表数据
fmProjectMilestoneService.remove(Wrappers.lambdaQuery(FmProjectMilestoneEntity.class)
.eq(FmProjectMilestoneEntity::getPaId, fmProjectApplication.getId()));
// 设置关联ID并批量保存
stoneList.forEach(x -> {
x.setId(null);
x.setPaId(fmProjectApplication.getId());
});
return fmProjectMilestoneService.saveBatch(stoneList);
}
return true;
}
return false;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void submitApproval(Long id,Long approverId,String approverName) {
// 查询项目信息
FmProjectApplicationEntity application = this.getById(id);
if (BeanUtil.isEmpty(application)) {
throw new RuntimeException("项目信息不存在");
}
// 判断是否为待审批状态
if (Objects.isNull(application.getApprovalStatus()) ||
!application.getApprovalStatus().equals(FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_DRAFT.getCode())) {
throw new RuntimeException("项目信息不是待审批状态");
}
// 用户所选审批人
// TODO: 2026/5/27 是否校验是否为节点配置审批人
R<User> userR = userClient.userInfoById(approverId);
if (!userR.isSuccess() || Objects.isNull(userR.getData())) {
throw new RuntimeException("审批人信息不存在");
}
User user = userR.getData();
if (!Objects.equals(user.getName(), approverName)) {
throw new RuntimeException("审批人信息不一致");
}
application.setApprovalMan(approverId);
application.setApprovalManName(approverName);
application.setApprovalStatus(FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_PENDING.getCode());
//向审批人发送通知
sendNotificationToAuditLeader(application);
this.updateById(application);
}
/**
* 生成下一个单据号
*/
@Override @Override
public List<FmProjectApplicationExcel> exportFmProjectApplication(Wrapper<FmProjectApplicationEntity> queryWrapper) { public String nextCode() {
List<FmProjectApplicationExcel> fmProjectApplicationList = baseMapper.exportFmProjectApplication(queryWrapper); // 自增总长度
//fmProjectApplicationList.forEach(fmProjectApplication -> { int len = 3;
// fmProjectApplication.setTypeName(DictCache.getValue(DictEnum.YES_NO, FmProjectApplication.getType())); // 自增值
//}); int num = 0;
return fmProjectApplicationList; // 编码模式
} String codePattern = new SimpleDateFormat("yyyyMMdd").format(new Date());
// 当前模式下最大编码
List<FmProjectApplicationEntity> pgrList = this.list(
new QueryWrapper<FmProjectApplicationEntity>().lambda()
.likeRight(FmProjectApplicationEntity::getPaCode, codePattern)
.orderByDesc(FmProjectApplicationEntity::getPaCode));
FmProjectApplicationEntity pgr = pgrList.size() > 0 ? pgrList.get(0) : null;
if (pgr != null) {
num = Integer.parseInt(pgr.getPaCode().substring(codePattern.length(), codePattern.length() + len));
}
num++;
// 下个编码
return codePattern + prefix(String.valueOf(num), "0", len);
}
@Override
public R updateOrSave(FmProjectApplicationEntity fmProjectApplication) {
//针对审批校验
if (Objects.isNull(fmProjectApplication.getId())) {
throw new RuntimeException("项目信息不存在");
}
FmProjectApplicationEntity entity = getById(fmProjectApplication.getId());
if (Objects.isNull(entity) ||
!FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_DRAFT.getCode().equals(entity.getApprovalStatus()) ||
!FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_REJECTED.getCode().equals(entity.getApprovalStatus()) ) {
throw new RuntimeException("项目信息状态异常");
}
List<FmProjectMilestoneEntity> stoneList = fmProjectApplication.getStoneList();
if(CollectionUtils.isNotEmpty(stoneList)){
//子项全删全增
List<FmProjectMilestoneEntity> oldStoneList = fmProjectMilestoneService.list(Wrappers.<FmProjectMilestoneEntity>lambdaQuery().eq(FmProjectMilestoneEntity::getPaId,fmProjectApplication.getId()));
List<Long> stoneIdList = oldStoneList.stream().map(BaseEntity::getId).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(stoneIdList)){
fmProjectMilestoneService.deleteLogic(stoneIdList);
}
stoneList.forEach(item -> {
item.setId(null);
item.setPaId(fmProjectApplication.getId());
});
fmProjectMilestoneService.saveBatch(stoneList);
}
return R.status(updateById(fmProjectApplication));
}
@Override
public void approval(FmProjectApplicationEntity fmProjectApplication) {
/**
* 前端审批传参
* {
* "id": "2059190659557314562",
* "approvalStatus": 3
* }
* */
FmProjectApplicationEntity application = getByIdAndCheck(fmProjectApplication);
application.setApprovalStatus(fmProjectApplication.getApprovalStatus());
updateById(application);
}
private FmProjectApplicationEntity getByIdAndCheck(FmProjectApplicationEntity fmProjectApplication) {
if (BeanUtil.isEmpty(fmProjectApplication) ||
Objects.isNull(fmProjectApplication.getId()) ||
Objects.isNull(fmProjectApplication.getApprovalStatus())) {
throw new RuntimeException("参数错误");
}
if (!fmProjectApplication.getApprovalStatus().equals(FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_REJECTED.getCode()) ||
!fmProjectApplication.getApprovalStatus().equals(FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_IN_PROGRESS.getCode())) {
throw new RuntimeException("审批结果参数错误");
}
// 查询项目信息
FmProjectApplicationEntity application = this.getById(fmProjectApplication.getId());
if (BeanUtil.isEmpty(application)) {
throw new RuntimeException("项目信息不存在");
}
// 判断是否为待审批状态
if (Objects.isNull(application.getApprovalStatus()) ||
!application.getApprovalStatus().equals(FmProjectApplicationEntity.ApprovalStatusEnum.STATUS_PENDING.getCode())) {
throw new RuntimeException("项目信息不是待审批状态");
}
Long userId = AuthUtil.getUserId();
if (Objects.isNull(application.getApprovalMan()) || !application.getApprovalMan().equals(userId)) {
throw new RuntimeException("项目信息不是当前审批人");
}
return application;
}
/**
* 前缀补零
*/
private static String prefix(String stringToFix, String fixChar, int targetLen) {
int len = stringToFix.length();
for (int i = 0; i < targetLen - len; i += fixChar.length()) {
stringToFix = fixChar + stringToFix;
}
return stringToFix;
}
private void sendNotificationToAuditLeader(FmProjectApplicationEntity application) {
try {
// 构建通知消息
String title = String.format("立项申请审批提醒 - %s", application.getPaCode());
String content = String.format("立项申请审批详情:- 审批单号:%s", application.getPaCode());
// 创建通知消息实体
MesNotifyMessageEntity notifyMessage = MesNotifyMessageEntity.builder()
.title(title)
.content(content)
.receiveUserId(application.getApprovalMan())
.build();
mesNotifyMessageClient.save(notifyMessage);
} catch (Exception e) {
log.error("发送外协结算审批提醒时发生异常,审批单号: {}", application.getPaCode(), e);
}
}
} }

@ -25,32 +25,43 @@
*/ */
package org.springblade.desk.process.service.impl; package org.springblade.desk.process.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springblade.core.log.exception.ServiceException; import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser; import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.BeanUtil; import org.springblade.core.tool.api.R;
import org.springblade.desk.common.feign.MesNotifyMessageClient;
import org.springblade.desk.common.pojo.entity.MesNotifyMessageEntity;
import org.springblade.desk.process.excel.FmProjectMilestoneExcel; import org.springblade.desk.process.excel.FmProjectMilestoneExcel;
import org.springblade.desk.process.mapper.FmProjectMilestoneMapper; import org.springblade.desk.process.mapper.FmProjectMilestoneMapper;
import org.springblade.desk.process.pojo.entity.FmProjectApplicationEntity; import org.springblade.desk.process.pojo.entity.FmProjectApplicationEntity;
import org.springblade.desk.process.pojo.entity.FmProjectMilestoneEntity; import org.springblade.desk.process.pojo.entity.FmProjectMilestoneEntity;
import org.springblade.desk.process.pojo.vo.FmProjectMilestoneVO; import org.springblade.desk.process.pojo.vo.FmProjectMilestoneVO;
import org.springblade.desk.process.service.IFmProjectApplicationService; import org.springblade.desk.process.service.IFmProjectApplicationService;
import org.springblade.desk.process.service.IFmProjectApprovalConfigService;
import org.springblade.desk.process.service.IFmProjectMilestoneService; import org.springblade.desk.process.service.IFmProjectMilestoneService;
import org.springblade.resource.feign.IAttachClient; import org.springblade.resource.feign.IAttachClient;
import org.springblade.resource.pojo.entity.Attach; import org.springblade.resource.pojo.entity.Attach;
import org.springblade.system.feign.IUserClient; import org.springblade.system.feign.IUserClient;
import org.springblade.system.pojo.entity.User; import org.springblade.system.pojo.entity.User;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* 项目里程碑 服务实现类 * 项目里程碑 服务实现类
@ -58,173 +69,310 @@ import java.util.List;
* @author BladeX * @author BladeX
* @since 2026-01-07 * @since 2026-01-07
*/ */
@Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class FmProjectMilestoneServiceImpl extends BaseServiceImpl<FmProjectMilestoneMapper, FmProjectMilestoneEntity> implements IFmProjectMilestoneService { public class FmProjectMilestoneServiceImpl extends BaseServiceImpl<FmProjectMilestoneMapper, FmProjectMilestoneEntity> implements IFmProjectMilestoneService {
@Lazy
@Resource
IFmProjectApplicationService fmProjectApplicationService;
private final IFmProjectApplicationService fmProjectApplicationService; private final IAttachClient attachClient;
private final IUserClient userClient;
private final IAttachClient attachClient; private final MesNotifyMessageClient mesNotifyMessageClient;
private final IUserClient userClient;
@Override @Override
public IPage<FmProjectMilestoneVO> selectFmProjectMilestonePage(IPage<FmProjectMilestoneVO> page, FmProjectMilestoneVO fmProjectMilestone) { public IPage<FmProjectMilestoneVO> selectFmProjectMilestonePage(IPage<FmProjectMilestoneVO> page, FmProjectMilestoneVO fmProjectMilestone) {
return page.setRecords(baseMapper.selectFmProjectMilestonePage(page, fmProjectMilestone)); return page.setRecords(baseMapper.selectFmProjectMilestonePage(page, fmProjectMilestone));
} }
@Override @Override
public List<FmProjectMilestoneExcel> exportFmProjectMilestone(Wrapper<FmProjectMilestoneEntity> queryWrapper) { public List<FmProjectMilestoneExcel> exportFmProjectMilestone(Wrapper<FmProjectMilestoneEntity> queryWrapper) {
List<FmProjectMilestoneExcel> fmProjectMilestoneList = baseMapper.exportFmProjectMilestone(queryWrapper); List<FmProjectMilestoneExcel> fmProjectMilestoneList = baseMapper.exportFmProjectMilestone(queryWrapper);
//fmProjectMilestoneList.forEach(fmProjectMilestone -> { //fmProjectMilestoneList.forEach(fmProjectMilestone -> {
// fmProjectMilestone.setTypeName(DictCache.getValue(DictEnum.YES_NO, FmProjectMilestone.getType())); // fmProjectMilestone.setTypeName(DictCache.getValue(DictEnum.YES_NO, FmProjectMilestone.getType()));
//}); //});
return fmProjectMilestoneList; return fmProjectMilestoneList;
} }
@Override @Override
public boolean sendCheck(FmProjectMilestoneEntity fmProjectMilestone) { public boolean sendCheck(FmProjectMilestoneEntity fmProjectMilestone) {
if (fmProjectMilestone != null && fmProjectMilestone.getId() != null) { if (BeanUtil.isEmpty(fmProjectMilestone) || Objects.isNull(fmProjectMilestone.getId())) {
// 如果是项目执行发送 throw new ServiceException("参数错误");
if (FmProjectMilestoneEntity.CHECK_RESULT_TREAT.equals(fmProjectMilestone.getCheckResult())) { }
fmProjectMilestone.setCheckMan(String.valueOf(AuthUtil.getUser().getUserId())); // TODO: 2026/5/27 是否手动更新
if (StringUtils.isBlank(fmProjectMilestone.getMilestoneMemo())) { FmProjectMilestoneEntity entity = getById(fmProjectMilestone.getId());
throw new ServiceException("请先维护节点信息"); if (BeanUtil.isEmpty(entity)) {
} throw new ServiceException("里程碑信息获取失败");
} }
// 如果是项目核查 if (Objects.isNull(fmProjectMilestone.getCheckResult())) {
if (FmProjectMilestoneEntity.CHECK_RESULT_OK.equals(fmProjectMilestone.getCheckResult()) || FmProjectMilestoneEntity.CHECK_RESULT_NO.equals(fmProjectMilestone.getCheckResult())) { throw new ServiceException("请选择核查结果");
// fmProjectMilestone.setCheckMan(pfUserInfo); }
if (FmProjectMilestoneEntity.CHECK_RESULT_OK.equals(fmProjectMilestone.getCheckResult())) { if (!FmProjectMilestoneEntity.CHECK_RESULT_OK.equals(fmProjectMilestone.getCheckResult()) ||
fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_TREAT); !FmProjectMilestoneEntity.CHECK_RESULT_NO.equals(fmProjectMilestone.getCheckResult())) {
fmProjectMilestone.setGradeMan(String.valueOf(AuthUtil.getUser().getUserId())); throw new ServiceException("请选择核查结果");
} }
fmProjectMilestone.setCheckTime(new Date());
}
baseMapper.updateById(fmProjectMilestone); //设置核查人为上一节点选择的审批人,校验当前登录人与上一节点所选审批人是否一致
return true; if (!entity.getNextApproverId().equals(AuthUtil.getUserId())) {
} throw new ServiceException("您不是当前里程碑的核查人");
return false; }
} fmProjectMilestone.setCheckMan(entity.getNextApproverId().toString());
@Override // 如果核查通过,需要流转到核准节点
public boolean gradeSubmit(FmProjectMilestoneEntity fmProjectMilestone) { if (FmProjectMilestoneEntity.CHECK_RESULT_OK.equals(fmProjectMilestone.getCheckResult())) {
if (fmProjectMilestone != null && fmProjectMilestone.getId() != null) { // 检查是否选择了下一节点审批人(核准人)
BladeUser bladeUser = AuthUtil.getUser(); if (Objects.isNull(fmProjectMilestone.getNextApproverId())) {
User user = userClient.userInfoById(bladeUser.getUserId()).getData(); throw new ServiceException("请选择下一节点(核准)的审批人");
fmProjectMilestone.setGradeMan(user.getRealName()); }
Double score= fmProjectMilestone.getScore(); R<User> userR = userClient.userInfoById(fmProjectMilestone.getNextApproverId());
fmProjectMilestone.setScore(score); if (!userR.isSuccess() || BeanUtil.isEmpty(userR.getData())) {
throw new RuntimeException("下一节点(核准)的审批人不存在");
if (score > 95) { }
fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_Y);
} else if (score >= 85 && score <= 95) { // 设置核准人为选择的审批人
fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_L); fmProjectMilestone.setGradeMan(userR.getData().getRealName());
} else if (score >= 75 && score <= 84) { fmProjectMilestone.setGradeManId(fmProjectMilestone.getNextApproverId());
fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_Z); // 设置评价状态为待评价
} else { fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_TREAT);
fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_C);
} //向下一节点审批人发送消息
fmProjectMilestone.setOkTime(new Date()); sendNotificationToNextApproverA(fmProjectMilestone);
fmProjectMilestone.setEvaluate(fmProjectMilestone.getEvolve()); }
// 如果评价分数在75分以上,并且执行类型不是延期。则代表本节点已经完成
if (score < 75 && !FmProjectMilestoneEntity.EXECUTE_RESULT_YQ.equals(fmProjectMilestone.getExecuteResult())) { fmProjectMilestone.setCheckTime(new Date());
fmProjectMilestone.setCheckResult(FmProjectMilestoneEntity.CHECK_RESULT_TREAT);
baseMapper.updateById(fmProjectMilestone); baseMapper.updateById(fmProjectMilestone);
return true; return true;
}
baseMapper.updateById(fmProjectMilestone); }
// 如果选择的是延期,则生成一条新的里程碑,此里程碑关闭 // 与旧mes一致
if (FmProjectMilestoneEntity.EXECUTE_RESULT_YQ.equals(fmProjectMilestone.getExecuteResult())) { @Override
FmProjectMilestoneEntity projectMilestoneClone = BeanUtil.copyProperties(fmProjectMilestone, FmProjectMilestoneEntity.class); public boolean gradeSubmit(FmProjectMilestoneEntity fmProjectMilestone) {
projectMilestoneClone.setId(null); if (BeanUtil.isEmpty(fmProjectMilestone) || Objects.isNull(fmProjectMilestone.getId())) {
projectMilestoneClone.setDelayDate(Boolean.TRUE); throw new ServiceException("参数错误");
String paIndex = fmProjectMilestone.getPaIndex(); }
Double paIndexDou = Double.valueOf(paIndex) + 0.01;
String format = "0"; BladeUser bladeUser = AuthUtil.getUser();
if (paIndexDou >= 2) { User user = userClient.userInfoById(bladeUser.getUserId()).getData();
paIndexDou = paIndexDou + 0.001; //检查当前登录人与评价人一致
format = String.format("%.2f",paIndexDou); if (!user.getId().equals(fmProjectMilestone.getNextApproverId())) {
}else { throw new ServiceException("您不是当前里程碑的评价人");
format = String.format("%.3f",paIndexDou); }
}
projectMilestoneClone.setPaIndex(format); fmProjectMilestone.setGradeMan(user.getRealName());
Double score = fmProjectMilestone.getScore();
projectMilestoneClone.setMilestoneNode(fmProjectMilestone.getDelayTime()); fmProjectMilestone.setScore(score);
projectMilestoneClone.setGrade((short) 0);
projectMilestoneClone.setScore((double) 0); if (score > 95.0) {
projectMilestoneClone.setExecuteResult((short) 0); fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_Y);
projectMilestoneClone.setDelayTime(null); } else if (score >= 85.0) {
projectMilestoneClone.setCheckResult((short) 0); fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_L);
projectMilestoneClone.setCheckMan(null); } else if (score >= 75.0 && score <= 84.0) {
projectMilestoneClone.setCheckTime(null); fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_Z);
projectMilestoneClone.setGradeMan(null); } else {
projectMilestoneClone.setEvaluate(null); fmProjectMilestone.setGrade(FmProjectMilestoneEntity.GRADE_C);
projectMilestoneClone.setOkTime(null); }
projectMilestoneClone.setUpdateTime(new Date());
baseMapper.insert(projectMilestoneClone); fmProjectMilestone.setOkTime(new Date());
} else { fmProjectMilestone.setEvaluate(fmProjectMilestone.getEvolve());
// 获取所有得节点信息,看是否都已经完成
FmProjectApplicationEntity fmProjectApplication = new FmProjectApplicationEntity(); // 如果评价分数在75分以上,并且执行类型不是延期。则代表本节点已经完成
List<FmProjectMilestoneEntity> fmProjectMilestoneList = baseMapper if (score < 75 && !FmProjectMilestoneEntity.EXECUTE_RESULT_YQ.equals(fmProjectMilestone.getExecuteResult())) {
.selectList(new QueryWrapper<FmProjectMilestoneEntity>().lambda() fmProjectMilestone.setCheckResult(FmProjectMilestoneEntity.CHECK_RESULT_TREAT);
.eq(FmProjectMilestoneEntity::getPaId,fmProjectMilestone.getPaId())); baseMapper.updateById(fmProjectMilestone);
Boolean isOk = Boolean.TRUE; return true;
if (fmProjectMilestoneList != null && fmProjectMilestoneList.size() > 0) { }
for (FmProjectMilestoneEntity projectMilestone : fmProjectMilestoneList) { baseMapper.updateById(fmProjectMilestone);
if (FmProjectMilestoneEntity.GRADE_NO.equals(projectMilestone.getGrade())) {
isOk = Boolean.FALSE; // 如果选择的是延期,则生成一条新的里程碑,此里程碑关闭
} if (FmProjectMilestoneEntity.EXECUTE_RESULT_YQ.equals(fmProjectMilestone.getExecuteResult())) {
} FmProjectMilestoneEntity projectMilestoneClone = BeanUtil.copyProperties(fmProjectMilestone, FmProjectMilestoneEntity.class);
if (isOk) { projectMilestoneClone.setId(null);
fmProjectApplication.setId(fmProjectMilestone.getPaId()); projectMilestoneClone.setDelayDate(Boolean.TRUE);
fmProjectApplication.setProjectEnd(new Date()); String paIndex = fmProjectMilestone.getPaIndex();
fmProjectApplication.setApprovalStatus(8L); Double paIndexDou = Double.parseDouble(paIndex) + 0.01;
fmProjectApplicationService.updateById(fmProjectApplication); String format = "0";
} if (paIndexDou >= 2) {
} paIndexDou = paIndexDou + 0.001;
} format = String.format("%.2f", paIndexDou);
return true; } else {
} format = String.format("%.3f", paIndexDou);
return false; }
} projectMilestoneClone.setPaIndex(format);
@Override projectMilestoneClone.setMilestoneNode(fmProjectMilestone.getDelayTime());
public boolean projectExecute(FmProjectMilestoneEntity fmProjectMilestone) { projectMilestoneClone.setGrade((short) 0);
if (fmProjectMilestone != null && fmProjectMilestone.getId() != null) { projectMilestoneClone.setScore((double) 0);
fmProjectMilestone.setUpdateTime(new Date()); projectMilestoneClone.setExecuteResult((short) 0);
baseMapper.updateById(fmProjectMilestone); projectMilestoneClone.setDelayTime(null);
//如果类型选择终止,则后面的里程碑就不需要继续执行 projectMilestoneClone.setCheckResult((short) 0);
if(fmProjectMilestone.getExecuteResult().equals(FmProjectMilestoneEntity.EXECUTE_RESULT_ZZ)){ projectMilestoneClone.setCheckMan(null);
FmProjectApplicationEntity fmProjectApplication = fmProjectMilestone.getFmProjectApplication(); projectMilestoneClone.setCheckTime(null);
String paIndex = fmProjectMilestone.getPaIndex(); projectMilestoneClone.setGradeMan(null);
List<FmProjectMilestoneEntity> fmProjectMilestoneList = baseMapper projectMilestoneClone.setEvaluate(null);
.selectList(new QueryWrapper<FmProjectMilestoneEntity>().lambda() projectMilestoneClone.setOkTime(null);
.eq(FmProjectMilestoneEntity::getPaId,fmProjectApplication.getId())); projectMilestoneClone.setUpdateTime(new Date());
for (FmProjectMilestoneEntity projectMilestone : fmProjectMilestoneList) { baseMapper.insert(projectMilestoneClone);
if(Double.valueOf(projectMilestone.getPaIndex())>Double.valueOf(paIndex)){ } else {
projectMilestone.setExecuteResult(FmProjectMilestoneEntity.EXECUTE_RESULT_ZZ); // 获取所有得节点信息,看是否都已经完成
baseMapper.updateById(projectMilestone); FmProjectApplicationEntity fmProjectApplication = new FmProjectApplicationEntity();
} List<FmProjectMilestoneEntity> fmProjectMilestoneList = baseMapper
} .selectList(Wrappers.lambdaQuery(FmProjectMilestoneEntity.class)
} .eq(FmProjectMilestoneEntity::getPaId, fmProjectMilestone.getPaId()));
return true;
} Boolean isOk = Boolean.TRUE;
return false; if (fmProjectMilestoneList != null && fmProjectMilestoneList.size() > 0) {
} for (FmProjectMilestoneEntity projectMilestone : fmProjectMilestoneList) {
if (FmProjectMilestoneEntity.GRADE_NO.equals(projectMilestone.getGrade())) {
@Override isOk = Boolean.FALSE;
public FmProjectMilestoneEntity getDetail(FmProjectMilestoneEntity fmProjectMilestone) { }
FmProjectMilestoneEntity detail=baseMapper.selectOne(Condition.getQueryWrapper(fmProjectMilestone)); }
if(detail==null){ if (isOk) {
detail=baseMapper.selectById(fmProjectMilestone.getId()); fmProjectApplication.setId(fmProjectMilestone.getPaId());
} fmProjectApplication.setProjectEnd(new Date());
FmProjectApplicationEntity fmProjectApplication=fmProjectApplicationService.getById(detail.getPaId()); fmProjectApplication.setApprovalStatus(8L);
if(StringUtils.isNotEmpty(detail.getFileId())){ fmProjectApplicationService.updateById(fmProjectApplication);
List<Attach> attachList=attachClient.listByIds(detail.getFileId()).getData(); }
detail.setAttachList(attachList); }
} }
detail.setFmProjectApplication(fmProjectApplication); return true;
return detail;
} }
@Override
@Transactional(rollbackFor = Exception.class)
public boolean projectExecute(FmProjectMilestoneEntity fmProjectMilestone) {
check(fmProjectMilestone);
// 如果执行结果为完成或延期,需要选择下一节点审批人
if (FmProjectMilestoneEntity.EXECUTE_RESULT_JXSQ.equals(fmProjectMilestone.getExecuteResult())
|| FmProjectMilestoneEntity.EXECUTE_RESULT_YQ.equals(fmProjectMilestone.getExecuteResult())) {
if (Objects.nonNull(fmProjectMilestone.getNextApproverId())) {
R<User> userR = userClient.userInfoById(fmProjectMilestone.getNextApproverId());
if (!userR.isSuccess() || BeanUtil.isEmpty(userR.getData())) {
throw new RuntimeException("请检查下一节点(核查)的审批人");
}
}
if (Objects.isNull(fmProjectMilestone.getNextApproverId())) {
fmProjectMilestone.setNextApproverId(AuthUtil.getUserId());
fmProjectMilestone.setNextApproverName(AuthUtil.getNickName());
}
}
FmProjectMilestoneEntity entity = getById(fmProjectMilestone.getId());
entity.setMilestoneMemo(fmProjectMilestone.getMilestoneMemo());
entity.setEvolve(fmProjectMilestone.getEvolve());
entity.setLastPlan(fmProjectMilestone.getLastPlan());
entity.setExecuteResult(fmProjectMilestone.getExecuteResult());
entity.setDelayTime(fmProjectMilestone.getDelayTime());
entity.setUpdateTime(new Date());
updateById(entity);
//如果类型选择终止,则后面的里程碑就不需要继续执行
if (fmProjectMilestone.getExecuteResult().equals(FmProjectMilestoneEntity.EXECUTE_RESULT_ZZ)) {
FmProjectApplicationEntity fmProjectApplication = fmProjectMilestone.getFmProjectApplication();
String paIndex = fmProjectMilestone.getPaIndex();
List<FmProjectMilestoneEntity> fmProjectMilestoneList = baseMapper
.selectList(new QueryWrapper<FmProjectMilestoneEntity>().lambda()
.eq(FmProjectMilestoneEntity::getPaId, fmProjectApplication.getId()));
for (FmProjectMilestoneEntity projectMilestone : fmProjectMilestoneList) {
if (Double.parseDouble(projectMilestone.getPaIndex()) > Double.parseDouble(paIndex)) {
projectMilestone.setExecuteResult(FmProjectMilestoneEntity.EXECUTE_RESULT_ZZ);
baseMapper.updateById(projectMilestone);
}
}
}
//向下一节点审批人发送消息
sendNotificationToNextApprover(fmProjectMilestone);
return true;
}
private void sendNotificationToNextApprover(FmProjectMilestoneEntity fmProjectMilestone) {
try {
// 构建通知消息
String title = String.format("里程碑计划核查提醒 - %s", fmProjectMilestone.getMilestonePlan());
String content = String.format("里程碑计划核查详情, 里程碑计划:%s", fmProjectMilestone.getMilestonePlan());
// 创建通知消息实体
MesNotifyMessageEntity notifyMessage = MesNotifyMessageEntity.builder()
.title(title)
.content(content)
.receiveUserId(fmProjectMilestone.getNextApproverId())
.build();
mesNotifyMessageClient.save(notifyMessage);
} catch (Exception e) {
log.error("发送里程碑计划审批提醒异常,里程碑计划: {}", fmProjectMilestone.getMilestonePlan(), e);
}
}
private void sendNotificationToNextApproverA(FmProjectMilestoneEntity fmProjectMilestone) {
try {
// 构建通知消息
String title = String.format("里程碑计划核准提醒 - %s", fmProjectMilestone.getMilestonePlan());
String content = String.format("里程碑计划核准详情 , 里程碑计划:%s", fmProjectMilestone.getMilestonePlan());
// 创建通知消息实体
MesNotifyMessageEntity notifyMessage = MesNotifyMessageEntity.builder()
.title(title)
.content(content)
.receiveUserId(fmProjectMilestone.getNextApproverId())
.build();
mesNotifyMessageClient.save(notifyMessage);
} catch (Exception e) {
log.error("发送里程碑计划审批提醒异常,里程碑计划: {}", fmProjectMilestone.getMilestonePlan(), e);
}
}
private void check(FmProjectMilestoneEntity fmProjectMilestone) {
if (BeanUtil.isEmpty(fmProjectMilestone) || Objects.isNull(fmProjectMilestone.getId())) {
throw new RuntimeException("参数异常");
}
if (Objects.isNull(fmProjectMilestone.getExecuteResult())) {
throw new RuntimeException("请选择执行结果");
}
// 剔除`无`选项
if (!FmProjectMilestoneEntity.executeResultMap.containsKey(fmProjectMilestone.getExecuteResult()) && !fmProjectMilestone.getExecuteResult().equals(FmProjectMilestoneEntity.EXECUTE_RESULT_NO)) {
throw new RuntimeException("请选择正确的执行结果");
}
if (StrUtil.isEmpty(fmProjectMilestone.getMilestoneMemo())) {
throw new RuntimeException("请填写里程碑描述");
}
if (StrUtil.isEmpty(fmProjectMilestone.getEvolve())) {
throw new RuntimeException("请填写进展情况");
}
if (StrUtil.isEmpty(fmProjectMilestone.getLastPlan())) {
throw new RuntimeException("请填写下一步计划");
}
if (Objects.isNull(fmProjectMilestone.getExecuteResult())) {
throw new RuntimeException("请选择执行结果");
}
if (StrUtil.isEmpty(fmProjectMilestone.getPaIndex())) {
throw new RuntimeException("请填写序号");
}
FmProjectApplicationEntity fmProjectApplication = fmProjectMilestone.getFmProjectApplication();
if (BeanUtil.isEmpty(fmProjectApplication) || Objects.isNull(fmProjectApplication.getId())) {
throw new RuntimeException("参数异常");
}
}
@Override
public FmProjectMilestoneEntity getDetail(FmProjectMilestoneEntity fmProjectMilestone) {
FmProjectMilestoneEntity detail = baseMapper.selectOne(Condition.getQueryWrapper(fmProjectMilestone));
if (detail == null) {
detail = baseMapper.selectById(fmProjectMilestone.getId());
}
FmProjectApplicationEntity fmProjectApplication = fmProjectApplicationService.getById(detail.getPaId());
if (StringUtils.isNotEmpty(detail.getFileId())) {
List<Attach> attachList = attachClient.listByIds(detail.getFileId()).getData();
detail.setAttachList(attachList);
}
detail.setFmProjectApplication(fmProjectApplication);
return detail;
}
} }

Loading…
Cancel
Save