|
@@ -0,0 +1,344 @@
|
|
|
+package com.dragoninfo.dcuc.auth.business.impl.zerotrust;
|
|
|
+
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.lang.Assert;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.dragoninfo.dcuc.auth.api.vo.zerotrust.ZeroTrustMessageRespVO;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.constance.zerotrust.approval.ApprovalConstance;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.dto.zerotrust.approval.*;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.entity.RoleInfo;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.entity.zerotrust.ApprovalResult;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.entity.zerotrust.RoleOperateContent;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.enumresources.zerotrust.approval.*;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.service.IRoleInfoService;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.service.zerotrust.IApprovalResultService;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.service.zerotrust.IRoleOperateApplyService;
|
|
|
+import com.dragoninfo.dcuc.auth.auth.vo.zerotrust.approval.ApprovalCallBackReqVO;
|
|
|
+import com.dragoninfo.dcuc.auth.business.zerotrust.IApprovalBusiness;
|
|
|
+import com.dragoninfo.dcuc.auth.business.zerotrust.IApproveRemoteCallBusiness;
|
|
|
+import com.dragoninfo.dcuc.auth.config.zerotrust.ApprovalProperties;
|
|
|
+import com.dragoninfo.dcuc.auth.constance.AuthRedisConstant;
|
|
|
+import com.dragoninfo.dcuc.auth.sub.enumresource.OperateTypeEnum;
|
|
|
+import com.dragoninfo.dcuc.common.enums.UserExtInfoEnum;
|
|
|
+import com.dragoninfo.dcuc.common.utils.ResponseUtil;
|
|
|
+import com.dragoninfo.dcuc.common.utils.SecurityUserUtil;
|
|
|
+import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
|
|
|
+import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
|
|
|
+import com.dragonsoft.duceap.base.utils.UserContextUtils;
|
|
|
+import com.dragonsoft.duceap.commons.util.ObjectUtils;
|
|
|
+import com.dragonsoft.duceap.commons.util.date.DateConst;
|
|
|
+import com.dragonsoft.duceap.commons.util.date.DateUtils;
|
|
|
+import com.dragonsoft.duceap.commons.util.enums.EnumUtils;
|
|
|
+import com.dragonsoft.duceap.commons.util.string.StringUtils;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 审批操作业务类
|
|
|
+ *
|
|
|
+ * @author mazq
|
|
|
+ * @date 2023/4/4
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class ApprovalBusinessImpl implements IApprovalBusiness {
|
|
|
+
|
|
|
+ private IRoleInfoService roleInfoService;
|
|
|
+
|
|
|
+ private ApprovalProperties approvalProperties;
|
|
|
+
|
|
|
+ private IRoleOperateApplyService roleOperateApplyService;
|
|
|
+
|
|
|
+ private IApprovalResultService approvalResultService;
|
|
|
+
|
|
|
+ private StringRedisTemplate stringRedisTemplate;
|
|
|
+
|
|
|
+ private IApproveRemoteCallBusiness approveRemoteCallBusiness;
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setApproveRemoteCallBusiness(IApproveRemoteCallBusiness approveRemoteCallBusiness) {
|
|
|
+ this.approveRemoteCallBusiness = approveRemoteCallBusiness;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
|
|
|
+ this.stringRedisTemplate = stringRedisTemplate;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setApprovalResultService(IApprovalResultService approvalResultService) {
|
|
|
+ this.approvalResultService = approvalResultService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setRoleInfoService(IRoleInfoService roleInfoService) {
|
|
|
+ this.roleInfoService = roleInfoService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setApprovalProperties(ApprovalProperties approvalProperties) {
|
|
|
+ this.approvalProperties = approvalProperties;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setRoleOperateApplyService(IRoleOperateApplyService roleOperateApplyService) {
|
|
|
+ this.roleOperateApplyService = roleOperateApplyService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResponseDTO<FlowApplyRespDTO> approvalFlowApply(FlowApplyReqDto flowApplyReqDto, String businessKey) {
|
|
|
+ String appTokenId = SecurityUserUtil.getUserExtInfoValue(UserExtInfoEnum.APP_TOKEN_ID);
|
|
|
+ flowApplyReqDto.setAppTokenId(appTokenId);
|
|
|
+
|
|
|
+ // 设置流程定义类型
|
|
|
+ String processDefId = flowApplyReqDto.getProcessDefId();
|
|
|
+ String applyType = processDefId;
|
|
|
+ if (ApprovalApplyTypeEnum.ROLE_OPERATE.getValue().equals(processDefId)) {
|
|
|
+ processDefId = approvalProperties.getRoleOperateDefId();
|
|
|
+ } else {
|
|
|
+ return ResponseDTO.fail("未定义的流程类型", (Object) null);
|
|
|
+ }
|
|
|
+ flowApplyReqDto.setProcessDefId(processDefId);
|
|
|
+
|
|
|
+ // 设置回调地址
|
|
|
+ flowApplyReqDto.setCallbackUrl(approvalProperties.getCallBackUrl());
|
|
|
+
|
|
|
+ // 设置taskId和签名值
|
|
|
+ setTaskId(flowApplyReqDto);
|
|
|
+
|
|
|
+ // 提交审批流程
|
|
|
+ ResponseDTO<FlowApplyRespDTO> flowApplyResponseDTO = approveRemoteCallBusiness.flowApply(flowApplyReqDto);
|
|
|
+
|
|
|
+ // 申请成功维护业务标识、业务类型和流程实例id的关系
|
|
|
+ if (ResponseUtil.isSuccess(flowApplyResponseDTO)) {
|
|
|
+ FlowApplyRespDTO flowApplyRespDTO = ResponseUtil.getResult(flowApplyResponseDTO);
|
|
|
+ String processInstId = flowApplyRespDTO.getProcessInstId();
|
|
|
+ saveApprovalResult(flowApplyReqDto, businessKey, processDefId, applyType, processInstId);
|
|
|
+ }
|
|
|
+ return flowApplyResponseDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResponseDTO<FlowSubmitRespDTO> approvalFlowApplyAndSubmitFirst(FlowApplyReqDto applyDto, String businessKey) {
|
|
|
+ ResponseDTO<FlowApplyRespDTO> flowApplyResponseDTO = approvalFlowApply(applyDto, businessKey);
|
|
|
+ if (ResponseUtil.isFail(flowApplyResponseDTO)) {
|
|
|
+ return ResponseUtil.dtoFail(flowApplyResponseDTO.getMessage());
|
|
|
+ }
|
|
|
+ FlowApplyRespDTO flowApplyRespDTO = ResponseUtil.getResult(flowApplyResponseDTO);
|
|
|
+ List<FlowApplyItemRespDTO> reviewer = flowApplyRespDTO.getReviewer();
|
|
|
+ if (CollUtil.isEmpty(reviewer)) {
|
|
|
+ return ResponseUtil.dtoFail("无下一节点审批人信息,请检查在审批服务中的流程定义");
|
|
|
+ }
|
|
|
+ String appTokenId = SecurityUserUtil.getUserExtInfoValue(UserExtInfoEnum.APP_TOKEN_ID);
|
|
|
+ String userTokenId = SecurityUserUtil.getUserExtInfoValue(UserExtInfoEnum.USER_TOKEN_ID);
|
|
|
+
|
|
|
+ String processInstId = flowApplyRespDTO.getProcessInstId();
|
|
|
+ String taskInstId = flowApplyRespDTO.getTaskInstId();
|
|
|
+ String openId = SecurityUserUtil.getUserExtInfoValue(UserExtInfoEnum.OPEN_ID);
|
|
|
+
|
|
|
+ FlowSubmitReqDTO flowSubmitReqDTO = FlowSubmitReqDTO.builder()
|
|
|
+ .appToken(appTokenId)
|
|
|
+ .userToken(userTokenId)
|
|
|
+ .processInstId(processInstId)
|
|
|
+ .taskInstId(taskInstId)
|
|
|
+ .result(ApprovalSubmitResultEnum.AGREE.getValue())
|
|
|
+ .taskClass(applyDto.getTaskClass())
|
|
|
+ .userCode(openId)
|
|
|
+ .reviewerCode(openId)
|
|
|
+ .vars(Collections.emptyMap())
|
|
|
+ .bo(Collections.emptyMap())
|
|
|
+ .bizData(Collections.emptyMap())
|
|
|
+ .approveType(ApprovalTypeEnum.APPROVE_SERVICE.getValue())
|
|
|
+ .build();
|
|
|
+
|
|
|
+ return approveRemoteCallBusiness.flowSubmit(flowSubmitReqDTO);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void setTaskId(FlowApplyReqDto applyDto) {
|
|
|
+ String securityOrg = UserContextUtils.getCurrentUser().getSecurityOrg();
|
|
|
+ Date date = DateUtils.getDate();
|
|
|
+ String taskId = generalTaskId(securityOrg, date);
|
|
|
+ applyDto.setTaskId(taskId);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成任务ID
|
|
|
+ *
|
|
|
+ * @param orgCode 机构代码
|
|
|
+ * @param date 日期
|
|
|
+ * @return 任务ID
|
|
|
+ */
|
|
|
+ protected String generalTaskId(String orgCode, Date date) {
|
|
|
+ Assert.notBlank(orgCode);
|
|
|
+
|
|
|
+ String currTimeStr = DateUtils.getTimeStr(date, DateConst.DB_STORE_TIME);
|
|
|
+ String dateTimeStr = DateUtils.getTimeStr(date, DateConst.DB_STORE_DATE);
|
|
|
+
|
|
|
+ // 当日的
|
|
|
+ String key = AuthRedisConstant.APPROVAL_TASK_ID_PREFIX + dateTimeStr;
|
|
|
+ Boolean hasKey = stringRedisTemplate.hasKey(key);
|
|
|
+ Long taskIdNo;
|
|
|
+ // 有Key直接加1
|
|
|
+ if (hasKey != null && hasKey) {
|
|
|
+ taskIdNo = stringRedisTemplate.opsForValue().increment(key);
|
|
|
+ } else {
|
|
|
+ String existTaskId = approvalResultService.getTaskIdByTime(dateTimeStr);
|
|
|
+ if (StringUtils.isBlank(existTaskId)) {
|
|
|
+ taskIdNo = 1L;
|
|
|
+ } else {
|
|
|
+ taskIdNo = Long.valueOf(existTaskId);
|
|
|
+ taskIdNo += 1;
|
|
|
+ }
|
|
|
+ // 都保留一天,存储量很小,不用担心存储问题
|
|
|
+ Boolean setIfAbsent = stringRedisTemplate.opsForValue().setIfAbsent(key, String.valueOf(taskIdNo), 1, TimeUnit.DAYS);
|
|
|
+ if (setIfAbsent == null || !setIfAbsent) {
|
|
|
+ taskIdNo = stringRedisTemplate.opsForValue().increment(key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 格式化为8位流水号
|
|
|
+ return ApprovalConstance.TASK_ID_PREFIX + orgCode + currTimeStr + String.format("%08d", taskIdNo);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveApprovalResult(FlowApplyReqDto applyDto, String businessKey, String processDefId, String applyType,
|
|
|
+ String processInstId) {
|
|
|
+ ApprovalResult approvalResult = new ApprovalResult();
|
|
|
+ approvalResult.setBusinessKey(businessKey);
|
|
|
+ approvalResult.setApplyType(applyType);
|
|
|
+ approvalResult.setProcessDefId(processDefId);
|
|
|
+ approvalResult.setProcessInstId(processInstId);
|
|
|
+ approvalResult.setTaskId(applyDto.getTaskId());
|
|
|
+ approvalResult.setTaskIdDate(DateUtils.getCurrTimeStr(DateConst.DB_STORE_DATE));
|
|
|
+ approvalResultService.save(approvalResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResponseStatus approvalFlowCancel(String processInstId) {
|
|
|
+ String appTokenId = SecurityUserUtil.getUserExtInfoValue(UserExtInfoEnum.APP_TOKEN_ID);
|
|
|
+ FlowOperateManageReqDto flowOperateManageReqDto = new FlowOperateManageReqDto();
|
|
|
+ flowOperateManageReqDto.setAppTokenId(appTokenId);
|
|
|
+ flowOperateManageReqDto.setProcessInstId(processInstId);
|
|
|
+ flowOperateManageReqDto.setActionType(FlowActionTypeEnum.CANCEL.getValue());
|
|
|
+ return approveRemoteCallBusiness.flowManage(flowOperateManageReqDto);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResponseDTO<FlowDetailRespDTO> flowDetail(String processInstId) {
|
|
|
+ String appTokenId = SecurityUserUtil.getUserExtInfoValue(UserExtInfoEnum.APP_TOKEN_ID).toString();
|
|
|
+ return approveRemoteCallBusiness.flowDetail(appTokenId, processInstId);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ZeroTrustMessageRespVO approvalCallBack(ApprovalCallBackReqVO approvalCallBackReqVO) {
|
|
|
+ log.info("接收到的安盟审批回调信息:{}", JSONUtil.toJsonStr(approvalCallBackReqVO));
|
|
|
+
|
|
|
+ String processInstId = approvalCallBackReqVO.getProcessInstId();
|
|
|
+ String status = approvalCallBackReqVO.getStatus();
|
|
|
+ ApprovalResult approvalResult = approvalResultService.getByProcessInstId(processInstId);
|
|
|
+ if (ObjectUtils.isEmpty(approvalResult)) {
|
|
|
+ log.error("processInstId {} can't find", processInstId);
|
|
|
+ return ZeroTrustMessageRespVO.requestErrorMessage("审批单不存在");
|
|
|
+ }
|
|
|
+ String applyType = approvalResult.getApplyType();
|
|
|
+
|
|
|
+ AmCallbackStatusEnum amCallbackStatusEnum = EnumUtils.enumOf(AmCallbackStatusEnum.class, status);
|
|
|
+ String endFlag = amCallbackStatusEnum.toEndFlag();
|
|
|
+ // 无该类型,默认使用end
|
|
|
+ String type = "end";
|
|
|
+
|
|
|
+ // 角色操作申请处理
|
|
|
+ ApprovalBaseRespDto approvalBaseRespDto = new ApprovalBaseRespDto().success();
|
|
|
+ if (ApprovalApplyTypeEnum.ROLE_OPERATE.getValue().equals(applyType)) {
|
|
|
+ approvalBaseRespDto = roleOperateCallBackHandle(processInstId, type, endFlag);
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO 更新审批结果
|
|
|
+ ZeroTrustMessageRespVO zeroTrustMessageRespVO = new ZeroTrustMessageRespVO();
|
|
|
+ BeanUtil.copyProperties(approvalBaseRespDto, zeroTrustMessageRespVO);
|
|
|
+ return zeroTrustMessageRespVO;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ApprovalBaseRespDto roleOperateCallBackHandle(String processInstId, String type, String endFlag) {
|
|
|
+ RoleOperateContent roleOperateContent = roleOperateApplyService.getByProcessInstIdId(processInstId);
|
|
|
+ if (null == roleOperateContent) {
|
|
|
+ return new ApprovalBaseRespDto().success();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理角色操作结果
|
|
|
+ return handleRoleOperateApproval(roleOperateContent, type, endFlag);
|
|
|
+ }
|
|
|
+
|
|
|
+ private ApprovalBaseRespDto handleRoleOperateApproval(RoleOperateContent roleOperateContent, String type, String endFlag) {
|
|
|
+ String id = roleOperateContent.getId();
|
|
|
+ // 流程被删除对应删除本地申请
|
|
|
+ if (FlowCallBackTypeEnum.DELETE.getValue().equals(type)) {
|
|
|
+ roleOperateApplyService.delete(roleOperateContent.getId());
|
|
|
+ return new ApprovalBaseRespDto().success();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 回调修改流程状态
|
|
|
+ String approvalResult = getApplyStatus(type, endFlag);
|
|
|
+ roleOperateApplyService.updateApprovalResult(id, approvalResult);
|
|
|
+
|
|
|
+ if (!AuthApplyStatusEnum.AGREE.getValue().equals(approvalResult)) {
|
|
|
+ return new ApprovalBaseRespDto().success();
|
|
|
+ }
|
|
|
+ // 开始操作角色
|
|
|
+ String operateType = roleOperateContent.getOperateType();
|
|
|
+ if (OperateTypeEnum.ADD.getValue().equals(operateType)) {
|
|
|
+ RoleInfo roleInfo = getNewRoleInfo(roleOperateContent);
|
|
|
+ roleInfoService.save(roleInfo);
|
|
|
+ } else if (OperateTypeEnum.DELETE.getValue().equals(operateType)) {
|
|
|
+ roleInfoService.deleteRole(roleOperateContent.getRoleId());
|
|
|
+ } else if (OperateTypeEnum.UPDATE.getValue().equals(operateType)) {
|
|
|
+ RoleInfo roleInfo = getNewRoleInfo(roleOperateContent);
|
|
|
+ roleInfo.setId(roleOperateContent.getRoleId());
|
|
|
+ roleInfoService.update(roleInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ return new ApprovalBaseRespDto().success();
|
|
|
+ }
|
|
|
+
|
|
|
+ private RoleInfo getNewRoleInfo(RoleOperateContent roleOperateContent) {
|
|
|
+ RoleInfo roleInfo = new RoleInfo();
|
|
|
+ roleInfo.setAppId(roleOperateContent.getAppId());
|
|
|
+ roleInfo.setName(roleOperateContent.getName());
|
|
|
+ roleInfo.setCode(roleOperateContent.getCode());
|
|
|
+ roleInfo.setRoleLevel(roleOperateContent.getRoleLevel());
|
|
|
+ roleInfo.setRoleCategory(roleOperateContent.getRoleCategory());
|
|
|
+ roleInfo.setRoleBusiness(roleOperateContent.getRoleBusiness());
|
|
|
+ roleInfo.setIsNotLimitCount(roleOperateContent.getLimitCount());
|
|
|
+ return roleInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getApplyStatus(String type, String endFlag) {
|
|
|
+ String applyStatus = "";
|
|
|
+ if (FlowCallBackTypeEnum.CANCEL.getValue().equals(type)) {
|
|
|
+ applyStatus = AuthApplyStatusEnum.CANCEL.getValue();
|
|
|
+ } else if (FlowCallBackTypeEnum.STOP.getValue().equals(type)) {
|
|
|
+ applyStatus = AuthApplyStatusEnum.STOP.getValue();
|
|
|
+ } else if (FlowCallBackTypeEnum.END.getValue().equals(type) ||
|
|
|
+ FlowCallBackTypeEnum.EFFECTIVE.getValue().equals(type)) {
|
|
|
+ if (ApprovalEndFlagEnum.AGREE.getValue().equals(endFlag)) {
|
|
|
+ applyStatus = AuthApplyStatusEnum.AGREE.getValue();
|
|
|
+ } else {
|
|
|
+ applyStatus = AuthApplyStatusEnum.DIS_AGREE.getValue();
|
|
|
+ }
|
|
|
+ } else if (FlowCallBackTypeEnum.NONE_EFFECTIVE.getValue().equals(type)) {
|
|
|
+ applyStatus = AuthApplyStatusEnum.NOT_EFF.getValue();
|
|
|
+ }
|
|
|
+ log.info("getApplyStatus result:{} ", applyStatus);
|
|
|
+ return applyStatus;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|