@@ -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()); | |||
// } | |||
} |
@@ -0,0 +1,42 @@ | |||
package com.ningdatech.pmapi.datascope.provider.impl; | |||
import com.google.common.collect.Lists; | |||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | |||
import com.ningdatech.pmapi.datascope.provider.DataScopeProvider; | |||
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Optional; | |||
/** | |||
* <p> | |||
* 数据权限 数据看板角色 | |||
* </p> | |||
* | |||
* @author ZPF | |||
* @since 2023/3/27 23:29 | |||
*/ | |||
@Slf4j | |||
@RequiredArgsConstructor | |||
@Component("DASHBOARD") | |||
public class DashboardUserDataScopeProviderImpl implements DataScopeProvider { | |||
private final UserInfoHelper userInfoHelper; | |||
@Override | |||
public Optional<DataScopeDTO> findDataFieldProperty() { | |||
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
DataScopeDTO ds = new DataScopeDTO(); | |||
ds.setEmployeeCode(userFullInfo.getOrganizationCode()); | |||
ds.setRegionCodes(Lists.newArrayList(userFullInfo.getRegionCode())); | |||
ds.setUserId(userFullInfo.getUserId()); | |||
ds.setRole(RoleEnum.DASHBOARD); | |||
return Optional.ofNullable(ds); | |||
} | |||
} |
@@ -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() { | |||
@@ -43,6 +43,10 @@ public class MeetingDetailBasicVO { | |||
@JSONField(format = "yyyy-MM-dd HH:mm") | |||
private LocalDateTime startTime; | |||
@ApiModelProperty("结束时间") | |||
@JSONField(format = "yyyy-MM-dd HH:mm") | |||
private LocalDateTime endTime; | |||
@ApiModelProperty("评委到场时间") | |||
@JSONField(format = "yyyy-MM-dd HH:mm") | |||
private LocalDateTime judgesAttendanceTime; | |||
@@ -95,8 +95,8 @@ | |||
</sql> | |||
<select id="pageReviewProjectList" resultType="com.ningdatech.pmapi.meeting.entity.dto.ReviewProjectDTO"> | |||
select mip.project_id, np.project_name, np.project_type, np.project_year, np.build_org_name, | |||
np.biz_domain, np.declare_amount declare_amount, mip.meeting_id, m.type meetingType, m.start_time reviewTime, | |||
select mip.project_id, np.project_name, np.project_type, np.project_year, np.build_org_name, m.type review_type, | |||
np.biz_domain, np.declare_amount declared_amount, mip.meeting_id, m.type meetingType, m.start_time reviewTime, | |||
m.connecter, m.contact, me.is_headman, (select count(1) from nd_expert_review ner where ner.project_id = np.id | |||
and ner.create_by = me.expert_id) reviewed | |||
from nd_project np inner join meeting_inner_project mip on mip.project_id = np.id | |||
@@ -111,7 +111,7 @@ | |||
and np.project_name like concat('%', #{p.projectName}, '%') | |||
</if> | |||
<if test="p.buildOrgName != null and p.buildOrgName.length > 0"> | |||
and np.build_org_name like concat('%', #{buildOrgName}, '%') | |||
and np.build_org_name like concat('%', #{p.buildOrgName}, '%') | |||
</if> | |||
<if test="p.reviewTimeMin != null"> | |||
and m.start_time >= #{p.reviewTimeMin} | |||
@@ -66,6 +66,7 @@ public class ExpertCallResultRewriteTask { | |||
private final DictionaryCache dictionaryCache; | |||
private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | |||
private final IExpertUserFullInfoService userFullInfoService; | |||
private final static int MINUTES_CALL_RESULT_FEEDBACK = 15; | |||
@PostConstruct | |||
public void initTask() { | |||
@@ -119,7 +120,7 @@ public class ExpertCallResultRewriteTask { | |||
// 极端情况下获取不到submitKey异常情况 | |||
continue; | |||
} | |||
Integer minutes = callbackMinutes.get(expert.getRuleId()); | |||
Integer minutes = callbackMinutes.getOrDefault(expert.getRuleId(), MINUTES_CALL_RESULT_FEEDBACK); | |||
Optional<Integer> status = getStatusByMsgRecordDetail(msgRecordDetail, minutes, expert.getCreateOn()); | |||
if (status.isPresent()) { | |||
MeetingExpert update = new MeetingExpert(); | |||
@@ -21,6 +21,7 @@ import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | |||
import com.ningdatech.pmapi.projectdeclared.model.dto.PretrialDeclaredExportDTO; | |||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectConditionDTO; | |||
import com.ningdatech.pmapi.projectdeclared.model.req.ConstrctionPlanListReq; | |||
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.helper.ProjectHelper; | |||
@@ -93,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(); | |||
@@ -151,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(); | |||
@@ -186,6 +187,7 @@ public class ConstructionPlanManage { | |||
ProjectInst projectInst = new ProjectInst(); | |||
projectInst.setProjectId(project.getId()); | |||
projectInst.setInstCode(instanceId); | |||
projectInst.setInstType(InstTypeEnum.CONSTRUCTION_PLAN_REVIEW.getCode()); | |||
projectInst.setCreatOn(LocalDateTime.now()); | |||
projectInst.setUpdateOn(LocalDateTime.now()); | |||
projectInstService.save(projectInst); | |||
@@ -207,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()); | |||
@@ -221,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()); | |||
@@ -1,9 +1,6 @@ | |||
package com.ningdatech.pmapi.projectlib.handle; | |||
import java.time.LocalDate; | |||
import java.time.LocalDateTime; | |||
import java.util.*; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | |||
@@ -31,10 +28,9 @@ import static com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum.*; | |||
@Order(7) | |||
@Component | |||
public class ProjectApprovalHandle extends AbstractProcessBusinessHandle { | |||
private final AnnualPlanLibManage annualPlanLibManage; | |||
private final INdProjectStatusChangeService projectStatusChangeService; | |||
private final IProjectService projectService; | |||
private final AnnualPlanLibManage annualPlanLibManage; | |||
/** | |||
* 项目状态为:待立项批复之前的状态 | |||
@@ -91,11 +87,12 @@ public class ProjectApprovalHandle extends AbstractProcessBusinessHandle { | |||
processDetailVO.setStepStatus(StepStatusEnum.ON_GOING); | |||
} else { | |||
// 当前项目状态为待立项批复之后的状态 | |||
// 根据立项批复的时间获取 | |||
LocalDate approvalDate = project.getApprovalDate(); | |||
LocalDateTime approvalDateTime = approvalDate.atStartOfDay(); | |||
processDetailVO.setFinishTime(approvalDateTime); | |||
// 取 状态机 改变状态时间 | |||
ProjectStatusChange projectStatusChange = projectStatusChangeService.getOne(Wrappers.lambdaQuery(ProjectStatusChange.class) | |||
.eq(ProjectStatusChange::getProjectId, projectId) | |||
.eq(ProjectStatusChange::getEvent, ProjectStatusChangeEvent.PROJECT_APPROVAL.name()) | |||
.last("limit 1")); | |||
processDetailVO.setFinishTime(projectStatusChange.getCreateOn()); | |||
processDetailVO.setStepStatus(StepStatusEnum.COMPLETED); | |||
} | |||
processDetailVO.setProcessName(CommonConst.PROJECT_APPROVAL); | |||
@@ -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,41 +208,43 @@ 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: | |||
//访客可以看全市的 | |||
break; | |||
case DASHBOARD: | |||
break; | |||
default: | |||
//没有权限的话 就让它查不到 | |||
query.eq(Project::getId,"NULL"); | |||
query.eq(Project::getId,0L); | |||
break; | |||
} | |||
return loginUser; | |||
return user; | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
package com.ningdatech.pmapi.sys.controller; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.basic.util.CollUtils; | |||
@@ -24,6 +25,7 @@ import org.springframework.validation.annotation.Validated; | |||
import org.springframework.web.bind.annotation.*; | |||
import javax.validation.Valid; | |||
import java.util.Collections; | |||
import java.util.List; | |||
/** | |||
@@ -69,7 +71,14 @@ public class MenuController { | |||
@ApiOperation(value = "查询当前登录用户的菜单", notes = "查询当前登录用户的菜单") | |||
@GetMapping("/myMenu") | |||
public List<MenuRoleVO> currentUserMenu() { | |||
List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class).orderByAsc(Menu::getSort)); | |||
List<Long> roleIdList = LoginUserUtil.getRoleIdList(); | |||
if (CollUtil.isEmpty(roleIdList)) { | |||
return Collections.emptyList(); | |||
} | |||
String tmpSql = "(" + CollUtils.joinByComma(roleIdList) + ")"; | |||
List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class) | |||
.exists("select 1 from nd_role_menu nur where nur.menu_id = nd_menu.id and nur.role_id in " + tmpSql) | |||
.orderByAsc(Menu::getSort)); | |||
return menuManage.buildUserMenu(list); | |||
} | |||
@@ -39,7 +39,8 @@ public class NotifyManage { | |||
.eq(Objects.nonNull(notifyListReq.getReaded()), Notify::getReaded, notifyListReq.getReaded()) | |||
.eq(Notify::getUserId, userId) | |||
.like(Objects.nonNull(notifyListReq.getTitle()), Notify::getTitle, notifyListReq.getTitle()) | |||
.eq(Objects.nonNull(notifyListReq.getType()), Notify::getType, notifyListReq.getType()); | |||
.eq(Objects.nonNull(notifyListReq.getType()), Notify::getType, notifyListReq.getType()) | |||
.orderByDesc(Notify::getCreateTime); | |||
notifyService.page(page,wrapper); | |||
if(page.getTotal() == 0L){ | |||
return PageVo.empty(); | |||
@@ -3,6 +3,8 @@ package com.ningdatech.pmapi.sys.service; | |||
import com.baomidou.mybatisplus.extension.service.IService; | |||
import com.ningdatech.pmapi.sys.model.entity.UserRole; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* 业务接口 | |||
@@ -20,4 +22,15 @@ public interface IUserRoleService extends IService<UserRole> { | |||
* @return 是否正确 | |||
*/ | |||
boolean initAdmin(Long userId); | |||
/** | |||
* 查询角色关联的用户ID | |||
* | |||
* @param roleId 角色ID | |||
* @return 用户ID集合 | |||
* @author WendyYang | |||
**/ | |||
List<Long> listUserIdByRoleId(Long roleId); | |||
} |
@@ -12,10 +12,10 @@ import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.basic.exception.code.ExceptionCode; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.cache.repository.CachePlusOps; | |||
import com.ningdatech.pmapi.sys.mapper.RoleMapper; | |||
import com.ningdatech.pmapi.sys.model.dto.MenuDataScopeDTO; | |||
import com.ningdatech.pmapi.sys.model.dto.RoleSaveDTO; | |||
import com.ningdatech.pmapi.sys.model.dto.RoleUpdateDTO; | |||
import com.ningdatech.pmapi.sys.mapper.RoleMapper; | |||
import com.ningdatech.pmapi.sys.model.entity.*; | |||
import com.ningdatech.pmapi.sys.service.*; | |||
import com.ningdatech.pmapi.sys.utils.AuthCacheKeyUtils; | |||
@@ -40,18 +40,12 @@ import java.util.stream.Collectors; | |||
@RequiredArgsConstructor | |||
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService { | |||
private final IUserRoleService IUserRoleService; | |||
private final IUserRoleService userRoleService; | |||
private final RoleMapper roleMapper; | |||
private final IRoleMenuDatascopeService roleMenuDatascopeService; | |||
private final CachePlusOps cachePlusOps; | |||
private final IRoleMenuService roleMenuService; | |||
private final IMenuService IMenuService; | |||
private static final String SUPER_ADMIN = "SUPER_ADMIN"; | |||
private final IMenuService menuService; | |||
/** | |||
* 删除角色时,需要级联删除跟角色相关的一切资源: | |||
@@ -68,7 +62,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR | |||
return true; | |||
} | |||
if (IUserRoleService.count(Wrappers.lambdaQuery(UserRole.class).select(UserRole::getUserId) | |||
if (userRoleService.count(Wrappers.lambdaQuery(UserRole.class).select(UserRole::getUserId) | |||
.in(UserRole::getRoleId, ids)) > 0) { | |||
throw new BizException(ExceptionCode.OPERATION_EX.getCode(), "该角色下还有用户 不能随意删除!"); | |||
} | |||
@@ -77,7 +71,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR | |||
boolean removeFlag = removeByIds(ids); | |||
//角色拥有的用户 | |||
IUserRoleService.remove(Wrappers.lambdaQuery(UserRole.class).in(UserRole::getRoleId, ids)); | |||
userRoleService.remove(Wrappers.lambdaQuery(UserRole.class).in(UserRole::getRoleId, ids)); | |||
if (removeFlag) { | |||
// 角色绑定了那些用户 | |||
if (roleMenuService.remove(Wrappers.lambdaQuery(RoleMenu.class).in(RoleMenu::getRoleId, ids))) { | |||
@@ -149,18 +143,19 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR | |||
public void updateRole(RoleUpdateDTO data, Long userId) { | |||
Role roleOld = roleMapper.selectById(data.getId()); | |||
if (Objects.isNull(roleOld)) { | |||
throw new BaseUncheckedException(HttpStatus.HTTP_OK, String.format("修改用户%d 为空", data.getId())); | |||
throw BizException.wrap("修改用户 %d 为空", data.getId()); | |||
} | |||
if (StrUtil.isNotBlank(data.getName()) && check(data.getName(), roleOld.getId())) { | |||
throw BizException.wrap("角色名{} 已经存在", data.getName()); | |||
throw BizException.wrap("角色名 %s 已经存在", data.getName()); | |||
} | |||
Role role = BeanUtil.toBean(data, Role.class); | |||
role.setUpdateBy(userId); | |||
updateById(role); | |||
saveRoleMenu(data.getMenuIds(), role.getId()); | |||
saveRoleMenuDatascope(data.getMenuDataScopeList(), role.getId()); | |||
cachePlusOps.del(AuthCacheKeyUtils.userResourceCacheKey(userId)); | |||
List<Long> userIdList = userRoleService.listUserIdByRoleId(role.getId()); | |||
userIdList.forEach(w -> cachePlusOps.del(AuthCacheKeyUtils.userResourceCacheKey(w))); | |||
} | |||
@Override | |||
@@ -180,11 +175,11 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR | |||
} | |||
private void saveRoleMenu(List<Long> menuIds, Long roleId) { | |||
roleMenuService.remove(Wrappers.lambdaQuery(RoleMenu.class).eq(RoleMenu::getRoleId, roleId)); | |||
if (CollUtil.isNotEmpty(menuIds)) { | |||
roleMenuService.remove(Wrappers.lambdaQuery(RoleMenu.class).eq(RoleMenu::getRoleId, roleId)); | |||
Set<RoleMenu> toAddMenus = new HashSet<>(); | |||
for (Long menuId : menuIds) { | |||
Menu menu = IMenuService.getById(menuId); | |||
Menu menu = menuService.getById(menuId); | |||
if (Objects.isNull(menu)) { | |||
continue; | |||
} | |||
@@ -203,7 +198,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR | |||
if (Objects.isNull(menu.getPid()) || menu.getPid().equals(0L)) { | |||
return; | |||
} | |||
Menu parent = IMenuService.getById(menu.getPid()); | |||
Menu parent = menuService.getById(menu.getPid()); | |||
if (Objects.isNull(parent)) { | |||
return; | |||
} | |||
@@ -4,16 +4,19 @@ import cn.hutool.http.HttpStatus; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
import com.ningdatech.basic.exception.BaseUncheckedException; | |||
import com.ningdatech.pmapi.sys.model.entity.Role; | |||
import com.ningdatech.pmapi.sys.model.entity.UserRole; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.pmapi.sys.mapper.RoleMapper; | |||
import com.ningdatech.pmapi.sys.mapper.UserRoleMapper; | |||
import com.ningdatech.pmapi.sys.model.entity.Role; | |||
import com.ningdatech.pmapi.sys.model.entity.UserRole; | |||
import com.ningdatech.pmapi.sys.service.IUserRoleService; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.stereotype.Service; | |||
import org.springframework.transaction.annotation.Transactional; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* 业务实现类 | |||
@@ -46,4 +49,12 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i | |||
return super.save(userRole); | |||
} | |||
@Override | |||
public List<Long> listUserIdByRoleId(Long roleId) { | |||
List<UserRole> userRoles = this.list(Wrappers.<UserRole>lambdaQuery() | |||
.eq(UserRole::getRoleId, roleId)); | |||
return CollUtils.fieldList(userRoles, UserRole::getUserId); | |||
} | |||
} |
@@ -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,11 +4,13 @@ package com.ningdatech.pmapi.todocenter.constant; | |||
* @author CMM | |||
* @since 2023/02/01 14:56 | |||
*/ | |||
public interface WorkNotice { | |||
public final String PASS_MSG_TEMPLATE = "标题:审核任务 内容:【%s】的【%s】需要您审核。"; | |||
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】被退回,请及时处理。"; | |||
public final String REJECT_MSG_TEMPLATE = "【%s】的【%s】被驳回,请及时处理。"; | |||
public final String AUDIT_WORK_TITLE = "审核任务"; | |||
} |
@@ -0,0 +1,223 @@ | |||
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.apache.commons.lang3.StringUtils; | |||
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(); | |||
//假设 作为上一个会签/或签的第一个点 | |||
ProgressNode beforeAndOrNode = null; | |||
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(beforeAndOrNode); | |||
} | |||
beforeAndOr.add(progressNodes.get(i)); | |||
} | |||
}else{ | |||
thisAndOrNodeId = progressNodes.get(i).getNodeId(); | |||
//存在假设可能 | |||
beforeAndOrNode = progressNodes.get(i); | |||
if(!enterBefore){ | |||
beforeNode = progressNodes.get(i); | |||
enterBefore = Boolean.TRUE; | |||
continue; | |||
} | |||
break; | |||
} | |||
} | |||
return beforeNode; | |||
} | |||
/** | |||
* 1.判断 当前 撤回人 是否是 发起人 | |||
* 2.并且流程 尚未开始审批 | |||
* @return | |||
*/ | |||
public boolean canRootWithDraw(HistoricProcessInstance instance,String employeeCode) { | |||
String startUserId = instance.getStartUserId(); | |||
//如果流程发起人 不是 当前登录人 直接返回false | |||
if(StringUtils.isBlank(employeeCode) || StringUtils.isBlank(startUserId) | |||
|| !employeeCode.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) { | |||
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; | |||
@@ -12,15 +9,12 @@ import java.util.stream.Collectors; | |||
import javax.servlet.http.HttpServletResponse; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.wflow.workflow.enums.ProcessStatusEnum; | |||
import com.ningdatech.pmapi.projectdeclared.manage.DeclaredProjectManage; | |||
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; | |||
@@ -32,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; | |||
@@ -47,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; | |||
@@ -67,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; | |||
@@ -89,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; | |||
@@ -144,6 +126,11 @@ public class TodoCenterManage { | |||
private final ICompanySignatureService companySignatureService; | |||
private final StatisticsService statisticsService; | |||
private final INotifyService notifyService; | |||
private final DeclaredProjectManage declaredProjectManage; | |||
private final HandlerManage handlerManage; | |||
private final WithDrawHandle withDrawHandle; | |||
/** | |||
* 待办中心待我处理项目列表查询 | |||
@@ -164,12 +151,13 @@ public class TodoCenterManage { | |||
ProjectListReq projectListReq = new ProjectListReq(); | |||
BeanUtils.copyProperties(param, projectListReq); | |||
List<Project> projects = projectLibManage.projectList(projectListReq); | |||
if(CollUtil.isEmpty(projects)){ | |||
return PageVo.empty(); | |||
} | |||
Map<Long, Project> projectsMap = projects.stream().collect(Collectors.toMap(Project::getId, v -> v)); | |||
// 再查出项目关联的流程实例ID | |||
List<Long> projectIdList = projects.stream().map(Project::getId).collect(Collectors.toList()); | |||
if(CollUtil.isEmpty(projectIdList)){ | |||
return PageVo.empty(); | |||
} | |||
List<ProjectInst> projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) | |||
.in(ProjectInst::getProjectId, projectIdList) | |||
.orderByDesc(ProjectInst::getProjectId)); | |||
@@ -192,6 +180,7 @@ public class TodoCenterManage { | |||
return PageVo.empty(); | |||
} | |||
todoList = todoList.stream().filter(Objects::nonNull).collect(Collectors.toList()); | |||
List<ProcessTaskVo> userTodoList = todoList.stream() | |||
.skip((long) (pageNumber - 1) * pageSize) | |||
.limit(pageSize) | |||
@@ -215,6 +204,7 @@ public class TodoCenterManage { | |||
res.setNodeId(taskVo.getTaskDefKey()); | |||
res.setProcessStatusName(taskVo.getStatus()); | |||
res.setProcessLaunchTime(d.getCreateTime()); | |||
res.setProcessDefName(d.getProcessDefName()); | |||
return res; | |||
}).collect(Collectors.toList()); | |||
return PageVo.of(resVos, todoList.size()); | |||
@@ -241,17 +231,18 @@ public class TodoCenterManage { | |||
ProjectListReq projectListReq = new ProjectListReq(); | |||
BeanUtils.copyProperties(param, projectListReq); | |||
List<Project> projects = projectLibManage.projectList(projectListReq); | |||
Map<Long, Project> projectsMap = projects.stream().collect(Collectors.toMap(Project::getId, v -> v)); | |||
// 再查出项目关联的流程实例ID | |||
List<Long> projectIdList = projects.stream().map(Project::getId).collect(Collectors.toList()); | |||
List<ProjectInst> projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) | |||
.in(ProjectInst::getProjectId, projectIdList) | |||
.orderByDesc(ProjectInst::getProjectId)); | |||
Map<String, Project> projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p-> projectsMap.get(p.getProjectId()))); | |||
List<String> instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); | |||
List<ProcessTaskVo> userTodoList = Lists.newArrayList(); | |||
if (CollUtil.isNotEmpty(instCodes)) { | |||
Map<String, Project> projectInfoMap = Maps.newHashMap(); | |||
if (CollUtil.isNotEmpty(projects)) { | |||
Map<Long, Project> projectsMap = projects.stream().collect(Collectors.toMap(Project::getId, v -> v)); | |||
// 再查出项目关联的流程实例ID | |||
List<Long> projectIdList = projects.stream().map(Project::getId).collect(Collectors.toList()); | |||
List<ProjectInst> projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) | |||
.in(ProjectInst::getProjectId, projectIdList) | |||
.orderByDesc(ProjectInst::getProjectId)); | |||
projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p-> projectsMap.get(p.getProjectId()))); | |||
List<String> instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); | |||
// 查出用户工作流 | |||
TodoCenterListReqDTO req = new TodoCenterListReqDTO(); | |||
req.setInstCodes(instCodes); | |||
@@ -293,7 +284,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(); | |||
// 获取入参 | |||
@@ -301,15 +292,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); | |||
@@ -317,9 +306,8 @@ public class TodoCenterManage { | |||
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery() | |||
.processInstanceId(processInstanceId) | |||
.singleResult(); | |||
// 获取流程定义名称 | |||
String processDefinitionName = instance.getProcessDefinitionName(); | |||
//进入处理逻辑 | |||
switch (param.getAction()) { | |||
// 通过 | |||
case PASS: | |||
@@ -327,134 +315,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,employeeCode)){ | |||
// 登录用户是流程发起人,且是流程发起人撤回 | |||
processTaskService.handleTask(param, employeeCode); | |||
// 若是流程发起人点击撤回,项目回到上一个状态,需调用状态机更新项目状态,流程状态更新为审核通过 | |||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(projectStatus))) { | |||
// 当前项目状态是单位内部审核中 | |||
case UNDER_INTERNAL_AUDIT: | |||
// 当前项目状态是预审中 | |||
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); | |||
}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); | |||
} | |||
break; | |||
default: | |||
@@ -462,150 +359,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()); | |||
VUtils.isTrue(!currentUserInfo.getOrganizationCode().equals(user.getOrganizationCode())) | |||
.throwMessage("当前审核人和您不是同一个部门,无法撤回!"); | |||
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(msg); | |||
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 | |||
@@ -666,166 +419,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) { | |||
stateMachineUtils.pass(declaredProject); | |||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||
declaredProject.setUpdateBy(userId); | |||
projectService.updateById(declaredProject); | |||
} | |||
/** | |||
* 获取流程发起节点的用户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); | |||
} catch (Exception e) { | |||
throw new BizException("状态机执行失败!"); | |||
} | |||
} | |||
/** | |||
* 查询流程表单数据及审批的进度步骤 | |||
* | |||
@@ -845,18 +438,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()); | |||
} | |||
/** | |||
* 待办中心我已处理项目列表查询 | |||
@@ -1290,14 +875,8 @@ public class TodoCenterManage { | |||
if(!modifyProject(projectDto)){ | |||
throw new BusinessException("调整项目失败!"); | |||
} | |||
//最后去审批(通过)当前退回节点的审核任务 | |||
ReqProcessHandlerDTO handlerDTO = new ReqProcessHandlerDTO(); | |||
handlerDTO.setProjectId(dto.getProjectId()); | |||
handlerDTO.setInstanceId(dto.getInstanceId()); | |||
handlerDTO.setTaskId(dto.getTaskId()); | |||
handlerDTO.setAction(ProcessHandlerEnum.PASS); | |||
handler(handlerDTO); | |||
// 更新当前流程状态为审核中 | |||
processTaskService.updateProInstStatus(dto.getInstanceId()); | |||
return dto.getInstanceId(); | |||
} | |||
@@ -14,4 +14,6 @@ public interface StatisticsMapper extends BaseMapper { | |||
TodoCenterStatisticsPO mysubmitNum(@Param("employeeCode") String employeeCode); | |||
TodoCenterStatisticsPO ccNums(@Param("employeeCode") String employeeCode); | |||
TodoCenterStatisticsPO getIdo(String employeeCode); | |||
} |
@@ -27,12 +27,18 @@ | |||
<select id="getTodoOrIdo" parameterType="java.lang.String" | |||
resultType="com.ningdatech.pmapi.todocenter.model.po.TodoCenterStatisticsPO"> | |||
SELECT | |||
sum(CASE WHEN ht.assignee_ = #{employeeCode} AND ht.end_time_ is NULL THEN 1 end) todoNum, | |||
sum(CASE WHEN ht.assignee_ = #{employeeCode} AND ht.end_time_ IS not NULL THEN 1 end) idoNum | |||
sum(CASE WHEN ht.assignee_ = #{employeeCode} AND ht.end_time_ is NULL THEN 1 end) todoNum | |||
FROM | |||
act_hi_taskinst ht | |||
</select> | |||
<select id="getIdo" parameterType="java.lang.String" | |||
resultType="com.ningdatech.pmapi.todocenter.model.po.TodoCenterStatisticsPO"> | |||
SELECT count(0) idoNum | |||
FROM act_hi_taskinst ht WHERE ht.assignee_ = #{employeeCode} | |||
AND ht.end_time_ IN (SELECT max(end_time_) FROM act_hi_taskinst WHERE ht.end_time_ is not NULL GROUP BY PROC_INST_ID_) | |||
</select> | |||
<select id="mysubmitNum" parameterType="java.lang.String" | |||
resultType="com.ningdatech.pmapi.todocenter.model.po.TodoCenterStatisticsPO"> | |||
SELECT | |||
@@ -60,4 +60,7 @@ public class ResToBeProcessedVO implements Serializable { | |||
@ApiModelProperty("流程处理时间") | |||
@JSONField(format = "yyyy-MM-dd HH:mm") | |||
private Date processHandleTime; | |||
@ApiModelProperty("流程定义名称") | |||
private String processDefName; | |||
} |
@@ -24,12 +24,14 @@ public class StatisticsServiceImpl implements StatisticsService { | |||
public TodoCenterStatisticsPO getStatistics(String employeeCode) { | |||
TodoCenterStatisticsPO res = new TodoCenterStatisticsPO(); | |||
TodoCenterStatisticsPO todoOrIdo = mapper.getTodoOrIdo(employeeCode); | |||
if(Objects.nonNull(todoOrIdo)){ | |||
res.setTodoNum(todoOrIdo.getTodoNum()); | |||
res.setIdoNum(todoOrIdo.getIdoNum()); | |||
TodoCenterStatisticsPO todo = mapper.getTodoOrIdo(employeeCode); | |||
if(Objects.nonNull(todo)){ | |||
res.setTodoNum(todo.getTodoNum()); | |||
} | |||
TodoCenterStatisticsPO ido = mapper.getIdo(employeeCode); | |||
if(Objects.nonNull(ido)){ | |||
res.setIdoNum(ido.getIdoNum()); | |||
} | |||
TodoCenterStatisticsPO submit = mapper.mysubmitNum(employeeCode); | |||
if(Objects.nonNull(submit)){ | |||
res.setMysubmitNum(submit.getMysubmitNum()); | |||
@@ -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,15 @@ 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.flowable.engine.runtime.ActivityInstance; | |||
import org.junit.Test; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import java.util.List; | |||
/** | |||
* @Classname InstanceTest | |||
* @Description | |||
@@ -18,6 +23,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 +33,25 @@ 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(); | |||
HistoricActivityInstance historicActivityInstance = finished.get(0); | |||
System.out.println(finished); | |||
} | |||
@Test | |||
public void testRuntime(){ | |||
//如果有已经被审核过的 节点 | |||
List<ActivityInstance> userTask = runtimeService.createActivityInstanceQuery() | |||
.processInstanceId("1709ebe3-d148-11ed-9351-02426daa406d") | |||
.activityType("userTask") | |||
.orderByActivityInstanceStartTime().asc().list(); | |||
System.out.println(userTask); | |||
} | |||
} |
@@ -24,10 +24,10 @@ public class StateMachineTest extends AppTests { | |||
@Test | |||
public void stateMachineTest() { | |||
Project project = new Project(); | |||
project.setStage(ProjectStatusEnum.PROJECT_APPROVED.getCode()); | |||
project.setStatus(ProjectStatusEnum.IN_THE_ANNUAL_PLAN.getCode()); | |||
project.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||
project.setStatus(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()); | |||
project.setDeclareAmount(BigDecimal.valueOf(2000)); | |||
stateMachineUtils.pass(project); | |||
stateMachineUtils.withDraw(project); | |||
System.out.println(String.format("project:%s", JSON.toJSONString(project))); | |||
} | |||
} |
@@ -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); | |||
// 放入工作通知暂存表中,通过扫表异步发送 | |||
@@ -1,5 +1,5 @@ | |||
server: | |||
port: 28888 | |||
port: 38888 | |||
servlet: | |||
context-path: /pm | |||
@@ -15,7 +15,7 @@ spring: | |||
timeout: 5000 | |||
host: 47.98.125.47 | |||
port: 26379 | |||
database: 0 | |||
database: 4 | |||
password: Ndkj1234 | |||
jedis: | |||
pool: | |||
@@ -87,7 +87,11 @@ spring: | |||
wall: | |||
config: | |||
multi-statement-allow: true | |||
#设置上传 单个文件的大小 | |||
servlet: | |||
multipart: | |||
max-file-size: 100MB | |||
max-request-size: 150MB | |||
mybatis-plus: | |||
configuration: | |||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | |||
@@ -97,22 +101,21 @@ mybatis-plus: | |||
logic-not-delete-value: false | |||
logging: | |||
config: classpath:logback-spring.xml | |||
#日志配置 | |||
#日志配置 | |||
level: | |||
root: info | |||
file: | |||
path: logs | |||
nd: | |||
log: | |||
enabled: true | |||
type: DB | |||
cache: | |||
type: REDIS | |||
serializerType: ProtoStuff | |||
cacheNullVal: true | |||
def: | |||
keyPrefix: pm | |||
log: | |||
enabled: true | |||
type: DB | |||
# 文件存储 | |||
file: | |||
storage-type: ALI_OSS | |||
@@ -172,15 +175,36 @@ sa-token: | |||
token-style: uuid | |||
# 是否输出操作日志 | |||
is-log: false | |||
#浙政钉公司顶级organizationCode | |||
organization: | |||
dept-visible-scopes: | |||
- GO_ff70e47bae684fdba0d64f4acab85661 | |||
yxt: | |||
# wsdl-url: http://115.239.137.23:9501/ws/v1?wsdl | |||
wsdl-url: classpath:/wsdl.xml | |||
#账号 | |||
user-code: hzndkj | |||
#密码 | |||
password: hzndkj@2021 | |||
#音信通开关 | |||
sms-enable: true | |||
tel-enable: true | |||
#省局联审 请求信息 | |||
provincial: | |||
host: http://zj.ningdatech.com/prometheus-zhejiang_foreign | |||
pushUrl: /api/v1/foreign/importantPro | |||
detailUrl: /api/v1/foreign/importantProView | |||
key: 7196317343a64e67895dc0375c098fe7 | |||
secret: 75152a97f20e4c4c854dc6301cf72ad4 | |||
#专有钉钉 | |||
ding: | |||
#扫码 | |||
app-auth-key: expert-base_dingoa-c5nnefYVnie | |||
app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L | |||
# #免登/获取信息 | |||
app-key: file-manage-4Mjx9358wuxjyYFjY3 | |||
app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O | |||
#专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | |||
tenantId: 31141 | |||
domain: openplatform.dg-work.cn | |||
#天印服务器接口信息 | |||
irs: | |||
seal-platform: | |||
project-id: 1 | |||
project-secret: 2 | |||
access-key: 3 | |||
secret-key: 4 | |||
api-url: https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220309000004/seal-platform/seal/v1/rest/sign/signPdf |
@@ -2,11 +2,9 @@ | |||
integration: | |||
zwdd: | |||
#扫码 | |||
app-auth-key: expert-base_dingoa-c5nnefYVnie | |||
app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L | |||
# #免登/获取信息 | |||
# app-key: file-manage-4Mjx9358wuxjyYFjY3 | |||
# app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O | |||
app-auth-key: ls-rebuild_dingoa-rgeWs3YVr26z | |||
app-auth-secret: 37qCe6ylNMW0N8K2741z0c2b9vJP2gtuMRQQtZ9P | |||
#免登/获取信息 | |||
app-key: ls_rebuild-10c8n5X0707yFV7jURr | |||
app-secret: gN8J3WazyXLMWKDuFmx6C4yaH5lFUY41x8rYLLo6 | |||
#专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | |||
@@ -1,11 +1,12 @@ | |||
#专有钉钉 | |||
ding: | |||
#扫码 | |||
app-auth-key: expert-base_dingoa-c5nnefYVnie | |||
app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L | |||
# #免登/获取信息 | |||
app-key: file-manage-4Mjx9358wuxjyYFjY3 | |||
app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O | |||
#专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | |||
tenantId: 31141 | |||
domain: openplatform.dg-work.cn | |||
integration: | |||
zwdd: | |||
#扫码 | |||
app-auth-key: ls-rebuild_dingoa-rgeWs3YVr26z | |||
app-auth-secret: 37qCe6ylNMW0N8K2741z0c2b9vJP2gtuMRQQtZ9P | |||
#免登/获取信息 | |||
app-key: ls_rebuild-10c8n5X0707yFV7jURr | |||
app-secret: gN8J3WazyXLMWKDuFmx6C4yaH5lFUY41x8rYLLo6 | |||
#专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | |||
tenantId: 31141 | |||
domain: openplatform.dg-work.cn |
@@ -2,7 +2,8 @@ security: | |||
auth: | |||
auth-require-url: /api/v1/user/auth/auth-require | |||
invalid-session-url: /api/v1/user/auth/invalid-session | |||
password-login-url: /api/v1/user/auth/login/password | |||
password-login-url: /api/v1/user/auth/login | |||
agent-login-url: /api/v1/user/auth/agent-login | |||
logout-url: /api/v1/user/auth/logout | |||
ignore-auth-urls: | |||
- /v2/api-docs | |||
@@ -15,13 +16,13 @@ security: | |||
- /api/v1/user/auth/invalid-session | |||
- /api/v1/user/auth/login/password | |||
- /api/v1/user/auth/forget-password | |||
- /api/v1/** | |||
- /doc.html | |||
- /ok.html | |||
- /open/api/** | |||
- /oa/** | |||
- /wflow/** | |||
- /sys/** | |||
- /api/v1/verification/** | |||
ignore-csrf-urls: | |||
- /api/v1/user/auth/** | |||
- /v2/api-docs | |||
@@ -38,6 +39,7 @@ security: | |||
- /oa/** | |||
- /wflow/** | |||
- /sys/** | |||
- /api/v1/verification/** | |||
role-map: | |||
"engineer": | |||
"project_manager": | |||
@@ -49,5 +51,4 @@ security: | |||
- /api/v1/user-info/save | |||
- /api/v1/user-info/del | |||
- /api/v1/user-info/kick-off/** | |||
- /api/v1/user-info/password/mod | |||
- /api/v1/** | |||
- /api/v1/user-info/password/mod |
@@ -2,7 +2,7 @@ security: | |||
auth: | |||
auth-require-url: /api/v1/user/auth/auth-require | |||
invalid-session-url: /api/v1/user/auth/invalid-session | |||
password-login-url: /api/v1/user/auth/login/password | |||
password-login-url: /api/v1/user/auth/login | |||
logout-url: /api/v1/user/auth/logout | |||
ignore-auth-urls: | |||
- /v2/api-docs | |||
@@ -0,0 +1,286 @@ | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||
<html | |||
xmlns="http://www.w3.org/1999/xhtml" | |||
xmlns:font-family="http://www.w3.org/1999/xhtml" | |||
> | |||
<head> | |||
<meta charset="UTF-8" /> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
<title>Document</title> | |||
<style> | |||
html, | |||
body { | |||
padding: 0; | |||
margin: 0; | |||
font-family: SimSun; | |||
} | |||
.pdf { | |||
margin: 0 auto; | |||
padding: 10px 0 30px; | |||
text-align: center; | |||
} | |||
.title { | |||
padding: 0 0 40px 0; | |||
font-size: 34px; | |||
margin: 40px 0 0 0; | |||
font-family: SimSun; | |||
} | |||
.tab { | |||
padding: 0 20px; | |||
} | |||
.projectId { | |||
color: #999999; | |||
text-align: left; | |||
margin-bottom: 8px; | |||
} | |||
.projectId > .time { | |||
float: right; | |||
} | |||
table { | |||
width: 100%; | |||
border-collapse: collapse; | |||
font-size: 16px; | |||
table-layout: fixed; | |||
word-break: break-all; | |||
word-wrap: break-word; | |||
text-align: left; | |||
} | |||
td { | |||
padding: 15px 8px; | |||
border: 1px solid; | |||
} | |||
.tabTit { | |||
background-color: #eee; | |||
} | |||
.label { | |||
width: 150px; | |||
} | |||
.sealTd { | |||
height: 200px; | |||
position: relative; | |||
} | |||
.seal { | |||
position: absolute; | |||
right: 20px; | |||
bottom: 30px; | |||
width: 150px; | |||
} | |||
.seal > .time { | |||
text-align: right; | |||
} | |||
.content { | |||
height: 150px; | |||
} | |||
.text { | |||
min-height: 150px; | |||
} | |||
.content > .right { | |||
float: right; | |||
margin-right: 10px; | |||
} | |||
</style> | |||
</head> | |||
<body> | |||
<div class="pdf"> | |||
<p class="title"> | |||
<span>#title#</span> | |||
</p> | |||
<div class="tab"> | |||
<p class="projectId"> | |||
<span> | |||
项目编号: | |||
<span>#projectNo#</span> | |||
</span> | |||
<span class="time">#time#</span> | |||
</p> | |||
<table> | |||
<tbody> | |||
<tr> | |||
<td class="tabTit" colspan="4">项目基本信息</td> | |||
</tr> | |||
<tr> | |||
<td class="label">项目名称</td> | |||
<td colspan="3" align="center">#projectName#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">是否临时增补</td> | |||
<td align="center">#isTemporaryAugment#</td> | |||
<td class="label">是否一地创新全省共享项目</td> | |||
<td align="center">#isInnovateWholeProvinceShare#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">项目负责人</td> | |||
<td align="center">#responsibleMan#</td> | |||
<td class="label">负责人手机号</td> | |||
<td align="center">#responsibleManMobile#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">项目联系人</td> | |||
<td align="center">#contactName#</td> | |||
<td class="label">项目联系人手机号</td> | |||
<td align="center">#contactPhone#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">建设单位</td> | |||
<td align="center">#buildOrgName#</td> | |||
<td class="label">建设单位统一社会信用代码</td> | |||
<td align="center">#orgCreditCode#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">项目类型</td> | |||
<td align="center">#projectType#</td> | |||
<td class="label">是否首次新建</td> | |||
<td align="center">#isFirst#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">预算年度</td> | |||
<td align="center">#projectYear#</td> | |||
<td class="label">建设起止时间</td> | |||
<td align="center">#beginAndEndTime#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">四大体系</td> | |||
<td colspan="3" align="center">#fourSystems#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">是否数字化改革项目</td> | |||
<td align="center">#isDigitalReform#</td> | |||
<td class="label">综合业务领域</td> | |||
<td align="center">#bizDomain#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">立项依据</td> | |||
<td colspan="3" align="center">#buildBasisList#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">是否上云</td> | |||
<td align="center">#isCloud#</td> | |||
<td class="label">云类型</td> | |||
<td align="center">#cloudType#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">项目简介</td> | |||
<td colspan="3" align="center">#projectIntroduction#</td> | |||
</tr> | |||
<tr> | |||
<td class="tabTit" colspan="4">资金申报情况</td> | |||
</tr> | |||
<tr> | |||
<td class="label">申报金额</td> | |||
<td colspan="3" align="center">#declareAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">自有资金</td> | |||
<td align="center">#declareHaveAmount#</td> | |||
<td class="label">政府投资-本级财政资金</td> | |||
<td align="center">#declareGovOwnFinanceAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">政府投资-上级补助资金</td> | |||
<td align="center">#declareGovSuperiorFinanceAmount#</td> | |||
<td class="label">银行贷款</td> | |||
<td align="center">#declareBankLendingAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">其他资金</td> | |||
<td colspan="3" align="center">#declareOtherAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">本年计划投资(万元)</td> | |||
<td colspan="3" align="center">#yearPlanInvest#</td> | |||
</tr> | |||
<tr> | |||
<td class="tabTit" colspan="4">资金分配情况</td> | |||
</tr> | |||
<tr> | |||
<td class="label">软件开发</td> | |||
<td align="center">#softwareDevelopmentAmount#</td> | |||
<td class="label">云资源、硬件购置</td> | |||
<td align="center">#cloudHardwarePurchaseAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">第三方服务</td> | |||
<td colspan="3" align="center">#thirdPartyAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="tabTit" colspan="4">年度支付计划</td> | |||
</tr> | |||
<tr> | |||
<td class="label">年度支付金额</td> | |||
<td colspan="3" align="center">#annualPlanAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">自有资金</td> | |||
<td align="center">#annualPlanHaveAmount#</td> | |||
<td class="label">政府投资-本级财政资金</td> | |||
<td align="center">#annualPlanGovOwnFinanceAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">政府投资-上级补助资金</td> | |||
<td align="center">#annualPlanGovSuperiorFinanceAmount#</td> | |||
<td class="label">银行贷款</td> | |||
<td align="center">#annualPlanBankLendingAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="label">其他资金</td> | |||
<td colspan="3" align="center">#annualPlanOtherAmount#</td> | |||
</tr> | |||
<tr> | |||
<td class="tabTit" colspan="4">备注</td> | |||
</tr> | |||
<tr> | |||
<td class="label">备注</td> | |||
<td colspan="3" align="center">#projectRemarks#</td> | |||
</tr> | |||
<tr> | |||
<td class="tabTit" colspan="4">单位意见</td> | |||
</tr> | |||
<tr> | |||
<td class="label">本级主管单位意见(盖章)</td> | |||
<td colspan="3" class="text content"> | |||
<div class="right"> | |||
<p> | |||
<span>#superOrgOpinion#</span> | |||
</p> | |||
<p> | |||
<span>#superOrgAuditDate#</span> | |||
</p> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td class="label">上级主管单位意见(盖章)</td> | |||
<td colspan="3" class="text content"> | |||
<div class="right"> | |||
<p> | |||
<span>#higherOrgOpinion#</span> | |||
</p> | |||
<p> | |||
<span>#higherOrgAuditDate#</span> | |||
</p> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td class="label"> | |||
<span>#bigDataBureauName#</span> | |||
意见(盖章) | |||
</td> | |||
<td colspan="3" class="text content"> | |||
<div class="right"> | |||
<p> | |||
<span>#bigDataBureauOpinion#</span> | |||
</p> | |||
<p> | |||
<span>#bigDataBureauAuditDate#</span> | |||
</p> | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</body> | |||
</html> |
@@ -0,0 +1,120 @@ | |||
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.v1.ws.api.service.yxt.gooben.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://v1.ws.api.service.yxt.gooben.com/" name="WsItfTask" targetNamespace="http://impl.v1.ws.api.service.yxt.gooben.com/"> | |||
<wsdl:import location="http://120.26.44.207:9501/ws/v1?wsdl=WsItfTask.wsdl" namespace="http://v1.ws.api.service.yxt.gooben.com/"> | |||
</wsdl:import> | |||
<wsdl:binding name="WsItfTaskSoapBinding" type="ns1:WsItfTask"> | |||
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> | |||
<wsdl:operation name="getSentResultCall"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="getSentResultCall"> | |||
<soap:header message="ns1:getSentResultCall" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="getSentResultCallResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="getSubmitResult"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="getSubmitResult"> | |||
<soap:header message="ns1:getSubmitResult" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="getSubmitResultResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="addFile"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="addFile"> | |||
<soap:header message="ns1:addFile" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="addFileResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="submitMCLZTask"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="submitMCLZTask"> | |||
<soap:header message="ns1:submitMCLZTask" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="submitMCLZTaskResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="getSentTaskResultCall"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="getSentTaskResultCall"> | |||
<soap:header message="ns1:getSentTaskResultCall" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="getSentTaskResultCallResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="getSentTaskResultSms"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="getSentTaskResultSms"> | |||
<soap:header message="ns1:getSentTaskResultSms" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="getSentTaskResultSmsResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="submitTask"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="submitTask"> | |||
<soap:header message="ns1:submitTask" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="submitTaskResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="getSentResultSms"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="getSentResultSms"> | |||
<soap:header message="ns1:getSentResultSms" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="getSentResultSmsResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="authorization"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="authorization"> | |||
<soap:body use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="authorizationResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
<wsdl:operation name="getSmsReceive"> | |||
<soap:operation soapAction="" style="document"/> | |||
<wsdl:input name="getSmsReceive"> | |||
<soap:header message="ns1:getSmsReceive" part="token" use="literal"> | |||
</soap:header> | |||
<soap:body parts="parameters" use="literal"/> | |||
</wsdl:input> | |||
<wsdl:output name="getSmsReceiveResponse"> | |||
<soap:body use="literal"/> | |||
</wsdl:output> | |||
</wsdl:operation> | |||
</wsdl:binding> | |||
<wsdl:service name="WsItfTask"> | |||
<wsdl:port binding="tns:WsItfTaskSoapBinding" name="WsItfTaskImplPort"> | |||
<soap:address location="http://120.26.44.207:9501/ws/v1"/> | |||
</wsdl:port> | |||
</wsdl:service> | |||
</wsdl:definitions> |