| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| | |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationHandoverReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmResignationApplicationDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmResignationApplicationMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmResignationTypeEnum; |
| | | import cn.iocoder.yudao.module.hrm.service.handover.HrmUserHandoverService; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import jakarta.annotation.Resource; |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | /** |
| | | * 离职申请 Service 实现类 |
| | | * |
| | | * @author 芋道源码 |
| | | * @author 超级管理员 |
| | | */ |
| | | @Service |
| | | @Validated |
| | |
| | | @Resource |
| | | private BpmCategoryService bpmCategoryService; |
| | | @Resource |
| | | private StorageAttachmentApi storageAttachmentApi; |
| | | @Resource |
| | | private BpmProcessDefinitionService bpmProcessDefinitionService; |
| | | @Resource |
| | | private HrmUserHandoverService handoverService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | String no = generateUniqueNo(); |
| | | AdminUserRespDTO user = adminUserApi.getUser(userId); |
| | | if (user == null) { |
| | | // 传入的可能不是系统用户ID(例如员工ID),回退到当前登录用户并重新查询,避免后续 NPE |
| | | userId = getCurrentUserId(); |
| | | user = adminUserApi.getUser(userId); |
| | | } |
| | | HrmResignationApplicationDO application = BeanUtils.toBean(createReqVO, HrmResignationApplicationDO.class); |
| | | application.setNo(no); |
| | | application.setUserId(userId); |
| | | application.setDeptId(createReqVO.getDeptId() != null ? createReqVO.getDeptId() : user.getDeptId()); |
| | | // 部门:优先取请求参数,其次取账号所属部门,最后兜底 0(该列 NOT NULL) |
| | | Long deptId = createReqVO.getDeptId() != null ? createReqVO.getDeptId() |
| | | : (user != null ? user.getDeptId() : null); |
| | | application.setDeptId(deptId != null ? deptId : 0L); |
| | | application.setStatus(HrmAuditStatusEnum.DRAFT.getStatus()); |
| | | application.setHandoverStatus(HANDOVER_STATUS_NOT_STARTED); |
| | | resignationApplicationMapper.insert(application); |
| | | storageAttachmentApi.bindAttachments("file", "hrm_resignation_application", |
| | | application.getId(), createReqVO.getBlobIds()); |
| | | return application.getId(); |
| | | } |
| | | |
| | |
| | | } |
| | | HrmResignationApplicationDO updateObj = BeanUtils.toBean(updateReqVO, HrmResignationApplicationDO.class); |
| | | resignationApplicationMapper.updateById(updateObj); |
| | | storageAttachmentApi.updateAttachments("file", "hrm_resignation_application", updateReqVO.getId(), updateReqVO.getBlobIds()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) { |
| | | throw exception(RESIGNATION_APPLICATION_UPDATE_FAIL_NOT_DRAFT); |
| | | } |
| | | storageAttachmentApi.deleteAttachmentsByRecord("hrm_resignation_application", id); |
| | | resignationApplicationMapper.deleteById(id); |
| | | } |
| | | |
| | |
| | | respVO.setResignationTypeName(HrmResignationTypeEnum.getNameByStatus(application.getResignationType())); |
| | | respVO.setHandoverStatusName(getHandoverStatusName(application.getHandoverStatus())); |
| | | respVO.setStatusName(HrmAuditStatusEnum.getNameByStatus(application.getStatus())); |
| | | respVO.setAttachmentList(storageAttachmentApi.listAttachments("hrm_resignation_application", id)); |
| | | return respVO; |
| | | } |
| | | |
| | |
| | | throw exception(RESIGNATION_APPLICATION_SUBMIT_FAIL_NOT_DRAFT); |
| | | } |
| | | validateApproveCategoryAndProcessDefinition(); |
| | | ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey); |
| | | // 未指定流程定义 Key 时,自动取「离职审批」分类下最新的活跃流程,避免前端未传 key 直接报系统异常 |
| | | String key = resolveProcessDefinitionKey(processDefinitionKey); |
| | | ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(key); |
| | | if (processDefinition == null) { |
| | | throw exception(RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() |
| | | .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id))); |
| | | .setProcessDefinitionKey(key).setBusinessKey(String.valueOf(id))); |
| | | resignationApplicationMapper.updateById(HrmResignationApplicationDO.builder() |
| | | .id(id) |
| | | .processInstanceId(processInstanceId) |
| | | .status(HrmAuditStatusEnum.PROCESS.getStatus()) |
| | | .build()); |
| | | } |
| | | |
| | | /** |
| | | * 解析流程定义 Key:优先使用调用方传入值,为空时取「离职审批」分类下最新的活跃流程 |
| | | */ |
| | | private String resolveProcessDefinitionKey(String processDefinitionKey) { |
| | | if (StrUtil.isNotBlank(processDefinitionKey)) { |
| | | return processDefinitionKey.trim(); |
| | | } |
| | | List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE); |
| | | if (CollUtil.isEmpty(definitionInfoList)) { |
| | | throw exception(RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId); |
| | | List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds); |
| | | return processDefinitions.stream() |
| | | .filter(pd -> !pd.isSuspended()) |
| | | .max(Comparator.comparingInt(ProcessDefinition::getVersion)) |
| | | .map(ProcessDefinition::getKey) |
| | | .orElseThrow(() -> exception(RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS)); |
| | | } |
| | | |
| | | private void validateApproveCategoryAndProcessDefinition() { |
| | |
| | | return resignationApplicationMapper.selectByProcessInstanceId(processInstanceId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateHandoverStatus(HrmResignationHandoverReqVO reqVO) { |
| | | HrmResignationApplicationDO application = validateResignationApplicationExists(reqVO.getId()); |
| | | resignationApplicationMapper.updateById(HrmResignationApplicationDO.builder() |
| | | .id(reqVO.getId()) |
| | | .handoverStatus(reqVO.getHandoverStatus()) |
| | | .build()); |
| | | // 交接完成时,创建用户数据交接映射 |
| | | if (Objects.equals(reqVO.getHandoverStatus(), HANDOVER_STATUS_COMPLETED) |
| | | && application.getHandoverUserId() != null) { |
| | | handoverService.createHandover( |
| | | application.getUserId(), |
| | | application.getHandoverUserId(), |
| | | application.getId()); |
| | | } |
| | | } |
| | | |
| | | } |