|
|
@@ -0,0 +1,223 @@
|
|
|
+package com.management.platform.service.impl;
|
|
|
+
|
|
|
+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.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.mapper.ProjectClosureApplierMapper;
|
|
|
+import com.management.platform.mapper.ProjectClosureApplyMapper;
|
|
|
+import com.management.platform.mapper.ProjectClosureApprovalLogMapper;
|
|
|
+import com.management.platform.mapper.ProjectClosureAttachmentMapper;
|
|
|
+import com.management.platform.service.ProjectClosureApplyService;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * 项目结项申请表 服务实现类
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author Seyason
|
|
|
+ * @since 2026-05-12
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class ProjectClosureApplyServiceImpl extends ServiceImpl<ProjectClosureApplyMapper, ProjectClosureApply> implements ProjectClosureApplyService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ProjectClosureApplierMapper closureApplierMapper;
|
|
|
+ @Resource
|
|
|
+ private ProjectClosureApprovalLogMapper approvalLogMapper;
|
|
|
+ @Resource
|
|
|
+ private ProjectClosureAttachmentMapper attachmentMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public ProjectClosureApply submitApply(Long projectId, Long userId, String reason, List<Long> attachmentIds) {
|
|
|
+ // 1. 获取项目信息(需要通过项目Service获取实际项目名称和编码)
|
|
|
+ String projectName = "项目-" + projectId;
|
|
|
+ String projectCode = "CODE-" + projectId;
|
|
|
+
|
|
|
+ // 2. 创建申请记录
|
|
|
+ ProjectClosureApply apply = new ProjectClosureApply();
|
|
|
+ apply.setProjectId(projectId);
|
|
|
+ apply.setProjectName(projectName);
|
|
|
+ apply.setProjectCode(projectCode);
|
|
|
+ apply.setApplicantId(userId);
|
|
|
+ apply.setApplicantName("用户" + userId); // TODO: 从用户表查询
|
|
|
+ apply.setCurrentStep(0);
|
|
|
+ apply.setApprovalStatus(0); // 待审批
|
|
|
+ apply.setRemark(reason);
|
|
|
+ apply.setCreateTime(LocalDateTime.now());
|
|
|
+ apply.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ // 保存申请记录
|
|
|
+ this.save(apply);
|
|
|
+
|
|
|
+ // 3. 保存附件
|
|
|
+ if (!CollectionUtils.isEmpty(attachmentIds)) {
|
|
|
+ for (Long attachmentId : attachmentIds) {
|
|
|
+ // TODO: 从附件Service获取附件信息并保存到project_closure_attachment表
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 获取审批流程,设置第一个审批人
|
|
|
+ this.setNextApprover(apply.getId());
|
|
|
+
|
|
|
+ return apply;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ProjectClosureApplier> getApprovalFlow(Long timeTypeId) {
|
|
|
+ QueryWrapper<ProjectClosureApplier> wrapper = new QueryWrapper<>();
|
|
|
+ wrapper.eq("time_type_id", timeTypeId)
|
|
|
+ .eq("status", 1) // 启用状态
|
|
|
+ .orderByAsc("sort_order");
|
|
|
+ return closureApplierMapper.selectList(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public boolean approve(Long applyId, Long applierId, String comment, Integer action) {
|
|
|
+ // 1. 获取申请记录
|
|
|
+ ProjectClosureApply apply = this.getById(applyId);
|
|
|
+ if (apply == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 检查是否是当前审批人
|
|
|
+ if (!applierId.equals(apply.getCurrentApproverId())) {
|
|
|
+ throw new RuntimeException("您不是当前审批人");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 创建审批记录
|
|
|
+ ProjectClosureApprovalLog log = new ProjectClosureApprovalLog();
|
|
|
+ log.setApplyId(applyId);
|
|
|
+ log.setApproverId(applierId);
|
|
|
+ log.setApproverName("用户" + applierId); // TODO: 从用户表查询
|
|
|
+ log.setAction(action);
|
|
|
+ log.setOpinion(comment);
|
|
|
+ log.setCreateTime(LocalDateTime.now());
|
|
|
+ approvalLogMapper.insert(log);
|
|
|
+
|
|
|
+ // 4. 根据审批结果处理
|
|
|
+ if (action == 1) { // 同意
|
|
|
+ apply.setCurrentStep(apply.getCurrentStep() + 1);
|
|
|
+
|
|
|
+ // 检查是否还有下一个审批人
|
|
|
+ ProjectClosureApplier nextApplier = this.getNextApprover(apply.getProjectId(), apply.getCurrentStep());
|
|
|
+ if (nextApplier != null) {
|
|
|
+ // 还有下一个审批人
|
|
|
+ apply.setCurrentApproverId(nextApplier.getApproverUserId());
|
|
|
+ apply.setCurrentApproverName(nextApplier.getApproverName());
|
|
|
+ apply.setApprovalStatus(1); // 审批中
|
|
|
+ this.updateById(apply);
|
|
|
+ } else {
|
|
|
+ // 所有审批人都同意
|
|
|
+ apply.setApprovalStatus(2); // 已通过
|
|
|
+ this.updateById(apply);
|
|
|
+ // 调用审批通过回调
|
|
|
+ this.onApprovalPassed(applyId);
|
|
|
+ }
|
|
|
+ } else { // 驳回
|
|
|
+ apply.setApprovalStatus(3); // 已驳回
|
|
|
+ this.updateById(apply);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getProgress(Long applyId) {
|
|
|
+ ProjectClosureApply apply = this.getById(applyId);
|
|
|
+ if (apply == null) {
|
|
|
+ return new HashMap<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Object> progress = new HashMap<>();
|
|
|
+ progress.put("apply", apply);
|
|
|
+ progress.put("logs", approvalLogMapper.selectList(
|
|
|
+ new QueryWrapper<ProjectClosureApprovalLog>()
|
|
|
+ .eq("apply_id", applyId)
|
|
|
+ .orderByDesc("create_time")
|
|
|
+ ));
|
|
|
+
|
|
|
+ // 获取审批流程
|
|
|
+ ProjectClosureApply actualApply = this.getById(applyId);
|
|
|
+ // TODO: 需要通过项目ID获取timeTypeId,然后获取审批流程
|
|
|
+ List<ProjectClosureApplier> flow = new ArrayList<>();
|
|
|
+ progress.put("flow", flow);
|
|
|
+
|
|
|
+ return progress;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ProjectClosureApprovalLog> getApprovalLogs(Long applyId) {
|
|
|
+ return approvalLogMapper.selectList(
|
|
|
+ new QueryWrapper<ProjectClosureApprovalLog>()
|
|
|
+ .eq("apply_id", applyId)
|
|
|
+ .orderByDesc("create_time")
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<ProjectClosureApply> getMyPendingApproval(Long userId, int current, int size) {
|
|
|
+ Page<ProjectClosureApply> page = new Page<>(current, size);
|
|
|
+ QueryWrapper<ProjectClosureApply> wrapper = new QueryWrapper<>();
|
|
|
+ wrapper.eq("current_approver_id", userId)
|
|
|
+ .in("approval_status", 0, 1) // 待审批或审批中
|
|
|
+ .orderByDesc("create_time");
|
|
|
+ return this.page(page, wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<ProjectClosureApply> getMyApplyList(Long userId, int current, int size) {
|
|
|
+ Page<ProjectClosureApply> page = new Page<>(current, size);
|
|
|
+ QueryWrapper<ProjectClosureApply> wrapper = new QueryWrapper<>();
|
|
|
+ wrapper.eq("applicant_id", userId)
|
|
|
+ .orderByDesc("create_time");
|
|
|
+ return this.page(page, wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void onApprovalPassed(Long applyId) {
|
|
|
+ // 审批通过后,更新项目状态
|
|
|
+ ProjectClosureApply apply = this.getById(applyId);
|
|
|
+ if (apply != null) {
|
|
|
+ // TODO: 调用项目Service更新项目状态为"已结项"
|
|
|
+ // projectService.updateStatus(apply.getProjectId(), ProjectStatus.CLOSED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取下一个审批人
|
|
|
+ */
|
|
|
+ private ProjectClosureApplier getNextApprover(Long projectId, int currentStep) {
|
|
|
+ // TODO: 需要通过项目获取timeTypeId,然后查询审批人
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置下一个审批人
|
|
|
+ */
|
|
|
+ private void setNextApprover(Long applyId) {
|
|
|
+ ProjectClosureApply apply = this.getById(applyId);
|
|
|
+ if (apply != null) {
|
|
|
+ ProjectClosureApplier firstApprover = this.getNextApprover(apply.getProjectId(), 0);
|
|
|
+ if (firstApprover != null) {
|
|
|
+ apply.setCurrentApproverId(firstApprover.getApproverUserId());
|
|
|
+ apply.setCurrentApproverName(firstApprover.getApproverName());
|
|
|
+ this.updateById(apply);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|