@@ -39,7 +39,11 @@ public class RegionsCacheHelperImpl extends AbstractRegionCacheHelper implements | |||
@Override | |||
public String getRegionName(String code, int level) { | |||
return getByCodeAndLevel(code, level).getRegionName(); | |||
RegionDTO dto = getByCodeAndLevel(code, level); | |||
if(Objects.nonNull(dto)){ | |||
return dto.getRegionName(); | |||
} | |||
return StringUtils.EMPTY; | |||
} | |||
@Override | |||
@@ -1,22 +0,0 @@ | |||
package com.ningdatech.pmapi.datascope.aop; | |||
import com.ningdatech.pmapi.datascope.contants.LambdaDataScopeTypeEnum; | |||
import java.lang.annotation.*; | |||
/** | |||
* @Classname LambdaDataScope | |||
* @Description | |||
* @Date 2022/11/11 15:34 | |||
* @Created by PoffyZhang | |||
*/ | |||
@Target(ElementType.METHOD) | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Documented | |||
public @interface LambdaDataScope { | |||
LambdaDataScopeTypeEnum type() default LambdaDataScopeTypeEnum.ORG; | |||
//wrapper的下标位置 如果是分页的话 可能是第二个 | |||
int wrapperIndex() default 0; | |||
} |
@@ -1,81 +0,0 @@ | |||
package com.ningdatech.pmapi.datascope.aop; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | |||
import com.ningdatech.pmapi.datascope.model.DataScopeEntity; | |||
import com.ningdatech.pmapi.datascope.provider.DataScopeContext; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import lombok.AllArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.aspectj.lang.JoinPoint; | |||
import org.aspectj.lang.annotation.Aspect; | |||
import org.aspectj.lang.annotation.Before; | |||
import org.aspectj.lang.annotation.Pointcut; | |||
import org.springframework.core.annotation.Order; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Objects; | |||
import java.util.Optional; | |||
/** | |||
* @program: | |||
* @description: 数据权限切面 | |||
* LambdaDataScopeAspect | |||
* @author: PoffyZhang | |||
* @created: 2023/3/11 09:12 | |||
*/ | |||
@Aspect | |||
@Component | |||
@Slf4j | |||
@AllArgsConstructor | |||
@Order(10) | |||
public class LambdaDataScopeAspect { | |||
@Pointcut("@annotation(com.ningdatech.pmapi.datascope.aop.LambdaDataScope)") | |||
public void lambdaDataScopeAspect() { | |||
} | |||
@Before("lambdaDataScopeAspect() && @annotation(lambdaDataScope)") | |||
public void before(JoinPoint joinPoint, LambdaDataScope lambdaDataScope) throws Throwable { | |||
Optional<DataScopeDTO> currentUserDataScoper = getCurrentUserDataScoper(); | |||
if (!currentUserDataScoper.isPresent()) { | |||
return; | |||
} | |||
DataScopeDTO dataScopeDto = currentUserDataScoper.get(); | |||
LambdaQueryWrapper<DataScopeEntity> wrapper = | |||
(LambdaQueryWrapper) joinPoint.getArgs()[lambdaDataScope.wrapperIndex()]; | |||
if (Objects.isNull(wrapper)) { | |||
return; | |||
} | |||
switch (lambdaDataScope.type()) { | |||
case REGION: | |||
wrapper.in(CollUtil.isNotEmpty(dataScopeDto.getRegionCodes()), DataScopeEntity::getRegionCode, dataScopeDto.getRegionCodes()); | |||
break; | |||
case ORG: | |||
wrapper.in(StringUtils.isNotBlank(dataScopeDto.getOrgCode()), DataScopeEntity::getOrgCode, dataScopeDto.getOrgCode()); | |||
break; | |||
case EMPLOYEE: | |||
wrapper.in(StringUtils.isNotBlank(dataScopeDto.getEmployeeCode()), DataScopeEntity::getEmployeeCode, dataScopeDto.getEmployeeCode()); | |||
break; | |||
case NONE: | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
public Optional<DataScopeDTO> getCurrentUserDataScoper() { | |||
UserInfoDetails loginUser = LoginUserUtil.loginUserDetail(); | |||
if (Objects.isNull(loginUser) || Objects.isNull(loginUser.getRoleCode())) { | |||
return Optional.empty(); | |||
} | |||
return DataScopeContext.getDataScope(loginUser.getRoleCode().name()); | |||
} | |||
} |
@@ -1,24 +0,0 @@ | |||
package com.ningdatech.pmapi.datascope.aop; | |||
import java.lang.annotation.*; | |||
/** | |||
* @Classname XmlDataScope | |||
* xml 可以join 所以要设置 别名 | |||
* @Description | |||
* @Date 2022/11/11 15:34 | |||
* @Created by PoffyZhang | |||
*/ | |||
@Target(ElementType.METHOD) | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Documented | |||
public @interface XmlDataScope { | |||
String regionAlias() default "r"; | |||
String orgAlias() default "o"; | |||
//实体的位置 默认0 如果有分页 那么可能是第二个 | |||
int entityIndex() default 0; | |||
} |
@@ -1,97 +0,0 @@ | |||
package com.ningdatech.pmapi.datascope.aop; | |||
import cn.hutool.core.collection.CollUtil; | |||
import lombok.AllArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.aspectj.lang.JoinPoint; | |||
import org.aspectj.lang.annotation.Aspect; | |||
import org.aspectj.lang.annotation.Before; | |||
import org.aspectj.lang.annotation.Pointcut; | |||
import org.springframework.core.annotation.Order; | |||
import org.springframework.stereotype.Component; | |||
import java.lang.reflect.Field; | |||
import java.util.List; | |||
import java.util.Objects; | |||
import java.util.Optional; | |||
; | |||
/** | |||
* @program: | |||
* @description: xml sql方式 | |||
* 数据权限切面 | |||
* @author: PoffyZhang | |||
* @created: 2022/11/11 09:12 | |||
*/ | |||
@Aspect | |||
@Component | |||
@Slf4j | |||
@AllArgsConstructor | |||
@Order(10) | |||
public class XmlDataScopeAspect { | |||
// @Pointcut("@annotation(com.ningdatech.carapi.datascope.aop.XmlDataScope)") | |||
// public void xmlDataScopeAspect() { | |||
// | |||
// } | |||
// | |||
// @Before("xmlDataScopeAspect() && @annotation(xmlDataScope)") | |||
// public void before(JoinPoint joinPoint, XmlDataScope xmlDataScope) throws Throwable { | |||
// Optional<DataScopeDto> currentUserDataScoper = getCurrentUserDataScoper(); | |||
// if(!currentUserDataScoper.isPresent()){ | |||
// return; | |||
// } | |||
// DataScopeDto dataScopeDto = currentUserDataScoper.get(); | |||
// Object entity = joinPoint.getArgs()[xmlDataScope.entityIndex()]; | |||
// | |||
// if(Objects.isNull(entity)){ | |||
// return; | |||
// } | |||
// | |||
// StringBuilder sql = new StringBuilder(); | |||
// if(CollUtil.isEmpty(dataScopeDto.getCompanyIds()) | |||
// && CollUtil.isEmpty(dataScopeDto.getRegionIds())){ | |||
// return; | |||
// } | |||
// | |||
// if(CollUtil.isNotEmpty(dataScopeDto.getCompanyIds())){ | |||
// sql.append(" AND " + xmlDataScope.companyAlias() + ".id in (" | |||
// + convertForStr(dataScopeDto.getCompanyIds()) + ")"); | |||
// } | |||
// | |||
// | |||
// if(CollUtil.isNotEmpty(dataScopeDto.getRegionIds())){ | |||
// sql.append(" AND " + xmlDataScope.regionAlias() + ".id in (" | |||
// + convertForStr(dataScopeDto.getRegionIds()) + ")"); | |||
// } | |||
// | |||
// if(sql.length() > 0){ | |||
// Class<?> clazz = entity.getClass(); | |||
// Field dataScopeSql = clazz.getDeclaredField("dataScopeSql"); | |||
// dataScopeSql.setAccessible(true); | |||
// dataScopeSql.set(entity, sql.toString()); | |||
// } | |||
// } | |||
// | |||
// private String convertForStr(List<Long> companyIds) { | |||
// if(CollUtil.isEmpty(companyIds)){ | |||
// return StringUtils.EMPTY; | |||
// } | |||
// StringBuilder sql = new StringBuilder(); | |||
// for(Long companyId : companyIds){ | |||
// sql.append(companyId + ","); | |||
// } | |||
// sql.delete(sql.length()-1,sql.length()); | |||
// return sql.toString(); | |||
// } | |||
// | |||
// public Optional<DataScopeDto> getCurrentUserDataScoper(){ | |||
// UserInfoDetails loginUser = LoginUserUtil.loginUserDetail(); | |||
// if(Objects.isNull(loginUser) || Objects.isNull(loginUser.getDataScope())){ | |||
// return Optional.empty(); | |||
// } | |||
// return DataScopeContext.getDataScope(loginUser.getDataScope()); | |||
// } | |||
} |
@@ -2,6 +2,7 @@ package com.ningdatech.pmapi.datascope.utils; | |||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | |||
import com.ningdatech.pmapi.datascope.provider.DataScopeContext; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
@@ -16,11 +17,11 @@ import java.util.Optional; | |||
*/ | |||
public class DataScopeUtil { | |||
public static Optional<DataScopeDTO> getCurrentUserDataScope(UserInfoDetails loginUser) { | |||
if (Objects.isNull(loginUser) || Objects.isNull(loginUser.getRoleCode())) { | |||
public static Optional<DataScopeDTO> getCurrentUserDataScope(UserFullInfoDTO user) { | |||
if (Objects.isNull(user) || Objects.isNull(user.getRoleCode())) { | |||
return Optional.empty(); | |||
} | |||
return DataScopeContext.getDataScope(loginUser.getRoleCode().name()); | |||
return DataScopeContext.getDataScope(user.getRoleCode().name()); | |||
} | |||
public static Optional<DataScopeDTO> getCurrentUserDataScope() { | |||
@@ -94,9 +94,9 @@ public class ConstructionPlanManage { | |||
*/ | |||
@Transactional(rollbackFor = Exception.class) | |||
public String startTheProcess(DefaultDeclaredDTO dto) { | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
String employeeCode = userInfoDetails.getEmployeeCode(); | |||
VUtils.isTrue(Objects.isNull(userInfoDetails) ||Objects.isNull(employeeCode)) | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
String employeeCode = user.getEmployeeCode(); | |||
VUtils.isTrue(Objects.isNull(user) ||Objects.isNull(employeeCode)) | |||
.throwMessage("获取登录用户失败!"); | |||
ProjectDTO projectDto = dto.getProjectInfo(); | |||
@@ -152,8 +152,8 @@ public class ConstructionPlanManage { | |||
*/ | |||
@Transactional(rollbackFor = Exception.class) | |||
public String restartTheProcess(DefaultDeclaredDTO dto) { | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
VUtils.isTrue(Objects.isNull(userInfoDetails) ||Objects.isNull(userInfoDetails.getEmployeeCode())) | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user) ||Objects.isNull(user.getEmployeeCode())) | |||
.throwMessage("获取登录用户失败!"); | |||
ProjectDTO projectDto = dto.getProjectInfo(); | |||
@@ -209,7 +209,7 @@ public class ConstructionPlanManage { | |||
//项目阶段 状态 已定 方案待申报 | |||
req.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||
req.setStatus(ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode()); | |||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||
//放入用户的单位 | |||
req.setBuildOrgCode(user.getOrganizationCode()); | |||
@@ -223,7 +223,7 @@ public class ConstructionPlanManage { | |||
//项目阶段 状态 已定 方案待申报 | |||
req.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||
req.setStatus(ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode()); | |||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||
//放入用户的单位 | |||
req.setBuildOrgCode(user.getOrganizationCode()); | |||
@@ -108,19 +108,19 @@ public class DeclaredProjectManage { | |||
*/ | |||
@Transactional(rollbackFor = Exception.class) | |||
public String startTheProcess(DefaultDeclaredDTO dto) { | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
String employeeCode = userInfoDetails.getEmployeeCode(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
String employeeCode = user.getEmployeeCode(); | |||
VUtils.isTrue(StringUtils.isBlank(employeeCode)).throwMessage("获取登录用户 员工号 失败!"); | |||
ProjectDTO projectInfo = dto.getProjectInfo(); | |||
if(StringUtils.isNotBlank(userInfoDetails.getRegionCode())){ | |||
projectInfo.setAreaCode(userInfoDetails.getRegionCode()); | |||
projectInfo.setArea(regionCacheHelper.getRegionName(userInfoDetails.getRegionCode(), RegionConst.RL_COUNTY)); | |||
if(StringUtils.isNotBlank(user.getRegionCode())){ | |||
projectInfo.setAreaCode(user.getRegionCode()); | |||
projectInfo.setArea(regionCacheHelper.getRegionName(user.getRegionCode(), RegionConst.RL_COUNTY)); | |||
} | |||
projectInfo.setBuildOrgCode(userInfoDetails.getOrganizationCode()); | |||
projectInfo.setBuildOrgName(userInfoDetails.getOrganizationName()); | |||
projectInfo.setBuildOrgCode(user.getOrganizationCode()); | |||
projectInfo.setBuildOrgName(user.getOrganizationName()); | |||
//项目名称去重 | |||
defaultDeclaredProjectManage.checkDuplication(projectInfo); | |||
@@ -129,8 +129,8 @@ public class DeclaredProjectManage { | |||
//如果主管单位没有 那么主管单位就是自己 | |||
if(CommonEnum.NO.getCode().equals(projectInfo.getIsSuperOrg())){ | |||
projectInfo.setSuperOrgCode(userInfoDetails.getOrganizationCode()); | |||
projectInfo.setSuperOrg(userInfoDetails.getOrganizationName()); | |||
projectInfo.setSuperOrgCode(user.getOrganizationCode()); | |||
projectInfo.setSuperOrg(user.getOrganizationName()); | |||
} | |||
//如果是重新提交的话 判断下 项目是否存在 | |||
@@ -139,7 +139,7 @@ public class DeclaredProjectManage { | |||
projectInfo.setId(null); | |||
} | |||
String regionCode = userInfoDetails.getRegionCode(); | |||
String regionCode = user.getRegionCode(); | |||
WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | |||
.eq(WflowModels::getRegionCode, regionCode) | |||
@@ -188,15 +188,15 @@ public class DeclaredProjectManage { | |||
*/ | |||
@Transactional(rollbackFor = Exception.class) | |||
public String reStartTheProcess(DefaultDeclaredDTO dto) { | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
VUtils.isTrue(Objects.isNull(userInfoDetails) || Objects.isNull(userInfoDetails.getEmployeeCode())) | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user) || Objects.isNull(user.getEmployeeCode())) | |||
.throwMessage("获取登录用户失败!"); | |||
String employeeCode = userInfoDetails.getEmployeeCode(); | |||
String employeeCode = user.getEmployeeCode(); | |||
ProjectDTO projectDto = dto.getProjectInfo(); | |||
projectDto.setAreaCode(userInfoDetails.getRegionCode()); | |||
projectDto.setArea(regionCacheHelper.getRegionName(userInfoDetails.getRegionCode(), RegionConst.RL_COUNTY)); | |||
projectDto.setBuildOrgCode(userInfoDetails.getOrganizationCode()); | |||
projectDto.setBuildOrgName(userInfoDetails.getOrganizationName()); | |||
projectDto.setAreaCode(user.getRegionCode()); | |||
projectDto.setArea(regionCacheHelper.getRegionName(user.getRegionCode(), RegionConst.RL_COUNTY)); | |||
projectDto.setBuildOrgCode(user.getOrganizationCode()); | |||
projectDto.setBuildOrgName(user.getOrganizationName()); | |||
VUtils.isTrue(Objects.isNull(projectDto.getId())).throwMessage("提交失败 缺少项目ID!"); | |||
Project projectInfo = projectService.getById(projectDto.getId()); | |||
@@ -343,15 +343,15 @@ public class DeclaredProjectManage { | |||
*/ | |||
public Long saveToDraft(ProjectDraftSaveDTO dto) { | |||
Long userId = LoginUserUtil.getUserId(); | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
ProjectDTO projectInfo = dto.getProjectInfo(); | |||
ProjectDraft draft = new ProjectDraft(); | |||
BeanUtils.copyProperties(projectInfo, draft); | |||
draft.setUserId(String.valueOf(userId)); | |||
draft.setBuildOrgCode(userInfoDetails.getOrganizationCode()); | |||
draft.setBuildOrgName(userInfoDetails.getOrganizationName()); | |||
draft.setAreaCode(userInfoDetails.getRegionCode()); | |||
draft.setBuildOrgCode(user.getOrganizationCode()); | |||
draft.setBuildOrgName(user.getOrganizationName()); | |||
draft.setAreaCode(user.getRegionCode()); | |||
if(CollUtil.isNotEmpty(projectInfo.getDynamicForm())){ | |||
draft.setDynamicForm(JSON.toJSONString(projectInfo.getDynamicForm())); | |||
@@ -374,18 +374,18 @@ public class DeclaredProjectManage { | |||
* @return | |||
*/ | |||
public PageVo<ProjectLibListItemVO> projectLibList(ProjectListReq req) { | |||
UserInfoDetails userFullInfo = LoginUserUtil.loginUserDetail(); | |||
VUtils.isTrue(Objects.isNull(userFullInfo)).throwMessage("获取登录用户失败!"); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||
//放入用户的单位 因为数据权限 只能看自己单位 | |||
req.setBuildOrgCode(userFullInfo.getOrganizationCode()); | |||
req.setBuildOrgCode(user.getOrganizationCode()); | |||
return projectlibManager.projectLibList(req); | |||
} | |||
public void exportList(HttpServletResponse response, ProjectListReq param) { | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
VUtils.isTrue(Objects.isNull(userInfoDetails)).throwMessage("获取登录用户失败!"); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||
//放入用户的单位 | |||
param.setBuildOrgCode(userInfoDetails.getOrganizationCode()); | |||
param.setBuildOrgCode(user.getOrganizationCode()); | |||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | |||
List<Project> records = projectService.list(query); | |||
@@ -250,15 +250,15 @@ public class DefaultDeclaredProjectManage { | |||
//根据提交者的单位 | |||
public DeclaredProjectStatisticsPO declaredProjectOrgStatistics(Integer year){ | |||
UserInfoDetails userInfo = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
//查此人建设单位的项目 | |||
return statisticsService.getOrgStatistics(userInfo.getOrganizationCode(),year); | |||
return statisticsService.getOrgStatistics(user.getOrganizationCode(),year); | |||
} | |||
//根据提交者的区域 他是区管或者超管 | |||
public DeclaredProjectStatisticsPO declaredProjectRegionStatistics(Integer year){ | |||
UserInfoDetails userInfo = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
//查此人建设单位的项目 | |||
return statisticsService.getRegionStatistics(userInfo.getRegionCode(),year); | |||
return statisticsService.getRegionStatistics(user.getRegionCode(),year); | |||
} | |||
} |
@@ -89,8 +89,8 @@ public class PrequalificationDeclaredProjectManage { | |||
*/ | |||
@Transactional(rollbackFor = Exception.class) | |||
public String startTheProcess(DefaultDeclaredDTO dto) { | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
String employeeCode = userInfoDetails.getEmployeeCode(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
String employeeCode = user.getEmployeeCode(); | |||
VUtils.isTrue(Objects.isNull(employeeCode)).throwMessage("获取登录用户失败!"); | |||
ProjectDTO projectDto = dto.getProjectInfo(); | |||
@@ -99,7 +99,7 @@ public class PrequalificationDeclaredProjectManage { | |||
VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | |||
//要判断 当前操作人 是不是项目主管单位的人 | |||
VUtils.isTrue(!userInfoDetails.getOrganizationCode().equals(projectInfo.getSuperOrgCode())) | |||
VUtils.isTrue(!user.getOrganizationCode().equals(projectInfo.getSuperOrgCode())) | |||
.throwMessage(String.format("只有主管单位 【%s】的人 才能够提交",projectInfo.getSuperOrg())); | |||
//首先要判断 项目当前状态 是不是 待预审 | |||
@@ -142,8 +142,8 @@ public class PrequalificationDeclaredProjectManage { | |||
*/ | |||
@Transactional(rollbackFor = Exception.class) | |||
public String restartTheProcess(DefaultDeclaredDTO dto) { | |||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||
String employeeCode = userInfoDetails.getEmployeeCode(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
String employeeCode = user.getEmployeeCode(); | |||
VUtils.isTrue(Objects.isNull(employeeCode)).throwMessage("获取登录用户失败!"); | |||
ProjectDTO projectDto = dto.getProjectInfo(); | |||
@@ -162,9 +162,9 @@ public class PrequalificationDeclaredProjectManage { | |||
* @return | |||
*/ | |||
public PageVo<ProjectLibListItemVO> projectLibList(PrequalificationDeclaredListReq preReq) { | |||
UserInfoDetails userInfoDetail = LoginUserUtil.loginUserDetail(); | |||
VUtils.isTrue(Objects.isNull(userInfoDetail)).throwMessage("获取登录用户失败!"); | |||
if(!userInfoDetail.getIsOrgAdmin()){ | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||
if(!user.getIsOrgAdmin()){ | |||
return PageVo.empty(); | |||
} | |||
//限定参数 复制bean | |||
@@ -175,7 +175,7 @@ public class PrequalificationDeclaredProjectManage { | |||
req.setStatus(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()); | |||
//放入用户的主管单位 | |||
req.setSuperOrgCode(userInfoDetail.getOrganizationCode()); | |||
req.setSuperOrgCode(user.getOrganizationCode()); | |||
return projectLibManage.projectLibList(req); | |||
} | |||
@@ -185,9 +185,9 @@ public class PrequalificationDeclaredProjectManage { | |||
//项目阶段 状态 已定 待预审 | |||
req.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||
req.setStatus(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()); | |||
UserInfoDetails userInfoDetail = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
//放入用户的单位 | |||
req.setSuperOrgCode(userInfoDetail.getOrganizationCode()); | |||
req.setSuperOrgCode(user.getOrganizationCode()); | |||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | |||
List<Project> records = projectService.list(query); | |||
@@ -147,7 +147,7 @@ public class ProjectAdjustmentManage { | |||
ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode(), | |||
ProjectStatusEnum.THE_JOINT_REVIEW_OF_PROVINCIAL_DEPARTMENTS_FAILED.getCode(), | |||
ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode())); | |||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||
//放入用户的单位 | |||
req.setBuildOrgCode(user.getOrganizationCode()); | |||
@@ -165,7 +165,7 @@ public class ProjectAdjustmentManage { | |||
ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode(), | |||
ProjectStatusEnum.THE_JOINT_REVIEW_OF_PROVINCIAL_DEPARTMENTS_FAILED.getCode(), | |||
ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode())); | |||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||
//放入用户的单位 | |||
req.setBuildOrgCode(user.getOrganizationCode()); | |||
@@ -13,6 +13,7 @@ import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.basic.util.ValidUtil; | |||
import com.ningdatech.pmapi.common.constant.CommonConst; | |||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||
import com.ningdatech.pmapi.common.model.entity.ExcelExportWriter; | |||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | |||
@@ -29,6 +30,7 @@ import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||
import com.ningdatech.pmapi.projectlib.model.req.StartProjectDeclareReq; | |||
import com.ningdatech.pmapi.projectlib.model.vo.AnnualPlanListItemVO; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import lombok.AllArgsConstructor; | |||
@@ -60,6 +62,8 @@ public class AnnualPlanLibManage { | |||
private final IProjectService projectService; | |||
private final StateMachineUtils stateMachine; | |||
private final UserInfoHelper userInfoHelper; | |||
/** | |||
* 年度计划查询状态 | |||
*/ | |||
@@ -269,34 +273,34 @@ public class AnnualPlanLibManage { | |||
* build 项目的角色权限到req | |||
* @param query | |||
*/ | |||
public UserInfoDetails buildProjectLibPermission(LambdaQueryWrapper<Project> query){ | |||
UserInfoDetails loginUser = LoginUserUtil.loginUserDetail(); | |||
Optional<DataScopeDTO> currentUserDataScope = DataScopeUtil.getCurrentUserDataScope(loginUser); | |||
public UserFullInfoDTO buildProjectLibPermission(LambdaQueryWrapper<Project> query){ | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
Optional<DataScopeDTO> currentUserDataScope = DataScopeUtil.getCurrentUserDataScope(user); | |||
if(!currentUserDataScope.isPresent()){ | |||
log.warn("没有取到权限信息 当前查询 没有权限条件"); | |||
return loginUser; | |||
return user; | |||
} | |||
switch (currentUserDataScope.get().getRole()){ | |||
case NORMAL_MEMBER: | |||
//普通用户 只能看到自己单位去申报的 | |||
query.eq(Project::getBuildOrgCode ,loginUser.getOrganizationCode()); | |||
query.eq(Project::getBuildOrgCode ,user.getOrganizationCode()); | |||
break; | |||
case COMPANY_MANAGER: | |||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
query.eq(Project::getBuildOrgCode ,loginUser.getOrganizationCode()); | |||
query.eq(Project::getBuildOrgCode ,user.getOrganizationCode()); | |||
break; | |||
case SUPER_ADMIN: | |||
//超级管理员 看到丽水全市的 并且也要判断他 同时是不是单位管理员 | |||
break; | |||
case REGION_MANAGER: | |||
//区域管理员 看到自己区域的项目 | |||
query.eq(Project::getAreaCode,loginUser.getRegionCode()); | |||
query.eq(Project::getAreaCode,user.getRegionCode()); | |||
break; | |||
default: | |||
//没有权限的话 就让它查不到 | |||
query.eq(Project::getId,"NULL"); | |||
break; | |||
} | |||
return loginUser; | |||
return user; | |||
} | |||
} |
@@ -7,6 +7,7 @@ import com.google.common.collect.Lists; | |||
import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.pmapi.common.constant.CommonConst; | |||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||
import com.ningdatech.pmapi.common.model.entity.ExcelExportWriter; | |||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | |||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | |||
@@ -24,6 +25,7 @@ import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectRenewalFundDeclarationService; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | |||
@@ -57,6 +59,8 @@ public class ProjectLibManage { | |||
private final IProjectRenewalFundDeclarationService renewalFundDeclarationService; | |||
private final ProcessExecuteChainHandle processExecuteHandle; | |||
private final UserInfoHelper userInfoHelper; | |||
public PageVo<ProjectLibListItemVO> projectLibList(ProjectListReq req) { | |||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | |||
Page<Project> page = projectService.page(req.page(), query); | |||
@@ -85,7 +89,7 @@ public class ProjectLibManage { | |||
public PageVo<ProjectLibListItemVO> projectLibListWithPermission(ProjectListReq req) { | |||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | |||
UserInfoDetails userInfoDetails = buildProjectLibPermission(query); | |||
UserFullInfoDTO user = buildProjectLibPermission(query); | |||
Page<Project> page = projectService.page(req.page(), query); | |||
long total; | |||
if ((total = page.getTotal()) == 0) { | |||
@@ -105,10 +109,10 @@ public class ProjectLibManage { | |||
item.setBizDomain(w.getBizDomain()); | |||
item.setProcessStatus(w.getProcessStatus()); | |||
item.setInstCode(w.getInstCode()); | |||
if(userInfoDetails.getIsOrgAdmin() && | |||
if(user.getIsOrgAdmin() && | |||
ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode().equals(item.getStatus()) | |||
&& StringUtils.isNotBlank(w.getSuperOrgCode()) && StringUtils.isNotBlank(userInfoDetails.getOrganizationCode()) | |||
&& w.getSuperOrgCode().equals(userInfoDetails.getOrganizationCode())){ | |||
&& StringUtils.isNotBlank(w.getSuperOrgCode()) && StringUtils.isNotBlank(user.getOrganizationCode()) | |||
&& w.getSuperOrgCode().equals(user.getOrganizationCode())){ | |||
item.setCanPreDeclared(Boolean.TRUE); | |||
} | |||
return item; | |||
@@ -204,32 +208,32 @@ public class ProjectLibManage { | |||
* build 项目的角色权限到req | |||
* @param query | |||
*/ | |||
public UserInfoDetails buildProjectLibPermission(LambdaQueryWrapper<Project> query){ | |||
UserInfoDetails loginUser = LoginUserUtil.loginUserDetail(); | |||
Optional<DataScopeDTO> currentUserDataScope = DataScopeUtil.getCurrentUserDataScope(loginUser); | |||
public UserFullInfoDTO buildProjectLibPermission(LambdaQueryWrapper<Project> query){ | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
Optional<DataScopeDTO> currentUserDataScope = DataScopeUtil.getCurrentUserDataScope(user); | |||
if(!currentUserDataScope.isPresent()){ | |||
log.warn("没有取到权限信息 当前查询 没有权限条件"); | |||
return loginUser; | |||
return user; | |||
} | |||
Boolean isOrgAdmin = Boolean.FALSE; | |||
switch (currentUserDataScope.get().getRole()){ | |||
case NORMAL_MEMBER: | |||
//普通用户 只能看到自己单位去申报的 | |||
query.eq(Project::getBuildOrgCode ,loginUser.getOrganizationCode()); | |||
query.eq(Project::getBuildOrgCode ,user.getOrganizationCode()); | |||
break; | |||
case COMPANY_MANAGER: | |||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||
query.and(q1 -> q1.eq(Project::getBuildOrgCode ,loginUser.getOrganizationCode()).or(q2 -> | |||
query.and(q1 -> q1.eq(Project::getBuildOrgCode ,user.getOrganizationCode()).or(q2 -> | |||
q2.eq(Project::getStage,ProjectStatusEnum.NOT_APPROVED.getCode()) | |||
.eq(Project::getStatus,ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()) | |||
.eq(Project::getSuperOrgCode,loginUser.getOrganizationCode()))); | |||
.eq(Project::getSuperOrgCode,user.getOrganizationCode()))); | |||
break; | |||
case SUPER_ADMIN: | |||
//超级管理员 看到丽水全市的 并且也要判断他 同时是不是单位管理员 | |||
break; | |||
case REGION_MANAGER: | |||
//区域管理员 看到自己区域的项目 | |||
query.eq(Project::getAreaCode,loginUser.getRegionCode()); | |||
query.eq(Project::getAreaCode,user.getRegionCode()); | |||
break; | |||
case VISITOR: | |||
//访客可以看全市的 | |||
@@ -241,6 +245,6 @@ public class ProjectLibManage { | |||
query.eq(Project::getId,0L); | |||
break; | |||
} | |||
return loginUser; | |||
return user; | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
package com.ningdatech.pmapi.todocenter.constant; | |||
/** | |||
* @author ZPF | |||
* @since 2023/04/02 14:56 | |||
*/ | |||
public interface TodoCenterContant { | |||
public class Handler { | |||
public final static String ACTIVITY_APPROVAL = "userTask"; | |||
} | |||
} |
@@ -4,7 +4,7 @@ package com.ningdatech.pmapi.todocenter.constant; | |||
* @author CMM | |||
* @since 2023/02/01 14:56 | |||
*/ | |||
public interface WorkNotice { | |||
public interface WorkNoticeContant { | |||
public final String PASS_MSG_TEMPLATE = "【%s】的【%s】需要您审核。"; | |||
public final String PASS_MSG_TEMPLATE2 = "【%s】已通过【%s】,请及时开始下一步操作。"; | |||
public final String BACK_MSG_TEMPLATE = "【%s】的【%s】被退回,请及时处理。"; |
@@ -0,0 +1,215 @@ | |||
package com.ningdatech.pmapi.todocenter.handle; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||
import com.ningdatech.pmapi.todocenter.constant.TodoCenterContant; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import com.wflow.workflow.bean.dto.ReqProcessHandlerDTO; | |||
import com.wflow.workflow.bean.process.ProgressNode; | |||
import com.wflow.workflow.bean.process.enums.NodeTypeEnum; | |||
import com.wflow.workflow.bean.vo.ProcessProgressVo; | |||
import com.wflow.workflow.enums.ProcessStatusEnum; | |||
import lombok.AllArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.assertj.core.util.Lists; | |||
import org.flowable.engine.HistoryService; | |||
import org.flowable.engine.history.HistoricActivityInstance; | |||
import org.flowable.engine.history.HistoricProcessInstance; | |||
import org.springframework.stereotype.Component; | |||
import java.util.List; | |||
import java.util.Objects; | |||
/** | |||
* @Classname WithDrawHandle | |||
* @Description | |||
* @Date 2023/4/2 14:46 | |||
* @Author PoffyZhang | |||
*/ | |||
@Component | |||
@Slf4j | |||
@AllArgsConstructor | |||
public class WithDrawHandle { | |||
private final UserInfoHelper userInfoHelper; | |||
private final HistoryService historyService; | |||
/** | |||
* 判断 当前流程 可否被当前登录人 所撤回 | |||
* @param instanceId | |||
* @param progressInstanceDetail | |||
* @return | |||
*/ | |||
public Boolean checkCanWithdraw(String instanceId, ProcessProgressVo progressInstanceDetail) { | |||
//如果不是当前登录人 | |||
if(!ProcessStatusEnum.UNDER_REVIEW.getDesc() | |||
.equals(progressInstanceDetail.getStatus())){ | |||
return Boolean.FALSE; | |||
} | |||
return checkUserIsRoot(instanceId,null) || | |||
checkUserIsBefore(progressInstanceDetail.getProgressInfo(),null); | |||
} | |||
//判断当前操作人 是上一个节点的审批人 | |||
public Boolean checkUserIsBefore(List<ProgressNode> currentProgressInfo, ReqProcessHandlerDTO param) { | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
//1.判断出 当前审批人和上一个审批人 | |||
ProgressNode progressNode = currentProgressInfo.get(currentProgressInfo.size() - 1); | |||
ProgressNode beforeProgressNode = null; | |||
ProgressNode currentProgressNode = null; | |||
// 说明当前节点是子流程节点 | |||
// 如果是会签 或签 当前和上个 | |||
List<ProgressNode> thisAndOr = Lists.newArrayList(); | |||
List<ProgressNode> beforeAndOr = Lists.newArrayList(); | |||
if (progressNode.getNodeType().name().equals(NodeTypeEnum.SUB.name())) { | |||
List<ProgressNode> children = progressNode.getChildren(); | |||
currentProgressNode = children.get(children.size() - 1); | |||
//把当前和上一个节点和 会签或签的情况 都check出来 | |||
beforeProgressNode = checkBeforeNodeAndOr(children,currentProgressNode,thisAndOr,beforeAndOr); | |||
} else { | |||
currentProgressNode = currentProgressInfo.get(currentProgressInfo.size() - 1); | |||
//把把当前和上一个节点和 会签或签的情况 都check出来 | |||
beforeProgressNode = checkBeforeNodeAndOr(currentProgressInfo,currentProgressNode,thisAndOr,beforeAndOr); | |||
} | |||
// 判断当前工作流任务前一个审核人的部门和当前登录用户的部门是否是同一个,如果是同一个才可以撤回,否则抛出异常 | |||
// 获取当前当前工作流任务当前审核人信息 | |||
UserFullInfoDTO currentUserInfo = userInfoHelper.getUserFullInfoByEmployeeCode(currentProgressNode.getUserId()); | |||
if(!currentUserInfo.getOrganizationCode().equals(user.getOrganizationCode())){ | |||
return Boolean.FALSE; | |||
} | |||
Boolean isAndOr = Boolean.FALSE; | |||
//如果上个会签没取到 还有种情况是 会签 或签 并且在上个节点 | |||
if(CollUtil.isNotEmpty(beforeAndOr)) { | |||
for (ProgressNode n : beforeAndOr) { | |||
if (n.getUserId().equals(user.getEmployeeCode())) { | |||
beforeProgressNode = n; | |||
//说明当前操作人 在上个会签或者或签节点 | |||
isAndOr = Boolean.TRUE; | |||
break; | |||
} | |||
} | |||
} | |||
//还有种情况是 会签 或签 并且在当前节点 并且已经通过 | |||
if(!isAndOr && CollUtil.isNotEmpty(thisAndOr)){ | |||
for(ProgressNode n : thisAndOr){ | |||
if(n.getUserId().equals(user.getEmployeeCode()) && | |||
Objects.nonNull(n.getFinishTime())){ | |||
beforeProgressNode = n; | |||
//说明当前操作人 在上个会签或者或签节点 | |||
isAndOr = Boolean.TRUE; | |||
break; | |||
} | |||
} | |||
} | |||
if(!isAndOr && (Objects.isNull(beforeProgressNode) | |||
|| !user.getEmployeeCode().equals(beforeProgressNode.getUserId()))){ | |||
return Boolean.FALSE; | |||
} | |||
//如果是true 把对应操作人 在上个审批节点的task 也传入 | |||
if(Objects.nonNull(param)){ | |||
param.setTaskId(beforeProgressNode.getTaskId()); | |||
} | |||
return Boolean.TRUE; | |||
} | |||
/** | |||
* 判断撤回用户 是不是发起人 | |||
* @param processInstanceId | |||
* @param task | |||
* @return | |||
*/ | |||
public Boolean checkUserIsRoot(String processInstanceId,String task){ | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
// 获取当前要处理的流程实例 | |||
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery() | |||
.processInstanceId(processInstanceId) | |||
.singleResult(); | |||
if (user.getEmployeeCode().equals(instance.getStartUserId()) && | |||
(Objects.isNull(task) || user.getEmployeeCode().equals(instance.getStartUserId()))) { | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
} | |||
/** | |||
* 把上一个节点 和 或签 会签情况都check出来 | |||
* @param progressNodes andOr | |||
* @param thisAndOr beforeAndOr | |||
* @return | |||
*/ | |||
public ProgressNode checkBeforeNodeAndOr(List<ProgressNode> progressNodes,ProgressNode curr, | |||
List<ProgressNode> thisAndOr,List<ProgressNode> beforeAndOr) { | |||
ProgressNode beforeNode = null; | |||
if(progressNodes.size() == 1){ | |||
return null; | |||
} | |||
//进入上一个节点的标识 | |||
Boolean enterBefore = Boolean.FALSE; | |||
String thisAndOrNodeId = curr.getNodeId(); | |||
for(int i = progressNodes.size() - 2;i >= 0;i--){ | |||
//说明有会签 或签 | |||
if(progressNodes.get(i).getNodeId().equals(thisAndOrNodeId)){ | |||
//还在当前节点 | |||
if(!enterBefore){ | |||
if(thisAndOr.isEmpty()){ | |||
thisAndOr.add(curr); | |||
} | |||
thisAndOr.add(progressNodes.get(i)); | |||
} | |||
//如果在上个节点了 | |||
else{ | |||
if(beforeAndOr.isEmpty()){ | |||
beforeAndOr.add(curr); | |||
} | |||
beforeAndOr.add(progressNodes.get(i)); | |||
} | |||
}else{ | |||
thisAndOrNodeId = progressNodes.get(i).getNodeId(); | |||
if(!enterBefore){ | |||
beforeNode = progressNodes.get(i); | |||
enterBefore = Boolean.TRUE; | |||
continue; | |||
} | |||
break; | |||
} | |||
} | |||
return beforeNode; | |||
} | |||
/** | |||
* 1.判断 当前 撤回人 是否是 发起人 | |||
* 2.并且流程 尚未开始审批 | |||
* @return | |||
*/ | |||
public boolean canRootWithDraw(HistoricProcessInstance instance) { | |||
Long userId = LoginUserUtil.getUserId(); | |||
String startUserId = instance.getStartUserId(); | |||
//如果流程发起人 不是 当前登录人 直接返回false | |||
if(!userId.equals(startUserId)){ | |||
return Boolean.FALSE; | |||
} | |||
List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery() | |||
.processInstanceId(instance.getId()).finished() | |||
.activityType(TodoCenterContant.Handler.ACTIVITY_APPROVAL) | |||
.orderByHistoricActivityInstanceEndTime().asc().list(); | |||
//如果有已经被审核过的 节点 返回false | |||
if(CollUtil.isNotEmpty(finished)){ | |||
return Boolean.FALSE; | |||
} | |||
return Boolean.TRUE; | |||
} | |||
} |
@@ -0,0 +1,355 @@ | |||
package com.ningdatech.pmapi.todocenter.manage; | |||
import cn.hutool.core.util.StrUtil; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.file.service.FileService; | |||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo; | |||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | |||
import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService; | |||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||
import com.ningdatech.pmapi.projectdeclared.manage.DeclaredProjectManage; | |||
import com.ningdatech.pmapi.projectdeclared.manage.DefaultDeclaredProjectManage; | |||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectDraftSaveDTO; | |||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||
import com.ningdatech.pmapi.signature.service.ICompanySignatureService; | |||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | |||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | |||
import com.ningdatech.pmapi.sys.model.entity.Notify; | |||
import com.ningdatech.pmapi.sys.service.INotifyService; | |||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | |||
import com.ningdatech.pmapi.todocenter.service.StatisticsService; | |||
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | |||
import com.ningdatech.pmapi.todocenter.utils.PdfUtils; | |||
import com.ningdatech.pmapi.user.entity.UserInfo; | |||
import com.ningdatech.pmapi.user.service.IUserInfoService; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import com.wflow.contants.HisProInsEndActId; | |||
import com.wflow.workflow.bean.process.ProgressNode; | |||
import com.wflow.workflow.bean.process.enums.NodeTypeEnum; | |||
import com.wflow.workflow.bean.vo.ProcessProgressVo; | |||
import com.wflow.workflow.service.ProcessInstanceService; | |||
import com.wflow.workflow.service.ProcessTaskService; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.flowable.engine.HistoryService; | |||
import org.flowable.engine.history.HistoricProcessInstance; | |||
import org.springframework.beans.BeanUtils; | |||
import org.springframework.stereotype.Component; | |||
import java.time.LocalDateTime; | |||
import java.util.List; | |||
import java.util.Objects; | |||
import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant.*; | |||
/** | |||
* @Classname HandlerManage | |||
* @Description | |||
* @Date 2023/4/2 14:25 | |||
* @Author PoffyZhang | |||
*/ | |||
@Component | |||
@RequiredArgsConstructor | |||
@Slf4j | |||
public class HandlerManage { | |||
private final ProcessTaskService processTaskService; | |||
private final HistoryService historyService; | |||
private final IUserInfoService userInfoService; | |||
private final IProjectService projectService; | |||
private final ProjectLibManage projectLibManage; | |||
private final StateMachineUtils stateMachineUtils; | |||
private final IDingEmployeeInfoService dingEmployeeInfoService; | |||
private final IDingOrganizationService dingOrganizationService; | |||
private final ProcessInstanceService processInstanceService; | |||
private final INdWorkNoticeStagingService workNoticeStagingService; | |||
private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | |||
private final IProjectApplicationService projectApplicationService; | |||
private final UserInfoHelper userInfoHelper; | |||
private final BuildUserUtils buildUserUtils; | |||
private final IProjectStagingService projectStagingService; | |||
private final IProjectInstService projectInstService; | |||
private final PdfUtils pdfUtils; | |||
private final FileService fileService; | |||
private final ICompanySignatureService companySignatureService; | |||
private final StatisticsService statisticsService; | |||
private final INotifyService notifyService; | |||
private final DeclaredProjectManage declaredProjectManage; | |||
/** | |||
* 审核通过后 所处理的逻辑 | |||
* @param declaredProject | |||
* @param instance | |||
*/ | |||
public void afterPassTodo(Project declaredProject, HistoricProcessInstance instance){ | |||
Long userId = LoginUserUtil.getUserId(); | |||
// 获取流程通过后的流程实例 | |||
HistoricProcessInstance newInstance = historyService.createHistoricProcessInstanceQuery() | |||
.processInstanceId(instance.getId()) | |||
.singleResult(); | |||
// 获取流程通过后当前流程详情 | |||
ProcessProgressVo newInstanceDetail = processInstanceService.getProgressInstanceDetail(null, instance.getId()); | |||
// 获取流程通过后当前审核人信息,向其发送工作通知 | |||
List<ProgressNode> newProgressInfo = newInstanceDetail.getProgressInfo(); | |||
ProgressNode currentNode = newProgressInfo.get(newProgressInfo.size() - 1); | |||
String currentEmployeeCode; | |||
// 说明当前节点是子流程节点 | |||
if (currentNode.getNodeType().name().equals(NodeTypeEnum.SUB.name())) { | |||
List<ProgressNode> children = currentNode.getChildren(); | |||
// 获取子流程当前审核人节点 | |||
ProgressNode subCurrentNode = children.get(children.size() - 1); | |||
currentEmployeeCode = subCurrentNode.getUserId(); | |||
} else { | |||
currentEmployeeCode = currentNode.getUserId(); | |||
} | |||
// 流程通过后,判断当前登录用户是不是最后一个审核人 | |||
// 若当前登录用户是最后一个审批人,需更新流程状态为审核完成,项目状态到下个状态 | |||
// 并向流程发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 | |||
if (HisProInsEndActId.END.equals(newInstance.getEndActivityId())) { | |||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(declaredProject.getStatus()))) { | |||
// 当前项目状态是预审中 | |||
case PRE_APPLYING: | |||
//先修改项目状态 | |||
updatePassProjectStatus(userId, declaredProject); | |||
//然后入库暂存库 | |||
projectStagingService.addByProject(declaredProject,"暂存入库 待提交部门联审"); | |||
break; | |||
// 当前项目状态是单位内部审核中 | |||
case UNDER_INTERNAL_AUDIT: | |||
// 当前项目状态是部门联审中 | |||
case DEPARTMENT_JOINT_REVIEW: | |||
// 当前项目状态是方案评审中 | |||
case SCHEME_UNDER_REVIEW: | |||
// 当前项目状态是终验审核中 | |||
case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | |||
updatePassProjectStatus(userId, declaredProject); | |||
break; | |||
default: | |||
throw new IllegalStateException("Unexpected value: " + declaredProject.getStatus()); | |||
} | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo passWorkNoticeInfo2 = getSendWorkNoticeInfo(currentEmployeeCode); | |||
String passMsg2 = String.format(PASS_MSG_TEMPLATE2, declaredProject.getProjectName(), instance.getProcessDefinitionName()); | |||
passWorkNoticeInfo2.setMsg(passMsg2); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(userId, declaredProject, passMsg2); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo2, MsgTypeEnum.PROJECT_REVIEW); | |||
} else { | |||
// 若有下一个审核人(当前节点的用户), | |||
// 向其发送浙政钉工作通知:标题:审核任务 内容:【单位名称】的【项目名称】需要您审核。 | |||
// 获取发送浙政钉工作通知必要信息 | |||
if (Objects.isNull(currentEmployeeCode)) { | |||
throw new BizException("审核人信息不存在!"); | |||
} | |||
WorkNoticeInfo sendWorkNoticeInfo = getSendWorkNoticeInfo(currentEmployeeCode); | |||
String msg = String.format(PASS_MSG_TEMPLATE, sendWorkNoticeInfo.getOrganizationName(), declaredProject.getProjectName()); | |||
sendWorkNoticeInfo.setMsg(msg); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(userId, declaredProject, msg); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(sendWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); | |||
} | |||
} | |||
/** | |||
* 驳回后 所处理的逻辑 | |||
* @param declaredProject | |||
* @param instance | |||
*/ | |||
public void afterRejectTodo(Project declaredProject, HistoricProcessInstance instance) { | |||
Long userId = LoginUserUtil.getUserId(); | |||
// 更新项目状态和流程状态 | |||
updateRejectProjectStatus(userId, declaredProject); | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo rejectWorkNoticeInfo = getSendWorkNoticeInfo(instance.getStartUserId()); | |||
String rejectMsg = String.format(REJECT_MSG_TEMPLATE, declaredProject.getProjectName(), | |||
instance.getProcessDefinitionName()); | |||
rejectWorkNoticeInfo.setMsg(rejectMsg); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(userId, declaredProject, rejectMsg); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(rejectWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); | |||
} | |||
/** | |||
* 发起人 撤回逻辑 | |||
*/ | |||
public void rootWithDraw(Project declaredProject, HistoricProcessInstance instance) { | |||
Long userId = LoginUserUtil.getUserId(); | |||
// 若是流程发起人点击撤回,项目回到上一个状态,需调用状态机更新项目状态,流程状态更新为审核通过 | |||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(declaredProject.getStatus()))) { | |||
// 当前项目状态是单位内部审核中 | |||
case UNDER_INTERNAL_AUDIT: | |||
// 更新项目状态为待申报 | |||
updateWithdrawProjectStatus(userId, declaredProject); | |||
// 保存到草稿箱中 | |||
ProjectDraftSaveDTO draftSaveDto = new ProjectDraftSaveDTO(); | |||
ProjectDTO projectInfo = new ProjectDTO(); | |||
BeanUtils.copyProperties(declaredProject,projectInfo); | |||
draftSaveDto.setProjectInfo(projectInfo); | |||
declaredProjectManage.saveToDraft(draftSaveDto); | |||
// 并删除项目库中该项目信息 | |||
projectService.removeById(declaredProject); | |||
break; | |||
// 当前项目状态是预审中 | |||
case PRE_APPLYING: | |||
// 当前项目状态是部门联审中 | |||
case DEPARTMENT_JOINT_REVIEW: | |||
// 当前项目状态是方案评审中 | |||
case SCHEME_UNDER_REVIEW: | |||
// 当前项目状态是终验审核中 | |||
case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | |||
updateWithdrawProjectStatus(userId, declaredProject); | |||
break; | |||
default: | |||
throw new IllegalStateException("Unexpected value: " + declaredProject.getStatus()); | |||
} | |||
} | |||
/** | |||
* 退回审核后 所处理的逻辑 | |||
* @param declaredProject | |||
* @param instance | |||
*/ | |||
public void afterBackTodo(Project declaredProject, HistoricProcessInstance instance) { | |||
Long userId = LoginUserUtil.getUserId(); | |||
// 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo backWorkNoticeInfo = getSendWorkNoticeInfo(instance.getStartUserId()); | |||
String backMsg = String.format(BACK_MSG_TEMPLATE, declaredProject.getProjectName(), | |||
instance.getProcessDefinitionName()); | |||
backWorkNoticeInfo.setMsg(backMsg); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(userId, declaredProject, backMsg); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(backWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); | |||
} | |||
/** | |||
* 当为通过操作时,更新项目表中项目状态 | |||
* | |||
* @param userId | |||
* @param declaredProject | |||
* @return void | |||
* @author CMM | |||
* @since 2023/02/08 | |||
*/ | |||
private void updatePassProjectStatus(Long userId, Project declaredProject) { | |||
try { | |||
stateMachineUtils.pass(declaredProject); | |||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||
declaredProject.setUpdateBy(userId); | |||
projectService.updateById(declaredProject); | |||
} catch (Exception e) { | |||
log.error("状态机执行失败",e); | |||
throw new BizException("状态机执行失败!"); | |||
} | |||
} | |||
/** | |||
* 当为驳回操作时,更新项目表中的项目状态 | |||
* | |||
* @param userId | |||
* @param declaredProject | |||
* @return void | |||
* @author CMM | |||
* @since 2023/02/08 | |||
*/ | |||
private void updateRejectProjectStatus(Long userId, Project declaredProject) { | |||
stateMachineUtils.reject(declaredProject); | |||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||
declaredProject.setUpdateBy(userId); | |||
projectService.updateById(declaredProject); | |||
} | |||
/** | |||
* 当为撤回操作时,更新项目表中的项目状态为前一个状态 | |||
* | |||
* @param userId | |||
* @param declaredProject | |||
* @return void | |||
* @author CMM | |||
* @since 2023/02/08 | |||
*/ | |||
private void updateWithdrawProjectStatus(Long userId, Project declaredProject) { | |||
try { | |||
stateMachineUtils.withDraw(declaredProject); | |||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||
declaredProject.setUpdateBy(userId); | |||
projectService.updateById(declaredProject); | |||
} catch (Exception e) { | |||
throw new BizException("状态机执行失败!"); | |||
} | |||
} | |||
/** | |||
* 装配项目审核工作通知 | |||
* @param userId | |||
* @param project | |||
* @param msg | |||
*/ | |||
private void assemblyAuditNotify(Long userId, Project project, String msg) { | |||
Notify notify = new Notify(); | |||
notify.setTitle(AUDIT_WORK_TITLE); | |||
notify.setUserId(userId); | |||
notify.setType(MsgTypeEnum.PROJECT_REVIEW.name()); | |||
notify.setInstanceId(project.getInstCode()); | |||
notify.setContent(msg); | |||
notify.setReaded(Boolean.FALSE); | |||
notify.setCreateTime(LocalDateTime.now()); | |||
notifyService.save(notify); | |||
} | |||
/** | |||
* 获取发送浙政钉工作通知的信息 | |||
* | |||
* @param currentEmployeeCode | |||
* @return com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo | |||
* @author CMM | |||
* @since 2023/02/15 14:04 | |||
*/ | |||
public WorkNoticeInfo getSendWorkNoticeInfo(String currentEmployeeCode) { | |||
UserInfo auditUserInfo = userInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getEmployeeCode,currentEmployeeCode).last("limit 1")); | |||
if (Objects.isNull(auditUserInfo)) { | |||
throw new BizException("该用户不存在!"); | |||
} | |||
WorkNoticeInfo workNoticeInfo = new WorkNoticeInfo(); | |||
Long accountId = auditUserInfo.getAccountId(); | |||
if (Objects.isNull(accountId)) { | |||
throw new BizException("该用户没有录入浙政钉信息!"); | |||
} | |||
workNoticeInfo.setAccountId(accountId); | |||
// 根据浙政钉用户ID获取部门code | |||
DingEmployeeInfo employeeInfo = dingEmployeeInfoService.getOne(Wrappers.lambdaQuery(DingEmployeeInfo.class) | |||
.eq(DingEmployeeInfo::getAccountId, accountId) | |||
.eq(DingEmployeeInfo::getMainJob,String.valueOf(Boolean.TRUE)) | |||
.last("limit 1")); | |||
String organizationCode = employeeInfo.getOrganizationCode(); | |||
workNoticeInfo.setOrganizationCode(organizationCode); | |||
// 根据部门code获取部门名称 | |||
DingOrganization dingOrganization = dingOrganizationService.getOne(Wrappers.lambdaQuery(DingOrganization.class) | |||
.eq(DingOrganization::getOrganizationCode, organizationCode)); | |||
String organizationName = dingOrganization.getOrganizationName(); | |||
workNoticeInfo.setOrganizationName(organizationName); | |||
// 构建唯一的消息ID | |||
String bizMsgId = "ZD_WORK_NOTICE_" + StrUtil.UNDERLINE + organizationCode + StrUtil.UNDERLINE | |||
+ organizationName + accountId + StrUtil.UNDERLINE + System.currentTimeMillis(); | |||
workNoticeInfo.setBizMsgId(bizMsgId); | |||
String receiverUserId = String.valueOf(accountId); | |||
workNoticeInfo.setReceiverUserId(receiverUserId); | |||
return workNoticeInfo; | |||
} | |||
} |
@@ -1,8 +1,5 @@ | |||
package com.ningdatech.pmapi.todocenter.manage; | |||
import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.*; | |||
import static com.wflow.workflow.task.TriggerServiceTask.runtimeService; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.math.BigDecimal; | |||
@@ -13,17 +10,11 @@ import java.util.stream.Collectors; | |||
import javax.servlet.http.HttpServletResponse; | |||
import com.ningdatech.pmapi.projectdeclared.manage.DeclaredProjectManage; | |||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectDraftSaveDTO; | |||
import com.ningdatech.pmapi.todocenter.constant.WorkNotice; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.wflow.workflow.enums.ProcessStatusEnum; | |||
import com.ningdatech.pmapi.todocenter.handle.WithDrawHandle; | |||
import org.apache.commons.io.FileUtils; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.assertj.core.util.Lists; | |||
import org.flowable.bpmn.model.*; | |||
import org.flowable.engine.HistoryService; | |||
import org.flowable.engine.history.HistoricProcessInstance; | |||
import org.flowable.engine.runtime.ActivityInstance; | |||
import org.springframework.beans.BeanUtils; | |||
import org.springframework.mock.web.MockMultipartFile; | |||
import org.springframework.stereotype.Component; | |||
@@ -35,7 +26,6 @@ import com.alibaba.fastjson.JSONObject; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.google.common.collect.Maps; | |||
import com.google.common.collect.Sets; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.basic.function.VUtils; | |||
import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.basic.util.CollUtils; | |||
@@ -50,14 +40,11 @@ import com.ningdatech.pmapi.common.model.entity.ExcelExportWriter; | |||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | |||
import com.ningdatech.pmapi.irs.sign.IRSAPIRequest; | |||
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo; | |||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | |||
import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService; | |||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||
import com.ningdatech.pmapi.projectdeclared.manage.DefaultDeclaredProjectManage; | |||
import com.ningdatech.pmapi.projectlib.enumeration.FourSystemEnum; | |||
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | |||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | |||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | |||
@@ -70,12 +57,9 @@ import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||
import com.ningdatech.pmapi.signature.entity.CompanySignature; | |||
import com.ningdatech.pmapi.signature.service.ICompanySignatureService; | |||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | |||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | |||
import com.ningdatech.pmapi.sys.model.entity.Notify; | |||
import com.ningdatech.pmapi.sys.service.INotifyService; | |||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | |||
import com.ningdatech.pmapi.todocenter.enumeration.IsAppendProjectEnum; | |||
import com.ningdatech.pmapi.todocenter.enumeration.IsOrNotEnum; | |||
import com.ningdatech.pmapi.todocenter.model.dto.AdjustHandleDTO; | |||
@@ -92,22 +76,17 @@ import com.ningdatech.pmapi.todocenter.model.vo.TodoCenterStatisticsVO; | |||
import com.ningdatech.pmapi.todocenter.service.StatisticsService; | |||
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | |||
import com.ningdatech.pmapi.todocenter.utils.PdfUtils; | |||
import com.ningdatech.pmapi.user.entity.UserInfo; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||
import com.ningdatech.pmapi.user.service.IUserInfoService; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import com.wflow.contants.HisProInsEndActId; | |||
import com.wflow.contants.ProcessConstant; | |||
import com.wflow.exception.BusinessException; | |||
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | |||
import com.wflow.workflow.bean.dto.ReqProcessHandlerDTO; | |||
import com.wflow.workflow.bean.dto.TodoCenterListReqDTO; | |||
import com.wflow.workflow.bean.process.ProgressNode; | |||
import com.wflow.workflow.bean.process.enums.NodeTypeEnum; | |||
import com.wflow.workflow.bean.vo.ProcessInstanceVo; | |||
import com.wflow.workflow.bean.vo.ProcessProgressVo; | |||
import com.wflow.workflow.bean.vo.ProcessTaskVo; | |||
import com.wflow.workflow.enums.ProcessHandlerEnum; | |||
import com.wflow.workflow.service.ProcessInstanceService; | |||
import com.wflow.workflow.service.ProcessTaskService; | |||
import cn.hutool.core.bean.BeanUtil; | |||
@@ -149,6 +128,10 @@ public class TodoCenterManage { | |||
private final INotifyService notifyService; | |||
private final DeclaredProjectManage declaredProjectManage; | |||
private final HandlerManage handlerManage; | |||
private final WithDrawHandle withDrawHandle; | |||
/** | |||
* 待办中心待我处理项目列表查询 | |||
* | |||
@@ -297,7 +280,7 @@ public class TodoCenterManage { | |||
*/ | |||
public void handler(ReqProcessHandlerDTO param) { | |||
// 获取登录用户ID | |||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
// 获取登录用户浙政钉code | |||
String employeeCode = user.getEmployeeCode(); | |||
// 获取入参 | |||
@@ -305,15 +288,13 @@ public class TodoCenterManage { | |||
Long projectId = param.getProjectId(); | |||
VUtils.isTrue(Objects.isNull(processInstanceId)).throwMessage("获取流程实例ID失败!"); | |||
VUtils.isTrue(Objects.isNull(projectId)).throwMessage("获取项目ID失败!"); | |||
// 获取当前申报项目 | |||
Project declaredProject = projectService.getOne(Wrappers.lambdaQuery(Project.class) | |||
.eq(Project::getInstCode, processInstanceId) | |||
.eq(Project::getId, projectId)); | |||
VUtils.isTrue(Objects.isNull(declaredProject)).throwMessage("获取项目失败!"); | |||
// 获取当前项目名称 | |||
String projectName = declaredProject.getProjectName(); | |||
// 获取当前项目状态 | |||
Integer projectStatus = declaredProject.getStatus(); | |||
// 获取当前未处理流程详情 | |||
ProcessProgressVo currentInstanceDetail = processInstanceService.getProgressInstanceDetail(null, processInstanceId); | |||
@@ -321,9 +302,8 @@ public class TodoCenterManage { | |||
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery() | |||
.processInstanceId(processInstanceId) | |||
.singleResult(); | |||
// 获取流程定义名称 | |||
String processDefinitionName = instance.getProcessDefinitionName(); | |||
//进入处理逻辑 | |||
switch (param.getAction()) { | |||
// 通过 | |||
case PASS: | |||
@@ -331,145 +311,43 @@ public class TodoCenterManage { | |||
case SEAL_PASS: | |||
// 通过该任务,流程到下一审核人处 | |||
processTaskService.handleTask(param, employeeCode); | |||
// 获取流程通过后的流程实例 | |||
HistoricProcessInstance newInstance = historyService.createHistoricProcessInstanceQuery() | |||
.processInstanceId(processInstanceId) | |||
.singleResult(); | |||
// 获取流程通过后当前流程详情 | |||
ProcessProgressVo newInstanceDetail = processInstanceService.getProgressInstanceDetail(null, processInstanceId); | |||
// 获取流程通过后当前审核人信息,向其发送工作通知 | |||
List<ProgressNode> newProgressInfo = newInstanceDetail.getProgressInfo(); | |||
ProgressNode currentNode = newProgressInfo.get(newProgressInfo.size() - 1); | |||
String currentEmployeeCode; | |||
// 说明当前节点是子流程节点 | |||
if (currentNode.getNodeType().name().equals(NodeTypeEnum.SUB.name())) { | |||
List<ProgressNode> children = currentNode.getChildren(); | |||
// 获取子流程当前审核人节点 | |||
ProgressNode subCurrentNode = children.get(children.size() - 1); | |||
currentEmployeeCode = subCurrentNode.getUserId(); | |||
} else { | |||
currentEmployeeCode = currentNode.getUserId(); | |||
} | |||
// 流程通过后,判断当前登录用户是不是最后一个审核人 | |||
// 若当前登录用户是最后一个审批人,需更新流程状态为审核完成,项目状态到下个状态 | |||
// 并向流程发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 | |||
if (HisProInsEndActId.END.equals(newInstance.getEndActivityId())) { | |||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(projectStatus))) { | |||
// 当前项目状态是预审中 | |||
case PRE_APPLYING: | |||
//先修改项目状态 | |||
updatePassProjectStatus(user.getUserId(), declaredProject); | |||
//然后入库暂存库 | |||
projectStagingService.addByProject(declaredProject,"暂存入库 待提交部门联审"); | |||
break; | |||
// 当前项目状态是单位内部审核中 | |||
case UNDER_INTERNAL_AUDIT: | |||
// 当前项目状态是部门联审中 | |||
case DEPARTMENT_JOINT_REVIEW: | |||
// 当前项目状态是方案评审中 | |||
case SCHEME_UNDER_REVIEW: | |||
// 当前项目状态是终验审核中 | |||
case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | |||
updatePassProjectStatus(user.getUserId(), declaredProject); | |||
break; | |||
default: | |||
throw new IllegalStateException("Unexpected value: " + projectStatus); | |||
} | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo passWorkNoticeInfo2 = getSendWorkNoticeInfo(currentEmployeeCode); | |||
String passMsg2 = String.format(PASS_MSG_TEMPLATE2, projectName, processDefinitionName); | |||
passWorkNoticeInfo2.setMsg(passMsg2); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(user.getUserId(), declaredProject, passMsg2); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo2, MsgTypeEnum.PROJECT_REVIEW); | |||
} else { | |||
// 若有下一个审核人(当前节点的用户), | |||
// 向其发送浙政钉工作通知:标题:审核任务 内容:【单位名称】的【项目名称】需要您审核。 | |||
// 获取发送浙政钉工作通知必要信息 | |||
if (Objects.isNull(currentEmployeeCode)) { | |||
throw new BizException("审核人信息不存在!"); | |||
} | |||
WorkNoticeInfo sendWorkNoticeInfo = getSendWorkNoticeInfo(currentEmployeeCode); | |||
String msg = String.format(PASS_MSG_TEMPLATE, sendWorkNoticeInfo.getOrganizationName(), projectName); | |||
sendWorkNoticeInfo.setMsg(msg); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(user.getUserId(), declaredProject, msg); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(sendWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); | |||
} | |||
//通过审核后 所处理的逻辑 | |||
handlerManage.afterPassTodo(declaredProject,instance); | |||
break; | |||
// 驳回 | |||
case REJECT: | |||
// 驳回该任务,中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知: | |||
// 【项目名称】的【流程名称】被驳回,请及时处理。 | |||
processTaskService.handleTask(param, employeeCode); | |||
// 更新项目状态和流程状态 | |||
updateRejectProjectStatus(user.getUserId(), declaredProject); | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo rejectWorkNoticeInfo = getSendWorkNoticeInfo(instance.getStartUserId()); | |||
String rejectMsg = String.format(REJECT_MSG_TEMPLATE, projectName, processDefinitionName); | |||
rejectWorkNoticeInfo.setMsg(rejectMsg); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(user.getUserId(), declaredProject, rejectMsg); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(rejectWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); | |||
//驳回审核后 所处理的逻辑 | |||
handlerManage.afterRejectTodo(declaredProject,instance); | |||
break; | |||
// 退回 | |||
case BACK: | |||
// 退回该任务 | |||
processTaskService.handleTask(param, employeeCode); | |||
// 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo backWorkNoticeInfo = getSendWorkNoticeInfo(instance.getStartUserId()); | |||
String backMsg = String.format(BACK_MSG_TEMPLATE, projectName, processDefinitionName); | |||
backWorkNoticeInfo.setMsg(backMsg); | |||
// 放入系统通知表中,保存记录 | |||
assemblyAuditNotify(user.getUserId(), declaredProject, backMsg); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
workNoticeStagingService.addByWorkNotice(backWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); | |||
//退回审核后 所处理的逻辑 | |||
handlerManage.afterBackTodo(declaredProject,instance); | |||
break; | |||
// 撤回(流程发起人和当前流程审核人的前一个审核人操作) | |||
case WITHDRAW: | |||
//如果发起的root 节点的 操作 | |||
if(ProcessConstant.Field.ROOT.equals(param.getTaskId())){ | |||
VUtils.isTrue(!employeeCode.equals(instance.getStartUserId())).throwMessage("您不是发起人 不能进行撤回"); | |||
/** | |||
* 新逻辑 | |||
* 不判断前端传的taskId | |||
* 1.先判断 用户是否是ROOT 发起人 并且流程没有开始审批 | |||
*/ | |||
if(withDrawHandle.canRootWithDraw(instance)){ | |||
// 登录用户是流程发起人,且是流程发起人撤回 | |||
processTaskService.handleTask(param, employeeCode); | |||
// 若是流程发起人点击撤回,项目回到上一个状态,需调用状态机更新项目状态,流程状态更新为审核通过 | |||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(projectStatus))) { | |||
// 当前项目状态是单位内部审核中 | |||
case UNDER_INTERNAL_AUDIT: | |||
// 更新项目状态为待申报 | |||
updateWithdrawProjectStatus(user.getUserId(), declaredProject); | |||
// 保存到草稿箱中 | |||
ProjectDraftSaveDTO draftSaveDto = new ProjectDraftSaveDTO(); | |||
ProjectDTO projectInfo = new ProjectDTO(); | |||
BeanUtils.copyProperties(declaredProject,projectInfo); | |||
draftSaveDto.setProjectInfo(projectInfo); | |||
declaredProjectManage.saveToDraft(draftSaveDto); | |||
// 并删除项目库中该项目信息 | |||
projectService.removeById(declaredProject); | |||
break; | |||
// 当前项目状态是预审中 | |||
case PRE_APPLYING: | |||
// 当前项目状态是部门联审中 | |||
case DEPARTMENT_JOINT_REVIEW: | |||
// 当前项目状态是方案评审中 | |||
case SCHEME_UNDER_REVIEW: | |||
// 当前项目状态是终验审核中 | |||
case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | |||
updateWithdrawProjectStatus(user.getUserId(), declaredProject); | |||
break; | |||
default: | |||
throw new IllegalStateException("Unexpected value: " + projectStatus); | |||
} | |||
processTaskService.rootWithdrawTask(param, employeeCode); | |||
//发起人撤回 | |||
handlerManage.rootWithDraw(declaredProject,instance); | |||
}else{ | |||
//判断当前操作人 是否上一个节点的审批人 | |||
VUtils.isTrue(!checkUserIsBefore(currentInstanceDetail.getProgressInfo())) | |||
.throwMessage("当前登录用户不是发起人或者上一个节点审批人 无法进行撤回操作!"); | |||
processTaskService.handleTask(param, employeeCode); | |||
// 2.如果用户不是ROOT发起人 或者 不满足root撤回 那么必定要判断 他是不是上个节点审批人 或者 当前会签已审批的审批人 | |||
// 这里有个小操作 check的同时 把对应的操作人的taskId 也塞入 | |||
VUtils.isTrue(!withDrawHandle.checkUserIsBefore(currentInstanceDetail.getProgressInfo(),param)) | |||
.throwMessage("当前登录用户不是上一个节点审批人或者当前会签已批审批人 无法进行撤回操作!"); | |||
//上个审批人处理逻辑 | |||
processTaskService.lastWithdrawTask(param, employeeCode); | |||
} | |||
break; | |||
default: | |||
@@ -477,151 +355,6 @@ public class TodoCenterManage { | |||
} | |||
} | |||
private Boolean checkUserIsRoot(String processInstanceId,String task){ | |||
UserInfoDetails userInfoDetail = LoginUserUtil.loginUserDetail(); | |||
// 获取当前要处理的流程实例 | |||
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery() | |||
.processInstanceId(processInstanceId) | |||
.singleResult(); | |||
if (userInfoDetail.getEmployeeCode().equals(instance.getStartUserId()) && | |||
(Objects.isNull(task) || userInfoDetail.getEmployeeCode().equals(instance.getStartUserId()))) { | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
} | |||
//判断当前操作人 是上一个节点的审批人 | |||
private Boolean checkUserIsBefore(List<ProgressNode> currentProgressInfo) { | |||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||
//1.判断出 当前审批人和上一个审批人 | |||
ProgressNode progressNode = currentProgressInfo.get(currentProgressInfo.size() - 1); | |||
ProgressNode beforeProgressNode = null; | |||
ProgressNode currentProgressNode = null; | |||
// 说明当前节点是子流程节点 | |||
// 如果是会签 或签 当前和上个 | |||
List<ProgressNode> thisAndOr = Lists.newArrayList(); | |||
List<ProgressNode> beforeAndOr = Lists.newArrayList(); | |||
if (progressNode.getNodeType().name().equals(NodeTypeEnum.SUB.name())) { | |||
List<ProgressNode> children = progressNode.getChildren(); | |||
currentProgressNode = children.get(children.size() - 1); | |||
//把上一个节点和 会签或签的情况 都check出来 | |||
beforeProgressNode = checkBeforeNodeAndOr(children,currentProgressNode,thisAndOr,beforeAndOr); | |||
} else { | |||
currentProgressNode = currentProgressInfo.get(currentProgressInfo.size() - 1); | |||
//把上一个节点和 会签或签的情况 都check出来 | |||
beforeProgressNode = checkBeforeNodeAndOr(currentProgressInfo,currentProgressNode,thisAndOr,beforeAndOr); | |||
} | |||
// 判断当前工作流任务前一个审核人的部门和当前登录用户的部门是否是同一个,如果是同一个才可以撤回,否则抛出异常 | |||
// 获取当前当前工作流任务当前审核人信息 | |||
UserFullInfoDTO currentUserInfo = userInfoHelper.getUserFullInfoByEmployeeCode(currentProgressNode.getUserId()); | |||
if(!currentUserInfo.getOrganizationCode().equals(user.getOrganizationCode())){ | |||
return Boolean.FALSE; | |||
} | |||
UserFullInfoDTO beforeUser = null; | |||
Boolean isAndOr = Boolean.FALSE; | |||
//如果上个会签没取到 还有种情况是 会签 或签 并且在上个节点 | |||
if(CollUtil.isNotEmpty(beforeAndOr)) { | |||
for (ProgressNode n : beforeAndOr) { | |||
if (n.getUserId().equals(user.getEmployeeCode())) { | |||
beforeProgressNode = n; | |||
//说明当前操作人 在上个会签或者或签节点 | |||
isAndOr = Boolean.TRUE; | |||
break; | |||
} | |||
} | |||
} | |||
//还有种情况是 会签 或签 并且在当前节点 并且已经通过 | |||
if(!isAndOr && CollUtil.isNotEmpty(thisAndOr)){ | |||
for(ProgressNode n : thisAndOr){ | |||
if(n.getUserId().equals(user.getEmployeeCode()) && | |||
Objects.nonNull(n.getFinishTime())){ | |||
beforeProgressNode = n; | |||
//说明当前操作人 在上个会签或者或签节点 | |||
isAndOr = Boolean.TRUE; | |||
break; | |||
} | |||
} | |||
} | |||
if(Objects.nonNull(beforeProgressNode)){ | |||
// 获取当前工作流任务前一个审核人信息 | |||
beforeUser = userInfoHelper.getUserFullInfoByEmployeeCode(beforeProgressNode.getUserId()); | |||
} | |||
if(!isAndOr && (Objects.isNull(beforeUser) || !user.getEmployeeCode().equals(beforeUser.getEmployeeCode()))){ | |||
return Boolean.FALSE; | |||
} | |||
return Boolean.TRUE; | |||
} | |||
/** | |||
* 把上一个节点 和 或签 会签情况都check出来 | |||
* @param progressNodes andOr | |||
* @param thisAndOr beforeAndOr | |||
* @return | |||
*/ | |||
private ProgressNode checkBeforeNodeAndOr(List<ProgressNode> progressNodes,ProgressNode curr, | |||
List<ProgressNode> thisAndOr,List<ProgressNode> beforeAndOr) { | |||
ProgressNode beforeNode = null; | |||
if(progressNodes.size() == 1){ | |||
return null; | |||
} | |||
//进入上一个节点的标识 | |||
Boolean enterBefore = Boolean.FALSE; | |||
String thisAndOrNodeId = curr.getNodeId(); | |||
for(int i = progressNodes.size() - 2;i >= 0;i--){ | |||
//说明有会签 或签 | |||
if(progressNodes.get(i).getNodeId().equals(thisAndOrNodeId)){ | |||
//还在当前节点 | |||
if(!enterBefore){ | |||
if(thisAndOr.isEmpty()){ | |||
thisAndOr.add(curr); | |||
} | |||
thisAndOr.add(progressNodes.get(i)); | |||
} | |||
//如果在上个节点了 | |||
else{ | |||
if(beforeAndOr.isEmpty()){ | |||
beforeAndOr.add(curr); | |||
} | |||
beforeAndOr.add(progressNodes.get(i)); | |||
} | |||
}else{ | |||
thisAndOrNodeId = progressNodes.get(i).getNodeId(); | |||
if(!enterBefore){ | |||
beforeNode = progressNodes.get(i); | |||
enterBefore = Boolean.TRUE; | |||
continue; | |||
} | |||
break; | |||
} | |||
} | |||
return beforeNode; | |||
} | |||
/** | |||
* 装配项目审核工作通知 | |||
* @param userId | |||
* @param project | |||
* @param msg | |||
*/ | |||
private void assemblyAuditNotify(Long userId, Project project, String msg) { | |||
Notify notify = new Notify(); | |||
notify.setTitle(AUDIT_WORK_TITLE); | |||
notify.setUserId(userId); | |||
notify.setType(MsgTypeEnum.PROJECT_REVIEW.name()); | |||
notify.setInstanceId(project.getInstCode()); | |||
notify.setContent(msg); | |||
notify.setReaded(Boolean.FALSE); | |||
notify.setCreateTime(LocalDateTime.now()); | |||
notifyService.save(notify); | |||
} | |||
/** | |||
* 调用IRS接口,获取盖章后的pdf文件,上传到OSS,并保存文件ID到项目库中 | |||
* @param req | |||
@@ -682,171 +415,6 @@ public class TodoCenterManage { | |||
return resultVo.getId(); | |||
} | |||
/** | |||
* 当为驳回操作时,更新项目表中的项目状态 | |||
* | |||
* @param userId | |||
* @param declaredProject | |||
* @return void | |||
* @author CMM | |||
* @since 2023/02/08 | |||
*/ | |||
private void updateRejectProjectStatus(Long userId, Project declaredProject) { | |||
stateMachineUtils.reject(declaredProject); | |||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||
declaredProject.setUpdateBy(userId); | |||
projectService.updateById(declaredProject); | |||
} | |||
/** | |||
* 获取发送浙政钉工作通知的信息 | |||
* | |||
* @param currentEmployeeCode | |||
* @return com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo | |||
* @author CMM | |||
* @since 2023/02/15 14:04 | |||
*/ | |||
public WorkNoticeInfo getSendWorkNoticeInfo(String currentEmployeeCode) { | |||
UserInfo auditUserInfo = userInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getEmployeeCode,currentEmployeeCode).last("limit 1")); | |||
if (Objects.isNull(auditUserInfo)) { | |||
throw new BizException("该用户不存在!"); | |||
} | |||
WorkNoticeInfo workNoticeInfo = new WorkNoticeInfo(); | |||
Long accountId = auditUserInfo.getAccountId(); | |||
if (Objects.isNull(accountId)) { | |||
throw new BizException("该用户没有录入浙政钉信息!"); | |||
} | |||
workNoticeInfo.setAccountId(accountId); | |||
// 根据浙政钉用户ID获取部门code | |||
DingEmployeeInfo employeeInfo = dingEmployeeInfoService.getOne(Wrappers.lambdaQuery(DingEmployeeInfo.class) | |||
.eq(DingEmployeeInfo::getAccountId, accountId) | |||
.eq(DingEmployeeInfo::getMainJob,String.valueOf(Boolean.TRUE)) | |||
.last("limit 1")); | |||
String organizationCode = employeeInfo.getOrganizationCode(); | |||
workNoticeInfo.setOrganizationCode(organizationCode); | |||
// 根据部门code获取部门名称 | |||
DingOrganization dingOrganization = dingOrganizationService.getOne(Wrappers.lambdaQuery(DingOrganization.class) | |||
.eq(DingOrganization::getOrganizationCode, organizationCode)); | |||
String organizationName = dingOrganization.getOrganizationName(); | |||
workNoticeInfo.setOrganizationName(organizationName); | |||
// 构建唯一的消息ID | |||
String bizMsgId = "ZD_WORK_NOTICE_" + StrUtil.UNDERLINE + organizationCode + StrUtil.UNDERLINE | |||
+ organizationName + accountId + StrUtil.UNDERLINE + System.currentTimeMillis(); | |||
workNoticeInfo.setBizMsgId(bizMsgId); | |||
String receiverUserId = String.valueOf(accountId); | |||
workNoticeInfo.setReceiverUserId(receiverUserId); | |||
return workNoticeInfo; | |||
} | |||
/** | |||
* 当为通过操作时,更新项目表中项目状态 | |||
* | |||
* @param userId | |||
* @param declaredProject | |||
* @return void | |||
* @author CMM | |||
* @since 2023/02/08 | |||
*/ | |||
private void updatePassProjectStatus(Long userId, Project declaredProject) { | |||
try { | |||
stateMachineUtils.pass(declaredProject); | |||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||
declaredProject.setUpdateBy(userId); | |||
projectService.updateById(declaredProject); | |||
} catch (Exception e) { | |||
throw new BizException("状态机执行失败!"); | |||
} | |||
} | |||
/** | |||
* 获取流程发起节点的用户ID | |||
* | |||
* @param rootNode 根节点 | |||
* @param processInstanceId | |||
* @return java.lang.String | |||
* @author CMM | |||
* @since 2023/02/02 | |||
*/ | |||
private String getRootUserId(FlowNode rootNode, String processInstanceId) { | |||
String rootUserId = null; | |||
// 输出连线 | |||
List<SequenceFlow> outgoingFlows = rootNode.getOutgoingFlows(); | |||
// 遍历返回下一个节点信息 | |||
for (SequenceFlow currentOutgoingFlow : outgoingFlows) { | |||
// 类型自己判断 | |||
FlowElement targetFlowElement = currentOutgoingFlow.getTargetFlowElement(); | |||
// TODO 若要会签需判断候选人 | |||
// 发起事件 | |||
if (targetFlowElement instanceof StartEvent) { | |||
String actId = targetFlowElement.getId(); | |||
ActivityInstance activityInstance = runtimeService.createActivityInstanceQuery() | |||
.processInstanceId(processInstanceId).activityId(actId).singleResult(); | |||
String executionId = activityInstance.getExecutionId(); | |||
rootUserId = runtimeService.getVariable(executionId, "initiator", String.class); | |||
break; | |||
} | |||
} | |||
return rootUserId; | |||
} | |||
/** | |||
* 获取当前节点的下一个节点的审核用户ID | |||
* | |||
* @param currentNode 当前节点 | |||
* @param processInstanceId | |||
* @return java.lang.String 下一个节点的审核用户ID | |||
* @author CMM | |||
* @since 2023/02/02 | |||
*/ | |||
private String getNextUserId(FlowNode currentNode, String processInstanceId) { | |||
String nextUserId = null; | |||
// 输出连线 | |||
List<SequenceFlow> outgoingFlows = currentNode.getOutgoingFlows(); | |||
// 遍历返回下一个节点信息 | |||
for (SequenceFlow currentOutgoingFlow : outgoingFlows) { | |||
// 类型自己判断 | |||
FlowElement targetFlowElement = currentOutgoingFlow.getTargetFlowElement(); | |||
// 如果下个审批节点为结束节点,那么跳过该节点 | |||
if (targetFlowElement instanceof EndEvent) { | |||
continue; | |||
} | |||
// TODO 若要会签需判断候选人 | |||
// 用户任务 | |||
if (targetFlowElement instanceof UserTask) { | |||
String actId = targetFlowElement.getId(); | |||
ActivityInstance activityInstance = runtimeService.createActivityInstanceQuery() | |||
.processInstanceId(processInstanceId).activityId(actId).singleResult(); | |||
String executionId = activityInstance.getExecutionId(); | |||
nextUserId = runtimeService.getVariable(executionId, "assignee", String.class); | |||
break; | |||
} | |||
} | |||
return nextUserId; | |||
} | |||
/** | |||
* 当为撤回操作时,更新项目表中的项目状态为前一个状态 | |||
* | |||
* @param userId | |||
* @param declaredProject | |||
* @return void | |||
* @author CMM | |||
* @since 2023/02/08 | |||
*/ | |||
private void updateWithdrawProjectStatus(Long userId, Project declaredProject) { | |||
try { | |||
stateMachineUtils.withDraw(declaredProject); | |||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||
declaredProject.setUpdateBy(userId); | |||
projectService.updateById(declaredProject); | |||
} catch (Exception e) { | |||
throw new BizException("状态机执行失败!"); | |||
} | |||
} | |||
/** | |||
* 查询流程表单数据及审批的进度步骤 | |||
* | |||
@@ -866,18 +434,10 @@ public class TodoCenterManage { | |||
res.setProcessProgressVo(progressInstanceDetail); | |||
res.setStatus(progressInstanceDetail.getStatus()); | |||
res.setProjectId(projectId); | |||
res.setCanWithdraw(checkCanWithdraw(instanceId,progressInstanceDetail)); | |||
res.setCanWithdraw(withDrawHandle.checkCanWithdraw(instanceId,progressInstanceDetail)); | |||
return res; | |||
} | |||
private Boolean checkCanWithdraw(String instanceId, ProcessProgressVo progressInstanceDetail) { | |||
if(!ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(progressInstanceDetail.getStatus())){ | |||
return Boolean.FALSE; | |||
} | |||
return checkUserIsRoot(instanceId,null) || checkUserIsBefore(progressInstanceDetail.getProgressInfo()); | |||
} | |||
/** | |||
* 待办中心我已处理项目列表查询 | |||
@@ -1,9 +1,13 @@ | |||
package com.ningdatech.pmapi.user.security.auth.model; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.ningdatech.pmapi.sys.model.entity.Role; | |||
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum; | |||
import lombok.Data; | |||
import java.util.List; | |||
import java.util.Objects; | |||
import java.util.stream.Collectors; | |||
/** | |||
* @author liuxinxin | |||
@@ -52,4 +56,28 @@ public class UserFullInfoDTO { | |||
*/ | |||
private List<Role> userRoleList; | |||
/** | |||
* 取最高的权限 | |||
* | |||
* @return | |||
*/ | |||
public RoleEnum getRoleCode() { | |||
if (CollUtil.isNotEmpty(this.userRoleList)) { | |||
return RoleEnum.checkHigherRole(this.userRoleList.stream() | |||
.map(Role::getCode).collect(Collectors.toList())); | |||
} | |||
return null; | |||
} | |||
public Boolean getIsOrgAdmin() { | |||
if (CollUtil.isNotEmpty(this.userRoleList)) { | |||
for (Role role : this.userRoleList) { | |||
RoleEnum roleEnum = RoleEnum.mathByName(role.getCode()); | |||
if (Objects.nonNull(roleEnum) && roleEnum.eq(RoleEnum.COMPANY_MANAGER.name())) { | |||
return Boolean.TRUE; | |||
} | |||
} | |||
} | |||
return Boolean.FALSE; | |||
} | |||
} |
@@ -50,7 +50,6 @@ public class WorkbenchManage { | |||
private final ProjectLibManage projectLibManage; | |||
public WorkbenchVO getWorkbenchData(Integer year){ | |||
UserInfoDetails userInfo = LoginUserUtil.loginUserDetail(); | |||
WorkbenchVO res = new WorkbenchVO(); | |||
//1.待办中心数据 | |||
@@ -64,7 +63,7 @@ public class WorkbenchManage { | |||
//2.项目统计数据 | |||
res.setOrgDeclared(WorkbenchConverter.convert(defaultDeclaredProjectManage.declaredProjectOrgStatistics(year))); | |||
if(userInfoHelper.isSuperOrRegionAdmin(userInfo.getUserId())){ | |||
if(userInfoHelper.isSuperOrRegionAdmin(LoginUserUtil.getUserId())){ | |||
res.setRegionDeclared(WorkbenchConverter.convert(defaultDeclaredProjectManage.declaredProjectRegionStatistics(year))); | |||
} | |||
ProjectListReq projectListReq = new ProjectListReq(); | |||
@@ -3,10 +3,14 @@ package com.ningdatech.pmapi.instance; | |||
import com.alibaba.fastjson.JSON; | |||
import com.ningdatech.pmapi.AppTests; | |||
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | |||
import org.flowable.engine.HistoryService; | |||
import org.flowable.engine.RuntimeService; | |||
import org.flowable.engine.history.HistoricActivityInstance; | |||
import org.junit.Test; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import java.util.List; | |||
/** | |||
* @Classname InstanceTest | |||
* @Description | |||
@@ -18,6 +22,9 @@ public class InstanceTest extends AppTests { | |||
@Autowired | |||
private RuntimeService runtimeService; | |||
@Autowired | |||
private HistoryService historyService; | |||
@Test | |||
public void test(){ | |||
String instanceId = "896fa188-96d8-11ed-9539-e2d4e8f16b2f"; | |||
@@ -25,4 +32,15 @@ public class InstanceTest extends AppTests { | |||
"owner"); | |||
System.out.println(JSON.toJSONString(user)); | |||
} | |||
@Test | |||
public void testHistory(){ | |||
//如果有已经被审核过的 节点 | |||
List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery() | |||
.processInstanceId("085af7ef-d133-11ed-a3f6-02426daa406d").finished() | |||
.activityType("userTask") | |||
.orderByHistoricActivityInstanceEndTime().asc().list(); | |||
System.out.println(finished); | |||
} | |||
} |
@@ -12,13 +12,12 @@ import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | |||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | |||
import com.ningdatech.pmapi.todocenter.manage.HandlerManage; | |||
import com.ningdatech.pmapi.todocenter.manage.TodoCenterManage; | |||
import com.ningdatech.pmapi.todocenter.model.dto.PdfGenerateDTO; | |||
import com.ningdatech.pmapi.todocenter.utils.PdfUtils; | |||
import com.ningdatech.pmapi.user.entity.UserInfo; | |||
import com.ningdatech.pmapi.user.service.IUserInfoService; | |||
import com.ningdatech.zwdd.client.ZwddClient; | |||
import com.wflow.contants.ProcessConstant; | |||
@@ -39,7 +38,7 @@ import java.io.InputStream; | |||
import java.time.LocalDateTime; | |||
import java.util.List; | |||
import java.util.concurrent.*; | |||
import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPLATE; | |||
import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant.PASS_MSG_TEMPLATE; | |||
/** | |||
* 待办中心测试 | |||
@@ -72,6 +71,9 @@ public class TodoCenterTest extends AppTests { | |||
@Autowired | |||
private HistoryService historyService; | |||
@Autowired | |||
private HandlerManage handlerManage; | |||
@Test | |||
public void sendWorkNoticeTest() throws ExecutionException, InterruptedException { | |||
//String msg = String.format(PASS_MSG_TEMPLATE, "发改委", "0223-00-测试项目"); | |||
@@ -87,7 +89,7 @@ public class TodoCenterTest extends AppTests { | |||
String userId = "4"; | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo workNoticeInfo = todoCenterManage.getSendWorkNoticeInfo(userId); | |||
WorkNoticeInfo workNoticeInfo = handlerManage.getSendWorkNoticeInfo(userId); | |||
// workNoticeInfo.setBizMsgId("1"); | |||
String msg = String.format(PASS_MSG_TEMPLATE, "发改委", "0223-02-测试项目"); | |||
@@ -126,7 +128,7 @@ public class TodoCenterTest extends AppTests { | |||
public void sendWorkNoticeTest2(){ | |||
String userId = "2"; | |||
// 获取发送浙政钉工作通知必要信息 | |||
WorkNoticeInfo passWorkNoticeInfo = todoCenterManage.getSendWorkNoticeInfo(userId); | |||
WorkNoticeInfo passWorkNoticeInfo = handlerManage.getSendWorkNoticeInfo(userId); | |||
String passMsg = String.format(PASS_MSG_TEMPLATE, passWorkNoticeInfo.getOrganizationName(), "测试项目0301-1"); | |||
passWorkNoticeInfo.setMsg(passMsg); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||