|
|
@@ -4,16 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import com.management.platform.entity.Project;
|
|
|
-import com.management.platform.entity.ProjectClosureApplier;
|
|
|
-import com.management.platform.entity.ProjectClosureApply;
|
|
|
-import com.management.platform.entity.ProjectClosureApprovalLog;
|
|
|
-import com.management.platform.entity.ProjectClosureAttachment;
|
|
|
-import com.management.platform.entity.User;
|
|
|
-import com.management.platform.mapper.ProjectClosureApplierMapper;
|
|
|
+import com.management.platform.entity.*;
|
|
|
import com.management.platform.mapper.ProjectClosureApplyMapper;
|
|
|
import com.management.platform.mapper.ProjectClosureApprovalLogMapper;
|
|
|
import com.management.platform.mapper.ProjectClosureAttachmentMapper;
|
|
|
+import com.management.platform.service.ProjectClosureApplierService;
|
|
|
import com.management.platform.service.ProjectClosureApplyService;
|
|
|
import com.management.platform.service.ProjectService;
|
|
|
import com.management.platform.service.UserService;
|
|
|
@@ -26,11 +21,7 @@ import javax.annotation.Resource;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Objects;
|
|
|
+import java.util.*;
|
|
|
|
|
|
/**
|
|
|
* 项目结项申请:提交、多级审批、通过后完成项目
|
|
|
@@ -40,13 +31,13 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
|
|
|
private static final DateTimeFormatter DT_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
- @Resource
|
|
|
- private ProjectClosureApplierMapper closureApplierMapper;
|
|
|
@Resource
|
|
|
private ProjectClosureApprovalLogMapper approvalLogMapper;
|
|
|
@Resource
|
|
|
private ProjectClosureAttachmentMapper attachmentMapper;
|
|
|
@Resource
|
|
|
+ private ProjectClosureApplierService closureApplierService;
|
|
|
+ @Resource
|
|
|
private ProjectService projectService;
|
|
|
@Resource
|
|
|
private UserService userService;
|
|
|
@@ -75,10 +66,17 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
throw new RuntimeException("该项目已有进行中的结项申请");
|
|
|
}
|
|
|
Integer companyId = project.getCompanyId();
|
|
|
- List<ProjectClosureApplier> flow = getApprovalFlow(companyId);
|
|
|
+
|
|
|
+ // 获取当前启用的配置版本ID
|
|
|
+ Integer configId = closureApplierService.getActiveConfigId(companyId);
|
|
|
+ if (configId == null) {
|
|
|
+ throw new RuntimeException("未配置结项审批流程,请在系统设置中配置后再申请");
|
|
|
+ }
|
|
|
+ List<ProjectClosureApplier> flow = closureApplierService.getFlowByConfigId(configId);
|
|
|
if (CollectionUtils.isEmpty(flow)) {
|
|
|
- throw new RuntimeException("未配置结项审批人,请在系统设置中配置后再申请");
|
|
|
+ throw new RuntimeException("审批流程节点为空,请在系统设置中配置后再申请");
|
|
|
}
|
|
|
+
|
|
|
User applicant = userService.getById(userId);
|
|
|
String applicantName = applicant != null && StringUtils.hasText(applicant.getName()) ? applicant.getName() : userId;
|
|
|
|
|
|
@@ -91,12 +89,19 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
apply.setCurrentStep(0);
|
|
|
apply.setApprovalStatus(1);
|
|
|
apply.setRemark(reason);
|
|
|
+ apply.setConfigId(configId);
|
|
|
+ apply.setTotalStep(flow.size());
|
|
|
apply.setCreateTime(LocalDateTime.now());
|
|
|
apply.setUpdateTime(LocalDateTime.now());
|
|
|
|
|
|
ProjectClosureApplier first = flow.get(0);
|
|
|
- apply.setCurrentApproverId(first.getApproverUserId());
|
|
|
- apply.setCurrentApproverName(first.getApproverName());
|
|
|
+ if (StringUtils.hasText(first.getApproverUserId())) {
|
|
|
+ apply.setCurrentApproverId(first.getApproverUserId());
|
|
|
+ apply.setCurrentApproverName(first.getApproverName());
|
|
|
+ } else {
|
|
|
+ apply.setCurrentApproverId(first.getRoleId());
|
|
|
+ apply.setCurrentApproverName(first.getApproverName());
|
|
|
+ }
|
|
|
|
|
|
this.save(apply);
|
|
|
|
|
|
@@ -134,22 +139,10 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
attachmentMapper.insert(attachment);
|
|
|
}
|
|
|
}
|
|
|
- decorateApply(apply, userId, companyId);
|
|
|
+ decorateApply(apply, userId);
|
|
|
return apply;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public List<ProjectClosureApplier> getApprovalFlow(Integer companyId) {
|
|
|
- if (companyId == null) {
|
|
|
- return new ArrayList<>();
|
|
|
- }
|
|
|
- QueryWrapper<ProjectClosureApplier> wrapper = new QueryWrapper<>();
|
|
|
- wrapper.eq("company_id", companyId)
|
|
|
- .eq("status", 1)
|
|
|
- .orderByAsc("sort_order");
|
|
|
- return closureApplierMapper.selectList(wrapper);
|
|
|
- }
|
|
|
-
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public boolean approve(Integer applyId, String applierId, String comment, Integer action) {
|
|
|
@@ -160,9 +153,6 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
if (apply == null) {
|
|
|
return false;
|
|
|
}
|
|
|
- if (!Objects.equals(applierId, apply.getCurrentApproverId())) {
|
|
|
- throw new RuntimeException("您不是当前审批人");
|
|
|
- }
|
|
|
int as = apply.getApprovalStatus() == null ? -1 : apply.getApprovalStatus();
|
|
|
if (as != 0 && as != 1) {
|
|
|
throw new RuntimeException("该申请已结束审批");
|
|
|
@@ -182,10 +172,29 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
log.setCreateTime(LocalDateTime.now());
|
|
|
approvalLogMapper.insert(log);
|
|
|
|
|
|
- Project project = projectService.getById(apply.getProjectId());
|
|
|
- Integer companyId = project != null ? project.getCompanyId() : null;
|
|
|
- List<ProjectClosureApplier> flow = companyId != null ? getApprovalFlow(companyId) : new ArrayList<>();
|
|
|
+ // 根据申请绑定的 configId 获取审批流程(不取最新配置)
|
|
|
+ List<ProjectClosureApplier> flow = closureApplierService.getFlowByConfigId(apply.getConfigId());
|
|
|
+ if (CollectionUtils.isEmpty(flow)) {
|
|
|
+ throw new RuntimeException("审批流程配置不存在");
|
|
|
+ }
|
|
|
+ int currentStepIndex = apply.getCurrentStep() == null ? 0 : apply.getCurrentStep();
|
|
|
+ ProjectClosureApplier currentNode = currentStepIndex < flow.size() ? flow.get(currentStepIndex) : null;
|
|
|
+ if (currentNode == null) {
|
|
|
+ throw new RuntimeException("当前审批节点不存在");
|
|
|
+ }
|
|
|
+ boolean allowed = false;
|
|
|
+ if (StringUtils.hasText(currentNode.getApproverUserId())) {
|
|
|
+ allowed = Objects.equals(applierId, currentNode.getApproverUserId());
|
|
|
+ } else if (StringUtils.hasText(currentNode.getRoleId())) {
|
|
|
+ User currentUser = userService.getById(applierId);
|
|
|
+ allowed = currentUser != null && currentUser.getRoleId() != null
|
|
|
+ && Objects.equals(String.valueOf(currentUser.getRoleId()), currentNode.getRoleId());
|
|
|
+ }
|
|
|
+ if (!allowed) {
|
|
|
+ throw new RuntimeException("您不是当前审批人");
|
|
|
+ }
|
|
|
|
|
|
+ Project project = projectService.getById(apply.getProjectId());
|
|
|
if (reject) {
|
|
|
apply.setApprovalStatus(3);
|
|
|
apply.setUpdateTime(LocalDateTime.now());
|
|
|
@@ -213,8 +222,13 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
onApprovalPassed(applyId);
|
|
|
} else {
|
|
|
ProjectClosureApplier next = flow.get(nextStepIndex);
|
|
|
- apply.setCurrentApproverId(next.getApproverUserId());
|
|
|
- apply.setCurrentApproverName(next.getApproverName());
|
|
|
+ if (StringUtils.hasText(next.getApproverUserId())) {
|
|
|
+ apply.setCurrentApproverId(next.getApproverUserId());
|
|
|
+ apply.setCurrentApproverName(next.getApproverName());
|
|
|
+ } else {
|
|
|
+ apply.setCurrentApproverId(next.getRoleId());
|
|
|
+ apply.setCurrentApproverName(StringUtils.hasText(next.getApproverName()) ? next.getApproverName() : next.getRoleId());
|
|
|
+ }
|
|
|
apply.setApprovalStatus(1);
|
|
|
apply.setUpdateTime(LocalDateTime.now());
|
|
|
this.updateById(apply);
|
|
|
@@ -229,22 +243,34 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
if (apply == null) {
|
|
|
return progress;
|
|
|
}
|
|
|
- Project project = projectService.getById(apply.getProjectId());
|
|
|
- Integer companyId = project != null ? project.getCompanyId() : null;
|
|
|
- List<ProjectClosureApplier> flowList = companyId != null ? getApprovalFlow(companyId) : new ArrayList<>();
|
|
|
+ List<ProjectClosureApplier> flowList = closureApplierService.getFlowByConfigId(apply.getConfigId());
|
|
|
List<Map<String, Object>> flow = new ArrayList<>();
|
|
|
for (int i = 0; i < flowList.size(); i++) {
|
|
|
ProjectClosureApplier step = flowList.get(i);
|
|
|
Map<String, Object> row = new HashMap<>();
|
|
|
row.put("approverName", step.getApproverName());
|
|
|
row.put("approverUserId", step.getApproverUserId());
|
|
|
+ row.put("roleId", step.getRoleId());
|
|
|
+ row.put("nodeType", StringUtils.hasText(step.getApproverUserId()) ? "USER" : "ROLE");
|
|
|
+ row.put("displayName", StringUtils.hasText(step.getApproverUserId()) ? step.getApproverName() : (StringUtils.hasText(step.getApproverName()) ? step.getApproverName() : step.getRoleId()));
|
|
|
row.put("stepOrder", i);
|
|
|
flow.add(row);
|
|
|
}
|
|
|
progress.put("flow", flow);
|
|
|
- boolean canApprove = StringUtils.hasText(viewerUserId)
|
|
|
- && Objects.equals(viewerUserId, apply.getCurrentApproverId())
|
|
|
- && (apply.getApprovalStatus() != null && (apply.getApprovalStatus() == 0 || apply.getApprovalStatus() == 1));
|
|
|
+ boolean canApprove = false;
|
|
|
+ if (StringUtils.hasText(viewerUserId) && (apply.getApprovalStatus() != null && (apply.getApprovalStatus() == 0 || apply.getApprovalStatus() == 1))) {
|
|
|
+ int currentStepIndex = apply.getCurrentStep() == null ? 0 : apply.getCurrentStep();
|
|
|
+ ProjectClosureApplier currentNode = currentStepIndex < flowList.size() ? flowList.get(currentStepIndex) : null;
|
|
|
+ if (currentNode != null) {
|
|
|
+ if (StringUtils.hasText(currentNode.getApproverUserId())) {
|
|
|
+ canApprove = Objects.equals(viewerUserId, currentNode.getApproverUserId());
|
|
|
+ } else if (StringUtils.hasText(currentNode.getRoleId())) {
|
|
|
+ User currentUser = userService.getById(viewerUserId);
|
|
|
+ canApprove = currentUser != null && currentUser.getRoleId() != null
|
|
|
+ && Objects.equals(String.valueOf(currentUser.getRoleId()), currentNode.getRoleId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
progress.put("canApprove", canApprove);
|
|
|
return progress;
|
|
|
}
|
|
|
@@ -275,7 +301,15 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
Integer companyId = viewer.getCompanyId();
|
|
|
QueryWrapper<ProjectClosureApply> wrapper = new QueryWrapper<>();
|
|
|
wrapper.inSql("project_id", "select id from project where company_id = " + companyId)
|
|
|
- .and(w -> w.eq("current_approver_id", userId).or().eq("applicant_id", userId));
|
|
|
+ .and(w -> {
|
|
|
+ w.eq("applicant_id", userId)
|
|
|
+ .or()
|
|
|
+ .eq("current_approver_id", userId);
|
|
|
+ if (viewer.getRoleId() != null) {
|
|
|
+ w.or().eq("current_approver_id", String.valueOf(viewer.getRoleId()));
|
|
|
+ }
|
|
|
+ return w;
|
|
|
+ });
|
|
|
if (StringUtils.hasText(projectKeyword)) {
|
|
|
wrapper.like("project_name", projectKeyword.trim());
|
|
|
}
|
|
|
@@ -292,7 +326,7 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
wrapper.orderByDesc("create_time");
|
|
|
IPage<ProjectClosureApply> result = this.page(page, wrapper);
|
|
|
for (ProjectClosureApply row : result.getRecords()) {
|
|
|
- decorateApply(row, userId, companyId);
|
|
|
+ decorateApply(row, userId);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
@@ -310,7 +344,7 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
wrapper.orderByDesc("create_time");
|
|
|
IPage<ProjectClosureApply> result = this.page(page, wrapper);
|
|
|
for (ProjectClosureApply row : result.getRecords()) {
|
|
|
- decorateApply(row, userId, companyId);
|
|
|
+ decorateApply(row, userId);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
@@ -335,11 +369,8 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
if (apply == null) {
|
|
|
return null;
|
|
|
}
|
|
|
- Project project = projectService.getById(apply.getProjectId());
|
|
|
- Integer companyId = project != null ? project.getCompanyId() : null;
|
|
|
- decorateApply(apply, viewerUserId, companyId);
|
|
|
+ decorateApply(apply, viewerUserId);
|
|
|
|
|
|
- // 查询附件列表
|
|
|
List<ProjectClosureAttachment> attachments = attachmentMapper.selectList(
|
|
|
new QueryWrapper<ProjectClosureAttachment>()
|
|
|
.eq("apply_id", id)
|
|
|
@@ -349,8 +380,10 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
return apply;
|
|
|
}
|
|
|
|
|
|
- private void decorateApply(ProjectClosureApply apply, String viewerUserId, Integer companyId) {
|
|
|
- int total = companyId != null ? getApprovalFlow(companyId).size() : 0;
|
|
|
+ private void decorateApply(ProjectClosureApply apply, String viewerUserId) {
|
|
|
+ // 从申请绑定的 configId 获取审批流程
|
|
|
+ List<ProjectClosureApplier> flow = closureApplierService.getFlowByConfigId(apply.getConfigId());
|
|
|
+ int total = flow.size();
|
|
|
apply.setTotalStep(total);
|
|
|
apply.setReason(apply.getRemark());
|
|
|
apply.setCurrentApplierName(apply.getCurrentApproverName());
|
|
|
@@ -374,17 +407,12 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
int cs = apply.getCurrentStep() == null ? 0 : apply.getCurrentStep();
|
|
|
apply.setCurrentStepDisplay(total > 0 ? (cs + 1) + "/" + total : "-");
|
|
|
|
|
|
- // 优化当前步骤显示
|
|
|
- if (companyId != null && total > 0) {
|
|
|
- List<ProjectClosureApplier> flow = getApprovalFlow(companyId);
|
|
|
+ if (total > 0) {
|
|
|
if (s != null && s == 2) {
|
|
|
- // 已通过 - 当前步骤显示"暂无"
|
|
|
apply.setCurrentStepDisplay("暂无");
|
|
|
} else if (s != null && s == 3) {
|
|
|
- // 已拒绝 - 当前步骤显示"暂无"
|
|
|
apply.setCurrentStepDisplay("暂无");
|
|
|
} else {
|
|
|
- // 进行中 - 当前步骤显示"XXX审核"
|
|
|
if (cs < flow.size()) {
|
|
|
ProjectClosureApplier currentApplier = flow.get(cs);
|
|
|
String currentStepText = "第" + (cs + 1) + "步:" + currentApplier.getApproverName() + "审核";
|
|
|
@@ -395,9 +423,19 @@ public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureAp
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- boolean can = StringUtils.hasText(viewerUserId)
|
|
|
- && Objects.equals(viewerUserId, apply.getCurrentApproverId())
|
|
|
- && (s != null && (s == 0 || s == 1));
|
|
|
+ boolean can = false;
|
|
|
+ if (StringUtils.hasText(viewerUserId) && (s != null && (s == 0 || s == 1))) {
|
|
|
+ if (Objects.equals(viewerUserId, apply.getCurrentApproverId())) {
|
|
|
+ can = true;
|
|
|
+ }
|
|
|
+ if (!can) {
|
|
|
+ User currentUser = userService.getById(viewerUserId);
|
|
|
+ if (currentUser != null && currentUser.getRoleId() != null
|
|
|
+ && Objects.equals(String.valueOf(currentUser.getRoleId()), apply.getCurrentApproverId())) {
|
|
|
+ can = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
apply.setCanApprove(can);
|
|
|
}
|
|
|
-}
|
|
|
+}
|