@@ -56,7 +56,7 @@ public class GeneratorCodeKingbaseConfig { | |||||
} | } | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
generate("Poffy", "projectlib", PATH_YYD, "nd_project_inst"); | |||||
generate("WendyYang", "expert", PATH_YYD, "nd_review_template_settings"); | |||||
} | } | ||||
} | } |
@@ -1,45 +0,0 @@ | |||||
package com.ningdatech.pmapi.common.config; | |||||
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient; | |||||
import com.ningdatech.pmapi.common.util.SpringContextHolder; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.context.annotation.Bean; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.context.annotation.DependsOn; | |||||
/** | |||||
* @author CMM | |||||
* @since 2023/02/03 09:24 | |||||
*/ | |||||
@Configuration | |||||
@Slf4j | |||||
public class BeanConfig { | |||||
@Bean | |||||
public SpringContextHolder springContextHolder() { | |||||
return new SpringContextHolder(); | |||||
} | |||||
@Bean("authExecutableClient") | |||||
@DependsOn(value = "govDingProperties") | |||||
public ExecutableClient executableAuthClientInit() { | |||||
ExecutableClient executableClient = ExecutableClient.getInstance(); | |||||
executableClient.setAccessKey(GovDingProperties.appAuthkey); | |||||
executableClient.setSecretKey(GovDingProperties.appAuthsecret); | |||||
executableClient.setDomainName(GovDingProperties.domain); | |||||
executableClient.setProtocal("https"); | |||||
executableClient.init(); | |||||
return executableClient; | |||||
} | |||||
@Bean("executableClient") | |||||
@DependsOn(value = "govDingProperties") | |||||
public ExecutableClient executableClientInit() { | |||||
ExecutableClient executableClient = new ExecutableClient(); | |||||
executableClient.setAccessKey(GovDingProperties.appkey); | |||||
executableClient.setSecretKey(GovDingProperties.appsecret); | |||||
executableClient.setDomainName(GovDingProperties.domain); | |||||
executableClient.setProtocal("https"); | |||||
executableClient.init(); | |||||
return executableClient; | |||||
} | |||||
} |
@@ -1,65 +0,0 @@ | |||||
package com.ningdatech.pmapi.common.config; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.stereotype.Component; | |||||
import lombok.Data; | |||||
/** | |||||
* @description: 浙政钉配置 | |||||
* @author: liushuai | |||||
* @date: 2022/5/5 15:10 | |||||
*/ | |||||
@Data | |||||
@Component | |||||
public class GovDingProperties { | |||||
public static String appkey; | |||||
public static String appsecret; | |||||
public static String appAuthkey; | |||||
public static String appAuthsecret; | |||||
public static String appSsoAuthkey; | |||||
public static String appSsoAuthsecret; | |||||
public static Long tenantId; | |||||
public static String domain; | |||||
@Value("${ding.app-key}") | |||||
public void setPrivateKey(String appkey) { | |||||
GovDingProperties.appkey = appkey; | |||||
} | |||||
@Value("${ding.app-secret}") | |||||
public void setAppsecret(String appsecret) { | |||||
GovDingProperties.appsecret = appsecret; | |||||
} | |||||
@Value("${ding.app-auth-key}") | |||||
public void setAppAuthKey(String appAuthkey) { | |||||
GovDingProperties.appAuthkey = appAuthkey; | |||||
} | |||||
@Value("${ding.app-auth-secret}") | |||||
public void setAppAuthsecret(String appAuthsecret) { | |||||
GovDingProperties.appAuthsecret = appAuthsecret; | |||||
} | |||||
// @Value("${ding.app-sso-auth-key}") | |||||
// public void setAppSsoAuthKey(String appSsoAuthkey) { | |||||
// GovDingProperties.appSsoAuthkey = appSsoAuthkey; | |||||
// } | |||||
// | |||||
// @Value("${ding.app-sso-auth-secret}") | |||||
// public void setAppSsoAuthsecret(String appSsoAuthsecret) { | |||||
// GovDingProperties.appSsoAuthsecret = appSsoAuthsecret; | |||||
// } | |||||
@Value("${ding.tenantId}") | |||||
public void setTenantId(Long tenantId) { | |||||
GovDingProperties.tenantId = tenantId; | |||||
} | |||||
@Value("${ding.domain}") | |||||
public void setDomain(String domain) { | |||||
GovDingProperties.domain = domain; | |||||
} | |||||
} |
@@ -10,7 +10,6 @@ public class CommonConstant { | |||||
public static final String COOKIE_KEY = "ND_JSESSION"; | public static final String COOKIE_KEY = "ND_JSESSION"; | ||||
public static final Integer EXPORT_PAGE_NUMBER = 1; | public static final Integer EXPORT_PAGE_NUMBER = 1; | ||||
public static final Integer EXPORT_PAGE_SIZE = 100000; | public static final Integer EXPORT_PAGE_SIZE = 100000; | ||||
public static final String CALL_STATUS = "status"; | public static final String CALL_STATUS = "status"; | ||||
public static final String CALL_STATUS_OK_VALUE = "ok"; | public static final String CALL_STATUS_OK_VALUE = "ok"; | ||||
@@ -5,8 +5,9 @@ package com.ningdatech.pmapi.common.constant; | |||||
* @since 2023/02/07 16:24 | * @since 2023/02/07 16:24 | ||||
*/ | */ | ||||
public class StateMachineHeaderNameConstants { | |||||
public class StateMachineConstants { | |||||
public static final String PROJECT_DECLARE = "projectDeclare"; | public static final String PROJECT_DECLARE = "projectDeclare"; | ||||
public static final String LI_SHUI_CITY_AREA_CODE = "331100"; | |||||
} | } |
@@ -2,7 +2,6 @@ package com.ningdatech.pmapi.common.handler; | |||||
import cn.hutool.json.JSONUtil; | import cn.hutool.json.JSONUtil; | ||||
import com.ningdatech.basic.model.ApiResponse; | import com.ningdatech.basic.model.ApiResponse; | ||||
import com.ningdatech.pmapi.common.util.BizUtils; | |||||
import org.springframework.core.MethodParameter; | import org.springframework.core.MethodParameter; | ||||
import org.springframework.http.MediaType; | import org.springframework.http.MediaType; | ||||
import org.springframework.http.converter.HttpMessageConverter; | import org.springframework.http.converter.HttpMessageConverter; | ||||
@@ -24,7 +23,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; | |||||
"com.ningdatech.pmapi.projectlib.controller", | "com.ningdatech.pmapi.projectlib.controller", | ||||
"com.ningdatech.pmapi.sys.controller", | "com.ningdatech.pmapi.sys.controller", | ||||
"com.ningdatech.pmapi.todocenter.controller", | "com.ningdatech.pmapi.todocenter.controller", | ||||
"com.ningdatech.pmapi.user.controller" | |||||
"com.ningdatech.pmapi.user.controller", | |||||
}) | }) | ||||
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> { | public class GlobalResponseHandler implements ResponseBodyAdvice<Object> { | ||||
@@ -1,6 +1,6 @@ | |||||
package com.ningdatech.pmapi.common.statemachine.action; | package com.ningdatech.pmapi.common.statemachine.action; | ||||
import com.ningdatech.pmapi.common.constant.StateMachineHeaderNameConstants; | |||||
import com.ningdatech.pmapi.common.constant.StateMachineConstants; | |||||
import com.ningdatech.pmapi.common.statemachine.builder.ProjectDeclareStateMachineBuilder; | import com.ningdatech.pmapi.common.statemachine.builder.ProjectDeclareStateMachineBuilder; | ||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | ||||
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | ||||
@@ -23,7 +23,7 @@ import org.springframework.statemachine.annotation.WithStateMachine; | |||||
@WithStateMachine(id = ProjectDeclareStateMachineBuilder.MACHINEID_TO) | @WithStateMachine(id = ProjectDeclareStateMachineBuilder.MACHINEID_TO) | ||||
public class ProjectDeclareAction { | public class ProjectDeclareAction { | ||||
private static final String PROJECT_DECLARE = StateMachineHeaderNameConstants.PROJECT_DECLARE; | |||||
private static final String PROJECT_DECLARE = StateMachineConstants.PROJECT_DECLARE; | |||||
@OnTransition(source = "UNDER_INTERNAL_AUDIT", target = "PENDING_PREQUALIFICATION") | @OnTransition(source = "UNDER_INTERNAL_AUDIT", target = "PENDING_PREQUALIFICATION") | ||||
public void UNDER_INTERNAL_PASS(Message<ProjectStatusChangeEvent> message) { | public void UNDER_INTERNAL_PASS(Message<ProjectStatusChangeEvent> message) { | ||||
@@ -1,6 +1,6 @@ | |||||
package com.ningdatech.pmapi.common.statemachine.action; | package com.ningdatech.pmapi.common.statemachine.action; | ||||
import com.ningdatech.pmapi.common.constant.StateMachineHeaderNameConstants; | |||||
import com.ningdatech.pmapi.common.constant.StateMachineConstants; | |||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | ||||
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
@@ -18,7 +18,7 @@ import org.springframework.statemachine.action.Action; | |||||
@Slf4j | @Slf4j | ||||
public class ProjectDeclareChoiceAction implements Action<ProjectStatusEnum, ProjectStatusChangeEvent> { | public class ProjectDeclareChoiceAction implements Action<ProjectStatusEnum, ProjectStatusChangeEvent> { | ||||
private static final String PROJECT_DECLARE = StateMachineHeaderNameConstants.PROJECT_DECLARE; | |||||
private static final String PROJECT_DECLARE = StateMachineConstants.PROJECT_DECLARE; | |||||
@Override | @Override | ||||
public void execute(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) { | public void execute(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) { | ||||
@@ -1,6 +1,6 @@ | |||||
package com.ningdatech.pmapi.common.statemachine.factory; | package com.ningdatech.pmapi.common.statemachine.factory; | ||||
import com.ningdatech.pmapi.common.constant.StateMachineHeaderNameConstants; | |||||
import com.ningdatech.pmapi.common.constant.StateMachineConstants; | |||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | ||||
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
@@ -16,7 +16,7 @@ import org.springframework.statemachine.guard.Guard; | |||||
*/ | */ | ||||
public class ProjectDeclareGuardFactory { | public class ProjectDeclareGuardFactory { | ||||
private static final String PROJECT_DECLARE = StateMachineHeaderNameConstants.PROJECT_DECLARE; | |||||
private static final String PROJECT_DECLARE = StateMachineConstants.PROJECT_DECLARE; | |||||
public class PendingPreQualificationChoiceGuard implements Guard<ProjectStatusEnum, ProjectStatusChangeEvent> { | public class PendingPreQualificationChoiceGuard implements Guard<ProjectStatusEnum, ProjectStatusChangeEvent> { | ||||
@Override | @Override | ||||
@@ -2,7 +2,7 @@ package com.ningdatech.pmapi.common.statemachine.util; | |||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.pmapi.common.constant.ProjectDeclareConstants; | import com.ningdatech.pmapi.common.constant.ProjectDeclareConstants; | ||||
import com.ningdatech.pmapi.common.constant.StateMachineHeaderNameConstants; | |||||
import com.ningdatech.pmapi.common.constant.StateMachineConstants; | |||||
import com.ningdatech.pmapi.common.statemachine.builder.ProjectDeclareStateMachineBuilder; | import com.ningdatech.pmapi.common.statemachine.builder.ProjectDeclareStateMachineBuilder; | ||||
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
@@ -29,7 +29,7 @@ import java.util.Objects; | |||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
public class StateMachineUtils { | public class StateMachineUtils { | ||||
private static final String PROJECT_DECLARE = StateMachineHeaderNameConstants.PROJECT_DECLARE; | |||||
private static final String PROJECT_DECLARE = StateMachineConstants.PROJECT_DECLARE; | |||||
private final ProjectDeclareStateMachineBuilder projectDeclareStateMachineBuilder; | private final ProjectDeclareStateMachineBuilder projectDeclareStateMachineBuilder; | ||||
@@ -64,7 +64,7 @@ public class StateMachineUtils { | |||||
} | } | ||||
/** | /** | ||||
* 判断项目建设层级是否为市级项目 | |||||
* 判断申报项目是否为市级项目 | |||||
* | * | ||||
* @param project | * @param project | ||||
* @return boolean | * @return boolean | ||||
@@ -72,8 +72,8 @@ public class StateMachineUtils { | |||||
* @since 2023/02/07 17:05 | * @since 2023/02/07 17:05 | ||||
*/ | */ | ||||
public static boolean isCityProject(Project project) { | public static boolean isCityProject(Project project) { | ||||
if (ProjectDeclareConstants.Number.CITY_BUILD_LEVEL.equals(project.getBuildLevel()) || | |||||
ProjectDeclareConstants.Number.CITY_SELF_BUILD_LEVEL.equals(project.getBuildLevel())) { | |||||
String areaCode = project.getAreaCode(); | |||||
if (areaCode.equals(StateMachineConstants.LI_SHUI_CITY_AREA_CODE)) { | |||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
@@ -1,77 +1,144 @@ | |||||
package com.ningdatech.pmapi.ding.task; | |||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.ningdatech.basic.model.GenericResult; | |||||
import com.ningdatech.pmapi.common.config.GovDingProperties; | |||||
import com.ningdatech.pmapi.organization.entity.DingOrganization; | |||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
import com.ningdatech.zwdd.client.ZwddClient; | |||||
import com.ningdatech.zwdd.model.Page; | |||||
import com.ningdatech.zwdd.model.query.PageOrganizationEmployeePositionsQuery; | |||||
import com.ningdatech.zwdd.model.response.OrganizationEmployeePosition; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/10 上午9:52 | |||||
*/ | |||||
@Component | |||||
public class EmployeeBatchGetTask { | |||||
private final static Integer PAGE_SIZE = 20; | |||||
@Autowired | |||||
private ZwddClient zwddClient; | |||||
private IDingOrganizationService iDingOrganizationService; | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void batchGetEmployeeTask() { | |||||
List<DingOrganization> dingOrganizationList = iDingOrganizationService.list(); | |||||
if (CollUtil.isNotEmpty(dingOrganizationList)) { | |||||
List<OrganizationEmployeePosition> allOrganizationEmployeePositionList = new ArrayList<>(); | |||||
for (DingOrganization dingOrganization : dingOrganizationList) { | |||||
String organizationCode = dingOrganization.getOrganizationCode(); | |||||
PageOrganizationEmployeePositionsQuery query = new PageOrganizationEmployeePositionsQuery(); | |||||
query.setEmployeeStatus("A"); | |||||
query.setOrganizationCode(organizationCode); | |||||
query.setReturnTotalSize(true); | |||||
query.setTenantId(GovDingProperties.tenantId); | |||||
int pageNo = 1; | |||||
query.setPageNo(pageNo); | |||||
query.setPageSize(PAGE_SIZE); | |||||
GenericResult<Page<OrganizationEmployeePosition>> firstPageGenericResult = zwddClient.pageOrganizationEmployeePositions(query); | |||||
Page<OrganizationEmployeePosition> data = firstPageGenericResult.getData(); | |||||
if (CollUtil.isNotEmpty(data.getData())) { | |||||
allOrganizationEmployeePositionList.addAll(data.getData()); | |||||
} | |||||
Long totalSize = data.getTotalSize(); | |||||
if (totalSize > PAGE_SIZE) { | |||||
int maxPageNo = (int) Math.ceil(totalSize / PAGE_SIZE); | |||||
for (pageNo = 2; pageNo <= maxPageNo; pageNo++) { | |||||
query.setPageNo(maxPageNo); | |||||
GenericResult<Page<OrganizationEmployeePosition>> pageGenericResult = zwddClient.pageOrganizationEmployeePositions(query); | |||||
if (CollUtil.isNotEmpty(pageGenericResult.getData().getData())) { | |||||
allOrganizationEmployeePositionList.addAll(pageGenericResult.getData().getData()); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// zwddClient.pageOrganizationEmployeePositions(query); | |||||
} | |||||
} | |||||
} | |||||
//package com.ningdatech.pmapi.ding.task; | |||||
// | |||||
//import cn.hutool.core.collection.CollUtil; | |||||
//import com.ningdatech.basic.model.GenericResult; | |||||
//import com.ningdatech.pmapi.organization.entity.DingEmployeeInfo; | |||||
//import com.ningdatech.pmapi.organization.entity.DingOrganization; | |||||
//import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService; | |||||
//import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
//import com.ningdatech.zwdd.client.ZwddClient; | |||||
//import com.ningdatech.zwdd.model.Page; | |||||
//import com.ningdatech.zwdd.model.dto.EmployeeAccountIdDTO; | |||||
//import com.ningdatech.zwdd.model.query.PageOrganizationEmployeePositionsQuery; | |||||
//import com.ningdatech.zwdd.model.response.OrganizationEmployeePosition; | |||||
//import com.ningdatech.zwdd.model.response.OrganizationEmployeePosition.GovEmployeePosition; | |||||
//import org.springframework.beans.BeanUtils; | |||||
//import org.springframework.beans.factory.annotation.Autowired; | |||||
//import org.springframework.stereotype.Component; | |||||
//import org.springframework.transaction.annotation.Transactional; | |||||
// | |||||
//import java.util.ArrayList; | |||||
//import java.util.List; | |||||
//import java.util.stream.Collectors; | |||||
// | |||||
///** | |||||
// * @author liuxinxin | |||||
// * @date 2023/2/10 上午9:52 | |||||
// */ | |||||
// | |||||
//@Component | |||||
//public class EmployeeBatchGetTask { | |||||
// | |||||
// private final static Integer PAGE_SIZE = 20; | |||||
// | |||||
// private final static Integer GROUP_SIZE = 100; | |||||
// | |||||
// @Autowired | |||||
// private ZwddClient zwddClient; | |||||
// | |||||
// @Autowired | |||||
// private IDingOrganizationService iDingOrganizationService; | |||||
// | |||||
// @Autowired | |||||
// private IDingEmployeeInfoService iDingEmployeeInfoService; | |||||
// | |||||
// @Transactional(rollbackFor = Exception.class) | |||||
// public void batchGetEmployeeTask() { | |||||
// | |||||
// // 获取所有的组织列表用户获取组织下的 用户信息 | |||||
// List<DingOrganization> dingOrganizationList = iDingOrganizationService.list(); | |||||
// if (CollUtil.isNotEmpty(dingOrganizationList)) { | |||||
// for (DingOrganization dingOrganization : dingOrganizationList) { | |||||
// List<OrganizationEmployeePosition> allOrganizationEmployeePositionList = new ArrayList<>(); | |||||
// String organizationCode = dingOrganization.getOrganizationCode(); | |||||
// PageOrganizationEmployeePositionsQuery query = new PageOrganizationEmployeePositionsQuery(); | |||||
// query.setEmployeeStatus("A"); | |||||
// query.setOrganizationCode(organizationCode); | |||||
// query.setReturnTotalSize(true); | |||||
//// query.setTenantId(GovDingProperties.tenantId); | |||||
// int pageNo = 1; | |||||
// query.setPageNo(pageNo); | |||||
// query.setPageSize(PAGE_SIZE); | |||||
// | |||||
// // 查询组织下 用户信息 | |||||
// GenericResult<Page<OrganizationEmployeePosition>> firstPageGenericResult = zwddClient.pageOrganizationEmployeePositions(query); | |||||
// Page<OrganizationEmployeePosition> data = firstPageGenericResult.getData(); | |||||
// if (CollUtil.isNotEmpty(data.getData())) { | |||||
// | |||||
// allOrganizationEmployeePositionList.addAll(data.getData()); | |||||
// } | |||||
// Long totalSize = data.getTotalSize(); | |||||
// if (totalSize > PAGE_SIZE) { | |||||
// int maxPageNo = (int) Math.ceil(totalSize / PAGE_SIZE); | |||||
// for (pageNo = 2; pageNo <= maxPageNo; pageNo++) { | |||||
// query.setPageNo(maxPageNo); | |||||
// GenericResult<Page<OrganizationEmployeePosition>> pageGenericResult = zwddClient.pageOrganizationEmployeePositions(query); | |||||
// if (CollUtil.isNotEmpty(pageGenericResult.getData().getData())) { | |||||
// allOrganizationEmployeePositionList.addAll(pageGenericResult.getData().getData()); | |||||
// } | |||||
// } | |||||
// } | |||||
// | |||||
// List<DingEmployeeInfo> dingEmployeeInfoList = new ArrayList<>(); | |||||
// if (allOrganizationEmployeePositionList.size() <= GROUP_SIZE) { | |||||
// List<String> employeeCodes = allOrganizationEmployeePositionList.stream().map(OrganizationEmployeePosition::getEmployeeCode).collect(Collectors.toList()); | |||||
// GenericResult<List<EmployeeAccountIdDTO>> listGenericResult = zwddClient.listEmployeeAccountIds(employeeCodes); | |||||
//// List<EmployeeAccountIdDTO> employeeAccountIdDTOList = listGenericResult.getData(); | |||||
// } else { | |||||
//// iDingEmployeeInfoService.saveBatch(); | |||||
// } | |||||
// // 批量保存用户信息 | |||||
// saveBatch(allOrganizationEmployeePositionList); | |||||
// } | |||||
// | |||||
// } | |||||
// | |||||
// | |||||
// } | |||||
// | |||||
// private List<DingEmployeeInfo> buildDingEmployeeInfoRecord(List<OrganizationEmployeePosition> allOrganizationEmployeePositionList) { | |||||
// List<DingEmployeeInfo> saveRecordList = new ArrayList<>(); | |||||
// for (OrganizationEmployeePosition organizationEmployeePosition : allOrganizationEmployeePositionList) { | |||||
// List<GovEmployeePosition> govEmployeePositions = organizationEmployeePosition.getGovEmployeePositions(); | |||||
// if (CollUtil.isNotEmpty(govEmployeePositions)) { | |||||
// List<DingEmployeeInfo> segmentSaveRecordList = new ArrayList<>(); | |||||
// for (GovEmployeePosition govEmployeePosition : govEmployeePositions) { | |||||
// DingEmployeeInfo dingEmployeeInfo = new DingEmployeeInfo(); | |||||
// BeanUtils.copyProperties(organizationEmployeePosition, dingEmployeeInfo); | |||||
// dingEmployeeInfo.setMainJob(govEmployeePosition.getMainJob()); | |||||
// dingEmployeeInfo.setEmpPosUnitCode(govEmployeePosition.getEmpPosUnitCode()); | |||||
// dingEmployeeInfo.setEmpPosEmployeeRoleCode(govEmployeePosition.getEmpPosEmployeeRoleCode()); | |||||
// dingEmployeeInfo.setEmpPosInnerInstitutionCode(govEmployeePosition.getEmpPosInnerInstitutionCode()); | |||||
// dingEmployeeInfo.setEmployeeCode(govEmployeePosition.getEmployeeCode()); | |||||
// dingEmployeeInfo.setJobAttributesCode(govEmployeePosition.getJobAttributesCode()); | |||||
// dingEmployeeInfo.setOrganizationCode(govEmployeePosition.getOrganizationCode()); | |||||
// dingEmployeeInfo.setEmpPosVirtualOrganizationCode(govEmployeePosition.getEmpPosVirtualOrganizationCode()); | |||||
// dingEmployeeInfo.setEmpStatus(govEmployeePosition.getStatus()); | |||||
// segmentSaveRecordList.add(dingEmployeeInfo); | |||||
// } | |||||
// saveRecordList.addAll(segmentSaveRecordList); | |||||
// } else { | |||||
// DingEmployeeInfo dingEmployeeInfo = new DingEmployeeInfo(); | |||||
// BeanUtils.copyProperties(organizationEmployeePosition, dingEmployeeInfo); | |||||
// saveRecordList.add(dingEmployeeInfo); | |||||
// } | |||||
// | |||||
// | |||||
// } | |||||
// return null; | |||||
// } | |||||
// | |||||
// private void saveBatch(List<OrganizationEmployeePosition> allOrganizationEmployeePositionList) { | |||||
// | |||||
//// // 批量保存 | |||||
//// if (saveRecordList.size() <= GROUP_SIZE) { | |||||
//// iDingOrganizationService.saveBatch(saveRecordList); | |||||
//// } else { | |||||
//// List<List<DingOrganization>> split = Lists.partition(saveRecordList, GROUP_SIZE); | |||||
//// for (List<DingOrganization> segment : split) { | |||||
//// iDingOrganizationService.saveBatch(segment); | |||||
//// } | |||||
//// } | |||||
// | |||||
// } | |||||
//} |
@@ -0,0 +1,23 @@ | |||||
package com.ningdatech.pmapi.expert.controller; | |||||
import io.swagger.annotations.Api; | |||||
import lombok.AllArgsConstructor; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
/** | |||||
* <p> | |||||
* 评审模版配置表 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023-02-14 | |||||
*/ | |||||
@RestController | |||||
@AllArgsConstructor | |||||
@Api(tags = "评审模版配置") | |||||
@RequestMapping("/api/v1/reviewTemplateSettings") | |||||
public class ReviewTemplateSettingsController { | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.expert.mapper; | |||||
import com.ningdatech.pmapi.expert.model.entity.ReviewTemplateSettings; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
/** | |||||
* <p> | |||||
* 评审模版配置表 Mapper 接口 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023-02-14 | |||||
*/ | |||||
public interface ReviewTemplateSettingsMapper extends BaseMapper<ReviewTemplateSettings> { | |||||
} |
@@ -0,0 +1,5 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
<mapper namespace="com.ningdatech.pmapi.expert.mapper.ReviewTemplateSettingsMapper"> | |||||
</mapper> |
@@ -0,0 +1,56 @@ | |||||
package com.ningdatech.pmapi.expert.model.dto; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.Valid; | |||||
import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.NotEmpty; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.util.List; | |||||
/** | |||||
* <p> | |||||
* ReviewTemplateSettingsDTO | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 17:06 2023/2/14 | |||||
*/ | |||||
@Data | |||||
public class ReviewTemplateSettingsDTO { | |||||
@ApiModelProperty("序号") | |||||
@NotNull(message = "序号不能为空") | |||||
private Integer serialNo; | |||||
@ApiModelProperty("标题") | |||||
@NotBlank(message = "标题不能为空") | |||||
private String title; | |||||
@Valid | |||||
@ApiModelProperty("选项") | |||||
@NotEmpty(message = "选项不能为空") | |||||
private List<OptionDTO> options; | |||||
@ApiModelProperty("选择类型:1 单选、2 多选") | |||||
@NotNull(message = "选择类型不能为空") | |||||
private Integer optionType; | |||||
@Data | |||||
@ApiModel("选项实体") | |||||
public static class OptionDTO { | |||||
@ApiModelProperty("序号") | |||||
@NotNull(message = "序号不能为空") | |||||
private Integer serialNo; | |||||
@ApiModelProperty("选项内容") | |||||
@NotBlank(message = "选项内容不能为空") | |||||
private String option; | |||||
} | |||||
} |
@@ -0,0 +1,113 @@ | |||||
package com.ningdatech.pmapi.expert.model.entity; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import java.io.Serializable; | |||||
import java.time.LocalDateTime; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
/** | |||||
* <p> | |||||
* 评审模版配置表 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023-02-14 | |||||
*/ | |||||
@TableName("nd_review_template_settings") | |||||
@ApiModel(value = "NdReviewTemplateSettings对象", description = "评审模版配置表") | |||||
public class ReviewTemplateSettings implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty("主键") | |||||
private Long id; | |||||
@ApiModelProperty("模版类型:1 初步方案评审模版、2 建设方案评审模版、3 验收方案评审模版") | |||||
private Integer templateType; | |||||
@ApiModelProperty("模版内容") | |||||
private String content; | |||||
private Long createBy; | |||||
private Long updateBy; | |||||
private LocalDateTime createOn; | |||||
private LocalDateTime updateOn; | |||||
@ApiModelProperty("是否是最新") | |||||
private Boolean isLast; | |||||
public Long getId() { | |||||
return id; | |||||
} | |||||
public void setId(Long id) { | |||||
this.id = id; | |||||
} | |||||
public Integer getTemplateType() { | |||||
return templateType; | |||||
} | |||||
public void setTemplateType(Integer templateType) { | |||||
this.templateType = templateType; | |||||
} | |||||
public String getContent() { | |||||
return content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
public Long getCreateBy() { | |||||
return createBy; | |||||
} | |||||
public void setCreateBy(Long createBy) { | |||||
this.createBy = createBy; | |||||
} | |||||
public Long getUpdateBy() { | |||||
return updateBy; | |||||
} | |||||
public void setUpdateBy(Long updateBy) { | |||||
this.updateBy = updateBy; | |||||
} | |||||
public LocalDateTime getCreateOn() { | |||||
return createOn; | |||||
} | |||||
public void setCreateOn(LocalDateTime createOn) { | |||||
this.createOn = createOn; | |||||
} | |||||
public LocalDateTime getUpdateOn() { | |||||
return updateOn; | |||||
} | |||||
public void setUpdateOn(LocalDateTime updateOn) { | |||||
this.updateOn = updateOn; | |||||
} | |||||
public Boolean getIsLast() { | |||||
return isLast; | |||||
} | |||||
public void setIsLast(Boolean isLast) { | |||||
this.isLast = isLast; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "NdReviewTemplateSettings{" + | |||||
"id=" + id + | |||||
", templateType=" + templateType + | |||||
", content=" + content + | |||||
", createBy=" + createBy + | |||||
", updateBy=" + updateBy + | |||||
", createOn=" + createOn + | |||||
", updateOn=" + updateOn + | |||||
", isLast=" + isLast + | |||||
"}"; | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.expert.service; | |||||
import com.ningdatech.pmapi.expert.model.entity.ReviewTemplateSettings; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
/** | |||||
* <p> | |||||
* 评审模版配置表 服务类 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023-02-14 | |||||
*/ | |||||
public interface IReviewTemplateSettingsService extends IService<ReviewTemplateSettings> { | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.expert.service.impl; | |||||
import com.ningdatech.pmapi.expert.model.entity.ReviewTemplateSettings; | |||||
import com.ningdatech.pmapi.expert.mapper.ReviewTemplateSettingsMapper; | |||||
import com.ningdatech.pmapi.expert.service.IReviewTemplateSettingsService; | |||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||||
import org.springframework.stereotype.Service; | |||||
/** | |||||
* <p> | |||||
* 评审模版配置表 服务实现类 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023-02-14 | |||||
*/ | |||||
@Service | |||||
public class ReviewTemplateSettingsServiceImpl extends ServiceImpl<ReviewTemplateSettingsMapper, ReviewTemplateSettings> implements IReviewTemplateSettingsService { | |||||
} |
@@ -24,6 +24,7 @@ import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.springframework.beans.BeanUtils; | import org.springframework.beans.BeanUtils; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -77,7 +78,7 @@ public class ConstructionPlanManage { | |||||
//首先要判断 项目当前状态 是不是 方案待申报 | //首先要判断 项目当前状态 是不是 方案待申报 | ||||
VUtils.isTrue(!ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode().equals(projectInfo.getStatus()) || | VUtils.isTrue(!ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode().equals(projectInfo.getStatus()) || | ||||
!ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) | |||||
!ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) | |||||
.throwMessage("提交失败 该项目不是 待预审状态或者未立项阶段"); | .throwMessage("提交失败 该项目不是 待预审状态或者未立项阶段"); | ||||
// TODO 再判断 该项目是否 真实走完 预审审批 | // TODO 再判断 该项目是否 真实走完 预审审批 | ||||
@@ -145,7 +145,7 @@ public class AnnualPlanLibManage { | |||||
try (InputStream inputStream = file.getInputStream()) { | try (InputStream inputStream = file.getInputStream()) { | ||||
EasyExcel.read(inputStream, new AnalysisEventListener<AnnualLibImportDTO>() { | EasyExcel.read(inputStream, new AnalysisEventListener<AnnualLibImportDTO>() { | ||||
private List<Project> records = new ArrayList<>(); | |||||
private final List<Project> records = new ArrayList<>(); | |||||
@Override | @Override | ||||
public void onException(Exception exception, AnalysisContext context) throws Exception { | public void onException(Exception exception, AnalysisContext context) throws Exception { | ||||
@@ -179,7 +179,7 @@ public class AnnualPlanLibManage { | |||||
project.setBeginTime(dataArr[0].trim()); | project.setBeginTime(dataArr[0].trim()); | ||||
project.setEndTime(dataArr[1].trim()); | project.setEndTime(dataArr[1].trim()); | ||||
project.setProjectIntroduction(data.getProjectIntroduction()); | project.setProjectIntroduction(data.getProjectIntroduction()); | ||||
project.setIsFirst(data.getIsFirst().equals("新建") ? 1 : 0); | |||||
project.setIsFirst("新建".equals(data.getIsFirst()) ? 1 : 0); | |||||
records.add(project); | records.add(project); | ||||
} | } | ||||
@@ -1,7 +1,6 @@ | |||||
package com.ningdatech.pmapi.sys.manage; | package com.ningdatech.pmapi.sys.manage; | ||||
import cn.hutool.core.bean.BeanUtil; | import cn.hutool.core.bean.BeanUtil; | ||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.ningdatech.basic.util.CollUtils; | import com.ningdatech.basic.util.CollUtils; | ||||
import com.ningdatech.pmapi.common.util.TreeUtil; | import com.ningdatech.pmapi.common.util.TreeUtil; | ||||
@@ -10,12 +9,11 @@ import com.ningdatech.pmapi.sys.model.entity.RoleMenu; | |||||
import com.ningdatech.pmapi.sys.model.vo.MenuRoleVO; | import com.ningdatech.pmapi.sys.model.vo.MenuRoleVO; | ||||
import com.ningdatech.pmapi.sys.service.IRoleMenuService; | import com.ningdatech.pmapi.sys.service.IRoleMenuService; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import java.util.Collections; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Objects; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
@@ -32,11 +30,11 @@ public class MenuManage { | |||||
private final IRoleMenuService roleMenuService; | private final IRoleMenuService roleMenuService; | ||||
public List<MenuRoleVO> buildUserMenu(List<Menu> list, UserInfoDetails loginUser) { | public List<MenuRoleVO> buildUserMenu(List<Menu> list, UserInfoDetails loginUser) { | ||||
if (Objects.isNull(loginUser) || CollUtil.isEmpty(loginUser.getRoleIdList())) { | |||||
/*if (Objects.isNull(loginUser) || CollUtil.isEmpty(loginUser.getRoleIdList())) { | |||||
return Collections.emptyList(); | return Collections.emptyList(); | ||||
} | |||||
}*/ | |||||
List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.lambdaQuery(RoleMenu.class) | List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.lambdaQuery(RoleMenu.class) | ||||
.in(RoleMenu::getRoleId, loginUser.getRoleIdList())); | |||||
.in(RoleMenu::getRoleId, LoginUserUtil.getRoleIdList())); | |||||
List<MenuRoleVO> menuRoles = CollUtils.convert(list, w -> BeanUtil.copyProperties(w, MenuRoleVO.class)); | List<MenuRoleVO> menuRoles = CollUtils.convert(list, w -> BeanUtil.copyProperties(w, MenuRoleVO.class)); | ||||
return TreeUtil.buildUserTree(menuRoles, roleMenus); | return TreeUtil.buildUserTree(menuRoles, roleMenus); | ||||
} | } | ||||
@@ -2,9 +2,11 @@ package com.ningdatech.pmapi.sys.model.enumeration; | |||||
import lombok.Getter; | import lombok.Getter; | ||||
import java.util.Arrays; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* DataScopeEnum | |||||
* 数据权限可见范围枚举 | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author WendyYang | * @author WendyYang | ||||
@@ -28,4 +30,23 @@ public enum DataScopeEnum { | |||||
this.code = code; | this.code = code; | ||||
this.desc = desc; | this.desc = desc; | ||||
} | } | ||||
public boolean eq(Integer code) { | |||||
return this.code.equals(code); | |||||
} | |||||
/** | |||||
* 根据code获取枚举实例 | |||||
* | |||||
* @param code 编码 | |||||
* @return {@link DataScopeEnum} | |||||
* @author WendyYang | |||||
**/ | |||||
public static DataScopeEnum getByCode(Integer code) { | |||||
return Arrays.stream(values()) | |||||
.filter(w -> w.eq(code)) | |||||
.findFirst() | |||||
.orElseThrow(() -> new IllegalArgumentException("无效的数据权限可见范围编码")); | |||||
} | |||||
} | } |
@@ -7,6 +7,7 @@ package com.ningdatech.pmapi.todocenter.constant; | |||||
public interface WorkNotice { | public interface WorkNotice { | ||||
public final String PASS_MSG_TEMPLATE = "标题:审核任务 内容:【%s】的【%s】需要您审核。"; | public final String PASS_MSG_TEMPLATE = "标题:审核任务 内容:【%s】的【%s】需要您审核。"; | ||||
public final String PASS_MSG_TEMPLATE2 = "【%s】已通过【%s】,请及时开始下一步操作。"; | public final String PASS_MSG_TEMPLATE2 = "【%s】已通过【%s】,请及时开始下一步操作。"; | ||||
public final String PASS_MSG_TEMPLATE3 = "【%s】的【%s】被退回,请及时处理。"; | |||||
} | } |
@@ -7,6 +7,7 @@ import javax.validation.Valid; | |||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | import com.ningdatech.pmapi.common.util.ExcelDownUtil; | ||||
import com.ningdatech.pmapi.todocenter.bean.vo.ProcessProgressDetailVo; | import com.ningdatech.pmapi.todocenter.bean.vo.ProcessProgressDetailVo; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; | import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.req.ReqToBeProcessedExportDTO; | |||||
import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||
import com.ningdatech.basic.model.ApiResponse; | import com.ningdatech.basic.model.ApiResponse; | ||||
@@ -53,7 +54,7 @@ public class TodoCenterController { | |||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/exportPending") | @PostMapping("/exportPending") | ||||
public void exportPendingProjectList(@Valid @RequestBody ReqToBeProcessedDTO param, HttpServletResponse response){ | |||||
public void exportPendingProjectList(@Valid @RequestBody ReqToBeProcessedExportDTO param, HttpServletResponse response){ | |||||
todoCenterManage.exportPendingProjectList(response,param); | todoCenterManage.exportPendingProjectList(response,param); | ||||
} | } | ||||
@@ -66,7 +67,6 @@ public class TodoCenterController { | |||||
@GetMapping("/progress/{instanceId}/{nodeId}") | @GetMapping("/progress/{instanceId}/{nodeId}") | ||||
public ApiResponse<ProcessProgressDetailVo> getProcessDetail(@PathVariable String instanceId, | public ApiResponse<ProcessProgressDetailVo> getProcessDetail(@PathVariable String instanceId, | ||||
@PathVariable(required = false) String nodeId) { | @PathVariable(required = false) String nodeId) { | ||||
return ApiResponse.ofSuccess(todoCenterManage.getProcessDetail(nodeId, instanceId)); | return ApiResponse.ofSuccess(todoCenterManage.getProcessDetail(nodeId, instanceId)); | ||||
} | } | ||||
@@ -99,7 +99,7 @@ public class TodoCenterController { | |||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/exportHandled") | @PostMapping("/exportHandled") | ||||
public void exportHandledProjectList(@Valid @RequestBody ReqToBeProcessedDTO param, HttpServletResponse response){ | |||||
public void exportHandledProjectList(@Valid @RequestBody ReqToBeProcessedExportDTO param, HttpServletResponse response){ | |||||
todoCenterManage.exportHandledProjectList(response,param); | todoCenterManage.exportHandledProjectList(response,param); | ||||
} | } | ||||
@@ -122,7 +122,7 @@ public class TodoCenterController { | |||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/exportMySubmitted") | @PostMapping("/exportMySubmitted") | ||||
public void exportMySubmittedProjectList(@Valid @RequestBody ReqToBeProcessedDTO param, HttpServletResponse response){ | |||||
public void exportMySubmittedProjectList(@Valid @RequestBody ReqToBeProcessedExportDTO param, HttpServletResponse response){ | |||||
todoCenterManage.exportMySubmittedProjectList(response,param); | todoCenterManage.exportMySubmittedProjectList(response,param); | ||||
} | } | ||||
@@ -145,7 +145,7 @@ public class TodoCenterController { | |||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/exportCcMe") | @PostMapping("/exportCcMe") | ||||
public void exportCcMeProjectList(@Valid @RequestBody ReqToBeProcessedDTO param, HttpServletResponse response){ | |||||
public void exportCcMeProjectList(@Valid @RequestBody ReqToBeProcessedExportDTO param, HttpServletResponse response){ | |||||
todoCenterManage.exportCcMeProjectList(response,param); | todoCenterManage.exportCcMeProjectList(response,param); | ||||
} | } | ||||
} | } |
@@ -4,9 +4,17 @@ import java.io.Serializable; | |||||
import java.util.*; | import java.util.*; | ||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.todocenter.enumeration.ProcessStatusEnum; | |||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | import com.wflow.workflow.enums.ProcessHandlerEnum; | ||||
import lombok.AllArgsConstructor; | |||||
import lombok.NoArgsConstructor; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.assertj.core.util.Sets; | import org.assertj.core.util.Sets; | ||||
import org.flowable.bpmn.model.BpmnModel; | |||||
import org.flowable.bpmn.model.FlowNode; | import org.flowable.bpmn.model.FlowNode; | ||||
import org.flowable.bpmn.model.Process; | import org.flowable.bpmn.model.Process; | ||||
import org.flowable.bpmn.model.UserTask; | import org.flowable.bpmn.model.UserTask; | ||||
@@ -14,6 +22,7 @@ import org.flowable.common.engine.api.FlowableException; | |||||
import org.flowable.common.engine.api.FlowableObjectNotFoundException; | import org.flowable.common.engine.api.FlowableObjectNotFoundException; | ||||
import org.flowable.common.engine.impl.interceptor.Command; | import org.flowable.common.engine.impl.interceptor.Command; | ||||
import org.flowable.common.engine.impl.interceptor.CommandContext; | import org.flowable.common.engine.impl.interceptor.CommandContext; | ||||
import org.flowable.engine.RepositoryService; | |||||
import org.flowable.engine.RuntimeService; | import org.flowable.engine.RuntimeService; | ||||
import org.flowable.engine.TaskService; | import org.flowable.engine.TaskService; | ||||
import org.flowable.engine.impl.delegate.ActivityBehavior; | import org.flowable.engine.impl.delegate.ActivityBehavior; | ||||
@@ -32,21 +41,15 @@ import com.wflow.workflow.utils.FlowableUtils; | |||||
* @date : 2022/10/14 | * @date : 2022/10/14 | ||||
*/ | */ | ||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
@AllArgsConstructor | |||||
public class BackToHisApprovalNodeCmd implements Command<String>, Serializable { | public class BackToHisApprovalNodeCmd implements Command<String>, Serializable { | ||||
private static final long serialVersionUID = -80075781855060928L; | private static final long serialVersionUID = -80075781855060928L; | ||||
protected TaskService taskService; | |||||
protected RuntimeService runtimeService; | protected RuntimeService runtimeService; | ||||
protected BpmnModel bpmnModel; | |||||
protected String taskId; | protected String taskId; | ||||
protected String targetNodeId; | protected String targetNodeId; | ||||
public BackToHisApprovalNodeCmd(RuntimeService runtimeService, String taskId, String targetNodeId) { | |||||
this.runtimeService = runtimeService; | |||||
this.taskId = taskId; | |||||
this.targetNodeId = targetNodeId; | |||||
} | |||||
@Override | @Override | ||||
public String execute(CommandContext commandContext) { | public String execute(CommandContext commandContext) { | ||||
@@ -60,28 +63,30 @@ public class BackToHisApprovalNodeCmd implements Command<String>, Serializable { | |||||
String sourceNodeId = task.getTaskDefinitionKey(); | String sourceNodeId = task.getTaskDefinitionKey(); | ||||
String processInstanceId = task.getProcessInstanceId(); | String processInstanceId = task.getProcessInstanceId(); | ||||
String processDefinitionId = task.getProcessDefinitionId(); | String processDefinitionId = task.getProcessDefinitionId(); | ||||
//获取流程定义 | //获取流程定义 | ||||
Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); | Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); | ||||
FlowNode sourceFlowElement = (FlowNode) process.getFlowElement(sourceNodeId, true); | |||||
// 传节点定义key 获取当前节点 | |||||
FlowNode sourceFlowElement = (FlowNode) bpmnModel.getFlowElement(sourceNodeId); | |||||
// 只支持从用户任务退回 | // 只支持从用户任务退回 | ||||
if (!(sourceFlowElement instanceof UserTask)) { | if (!(sourceFlowElement instanceof UserTask)) { | ||||
throw new FlowableException("只能从审批节点进行回退"); | throw new FlowableException("只能从审批节点进行回退"); | ||||
} | } | ||||
FlowNode targetFlowElement = (FlowNode) process.getFlowElement(targetNodeId, true); | |||||
FlowNode targetFlowElement = (FlowNode) bpmnModel.getFlowElement(targetNodeId); | |||||
// 退回节点到当前节点不可达到,不允许退回 | // 退回节点到当前节点不可达到,不允许退回 | ||||
if (!ExecutionGraphUtil.isReachable(processDefinitionId, targetNodeId, sourceNodeId)) { | if (!ExecutionGraphUtil.isReachable(processDefinitionId, targetNodeId, sourceNodeId)) { | ||||
throw new FlowableException("无法回退到目标节点"); | throw new FlowableException("无法回退到目标节点"); | ||||
} | } | ||||
//目标节点如果相对当前节点是在子流程内部,则无法直接退回,目前处理是只能退回到子流程开始节点 | |||||
// 目标节点如果相对当前节点是在子流程内部,则无法直接退回,目前处理是只能退回到子流程开始节点 | |||||
String[] sourceAndTargetRealActivityId = FlowableUtils.getSourceAndTargetRealActivityId(sourceFlowElement, targetFlowElement); | String[] sourceAndTargetRealActivityId = FlowableUtils.getSourceAndTargetRealActivityId(sourceFlowElement, targetFlowElement); | ||||
// 实际应操作的当前节点ID | // 实际应操作的当前节点ID | ||||
String sourceRealActivityId = sourceAndTargetRealActivityId[0]; | String sourceRealActivityId = sourceAndTargetRealActivityId[0]; | ||||
//// 实际应操作的目标节点ID | |||||
//String targetRealActivityId = sourceAndTargetRealActivityId[1]; | |||||
// 实际应操作的目标节点的发起人ID | |||||
String targetRealActivityId = sourceAndTargetRealActivityId[0]; | |||||
// 实际应操作的目标节点ID | |||||
String targetRealActivityId = sourceAndTargetRealActivityId[1]; | |||||
Map<String, Set<String>> specialGatewayNodes = FlowableUtils.getSpecialGatewayElements(process); | Map<String, Set<String>> specialGatewayNodes = FlowableUtils.getSpecialGatewayElements(process); | ||||
// 当前节点处在的并行网关list | // 当前节点处在的并行网关list | ||||
@@ -146,10 +151,6 @@ public class BackToHisApprovalNodeCmd implements Command<String>, Serializable { | |||||
if (targetRealSpecialGateway != null) { | if (targetRealSpecialGateway != null) { | ||||
createTargetInSpecialGatewayEndExecutions(commandContext, realExecutions, process, targetInSpecialGatewayList, targetRealSpecialGateway); | createTargetInSpecialGatewayEndExecutions(commandContext, realExecutions, process, targetInSpecialGatewayList, targetRealSpecialGateway); | ||||
} | } | ||||
// TODO 调用原生的execute方法 在流程实例表中END_ACT_ID添加对应的字段标识 | |||||
Map<String, Object> var = new HashMap<>(16); | |||||
var.put("approve_" + task.getId(), ProcessHandlerEnum.BACK); | |||||
taskService.complete(task.getId(), var); | |||||
return targetRealActivityId; | return targetRealActivityId; | ||||
} | } | ||||
@@ -1,19 +1,13 @@ | |||||
package com.ningdatech.pmapi.todocenter.manage; | package com.ningdatech.pmapi.todocenter.manage; | ||||
import cn.hutool.core.collection.CollectionUtil; | |||||
import cn.hutool.core.util.ObjectUtil; | import cn.hutool.core.util.ObjectUtil; | ||||
import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||
import cn.hutool.json.JSONUtil; | import cn.hutool.json.JSONUtil; | ||||
import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
import com.alibaba.fastjson.JSONObject; | import com.alibaba.fastjson.JSONObject; | ||||
import com.alibaba.xxpt.gateway.shared.api.request.OapiMessageWorkNotificationRequest; | |||||
import com.alibaba.xxpt.gateway.shared.api.response.OapiMessageWorkNotificationResponse; | |||||
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient; | |||||
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentGetClient; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||||
import com.ningdatech.basic.enumeration.Status; | import com.ningdatech.basic.enumeration.Status; | ||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
@@ -38,6 +32,7 @@ import com.ningdatech.pmapi.todocenter.extension.cmd.BackToHisApprovalNodeCmd; | |||||
import com.ningdatech.pmapi.todocenter.extension.cmd.SaveCommentCmd; | import com.ningdatech.pmapi.todocenter.extension.cmd.SaveCommentCmd; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; | import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.req.ReqToBeProcessedDTO; | import com.ningdatech.pmapi.todocenter.model.dto.req.ReqToBeProcessedDTO; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.req.ReqToBeProcessedExportDTO; | |||||
import com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProcessedDTO; | import com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProcessedDTO; | ||||
import com.ningdatech.pmapi.todocenter.zwdd.model.MessageContent; | import com.ningdatech.pmapi.todocenter.zwdd.model.MessageContent; | ||||
import com.ningdatech.pmapi.todocenter.zwdd.model.MessageText; | import com.ningdatech.pmapi.todocenter.zwdd.model.MessageText; | ||||
@@ -64,18 +59,18 @@ import com.wflow.workflow.bean.vo.ProcessTaskVo; | |||||
import com.wflow.workflow.config.WflowGlobalVarDef; | import com.wflow.workflow.config.WflowGlobalVarDef; | ||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | import com.wflow.workflow.enums.ProcessHandlerEnum; | ||||
import com.wflow.workflow.service.FormService; | import com.wflow.workflow.service.FormService; | ||||
import com.wflow.workflow.service.*; | |||||
import com.wflow.workflow.service.ProcessModelService; | |||||
import com.wflow.workflow.service.ProcessNodeCatchService; | |||||
import com.wflow.workflow.service.UserDeptOrLeaderService; | |||||
import com.wflow.workflow.utils.Executor; | import com.wflow.workflow.utils.Executor; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.assertj.core.util.Maps; | import org.assertj.core.util.Maps; | ||||
import org.flowable.bpmn.model.Process; | |||||
import org.flowable.bpmn.model.*; | import org.flowable.bpmn.model.*; | ||||
import org.flowable.engine.*; | import org.flowable.engine.*; | ||||
import org.flowable.engine.history.HistoricActivityInstance; | import org.flowable.engine.history.HistoricActivityInstance; | ||||
import org.flowable.engine.history.HistoricProcessInstance; | import org.flowable.engine.history.HistoricProcessInstance; | ||||
import org.flowable.engine.history.HistoricProcessInstanceQuery; | import org.flowable.engine.history.HistoricProcessInstanceQuery; | ||||
import org.flowable.engine.impl.util.ProcessDefinitionUtil; | |||||
import org.flowable.engine.runtime.ActivityInstance; | import org.flowable.engine.runtime.ActivityInstance; | ||||
import org.flowable.engine.runtime.Execution; | import org.flowable.engine.runtime.Execution; | ||||
import org.flowable.engine.task.Comment; | import org.flowable.engine.task.Comment; | ||||
@@ -95,8 +90,9 @@ import java.time.format.DateTimeFormatter; | |||||
import java.util.*; | import java.util.*; | ||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPLATE; | |||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPLATE2; | |||||
import static cn.hutool.core.collection.CollUtil.isEmpty; | |||||
import static cn.hutool.core.collection.CollUtil.isNotEmpty; | |||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.*; | |||||
/** | /** | ||||
* @author CMM | * @author CMM | ||||
@@ -122,8 +118,8 @@ public class TodoCenterManage { | |||||
private final IUserInfoService userInfoService; | private final IUserInfoService userInfoService; | ||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final StateMachineUtils stateMachineUtils; | private final StateMachineUtils stateMachineUtils; | ||||
@Resource(name = "executableClient") | |||||
private ExecutableClient client; | |||||
// @Resource(name = "executableClient") | |||||
// private ExecutableClient client; | |||||
/** | /** | ||||
* 待办中心待我处理项目列表查询 | * 待办中心待我处理项目列表查询 | ||||
@@ -144,6 +140,15 @@ public class TodoCenterManage { | |||||
taskQuery.active().taskCandidateOrAssigned(String.valueOf(userId)).orderByTaskCreateTime().desc(); | taskQuery.active().taskCandidateOrAssigned(String.valueOf(userId)).orderByTaskCreateTime().desc(); | ||||
List<Task> taskList = taskQuery.list(); | List<Task> taskList = taskQuery.list(); | ||||
List<Project> results = getToBeProcessedProjects(param, taskList); | List<Project> results = getToBeProcessedProjects(param, taskList); | ||||
// 总数 | |||||
int total = results.size(); | |||||
// 获取传入的分页参数 | |||||
Integer pageNumber = param.getPageNumber(); | |||||
Integer pageSize = param.getPageSize(); | |||||
List<Project> records = results.stream() | |||||
.skip((long) (pageNumber - 1) * pageSize) | |||||
.limit(pageSize) | |||||
.collect(Collectors.toList()); | |||||
Map<String, Task> taskMap = taskList.stream() | Map<String, Task> taskMap = taskList.stream() | ||||
.collect(Collectors.toMap(Task::getProcessInstanceId, t -> t)); | .collect(Collectors.toMap(Task::getProcessInstanceId, t -> t)); | ||||
@@ -153,13 +158,13 @@ public class TodoCenterManage { | |||||
Set<String> staterUsers = new HashSet<>(); | Set<String> staterUsers = new HashSet<>(); | ||||
// 将申报项目待登录用户处理的流程实例一次性取出来,减少查询次数 | // 将申报项目待登录用户处理的流程实例一次性取出来,减少查询次数 | ||||
Map<String, HistoricProcessInstance> instanceMap = CollectionUtil.isNotEmpty(taskList) | |||||
Map<String, HistoricProcessInstance> instanceMap = isNotEmpty(taskList) | |||||
? historyService.createHistoricProcessInstanceQuery() | ? historyService.createHistoricProcessInstanceQuery() | ||||
.processInstanceIds(processInsIds).list().stream() | .processInstanceIds(processInsIds).list().stream() | ||||
.collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) | .collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) | ||||
: new HashMap<>(); | : new HashMap<>(); | ||||
List<ResToBeProcessedDTO> resVos = results.stream().map(d -> { | |||||
List<ResToBeProcessedDTO> resVos = records.stream().map(d -> { | |||||
ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ||||
BeanUtils.copyProperties(d, res); | BeanUtils.copyProperties(d, res); | ||||
res.setProjectId(d.getId()); | res.setProjectId(d.getId()); | ||||
@@ -185,17 +190,19 @@ public class TodoCenterManage { | |||||
return res; | return res; | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
// 取用户信息,减少数据库查询,一次构建 | // 取用户信息,减少数据库查询,一次构建 | ||||
List<ResToBeProcessedDTO> result = null; | |||||
if (CollectionUtil.isNotEmpty(staterUsers)) { | |||||
if (isNotEmpty(staterUsers)) { | |||||
Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | ||||
result = resVos.stream() | |||||
resVos.stream() | |||||
.peek(v -> v.getProcessTaskInfo().setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))) | .peek(v -> v.getProcessTaskInfo().setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
// Map<Long,UserInfo> userMap = userInfoService.getUserMapByIds(staterUsers); | // Map<Long,UserInfo> userMap = userInfoService.getUserMapByIds(staterUsers); | ||||
// result = resVos.stream().peek(v -> v.setOwner(userMap.get(userId))) | // result = resVos.stream().peek(v -> v.setOwner(userMap.get(userId))) | ||||
// .collect(Collectors.toList()); | // .collect(Collectors.toList()); | ||||
} | } | ||||
return PageVo.of(result, result.size()); | |||||
if (isEmpty(resVos)) { | |||||
return PageVo.empty(); | |||||
} | |||||
return PageVo.of(resVos, total); | |||||
} | } | ||||
/** | /** | ||||
@@ -207,7 +214,7 @@ public class TodoCenterManage { | |||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/01 | * @since 2023/02/01 | ||||
*/ | */ | ||||
public void exportPendingProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { | |||||
public void exportPendingProjectList(HttpServletResponse response, ReqToBeProcessedExportDTO param) { | |||||
param.setPageNumber(1); | param.setPageNumber(1); | ||||
param.setPageSize(10000); | param.setPageSize(10000); | ||||
// 获取登录用户ID | // 获取登录用户ID | ||||
@@ -218,8 +225,9 @@ public class TodoCenterManage { | |||||
TaskQuery taskQuery = taskService.createTaskQuery(); | TaskQuery taskQuery = taskService.createTaskQuery(); | ||||
taskQuery.active().taskCandidateOrAssigned(String.valueOf(userId)).orderByTaskCreateTime().desc(); | taskQuery.active().taskCandidateOrAssigned(String.valueOf(userId)).orderByTaskCreateTime().desc(); | ||||
List<Task> taskList = taskQuery.list(); | List<Task> taskList = taskQuery.list(); | ||||
List<Project> records = getToBeProcessedProjects(param, taskList); | |||||
ReqToBeProcessedDTO reqToBeProcessedDTO = new ReqToBeProcessedDTO(); | |||||
BeanUtils.copyProperties(param, reqToBeProcessedDTO); | |||||
List<Project> records = getToBeProcessedProjects(reqToBeProcessedDTO, taskList); | |||||
ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ||||
String fileName = null; | String fileName = null; | ||||
@@ -269,7 +277,6 @@ public class TodoCenterManage { | |||||
* @since 2023/02/11 | * @since 2023/02/11 | ||||
*/ | */ | ||||
private List<Project> getToBeProcessedProjects(ReqToBeProcessedDTO param, List<Task> taskList) { | private List<Project> getToBeProcessedProjects(ReqToBeProcessedDTO param, List<Task> taskList) { | ||||
Page<Project> page = param.page(); | |||||
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | ||||
wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | ||||
.like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | .like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | ||||
@@ -278,12 +285,13 @@ public class TodoCenterManage { | |||||
.ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | .ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | ||||
param.getProcessLaunchStartTime()) | param.getProcessLaunchStartTime()) | ||||
.le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | .le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | ||||
projectService.page(page, wrapper); | |||||
List<Project> results = projectService.list(wrapper); | |||||
List<String> taskProcessInsIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toList()); | List<String> taskProcessInsIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toList()); | ||||
// 过滤申报项目中待登录用户审核的项目 | // 过滤申报项目中待登录用户审核的项目 | ||||
return page.getRecords().stream().filter(w -> taskProcessInsIds.contains(w.getInstCode())) | |||||
return results.stream().filter(w -> taskProcessInsIds.contains(w.getInstCode())) | |||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
} | } | ||||
@@ -301,12 +309,12 @@ public class TodoCenterManage { | |||||
// Long userId = LoginUserUtil.getUserId(); | // Long userId = LoginUserUtil.getUserId(); | ||||
Long userId = 381496L; | |||||
// Long userId = 381496L; | |||||
// Long userId = 6418616L; | // Long userId = 6418616L; | ||||
Long userId = 61769799L; | |||||
// 若进行的是撤回操作(流程发起人和当前流程审核人的前一个审核人操作) | // 若进行的是撤回操作(流程发起人和当前流程审核人的前一个审核人操作) | ||||
if (param.getAction().equals(ProcessHandlerEnum.WITHDRAW)){ | |||||
if (param.getAction().equals(ProcessHandlerEnum.WITHDRAW)) { | |||||
HistoricTaskInstance handledTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(param.getTaskId()).singleResult(); | HistoricTaskInstance handledTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(param.getTaskId()).singleResult(); | ||||
doWithDrawProcess(handledTaskInstance, userId); | doWithDrawProcess(handledTaskInstance, userId); | ||||
return; | return; | ||||
@@ -375,13 +383,14 @@ public class TodoCenterManage { | |||||
// TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 | // TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 | ||||
// sendWorkNoticeToStartUser(task, projectName, rootNode); | // sendWorkNoticeToStartUser(task, projectName, rootNode); | ||||
// 更新项目状态 | |||||
updateRejectProjectStatus(userId,declaredProject); | |||||
// 更新项目状态和流程状态 | |||||
updateRejectProjectStatus(userId, declaredProject); | |||||
taskService.complete(param.getTaskId(), var); | taskService.complete(param.getTaskId(), var); | ||||
} | } | ||||
/** | /** | ||||
* 当为驳回操作时,更新项目表中的项目状态 | * 当为驳回操作时,更新项目表中的项目状态 | ||||
* | |||||
* @param userId | * @param userId | ||||
* @param declaredProject | * @param declaredProject | ||||
* @return void | * @return void | ||||
@@ -400,7 +409,10 @@ public class TodoCenterManage { | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
throw new BizException("状态机执行失败!"); | throw new BizException("状态机执行失败!"); | ||||
} | } | ||||
// 更新项目状态到下一个状态 | |||||
// 更新流程状态、项目状态到下一个状态 | |||||
declaredProject.setProcessStatus(ProcessStatusEnum.BE_REJECTED.getCode()); | |||||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||||
declaredProject.setUpdateBy(userId); | |||||
projectService.updateById(declaredProject); | projectService.updateById(declaredProject); | ||||
} | } | ||||
@@ -466,23 +478,39 @@ public class TodoCenterManage { | |||||
managementService.executeCommand(new SaveCommentCmd(param.getTaskId(), param.getInstanceId(), | managementService.executeCommand(new SaveCommentCmd(param.getTaskId(), param.getInstanceId(), | ||||
String.valueOf(userId), JSONObject.toJSONString(param.getAuditInfo()))); | String.valueOf(userId), JSONObject.toJSONString(param.getAuditInfo()))); | ||||
} | } | ||||
// 如果流程状态是被退回状态,流程通过后,当前审核人一定不是最后一个审核人(至多是最后一个),更新流程状态为审核中 | |||||
if (ProcessStatusEnum.BE_BACKED.getCode().equals(declaredProject.getProcessStatus())) { | |||||
// 通过该任务,流程到下一审核人处 | |||||
taskService.complete(param.getTaskId(), var); | |||||
// 更新流程状态为审核中 | |||||
declaredProject.setProcessStatus(ProcessStatusEnum.UNDER_REVIEW.getCode()); | |||||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||||
declaredProject.setUpdateBy(userId); | |||||
projectService.updateById(declaredProject); | |||||
// 获取此时待审核任务 | |||||
Task currentTask = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); | |||||
// 获取审核人信息,向审核人发送工作通知 | |||||
String currentUserId = currentTask.getAssignee(); | |||||
// UserInfo auditUserInfo = userInfoService.getById(Long.valueOf(currentUserId)); | |||||
// TODO 获取浙政钉用户dingKey,向其发送浙政钉工作通知 | |||||
String msg = String.format(PASS_MSG_TEMPLATE, null, projectName); | |||||
// sendWorkNotice(auditUserInfo,msg); | |||||
return; | |||||
} | |||||
// 获取bpm对象 | // 获取bpm对象 | ||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); | BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); | ||||
// 传节点定义key 获取当前节点 | |||||
// 若不是被退回项目,传节点定义key 获取当前节点 | |||||
FlowNode currentNode = (FlowNode) bpmnModel.getFlowElement(task.getTaskDefinitionKey()); | FlowNode currentNode = (FlowNode) bpmnModel.getFlowElement(task.getTaskDefinitionKey()); | ||||
// TODO 若当前流程是预审流程,需要在提交预审申报的时候,调用状态机判断申报后的项目状态, | // TODO 若当前流程是预审流程,需要在提交预审申报的时候,调用状态机判断申报后的项目状态, | ||||
// 若是省级部门联审中,要对接外部接口,获取省级部门联审的结果,更新项目状态(预审申报提交的时候处理) | // 若是省级部门联审中,要对接外部接口,获取省级部门联审的结果,更新项目状态(预审申报提交的时候处理) | ||||
// 需要先通过后才能有下一个节点的信息 | // 需要先通过后才能有下一个节点的信息 | ||||
taskService.complete(param.getTaskId(), var); | taskService.complete(param.getTaskId(), var); | ||||
// 获取流程下一个节点的审核用户ID | |||||
String nextUserId = getNextUserId(currentNode, processInstanceId); | String nextUserId = getNextUserId(currentNode, processInstanceId); | ||||
// 获取当前流程状态 | |||||
// 获取当前项目状态 | |||||
Integer status = declaredProject.getStatus(); | Integer status = declaredProject.getStatus(); | ||||
// 若当前登录用户是最后一个审批人 | |||||
// 若当前登录用户是最后一个审批人,需更新流程状态为审核完成,项目状态到下个状态 | |||||
HistoricProcessInstance instance = historyService | HistoricProcessInstance instance = historyService | ||||
.createHistoricProcessInstanceQuery() | .createHistoricProcessInstanceQuery() | ||||
.processInstanceId(processInstanceId) | .processInstanceId(processInstanceId) | ||||
@@ -491,13 +519,13 @@ public class TodoCenterManage { | |||||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(status))) { | switch (Objects.requireNonNull(ProjectStatusEnum.getValue(status))) { | ||||
// 当前项目状态是单位内部审核中 | // 当前项目状态是单位内部审核中 | ||||
case UNDER_INTERNAL_AUDIT: | case UNDER_INTERNAL_AUDIT: | ||||
// 当前项目状态是预审中 | |||||
// 当前项目状态是预审中 | |||||
case PRE_APPLYING: | case PRE_APPLYING: | ||||
// 当前项目状态是部门联审中 | |||||
// 当前项目状态是部门联审中 | |||||
case DEPARTMENT_JOINT_REVIEW: | case DEPARTMENT_JOINT_REVIEW: | ||||
// 当前项目状态是方案评审中 | |||||
// 当前项目状态是方案评审中 | |||||
case SCHEME_UNDER_REVIEW: | case SCHEME_UNDER_REVIEW: | ||||
// 当前项目状态是终验审核中 | |||||
// 当前项目状态是终验审核中 | |||||
case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | ||||
updatePassProjectStatus(userId, declaredProject); | updatePassProjectStatus(userId, declaredProject); | ||||
break; | break; | ||||
@@ -516,12 +544,13 @@ public class TodoCenterManage { | |||||
// TODO 向其发送浙政钉工作通知 获取根节点的孩子节点(即发起人节点),向其发送浙政钉工作通知 | // TODO 向其发送浙政钉工作通知 获取根节点的孩子节点(即发起人节点),向其发送浙政钉工作通知 | ||||
// 获取根节点即流程发起节点 | // 获取根节点即流程发起节点 | ||||
// FlowNode rootNode = (FlowNode) bpmnModel.getFlowElement("root"); | // FlowNode rootNode = (FlowNode) bpmnModel.getFlowElement("root"); | ||||
// sendWorkNoticeToStartUser(task, projectName, rootNode); | |||||
// sendPassWorkNoticeToStartUser(task, projectName, rootNode); | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* 当为通过操作时,更新项目表中项目状态 | * 当为通过操作时,更新项目表中项目状态 | ||||
* | |||||
* @param userId | * @param userId | ||||
* @param declaredProject | * @param declaredProject | ||||
* @return void | * @return void | ||||
@@ -540,7 +569,10 @@ public class TodoCenterManage { | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
throw new BizException("状态机执行失败!"); | throw new BizException("状态机执行失败!"); | ||||
} | } | ||||
// 更新项目状态到下一个状态 | |||||
// 更新流程状态、项目状态到下一个状态 | |||||
declaredProject.setProcessStatus(ProcessStatusEnum.APPROVED.getCode()); | |||||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||||
declaredProject.setUpdateBy(userId); | |||||
projectService.updateById(declaredProject); | projectService.updateById(declaredProject); | ||||
} | } | ||||
@@ -554,7 +586,7 @@ public class TodoCenterManage { | |||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/03 | * @since 2023/02/03 | ||||
*/ | */ | ||||
private void sendWorkNoticeToStartUser(Task task, String projectName, FlowNode rootNode) { | |||||
private void sendPassWorkNoticeToStartUser(Task task, String projectName, FlowNode rootNode) { | |||||
String startUserId = getRootUserId(rootNode, task.getProcessInstanceId()); | String startUserId = getRootUserId(rootNode, task.getProcessInstanceId()); | ||||
UserInfo startUserInfo = userInfoService.getById(Long.valueOf(startUserId)); | UserInfo startUserInfo = userInfoService.getById(Long.valueOf(startUserId)); | ||||
// 从历史表获取最新版本的流程 | // 从历史表获取最新版本的流程 | ||||
@@ -567,7 +599,7 @@ public class TodoCenterManage { | |||||
/** | /** | ||||
* 获取流程发起节点的用户ID | * 获取流程发起节点的用户ID | ||||
* | * | ||||
* @param rootNode 根节点 | |||||
* @param rootNode 根节点 | |||||
* @param processInstanceId | * @param processInstanceId | ||||
* @return java.lang.String | * @return java.lang.String | ||||
* @author CMM | * @author CMM | ||||
@@ -599,9 +631,9 @@ public class TodoCenterManage { | |||||
/** | /** | ||||
* 获取当前节点的下一个节点的审核用户ID | * 获取当前节点的下一个节点的审核用户ID | ||||
* | * | ||||
* @param currentNode 当前节点 | |||||
* @param currentNode 当前节点 | |||||
* @param processInstanceId | * @param processInstanceId | ||||
* @return java.lang.String 下一个节点的浙政钉用户ID | |||||
* @return java.lang.String 下一个节点的审核用户ID | |||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/02 | * @since 2023/02/02 | ||||
*/ | */ | ||||
@@ -641,7 +673,7 @@ public class TodoCenterManage { | |||||
*/ | */ | ||||
private boolean hasComment(ProcessComment comment) { | private boolean hasComment(ProcessComment comment) { | ||||
return Objects.nonNull(comment) | return Objects.nonNull(comment) | ||||
&& (StrUtil.isNotBlank(comment.getText()) || CollectionUtil.isNotEmpty(comment.getAttachments())); | |||||
&& (StrUtil.isNotBlank(comment.getText()) || isNotEmpty(comment.getAttachments())); | |||||
} | } | ||||
/** | /** | ||||
@@ -655,38 +687,38 @@ public class TodoCenterManage { | |||||
*/ | */ | ||||
private void sendWorkNotice(UserInfo auditUserInfo, String msg) { | private void sendWorkNotice(UserInfo auditUserInfo, String msg) { | ||||
// TODO 获取浙政钉唯一标识 | // TODO 获取浙政钉唯一标识 | ||||
String dingKey = null; | |||||
IntelligentGetClient intelligentGetClient = client.newIntelligentGetClient(DingConstant.WORKING_NOTICE); | |||||
OapiMessageWorkNotificationRequest request = new OapiMessageWorkNotificationRequest(); | |||||
// 消息体(参考下文示例消息格式) | |||||
MessageText messageText = new MessageText(); | |||||
messageText.setMsgType("text"); | |||||
MessageContent messageContent = new MessageContent(); | |||||
messageContent.setContent(msg); | |||||
messageText.setText(messageContent); | |||||
request.setMsg(JSONUtil.toJsonStr(messageText)); | |||||
// 构建唯一的消息ID | |||||
// String bizMsgId = "ZB_URGE_NOTICE_" + "_" + auditUserInfo.getDeptId() + "_" + auditUserInfo.getUserId(); | |||||
// request.setBizMsgId(bizMsgId); | |||||
request.setBizMsgId(null); | |||||
// 租户id | |||||
// request.setTenantId(GovDingProperties.tenantId.toString()); | |||||
request.setReceiverIds(dingKey); | |||||
// 获取结果 | |||||
OapiMessageWorkNotificationResponse apiResult = intelligentGetClient.get(request); | |||||
if (!apiResult.getSuccess() || !JSONUtil.parseObj(apiResult.getContent()).getBool("success")) { | |||||
log.warn("发送工作通知失败: {}", apiResult.getContent()); | |||||
throw new BizException(Status.BAD_REQUEST.toString()); | |||||
} | |||||
// String dingKey = null; | |||||
// IntelligentGetClient intelligentGetClient = client.newIntelligentGetClient(DingConstant.WORKING_NOTICE); | |||||
// OapiMessageWorkNotificationRequest request = new OapiMessageWorkNotificationRequest(); | |||||
// // 消息体(参考下文示例消息格式) | |||||
// MessageText messageText = new MessageText(); | |||||
// messageText.setMsgType("text"); | |||||
// MessageContent messageContent = new MessageContent(); | |||||
// | |||||
// messageContent.setContent(msg); | |||||
// messageText.setText(messageContent); | |||||
// request.setMsg(JSONUtil.toJsonStr(messageText)); | |||||
// // 构建唯一的消息ID | |||||
// // String bizMsgId = "ZB_URGE_NOTICE_" + "_" + auditUserInfo.getDeptId() + "_" + auditUserInfo.getUserId(); | |||||
// // request.setBizMsgId(bizMsgId); | |||||
// request.setBizMsgId(null); | |||||
// // 租户id | |||||
// // request.setTenantId(GovDingProperties.tenantId.toString()); | |||||
// request.setReceiverIds(dingKey); | |||||
// // 获取结果 | |||||
// OapiMessageWorkNotificationResponse apiResult = intelligentGetClient.get(request); | |||||
// if (!apiResult.getSuccess() || !JSONUtil.parseObj(apiResult.getContent()).getBool("success")) { | |||||
// log.warn("发送工作通知失败: {}", apiResult.getContent()); | |||||
// throw new BizException(Status.BAD_REQUEST.toString()); | |||||
// } | |||||
} | } | ||||
/** | /** | ||||
* 撤销流程处理 | * 撤销流程处理 | ||||
* | * | ||||
* @param handledTaskInstance 已处理的历史任务实例 | |||||
* @param userId 当前登录用户ID | |||||
* @param handledTaskInstance 已处理的历史任务实例 | |||||
* @param userId 当前登录用户ID | |||||
*/ | */ | ||||
private void doWithDrawProcess(HistoricTaskInstance handledTaskInstance, Long userId) { | private void doWithDrawProcess(HistoricTaskInstance handledTaskInstance, Long userId) { | ||||
String processInstanceId = handledTaskInstance.getProcessInstanceId(); | String processInstanceId = handledTaskInstance.getProcessInstanceId(); | ||||
@@ -715,17 +747,17 @@ public class TodoCenterManage { | |||||
// 判断当前登录用户是否是流程发起人 | // 判断当前登录用户是否是流程发起人 | ||||
if (startUserId.equals(String.valueOf(userId))) { | if (startUserId.equals(String.valueOf(userId))) { | ||||
// TODO 若是流程发起人点击撤回,项目回到上一个状态,并删除当前审核人对应的待办记录 | // TODO 若是流程发起人点击撤回,项目回到上一个状态,并删除当前审核人对应的待办记录 | ||||
// 若是流程发起人点击撤回,项目回到上一个状态,需调用状态机更新项目状态 | |||||
// 若是流程发起人点击撤回,项目回到上一个状态,需调用状态机更新项目状态,流程状态更新为审核通过 | |||||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(status))) { | switch (Objects.requireNonNull(ProjectStatusEnum.getValue(status))) { | ||||
// 当前项目状态是单位内部审核中 | // 当前项目状态是单位内部审核中 | ||||
case UNDER_INTERNAL_AUDIT: | case UNDER_INTERNAL_AUDIT: | ||||
// 当前项目状态是预审中 | |||||
// 当前项目状态是预审中 | |||||
case PRE_APPLYING: | case PRE_APPLYING: | ||||
// 当前项目状态是部门联审中 | |||||
// 当前项目状态是部门联审中 | |||||
case DEPARTMENT_JOINT_REVIEW: | case DEPARTMENT_JOINT_REVIEW: | ||||
// 当前项目状态是方案评审中 | |||||
// 当前项目状态是方案评审中 | |||||
case SCHEME_UNDER_REVIEW: | case SCHEME_UNDER_REVIEW: | ||||
// 当前项目状态是终验审核中 | |||||
// 当前项目状态是终验审核中 | |||||
case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | ||||
updateWithdrawProjectStatus(userId, declaredProject); | updateWithdrawProjectStatus(userId, declaredProject); | ||||
break; | break; | ||||
@@ -743,12 +775,25 @@ public class TodoCenterManage { | |||||
.collect(Collectors.toList()), HisProInsEndActId.WITHDRAW) | .collect(Collectors.toList()), HisProInsEndActId.WITHDRAW) | ||||
.changeState(); | .changeState(); | ||||
} else { | } else { | ||||
// TODO 获取前一个审核节点审核人信息 | |||||
// 获取当前流程待审核节点 | |||||
FlowNode currentNode = (FlowNode) bpmnModel.getFlowElement(task.getTaskDefinitionKey()); | |||||
SequenceFlow sequenceFlow = currentNode.getIncomingFlows().get(0); | |||||
// 获取上一个节点的activityId | |||||
String sourceRef = sequenceFlow.getSourceRef(); | |||||
HistoricActivityInstance lastInstance = historyService.createHistoricActivityInstanceQuery() | |||||
.processInstanceId(task.getProcessInstanceId()) | |||||
.activityId(sourceRef) | |||||
.activityType("userTask") | |||||
.finished() | |||||
.singleResult(); | |||||
// 获取前一个审核节点审核人信息 | |||||
String beforeUserId = lastInstance.getAssignee(); | |||||
// TODO 判断前一个审核人的部门和当前登录用户的部门是否是同一个,如果是同一个才可以撤回,否则抛出异常 | // TODO 判断前一个审核人的部门和当前登录用户的部门是否是同一个,如果是同一个才可以撤回,否则抛出异常 | ||||
Boolean orgFlag = true; | Boolean orgFlag = true; | ||||
if (orgFlag){ | |||||
// 注意:是前一个审核人,说明此时仍在一个审核流程中,项目状态不需要改变 | |||||
if (orgFlag) { | |||||
// 注意:是前一个审核人,说明此时仍在一个审核流程中,项目状态不需要改变,流程状态也不要改变,仍为审核中 | |||||
// 在审核记录中移除前一个审核人提交过的审核意见 | // 在审核记录中移除前一个审核人提交过的审核意见 | ||||
Comment comment = taskService.getProcessInstanceComments(processInstanceId).stream() | Comment comment = taskService.getProcessInstanceComments(processInstanceId).stream() | ||||
.filter(c -> c.getTaskId().equals(handledTaskInstance.getId())) | .filter(c -> c.getTaskId().equals(handledTaskInstance.getId())) | ||||
@@ -768,7 +813,7 @@ public class TodoCenterManage { | |||||
.map(Execution::getActivityId) | .map(Execution::getActivityId) | ||||
.collect(Collectors.toList()), handledNode.getId()) | .collect(Collectors.toList()), handledNode.getId()) | ||||
.changeState(); | .changeState(); | ||||
}else { | |||||
} else { | |||||
throw new BizException("下一个审核人和您不是同一个部门,无法撤回!"); | throw new BizException("下一个审核人和您不是同一个部门,无法撤回!"); | ||||
} | } | ||||
@@ -778,6 +823,7 @@ public class TodoCenterManage { | |||||
/** | /** | ||||
* 当为撤回操作时,更新项目表中的项目状态为前一个状态 | * 当为撤回操作时,更新项目表中的项目状态为前一个状态 | ||||
* | |||||
* @param userId | * @param userId | ||||
* @param declaredProject | * @param declaredProject | ||||
* @return void | * @return void | ||||
@@ -797,6 +843,9 @@ public class TodoCenterManage { | |||||
throw new BizException("状态机执行失败!"); | throw new BizException("状态机执行失败!"); | ||||
} | } | ||||
// 更新项目状态 | // 更新项目状态 | ||||
declaredProject.setProcessStatus(ProcessStatusEnum.APPROVED.getCode()); | |||||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||||
declaredProject.setUpdateBy(userId); | |||||
projectService.updateById(declaredProject); | projectService.updateById(declaredProject); | ||||
} | } | ||||
@@ -812,19 +861,56 @@ public class TodoCenterManage { | |||||
Project declaredProject = projectService | Project declaredProject = projectService | ||||
.getOne(Wrappers.lambdaQuery(Project.class).eq(Project::getInstCode, task.getProcessInstanceId())); | .getOne(Wrappers.lambdaQuery(Project.class).eq(Project::getInstCode, task.getProcessInstanceId())); | ||||
String projectName = declaredProject.getProjectName(); | String projectName = declaredProject.getProjectName(); | ||||
// 获取流程定义 | |||||
Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); | |||||
// 获取根节点即流程发起节点 | |||||
FlowNode rootNode = (FlowNode) process.getFlowElement("root", true); | |||||
// TODO 流程变成【被退回】状态,待我处理中,为流程发起人增加一条待办记录,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 | |||||
sendWorkNoticeToStartUser(task, projectName, rootNode); | |||||
// 保存审核意见 | |||||
if (hasComment(param.getAuditInfo())) { | |||||
// 执行自定义的保存评论的功能 | |||||
managementService.executeCommand(new SaveCommentCmd(param.getTaskId(), param.getInstanceId(), | |||||
String.valueOf(userId), JSONObject.toJSONString(param.getAuditInfo()))); | |||||
} | |||||
// 获取bpm对象 | |||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); | |||||
// 传节点定义key 获取根节点即流程发起节点 | |||||
FlowNode rootNode = (FlowNode) bpmnModel.getFlowElement("root"); | |||||
// TODO 流程变成【被退回】状态,待我处理中,为流程发起人增加一条待办记录, | |||||
// 执行自定义回退逻辑,回退到流程发起人 | // 执行自定义回退逻辑,回退到流程发起人 | ||||
managementService | |||||
.executeCommand(new BackToHisApprovalNodeCmd(runtimeService, param.getTaskId(), rootNode.getId())); | |||||
// 注意:因为审核人有执行退回的权限,且是退回到流程发起人,说明是在同一个流程实例中,所以项目状态不需要更新 | |||||
managementService.executeCommand(new BackToHisApprovalNodeCmd(runtimeService, bpmnModel, param.getTaskId(), rootNode.getId())); | |||||
runtimeService.setVariables(param.getInstanceId(), | runtimeService.setVariables(param.getInstanceId(), | ||||
Maps.newHashMap("approve_" + param.getTaskId(), param.getAction())); | Maps.newHashMap("approve_" + param.getTaskId(), param.getAction())); | ||||
log.info("用户[{}] 退回流程[{}] [{} -> {}]", userId, param.getInstanceId(), task.getTaskDefinitionKey(), | |||||
log.info("用户[{}] 退回流程[{}] [{} -> {}]", userId, param.getInstanceId(), | |||||
task.getTaskDefinitionKey(), | |||||
param.getTargetNode()); | param.getTargetNode()); | ||||
// 更新申报项目表中的流程状态为被退回 | |||||
declaredProject.setProcessStatus(ProcessStatusEnum.BE_BACKED.getCode()); | |||||
declaredProject.setUpdateOn(LocalDateTime.now()); | |||||
declaredProject.setUpdateBy(userId); | |||||
projectService.updateById(declaredProject); | |||||
// TODO 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 | |||||
// sendBackWorkNoticeToStartUser(task, projectName, rootNode); | |||||
} | |||||
/** | |||||
* 给流程发起人发送流程退回工作通知 | |||||
* | |||||
* @param task | |||||
* @param projectName | |||||
* @param rootNode | |||||
* @return void | |||||
* @author CMM | |||||
* @since 2023/02/14 15:32 | |||||
*/ | |||||
private void sendBackWorkNoticeToStartUser(Task task, String projectName, FlowNode rootNode) { | |||||
String startUserId = getRootUserId(rootNode, task.getProcessInstanceId()); | |||||
UserInfo startUserInfo = userInfoService.getById(Long.valueOf(startUserId)); | |||||
// 从历史表获取最新版本的流程 | |||||
WflowModels wflowModels = getLastWflowModels(task); | |||||
String formName = wflowModels.getFormName(); | |||||
String msg = String.format(PASS_MSG_TEMPLATE3, projectName, formName); | |||||
sendWorkNotice(startUserInfo, msg); | |||||
} | } | ||||
/** | /** | ||||
@@ -835,13 +921,27 @@ public class TodoCenterManage { | |||||
* @return 流程进度及表单详情 | * @return 流程进度及表单详情 | ||||
*/ | */ | ||||
public ProcessProgressDetailVo getProcessDetail(String nodeId, String instanceId) { | public ProcessProgressDetailVo getProcessDetail(String nodeId, String instanceId) { | ||||
HistoricProcessInstance instance = | |||||
historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult(); | |||||
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery() | |||||
.processInstanceId(instanceId).singleResult(); | |||||
// 取表单及表单数据 | // 取表单及表单数据 | ||||
HistoricVariableInstance forms = historyService.createHistoricVariableInstanceQuery() | HistoricVariableInstance forms = historyService.createHistoricVariableInstanceQuery() | ||||
.processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_FORMS).singleResult(); | |||||
List<HistoricVariableInstance> formDatas = | |||||
historyService.createHistoricVariableInstanceQuery().processInstanceId(instanceId).list(); | |||||
.processInstanceId(instanceId) | |||||
.variableName(WflowGlobalVarDef.WFLOW_FORMS) | |||||
.singleResult(); | |||||
List<HistoricVariableInstance> formDatas = null; | |||||
if (nodeId.equals("undefined")) { | |||||
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).list(); | |||||
formDatas = historyService | |||||
.createHistoricVariableInstanceQuery() | |||||
.executionIds(historicTaskInstances.stream().map(HistoricTaskInstance::getExecutionId).collect(Collectors.toSet())) | |||||
.processInstanceId(instanceId) | |||||
.list(); | |||||
} else { | |||||
formDatas = historyService | |||||
.createHistoricVariableInstanceQuery() | |||||
.processInstanceId(instanceId) | |||||
.list(); | |||||
} | |||||
// 取节点设置 | // 取节点设置 | ||||
HistoricVariableInstance nodeProps = historyService.createHistoricVariableInstanceQuery() | HistoricVariableInstance nodeProps = historyService.createHistoricVariableInstanceQuery() | ||||
.processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult(); | .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult(); | ||||
@@ -914,7 +1014,7 @@ public class TodoCenterManage { | |||||
.name(task.getNodeName()).user(OrgUser.builder().id(task.getUserId()).build()) | .name(task.getNodeName()).user(OrgUser.builder().id(task.getUserId()).build()) | ||||
.startTime(task.getCreateTime()).finishTime(task.getCreateTime()).build(); | .startTime(task.getCreateTime()).finishTime(task.getCreateTime()).build(); | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
if (CollectionUtil.isNotEmpty(ccUsers)) { | |||||
if (isNotEmpty(ccUsers)) { | |||||
Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(ccUsers); | Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(ccUsers); | ||||
ccList.stream().peek(v -> v.setUser(userMap.get(v.getUser().getId()))).collect(Collectors.toList()); | ccList.stream().peek(v -> v.setUser(userMap.get(v.getUser().getId()))).collect(Collectors.toList()); | ||||
} | } | ||||
@@ -975,7 +1075,7 @@ public class TodoCenterManage { | |||||
.approvalMode(approvalMode).auditInfo(commentsMap.get(his.getTaskId())) | .approvalMode(approvalMode).auditInfo(commentsMap.get(his.getTaskId())) | ||||
.result(varMap.get("approve_" + his.getTaskId())).build(); | .result(varMap.get("approve_" + his.getTaskId())).build(); | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
if (CollectionUtil.isNotEmpty(userSet)) { | |||||
if (isNotEmpty(userSet)) { | |||||
Map<String, OrgUser> map = userDeptOrLeaderService.getUserMapByIds(userSet); | Map<String, OrgUser> map = userDeptOrLeaderService.getUserMapByIds(userSet); | ||||
progressNodes.forEach(n -> n.setUser(map.get(n.getUser().getId()))); | progressNodes.forEach(n -> n.setUser(map.get(n.getUser().getId()))); | ||||
} | } | ||||
@@ -1016,18 +1116,29 @@ public class TodoCenterManage { | |||||
.collect(Collectors.toSet()); | .collect(Collectors.toSet()); | ||||
List<Project> results = getHandledProjects(param, taskProcessInsIds); | List<Project> results = getHandledProjects(param, taskProcessInsIds); | ||||
// 总数 | |||||
int total = results.size(); | |||||
// 获取传入的分页参数 | |||||
Integer pageNumber = param.getPageNumber(); | |||||
Integer pageSize = param.getPageSize(); | |||||
List<Project> records = results.stream() | |||||
.skip((long) (pageNumber - 1) * pageSize) | |||||
.limit(pageSize) | |||||
.collect(Collectors.toList()); | |||||
// 把已办任务实例一次性取出来,减少查询次数 | // 把已办任务实例一次性取出来,减少查询次数 | ||||
Map<String, HistoricTaskInstance> taskInstanceMap = taskInstances.stream() | Map<String, HistoricTaskInstance> taskInstanceMap = taskInstances.stream() | ||||
.collect(Collectors.toMap(HistoricTaskInstance::getProcessInstanceId, v -> v)); | .collect(Collectors.toMap(HistoricTaskInstance::getProcessInstanceId, v -> v)); | ||||
Map<String, HistoricProcessInstance> instanceMap = CollectionUtil.isNotEmpty(taskInstances) | |||||
Map<String, HistoricProcessInstance> instanceMap = isNotEmpty(taskInstances) | |||||
? historyService.createHistoricProcessInstanceQuery() | ? historyService.createHistoricProcessInstanceQuery() | ||||
.processInstanceIds(taskProcessInsIds) | .processInstanceIds(taskProcessInsIds) | ||||
.list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) | .list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) | ||||
: new HashMap<>(); | : new HashMap<>(); | ||||
Set<String> staterUsers = new HashSet<>(); | Set<String> staterUsers = new HashSet<>(); | ||||
List<ResToBeProcessedDTO> resVos = results.stream().map(d -> { | |||||
List<ResToBeProcessedDTO> resVos = records.stream().map(d -> { | |||||
ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ||||
BeanUtils.copyProperties(d, res); | BeanUtils.copyProperties(d, res); | ||||
@@ -1060,18 +1171,19 @@ public class TodoCenterManage { | |||||
return res; | return res; | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
// 取用户信息,减少数据库查询,一次构建 | // 取用户信息,减少数据库查询,一次构建 | ||||
List<ResToBeProcessedDTO> result = null; | |||||
if (CollectionUtil.isNotEmpty(staterUsers)) { | |||||
if (isNotEmpty(staterUsers)) { | |||||
Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | ||||
result = resVos.stream() | |||||
resVos.stream() | |||||
.peek(v -> v.getProcessTaskInfo().setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))) | .peek(v -> v.getProcessTaskInfo().setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
// Map<Long,UserInfo> userMap = userInfoService.getUserMapByIds(staterUsers); | // Map<Long,UserInfo> userMap = userInfoService.getUserMapByIds(staterUsers); | ||||
// result = resVos.stream().peek(v -> v.setOwner(userMap.get(userId))) | // result = resVos.stream().peek(v -> v.setOwner(userMap.get(userId))) | ||||
// .collect(Collectors.toList()); | // .collect(Collectors.toList()); | ||||
} | } | ||||
return PageVo.of(result, result.size()); | |||||
if (isEmpty(resVos)) { | |||||
return PageVo.empty(); | |||||
} | |||||
return PageVo.of(resVos, total); | |||||
} | } | ||||
/** | /** | ||||
@@ -1084,8 +1196,6 @@ public class TodoCenterManage { | |||||
* @since 2023/02/11 | * @since 2023/02/11 | ||||
*/ | */ | ||||
private List<Project> getHandledProjects(ReqToBeProcessedDTO param, Set<String> taskProcessInsIds) { | private List<Project> getHandledProjects(ReqToBeProcessedDTO param, Set<String> taskProcessInsIds) { | ||||
// 获取入参分页信息 | |||||
Page<Project> page = param.page(); | |||||
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | ||||
wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | ||||
.like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | .like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | ||||
@@ -1094,10 +1204,10 @@ public class TodoCenterManage { | |||||
.ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | .ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | ||||
param.getProcessLaunchStartTime()) | param.getProcessLaunchStartTime()) | ||||
.le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | .le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | ||||
projectService.page(page, wrapper); | |||||
List<Project> results = projectService.list(wrapper); | |||||
// 过滤申报项目中登录用户已审核的项目 | // 过滤申报项目中登录用户已审核的项目 | ||||
return page.getRecords().stream() | |||||
return results.stream() | |||||
.filter(w -> taskProcessInsIds.contains(w.getInstCode())) | .filter(w -> taskProcessInsIds.contains(w.getInstCode())) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
} | } | ||||
@@ -1111,7 +1221,7 @@ public class TodoCenterManage { | |||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/06 | * @since 2023/02/06 | ||||
*/ | */ | ||||
public void exportHandledProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { | |||||
public void exportHandledProjectList(HttpServletResponse response, ReqToBeProcessedExportDTO param) { | |||||
param.setPageNumber(1); | param.setPageNumber(1); | ||||
param.setPageSize(10000); | param.setPageSize(10000); | ||||
// 获取登录用户ID | // 获取登录用户ID | ||||
@@ -1129,7 +1239,9 @@ public class TodoCenterManage { | |||||
Set<String> taskProcessInsIds = taskInstances.stream() | Set<String> taskProcessInsIds = taskInstances.stream() | ||||
.map(HistoricTaskInstance::getProcessInstanceId) | .map(HistoricTaskInstance::getProcessInstanceId) | ||||
.collect(Collectors.toSet()); | .collect(Collectors.toSet()); | ||||
List<Project> records = getHandledProjects(param, taskProcessInsIds); | |||||
ReqToBeProcessedDTO reqToBeProcessedDTO = new ReqToBeProcessedDTO(); | |||||
BeanUtils.copyProperties(param, reqToBeProcessedDTO); | |||||
List<Project> records = getHandledProjects(reqToBeProcessedDTO, taskProcessInsIds); | |||||
ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ||||
@@ -1188,20 +1300,30 @@ public class TodoCenterManage { | |||||
List<HistoricProcessInstance> historicProcessInstances = | List<HistoricProcessInstance> historicProcessInstances = | ||||
instanceQuery.orderByProcessInstanceStartTime().desc().orderByProcessInstanceEndTime().desc().list(); | instanceQuery.orderByProcessInstanceStartTime().desc().orderByProcessInstanceEndTime().desc().list(); | ||||
Set<String> historicProcessInstanceIds = | Set<String> historicProcessInstanceIds = | ||||
historicProcessInstances.stream().map(h -> h.getId()).collect(Collectors.toSet()); | |||||
historicProcessInstances.stream().map(HistoricProcessInstance::getId).collect(Collectors.toSet()); | |||||
List<Project> results = getMySubmittedProjects(param, historicProcessInstanceIds); | List<Project> results = getMySubmittedProjects(param, historicProcessInstanceIds); | ||||
// 总数 | |||||
int total = results.size(); | |||||
// 获取传入的分页参数 | |||||
Integer pageNumber = param.getPageNumber(); | |||||
Integer pageSize = param.getPageSize(); | |||||
List<Project> records = results.stream() | |||||
.skip((long) (pageNumber - 1) * pageSize) | |||||
.limit(pageSize) | |||||
.collect(Collectors.toList()); | |||||
// 把已办任务流程实例一次性取出来,减少查询次数 | // 把已办任务流程实例一次性取出来,减少查询次数 | ||||
Map<String, HistoricProcessInstance> instanceMap = CollectionUtil.isNotEmpty(historicProcessInstances) ? historyService | |||||
Map<String, HistoricProcessInstance> instanceMap = isNotEmpty(historicProcessInstances) ? historyService | |||||
.createHistoricProcessInstanceQuery() | .createHistoricProcessInstanceQuery() | ||||
.processInstanceIds(historicProcessInstances.stream().map(h -> h.getId()).collect(Collectors.toSet())) | |||||
.processInstanceIds(historicProcessInstances.stream().map(HistoricProcessInstance::getId).collect(Collectors.toSet())) | |||||
.list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) : new HashMap<>(); | .list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) : new HashMap<>(); | ||||
Set<String> staterUsers = new HashSet<>(); | Set<String> staterUsers = new HashSet<>(); | ||||
List<ResToBeProcessedDTO> resVos = | List<ResToBeProcessedDTO> resVos = | ||||
results.stream().map(d -> { | |||||
records.stream().map(d -> { | |||||
ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ||||
BeanUtils.copyProperties(d, res); | BeanUtils.copyProperties(d, res); | ||||
res.setProjectId(d.getId()); | res.setProjectId(d.getId()); | ||||
@@ -1218,7 +1340,7 @@ public class TodoCenterManage { | |||||
return res; | return res; | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
if (CollectionUtil.isNotEmpty(staterUsers)) { | |||||
if (isNotEmpty(staterUsers)) { | |||||
Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | ||||
resVos.stream().map(v -> { | resVos.stream().map(v -> { | ||||
v.getProcessInstanceInfo().setStaterUser(userMap.get(v.getProcessInstanceInfo().getStaterUserId())); | v.getProcessInstanceInfo().setStaterUser(userMap.get(v.getProcessInstanceInfo().getStaterUserId())); | ||||
@@ -1231,7 +1353,7 @@ public class TodoCenterManage { | |||||
// resVos.stream().peek(v -> v.setOwner(userMap.get(startUserId))) | // resVos.stream().peek(v -> v.setOwner(userMap.get(startUserId))) | ||||
// .collect(Collectors.toList()); | // .collect(Collectors.toList()); | ||||
// } | // } | ||||
return PageVo.of(resVos, resVos.size()); | |||||
return PageVo.of(resVos, total); | |||||
} | } | ||||
/** | /** | ||||
@@ -1244,7 +1366,6 @@ public class TodoCenterManage { | |||||
* @since 2023/02/11 | * @since 2023/02/11 | ||||
*/ | */ | ||||
private List<Project> getMySubmittedProjects(ReqToBeProcessedDTO param, Set<String> historicProcessInstanceIds) { | private List<Project> getMySubmittedProjects(ReqToBeProcessedDTO param, Set<String> historicProcessInstanceIds) { | ||||
Page<Project> page = param.page(); | |||||
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | ||||
wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | ||||
.like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | .like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | ||||
@@ -1253,13 +1374,12 @@ public class TodoCenterManage { | |||||
.ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | .ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | ||||
param.getProcessLaunchStartTime()) | param.getProcessLaunchStartTime()) | ||||
.le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | .le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | ||||
projectService.page(page, wrapper); | |||||
List<Project> results = projectService.list(wrapper); | |||||
// 筛选出申报项目中我发起的项目 | // 筛选出申报项目中我发起的项目 | ||||
List<Project> results = page.getRecords().stream() | |||||
return results.stream() | |||||
.filter(d -> historicProcessInstanceIds.contains(d.getInstCode())) | .filter(d -> historicProcessInstanceIds.contains(d.getInstCode())) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
return results; | |||||
} | } | ||||
/** | /** | ||||
@@ -1294,7 +1414,7 @@ public class TodoCenterManage { | |||||
List<Task> list = | List<Task> list = | ||||
taskService.createTaskQuery().processInstanceId(ist.getId()).includeIdentityLinks().active().list(); | taskService.createTaskQuery().processInstanceId(ist.getId()).includeIdentityLinks().active().list(); | ||||
instanceVo.setNodeId(Optional.ofNullable(instanceVo.getNodeId()).orElseGet(() -> { | instanceVo.setNodeId(Optional.ofNullable(instanceVo.getNodeId()).orElseGet(() -> { | ||||
if (CollectionUtil.isNotEmpty(list)) { | |||||
if (isNotEmpty(list)) { | |||||
return list.get(0).getTaskDefinitionKey(); | return list.get(0).getTaskDefinitionKey(); | ||||
} | } | ||||
return null; | return null; | ||||
@@ -1322,7 +1442,7 @@ public class TodoCenterManage { | |||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/11 | * @since 2023/02/11 | ||||
*/ | */ | ||||
public void exportMySubmittedProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { | |||||
public void exportMySubmittedProjectList(HttpServletResponse response, ReqToBeProcessedExportDTO param) { | |||||
param.setPageNumber(1); | param.setPageNumber(1); | ||||
param.setPageSize(10000); | param.setPageSize(10000); | ||||
@@ -1337,7 +1457,9 @@ public class TodoCenterManage { | |||||
Set<String> historicProcessInstanceIds = historicProcessInstances.stream() | Set<String> historicProcessInstanceIds = historicProcessInstances.stream() | ||||
.map(h -> h.getId()) | .map(h -> h.getId()) | ||||
.collect(Collectors.toSet()); | .collect(Collectors.toSet()); | ||||
List<Project> records = getMySubmittedProjects(param, historicProcessInstanceIds); | |||||
ReqToBeProcessedDTO reqToBeProcessedDTO = new ReqToBeProcessedDTO(); | |||||
BeanUtils.copyProperties(param, reqToBeProcessedDTO); | |||||
List<Project> records = getMySubmittedProjects(reqToBeProcessedDTO, historicProcessInstanceIds); | |||||
ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ||||
@@ -1400,15 +1522,25 @@ public class TodoCenterManage { | |||||
List<Project> results = getCcMeProjects(param, processInsIds); | List<Project> results = getCcMeProjects(param, processInsIds); | ||||
// 总数 | |||||
int total = results.size(); | |||||
// 获取传入的分页参数 | |||||
Integer pageNumber = param.getPageNumber(); | |||||
Integer pageSize = param.getPageSize(); | |||||
List<Project> records = results.stream() | |||||
.skip((long) (pageNumber - 1) * pageSize) | |||||
.limit(pageSize) | |||||
.collect(Collectors.toList()); | |||||
Set<String> staterUsers = new HashSet<>(); | Set<String> staterUsers = new HashSet<>(); | ||||
// 将抄送我的流程实例一次性取出来,减少查询次数 | // 将抄送我的流程实例一次性取出来,减少查询次数 | ||||
Map<String, HistoricProcessInstance> instanceMap = CollectionUtil.isNotEmpty(ccTasks) | |||||
Map<String, HistoricProcessInstance> instanceMap = isNotEmpty(ccTasks) | |||||
? historyService.createHistoricProcessInstanceQuery() | ? historyService.createHistoricProcessInstanceQuery() | ||||
.processInstanceIds(ccTasks.stream().map(WflowCcTasks::getInstanceId).collect(Collectors.toSet())) | .processInstanceIds(ccTasks.stream().map(WflowCcTasks::getInstanceId).collect(Collectors.toSet())) | ||||
.list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) | .list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) | ||||
: new HashMap<>(); | : new HashMap<>(); | ||||
List<ResToBeProcessedDTO> resVos = | List<ResToBeProcessedDTO> resVos = | ||||
results.stream().map(d -> { | |||||
records.stream().map(d -> { | |||||
ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ResToBeProcessedDTO res = new ResToBeProcessedDTO(); | ||||
BeanUtils.copyProperties(d, res); | BeanUtils.copyProperties(d, res); | ||||
res.setProjectId(d.getId()); | res.setProjectId(d.getId()); | ||||
@@ -1425,7 +1557,7 @@ public class TodoCenterManage { | |||||
return res; | return res; | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
if (CollectionUtil.isNotEmpty(staterUsers)) { | |||||
if (isNotEmpty(staterUsers)) { | |||||
Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | Map<String, OrgUser> userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); | ||||
resVos.stream().map(v -> { | resVos.stream().map(v -> { | ||||
v.getProcessInstanceInfo().setStaterUser(userMap.get(v.getProcessInstanceInfo().getStaterUserId())); | v.getProcessInstanceInfo().setStaterUser(userMap.get(v.getProcessInstanceInfo().getStaterUserId())); | ||||
@@ -1438,7 +1570,7 @@ public class TodoCenterManage { | |||||
// resVos.stream().peek(v -> v.setOwner(userMap.get(startUserId))) | // resVos.stream().peek(v -> v.setOwner(userMap.get(startUserId))) | ||||
// .collect(Collectors.toList()); | // .collect(Collectors.toList()); | ||||
// } | // } | ||||
return PageVo.of(resVos, resVos.size()); | |||||
return PageVo.of(resVos, total); | |||||
} | } | ||||
/** | /** | ||||
@@ -1451,7 +1583,6 @@ public class TodoCenterManage { | |||||
* @since 2023/02/11 | * @since 2023/02/11 | ||||
*/ | */ | ||||
private List<Project> getCcMeProjects(ReqToBeProcessedDTO param, List<String> processInsIds) { | private List<Project> getCcMeProjects(ReqToBeProcessedDTO param, List<String> processInsIds) { | ||||
Page<Project> page = param.page(); | |||||
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class); | ||||
wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | wrapper.like(StrUtil.isNotBlank(param.getProjectName()), Project::getProjectName, param.getProjectName()) | ||||
.like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | .like(StrUtil.isNotBlank(param.getBuildUnitName()), Project::getBuildOrgName, param.getBuildUnitName()) | ||||
@@ -1460,9 +1591,9 @@ public class TodoCenterManage { | |||||
.ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | .ge(Objects.nonNull(param.getProcessLaunchStartTime()), Project::getBeginTime, | ||||
param.getProcessLaunchStartTime()) | param.getProcessLaunchStartTime()) | ||||
.le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | .le(Objects.nonNull(param.getProcessLaunchEndTime()), Project::getEndTime, param.getProcessLaunchEndTime()); | ||||
projectService.page(page, wrapper); | |||||
List<Project> results = projectService.list(wrapper); | |||||
return page.getRecords().stream() | |||||
return results.stream() | |||||
.filter(d -> processInsIds.contains(d.getInstCode())) | .filter(d -> processInsIds.contains(d.getInstCode())) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
} | } | ||||
@@ -1476,7 +1607,7 @@ public class TodoCenterManage { | |||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/11 | * @since 2023/02/11 | ||||
*/ | */ | ||||
public void exportCcMeProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { | |||||
public void exportCcMeProjectList(HttpServletResponse response, ReqToBeProcessedExportDTO param) { | |||||
param.setPageNumber(1); | param.setPageNumber(1); | ||||
param.setPageSize(10000); | param.setPageSize(10000); | ||||
@@ -1490,7 +1621,9 @@ public class TodoCenterManage { | |||||
.map(WflowCcTasks::getInstanceId) | .map(WflowCcTasks::getInstanceId) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
List<Project> records = getCcMeProjects(param, processInsIds); | |||||
ReqToBeProcessedDTO reqToBeProcessedDTO = new ReqToBeProcessedDTO(); | |||||
BeanUtils.copyProperties(param, reqToBeProcessedDTO); | |||||
List<Project> records = getCcMeProjects(reqToBeProcessedDTO, processInsIds); | |||||
ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ||||
@@ -15,7 +15,7 @@ import lombok.NoArgsConstructor; | |||||
import javax.validation.constraints.NotNull; | import javax.validation.constraints.NotNull; | ||||
/** | /** | ||||
* 待办中心-待我处理查询实体信息 | |||||
* 待办中心-列表查询实体信息 | |||||
* | * | ||||
* @author CMM | * @author CMM | ||||
* @since 2023/01/12 16:01 | * @since 2023/01/12 16:01 | ||||
@@ -44,8 +44,4 @@ public class ReqToBeProcessedDTO extends PagePo implements Serializable { | |||||
@ApiModelProperty(value = "是否增补项目",allowableValues = "非增补项目 0,增补项目 1") | @ApiModelProperty(value = "是否增补项目",allowableValues = "非增补项目 0,增补项目 1") | ||||
@NotNull(message = "是否增补字段不能为空!") | @NotNull(message = "是否增补字段不能为空!") | ||||
private Integer isSupplement; | private Integer isSupplement; | ||||
@ApiModelProperty("导出选项") | |||||
private List<ExportOptionEnum> exportOptionList; | |||||
} | } |
@@ -0,0 +1,52 @@ | |||||
package com.ningdatech.pmapi.todocenter.model.dto.req; | |||||
import java.io.Serializable; | |||||
import java.time.LocalDateTime; | |||||
import java.util.List; | |||||
import javax.validation.constraints.NotNull; | |||||
import com.ningdatech.basic.model.PagePo; | |||||
import com.ningdatech.pmapi.common.enumeration.ExportOptionEnum; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
/** | |||||
* 待办中心-导出查询实体信息 | |||||
* | |||||
* @author CMM | |||||
* @since 2023/01/12 16:01 | |||||
*/ | |||||
@Data | |||||
@NoArgsConstructor | |||||
@AllArgsConstructor | |||||
public class ReqToBeProcessedExportDTO extends PagePo implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty("项目名称") | |||||
private String projectName; | |||||
@ApiModelProperty("申报单位名称") | |||||
private String buildUnitName; | |||||
@ApiModelProperty("预算年度") | |||||
private Integer projectYear; | |||||
@ApiModelProperty("流程发起开始时间") | |||||
private LocalDateTime processLaunchStartTime; | |||||
@ApiModelProperty("流程发起结束时间") | |||||
private LocalDateTime processLaunchEndTime; | |||||
@ApiModelProperty(value = "是否增补项目",allowableValues = "非增补项目 0,增补项目 1") | |||||
@NotNull(message = "是否增补字段不能为空!") | |||||
private Integer isSupplement; | |||||
@ApiModelProperty("导出选项") | |||||
@NotNull(message = "导出选项不能为空") | |||||
private List<ExportOptionEnum> exportOptionList; | |||||
} |
@@ -0,0 +1,30 @@ | |||||
package com.ningdatech.pmapi.user.constant; | |||||
import io.swagger.annotations.ApiModel; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Getter; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2022/8/17 下午5:55 | |||||
*/ | |||||
@AllArgsConstructor | |||||
@Getter | |||||
@ApiModel("登陆类型") | |||||
public enum LoginTypeEnum { | |||||
/** | |||||
* 浙政钉扫码登陆 | |||||
*/ | |||||
DING_QR_LOGIN, | |||||
/** | |||||
* 手机号验证码登陆 | |||||
*/ | |||||
PHONE_VERIFICATION_CODE_LOGIN, | |||||
/** | |||||
* 账号密码登陆 | |||||
*/ | |||||
USERNAME_PASSWORD_LOGIN; | |||||
} |
@@ -1,20 +0,0 @@ | |||||
package com.ningdatech.pmapi.user.controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.stereotype.Controller; | |||||
/** | |||||
* <p> | |||||
* 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-01 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.user/nd-user-auth") | |||||
public class NdUserAuthController { | |||||
} |
@@ -1,20 +0,0 @@ | |||||
package com.ningdatech.pmapi.user.controller; | |||||
import org.springframework.stereotype.Controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
/** | |||||
* <p> | |||||
* 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-01 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.user/nd-user-info") | |||||
public class NdUserInfoController { | |||||
} |
@@ -36,13 +36,16 @@ public class UserAuthController { | |||||
private final ObjectMapper objectMapper; | private final ObjectMapper objectMapper; | ||||
@PostMapping(value = "/login/password", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) | |||||
@ApiOperation(value = "账号密码的登陆方式") | |||||
@PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) | |||||
@ApiOperation(value = "登陆") | |||||
@ApiImplicitParams({ | @ApiImplicitParams({ | ||||
@ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "form", dataType = "String"), | |||||
@ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "form", dataType = "String")}) | |||||
public void loginByUsernameAndPassword(@RequestParam("username") String username, | |||||
@RequestParam("password") String password) { | |||||
@ApiImplicitParam(name = "identifier", value = "账号", required = true, paramType = "form", dataType = "String"), | |||||
@ApiImplicitParam(name = "credential", value = "凭证", required = true, paramType = "form", dataType = "String"), | |||||
@ApiImplicitParam(name = "loginType", value = "DING_QR_LOGIN 浙政钉扫码登陆,PHONE_VERIFICATION_CODE_LOGIN 手机号验证码登陆" | |||||
, required = true, paramType = "form", dataType = "String")}) | |||||
public void loginByUsernameAndPassword(@RequestParam(value = "identifier",required = false) String identifier, | |||||
@RequestParam(value = "credential",required = false) String credential, | |||||
@RequestParam("loginType") String loginType) { | |||||
// 不实现任何内容,只是为了出api文档 | // 不实现任何内容,只是为了出api文档 | ||||
} | } | ||||
@@ -3,8 +3,10 @@ package com.ningdatech.pmapi.user.controller; | |||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.pmapi.user.manage.UserInfoManage; | import com.ningdatech.pmapi.user.manage.UserInfoManage; | ||||
import com.ningdatech.pmapi.user.model.po.ReqUserDetailEditPO; | |||||
import com.ningdatech.pmapi.user.model.po.ReqUserDisablePO; | import com.ningdatech.pmapi.user.model.po.ReqUserDisablePO; | ||||
import com.ningdatech.pmapi.user.model.po.ReqUserInfoListPO; | import com.ningdatech.pmapi.user.model.po.ReqUserInfoListPO; | ||||
import com.ningdatech.pmapi.user.model.vo.ResUserDetailVO; | |||||
import com.ningdatech.pmapi.user.model.vo.ResUserInfoListVO; | import com.ningdatech.pmapi.user.model.vo.ResUserInfoListVO; | ||||
import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
@@ -40,8 +42,21 @@ public class UserInfoController { | |||||
@ApiOperation(value = "用户禁用", notes = "用户禁用") | @ApiOperation(value = "用户禁用", notes = "用户禁用") | ||||
@PostMapping("/disable") | @PostMapping("/disable") | ||||
public void disable(@Valid @RequestBody ReqUserDisablePO reqUserDisablePO){ | |||||
public void disable(@Valid @RequestBody ReqUserDisablePO reqUserDisablePO) { | |||||
userInfoManage.disable(reqUserDisablePO); | userInfoManage.disable(reqUserDisablePO); | ||||
} | } | ||||
@ApiOperation(value = "用户详情", notes = "用户详情") | |||||
@PostMapping("/detail") | |||||
public ResUserDetailVO userInfoDetail(@Valid @RequestBody ReqUserInfoListPO reqUserInfoListPO) { | |||||
return userInfoManage.userInfoDetail(reqUserInfoListPO); | |||||
} | |||||
@ApiOperation(value = "用户详情编辑", notes = "用户详情编辑") | |||||
@PostMapping("/detail/edit") | |||||
public void userInfoDetailEdit(@Valid @RequestBody ReqUserDetailEditPO reqUserDetailEditPO) { | |||||
userInfoManage.userInfoDetailEdit(reqUserDetailEditPO); | |||||
} | |||||
} | } |
@@ -18,6 +18,12 @@ public class UserAuthLoginManage { | |||||
private final IUserAuthService iUserAuthService; | private final IUserAuthService iUserAuthService; | ||||
private final IUserInfoService iUserInfoService; | private final IUserInfoService iUserInfoService; | ||||
/** | |||||
* 根据用户名获取 | |||||
* | |||||
* @param username | |||||
* @return | |||||
*/ | |||||
public UserFullInfoDTO queryUserInfoInPasswordAuth(String username) { | public UserFullInfoDTO queryUserInfoInPasswordAuth(String username) { | ||||
UserFullInfoDTO userFullInfoDTO = new UserFullInfoDTO(); | UserFullInfoDTO userFullInfoDTO = new UserFullInfoDTO(); | ||||
userFullInfoDTO.setCompanyId(1L); | userFullInfoDTO.setCompanyId(1L); | ||||
@@ -27,4 +33,36 @@ public class UserAuthLoginManage { | |||||
userFullInfoDTO.setUsername("测试账号"); | userFullInfoDTO.setUsername("测试账号"); | ||||
return userFullInfoDTO; | return userFullInfoDTO; | ||||
} | } | ||||
/** | |||||
* 根据手机号获取 | |||||
* | |||||
* @param phoneNo | |||||
* @return | |||||
*/ | |||||
public UserFullInfoDTO queryUserInfoInPhoneNoAuth(String phoneNo) { | |||||
UserFullInfoDTO userFullInfoDTO = new UserFullInfoDTO(); | |||||
userFullInfoDTO.setCompanyId(1L); | |||||
userFullInfoDTO.setUserId(1L); | |||||
userFullInfoDTO.setIdentifier("123456"); | |||||
userFullInfoDTO.setRealName("测试账号"); | |||||
userFullInfoDTO.setUsername("测试账号"); | |||||
return userFullInfoDTO; | |||||
} | |||||
/** | |||||
* 根据accountId | |||||
* | |||||
* @param accountId | |||||
* @return | |||||
*/ | |||||
public UserFullInfoDTO queryUserInfoInAccountIdAuth(String accountId) { | |||||
UserFullInfoDTO userFullInfoDTO = new UserFullInfoDTO(); | |||||
userFullInfoDTO.setCompanyId(1L); | |||||
userFullInfoDTO.setUserId(1L); | |||||
userFullInfoDTO.setIdentifier("123456"); | |||||
userFullInfoDTO.setRealName("测试账号"); | |||||
userFullInfoDTO.setUsername("测试账号"); | |||||
return userFullInfoDTO; | |||||
} | |||||
} | } |
@@ -2,8 +2,10 @@ package com.ningdatech.pmapi.user.manage; | |||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.pmapi.user.mapper.UserInfoMapper; | import com.ningdatech.pmapi.user.mapper.UserInfoMapper; | ||||
import com.ningdatech.pmapi.user.model.po.ReqUserDetailEditPO; | |||||
import com.ningdatech.pmapi.user.model.po.ReqUserDisablePO; | import com.ningdatech.pmapi.user.model.po.ReqUserDisablePO; | ||||
import com.ningdatech.pmapi.user.model.po.ReqUserInfoListPO; | import com.ningdatech.pmapi.user.model.po.ReqUserInfoListPO; | ||||
import com.ningdatech.pmapi.user.model.vo.ResUserDetailVO; | |||||
import com.ningdatech.pmapi.user.model.vo.ResUserInfoListVO; | import com.ningdatech.pmapi.user.model.vo.ResUserInfoListVO; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
@@ -26,4 +28,12 @@ public class UserInfoManage { | |||||
public void disable(ReqUserDisablePO reqUserDisablePO) { | public void disable(ReqUserDisablePO reqUserDisablePO) { | ||||
} | } | ||||
public ResUserDetailVO userInfoDetail(ReqUserInfoListPO reqUserInfoListPO) { | |||||
return null; | |||||
} | |||||
public void userInfoDetailEdit(ReqUserDetailEditPO reqUserDetailEditPO) { | |||||
} | |||||
} | } |
@@ -0,0 +1,33 @@ | |||||
package com.ningdatech.pmapi.user.model.base; | |||||
import com.baomidou.mybatisplus.annotation.TableField; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.Size; | |||||
import static com.baomidou.mybatisplus.annotation.SqlCondition.LIKE; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2022/8/22 下午4:12 | |||||
*/ | |||||
@Data | |||||
@ApiModel("用户角色信息") | |||||
public class UserRoleInfo { | |||||
@ApiModelProperty(value = "名称") | |||||
private String name; | |||||
@ApiModelProperty(value = "枚举code") | |||||
private String code; | |||||
@ApiModelProperty(value = "描述") | |||||
@Size(max = 100, message = "描述长度不能超过100") | |||||
@TableField(value = "describe", condition = LIKE) | |||||
private String describe; | |||||
@ApiModelProperty(value = "排序") | |||||
private Integer roleSort; | |||||
} |
@@ -0,0 +1,29 @@ | |||||
package com.ningdatech.pmapi.user.model.po; | |||||
import com.ningdatech.pmapi.user.model.base.UserRoleInfo; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import java.util.List; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/15 上午8:43 | |||||
*/ | |||||
@Data | |||||
@ApiModel("获取用户详情编辑请求") | |||||
public class ReqUserDetailEditPO { | |||||
@ApiModelProperty("userId") | |||||
private Long userId; | |||||
@ApiModelProperty("手机号") | |||||
private String phoneNo; | |||||
@ApiModelProperty("状态 启用/禁用") | |||||
private Boolean status; | |||||
@ApiModelProperty("用户角色信息列表") | |||||
private List<UserRoleInfo> userRoleInfoList; | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.user.model.po; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/15 上午8:43 | |||||
*/ | |||||
@Data | |||||
@ApiModel("获取用户详情请求") | |||||
public class ReqUserDetailPO { | |||||
@NotNull(message = "用户id 不能为空") | |||||
@ApiModelProperty("用户id") | |||||
private Long userId; | |||||
} |
@@ -0,0 +1,29 @@ | |||||
package com.ningdatech.pmapi.user.model.vo; | |||||
import com.ningdatech.pmapi.user.model.base.UserRoleInfo; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import java.util.List; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/15 上午8:43 | |||||
*/ | |||||
@Data | |||||
@ApiModel("获取用户详情请求") | |||||
public class ResUserDetailVO { | |||||
@ApiModelProperty("userId") | |||||
private Long userId; | |||||
@ApiModelProperty("手机号") | |||||
private String phoneNo; | |||||
@ApiModelProperty("状态 启用/禁用") | |||||
private Boolean status; | |||||
@ApiModelProperty("用户角色信息列表") | |||||
private List<UserRoleInfo> userRoleInfoList; | |||||
} |
@@ -1,13 +1,11 @@ | |||||
package com.ningdatech.pmapi.user.security.auth; | package com.ningdatech.pmapi.user.security.auth; | ||||
import com.google.common.collect.Lists; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.basic.util.NdJsonUtil; | import com.ningdatech.basic.util.NdJsonUtil; | ||||
import com.ningdatech.basic.util.StrPool; | import com.ningdatech.basic.util.StrPool; | ||||
import com.ningdatech.pmapi.common.constant.BizConst; | import com.ningdatech.pmapi.common.constant.BizConst; | ||||
import com.ningdatech.pmapi.common.constant.CommonConstant; | import com.ningdatech.pmapi.common.constant.CommonConstant; | ||||
import com.ningdatech.pmapi.user.security.auth.handler.DefaultExpiredSessionStrategy; | import com.ningdatech.pmapi.user.security.auth.handler.DefaultExpiredSessionStrategy; | ||||
import com.ningdatech.pmapi.user.security.auth.password.UsernamePasswordAuthSecurityConfig; | |||||
import com.ningdatech.pmapi.user.security.auth.credential.CredentialAuthSecurityConfig; | |||||
import org.springframework.beans.factory.annotation.Qualifier; | import org.springframework.beans.factory.annotation.Qualifier; | ||||
import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||
import org.springframework.http.HttpStatus; | import org.springframework.http.HttpStatus; | ||||
@@ -18,7 +16,6 @@ import org.springframework.security.web.authentication.logout.LogoutSuccessHandl | |||||
import org.springframework.security.web.csrf.CookieCsrfTokenRepository; | import org.springframework.security.web.csrf.CookieCsrfTokenRepository; | ||||
import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
import java.util.ArrayList; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | import java.util.Set; | ||||
@@ -31,16 +28,16 @@ import java.util.Set; | |||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | ||||
private final AuthProperties authProperties; | private final AuthProperties authProperties; | ||||
private final UsernamePasswordAuthSecurityConfig usernamePasswordAuthSecurityConfig; | |||||
private final CredentialAuthSecurityConfig credentialAuthSecurityConfig; | |||||
private final LogoutSuccessHandler logoutSuccessHandler; | private final LogoutSuccessHandler logoutSuccessHandler; | ||||
private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy; | private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy; | ||||
public WebSecurityConfig(AuthProperties authProperties, | public WebSecurityConfig(AuthProperties authProperties, | ||||
UsernamePasswordAuthSecurityConfig usernamePasswordAuthSecurityConfig, | |||||
CredentialAuthSecurityConfig credentialAuthSecurityConfig, | |||||
@Qualifier(value = "defaultLogoutSuccessHandler") LogoutSuccessHandler logoutSuccessHandler, | @Qualifier(value = "defaultLogoutSuccessHandler") LogoutSuccessHandler logoutSuccessHandler, | ||||
DefaultExpiredSessionStrategy defaultExpiredSessionStrategy) { | DefaultExpiredSessionStrategy defaultExpiredSessionStrategy) { | ||||
this.authProperties = authProperties; | this.authProperties = authProperties; | ||||
this.usernamePasswordAuthSecurityConfig = usernamePasswordAuthSecurityConfig; | |||||
this.credentialAuthSecurityConfig = credentialAuthSecurityConfig; | |||||
this.logoutSuccessHandler = logoutSuccessHandler; | this.logoutSuccessHandler = logoutSuccessHandler; | ||||
this.defaultExpiredSessionStrategy = defaultExpiredSessionStrategy; | this.defaultExpiredSessionStrategy = defaultExpiredSessionStrategy; | ||||
} | } | ||||
@@ -50,7 +47,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | |||||
assemblerPreAuthUrls(http); | assemblerPreAuthUrls(http); | ||||
http.formLogin() | http.formLogin() | ||||
.loginPage(authProperties.getAuthRequireUrl()) | .loginPage(authProperties.getAuthRequireUrl()) | ||||
.and().apply(usernamePasswordAuthSecurityConfig) | |||||
.and().apply(credentialAuthSecurityConfig) | |||||
.and() | .and() | ||||
.authorizeRequests().antMatchers(authProperties.getIgnoreAuthUrlsArray()).permitAll().anyRequest() | .authorizeRequests().antMatchers(authProperties.getIgnoreAuthUrlsArray()).permitAll().anyRequest() | ||||
.authenticated().and() | .authenticated().and() | ||||
@@ -0,0 +1,11 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.constants; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/14 上午11:29 | |||||
*/ | |||||
public class UserDeatilsServiceConstant { | |||||
public static final String USER_DETAILS_SERVICE_SEPARATOR = "@###@"; | |||||
} |
@@ -1,4 +1,4 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.password; | |||||
package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.pmapi.user.manage.UserAuthLoginManage; | import com.ningdatech.pmapi.user.manage.UserAuthLoginManage; | ||||
@@ -16,17 +16,17 @@ import java.util.Objects; | |||||
* @date 2022/9/30 上午9:49 | * @date 2022/9/30 上午9:49 | ||||
*/ | */ | ||||
@Service("passwordLoginUserDetailService") | |||||
@Service("accountIdLoginUserDetailService") | |||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
public class PasswordLoginUserDetailService implements UserDetailsService { | |||||
public class AccountIdLoginUserDetailService implements UserDetailsService { | |||||
private final UserAuthLoginManage userAuthLoginManage; | private final UserAuthLoginManage userAuthLoginManage; | ||||
@Override | @Override | ||||
public UserInfoDetails loadUserByUsername(String username) throws UsernameNotFoundException { | |||||
UserFullInfoDTO userFullInfoDTO = userAuthLoginManage.queryUserInfoInPasswordAuth(username); | |||||
public UserInfoDetails loadUserByUsername(String accountId) throws UsernameNotFoundException { | |||||
UserFullInfoDTO userFullInfoDTO = userAuthLoginManage.queryUserInfoInAccountIdAuth(accountId); | |||||
if (Objects.isNull(userFullInfoDTO)) { | if (Objects.isNull(userFullInfoDTO)) { | ||||
throw new UsernameNotFoundException(String.format("%s user not exist", username)); | |||||
throw new UsernameNotFoundException(String.format("%s user not exist", accountId)); | |||||
} | } | ||||
UserInfoDetails userInfoDetails = new UserInfoDetails(); | UserInfoDetails userInfoDetails = new UserInfoDetails(); | ||||
userInfoDetails.setUserId(userFullInfoDTO.getUserId()); | userInfoDetails.setUserId(userFullInfoDTO.getUserId()); |
@@ -0,0 +1,108 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.http.HttpMethod; | |||||
import org.springframework.security.authentication.AuthenticationServiceException; | |||||
import org.springframework.security.authentication.BadCredentialsException; | |||||
import org.springframework.security.authentication.InternalAuthenticationServiceException; | |||||
import org.springframework.security.core.Authentication; | |||||
import org.springframework.security.core.AuthenticationException; | |||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; | |||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
/** | |||||
* @Author LiuXinXin | |||||
* @Date 2020/8/3 8:46 下午 | |||||
* @Version 1.0 | |||||
**/ | |||||
public class CredentialAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
private boolean postOnly = true; | |||||
private static final String IDENTIFIER_PARAMETER = "identifier"; | |||||
private static final String CREDENTIAL_PARAMETER = "credential"; | |||||
private static final String LOGIN_TYPE_PARAMETER = "loginType"; | |||||
// ~ Constructors | |||||
// =================================================================================================== | |||||
public CredentialAuthFilter(String processingUrl) { | |||||
super(new AntPathRequestMatcher(processingUrl, HttpMethod.POST.name())); | |||||
} | |||||
// ~ Methods | |||||
// ======================================================================================================== | |||||
@Override | |||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) | |||||
throws AuthenticationException { | |||||
if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) { | |||||
throw new AuthenticationServiceException("请求方法错误"); | |||||
} | |||||
String identifier = request.getParameter(IDENTIFIER_PARAMETER); | |||||
String credential = request.getParameter(CREDENTIAL_PARAMETER); | |||||
String loginType = request.getParameter(LOGIN_TYPE_PARAMETER); | |||||
if (StringUtils.isBlank(loginType)) { | |||||
throw new BadCredentialsException("登陆类型不能为空"); | |||||
} | |||||
paramValid(identifier, credential, loginType); | |||||
identifier = trim(identifier); | |||||
credential = trim(credential); | |||||
loginType = trim(loginType); | |||||
try { | |||||
CredentialAuthToken authRequest = new CredentialAuthToken(identifier, credential, loginType); | |||||
// Allow subclasses to set the "details" property | |||||
setDetails(request, authRequest); | |||||
return this.getAuthenticationManager().authenticate(authRequest); | |||||
} catch (AuthenticationException e) { | |||||
throw new BadCredentialsException("账号或密码错误"); | |||||
} catch (BizException e) { | |||||
throw new BadCredentialsException(e.getMessage()); | |||||
} catch (Exception e) { | |||||
throw new InternalAuthenticationServiceException("授权失败:", e); | |||||
} | |||||
} | |||||
protected void setDetails(HttpServletRequest request, CredentialAuthToken authRequest) { | |||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | |||||
} | |||||
private void paramValid(String identifier, String credential, String loginType) { | |||||
LoginTypeEnum loginTypeEnum = LoginTypeEnum.valueOf(loginType); | |||||
switch (loginTypeEnum) { | |||||
case DING_QR_LOGIN: { | |||||
if (StringUtils.isBlank(credential)) { | |||||
throw new BadCredentialsException("浙政钉扫码登陆 授权码 不能为空 credential"); | |||||
} | |||||
} | |||||
break; | |||||
case USERNAME_PASSWORD_LOGIN: { | |||||
if (StringUtils.isBlank(identifier) || StringUtils.isBlank(credential)) { | |||||
throw new BadCredentialsException("账号密码登陆 账号密码不能为空 identifier credential"); | |||||
} | |||||
} | |||||
break; | |||||
case PHONE_VERIFICATION_CODE_LOGIN: { | |||||
if (StringUtils.isBlank(identifier) || StringUtils.isBlank(credential)) { | |||||
throw new BadCredentialsException("手机号验证码登陆 手机号或验证码不能为空 identifier credential"); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
private String trim(String trimStr) { | |||||
if (StringUtils.isNotBlank(trimStr)) { | |||||
return trimStr.trim(); | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,103 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.basic.model.GenericResult; | |||||
import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | |||||
import com.ningdatech.pmapi.user.security.auth.constants.UserDeatilsServiceConstant; | |||||
import com.ningdatech.zwdd.client.ZwddAuthClient; | |||||
import org.springframework.security.authentication.AuthenticationProvider; | |||||
import org.springframework.security.authentication.BadCredentialsException; | |||||
import org.springframework.security.authentication.InternalAuthenticationServiceException; | |||||
import org.springframework.security.core.Authentication; | |||||
import org.springframework.security.core.AuthenticationException; | |||||
import org.springframework.security.core.userdetails.UserDetails; | |||||
import org.springframework.security.core.userdetails.UserDetailsService; | |||||
import org.springframework.security.crypto.password.PasswordEncoder; | |||||
import java.util.Objects; | |||||
/** | |||||
* @Author LiuXinXin | |||||
* @Date 2020/8/3 8:55 下午 | |||||
* @Version 1.0 | |||||
**/ | |||||
public class CredentialAuthProvider implements AuthenticationProvider { | |||||
private UserDetailsService userDetailsService; | |||||
private PasswordEncoder passwordEncoder; | |||||
private ZwddAuthClient zwddAuthClient; | |||||
@Override | |||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException { | |||||
if (!(authentication instanceof CredentialAuthToken)) { | |||||
throw new RuntimeException("CustomAuthProvider 只支持 CustomAuthToken"); | |||||
} | |||||
CredentialAuthToken authenticationToken = (CredentialAuthToken) authentication; | |||||
String principal = (String) authenticationToken.getPrincipal(); | |||||
UserDetails user = null; | |||||
LoginTypeEnum loginTypeEnum = authenticationToken.getLoginTypeEnum(); | |||||
switch (loginTypeEnum) { | |||||
case DING_QR_LOGIN: { | |||||
String code = (String) authenticationToken.getCredentials(); | |||||
GenericResult<String> accountResult = zwddAuthClient.getAccountId(code); | |||||
if (!accountResult.isSuccess()) { | |||||
throw new BadCredentialsException("login fail! 浙政钉校验失败"); | |||||
} | |||||
String accountId = accountResult.getData(); | |||||
if (Objects.isNull(accountId)) { | |||||
throw new BadCredentialsException("login fail! 浙政钉校验失败"); | |||||
} | |||||
user = userDetailsService.loadUserByUsername(accountId + UserDeatilsServiceConstant.USER_DETAILS_SERVICE_SEPARATOR + loginTypeEnum.name()); | |||||
} | |||||
break; | |||||
case PHONE_VERIFICATION_CODE_LOGIN: { | |||||
// TODO 校验短信验证码 | |||||
user = userDetailsService.loadUserByUsername(principal + UserDeatilsServiceConstant.USER_DETAILS_SERVICE_SEPARATOR + loginTypeEnum.name()); | |||||
} | |||||
break; | |||||
case USERNAME_PASSWORD_LOGIN: { | |||||
user = userDetailsService.loadUserByUsername((String) authenticationToken.getPrincipal()); | |||||
if (user == null) { | |||||
throw new InternalAuthenticationServiceException("can not get user info!"); | |||||
} | |||||
// 账号密码登陆 更改 | |||||
additionalAuthenticationChecks(user, authenticationToken); | |||||
} | |||||
break; | |||||
} | |||||
// 将用户定义的user放入token中,这样可以在session中查询到所有自定义的用户信息 | |||||
return new CredentialAuthToken(user, user.getPassword(), user.getAuthorities()); | |||||
} | |||||
protected void additionalAuthenticationChecks(UserDetails userDetails, CredentialAuthToken authentication) | |||||
throws AuthenticationException { | |||||
if (authentication.getCredentials() == null) { | |||||
throw new BadCredentialsException("login fail! password is null"); | |||||
} | |||||
String presentedPassword = authentication.getCredentials().toString(); | |||||
if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { | |||||
throw new BadCredentialsException("login fail! password is error"); | |||||
} | |||||
} | |||||
@Override | |||||
public boolean supports(Class<?> authentication) { | |||||
return CredentialAuthToken.class.isAssignableFrom(authentication); | |||||
} | |||||
public void setUserDetailsService(UserDetailsService userDetailsService) { | |||||
this.userDetailsService = userDetailsService; | |||||
} | |||||
public void setPasswordEncoder(PasswordEncoder passwordEncoder) { | |||||
this.passwordEncoder = passwordEncoder; | |||||
} | |||||
public void setZwddAuthClient(ZwddAuthClient zwddAuthClient) { | |||||
this.zwddAuthClient = zwddAuthClient; | |||||
} | |||||
} |
@@ -1,6 +1,7 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.password; | |||||
package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.pmapi.user.security.auth.AuthProperties; | import com.ningdatech.pmapi.user.security.auth.AuthProperties; | ||||
import com.ningdatech.zwdd.client.ZwddAuthClient; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.beans.factory.annotation.Qualifier; | import org.springframework.beans.factory.annotation.Qualifier; | ||||
import org.springframework.security.authentication.AuthenticationManager; | import org.springframework.security.authentication.AuthenticationManager; | ||||
@@ -18,7 +19,7 @@ import org.springframework.stereotype.Component; | |||||
* 账号密码登陆的认证配置 | * 账号密码登陆的认证配置 | ||||
*/ | */ | ||||
@Component | @Component | ||||
public class UsernamePasswordAuthSecurityConfig | |||||
public class CredentialAuthSecurityConfig | |||||
extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> { | extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> { | ||||
@Autowired | @Autowired | ||||
@@ -30,8 +31,8 @@ public class UsernamePasswordAuthSecurityConfig | |||||
protected AuthenticationFailureHandler defaultLoginFailureHandler; | protected AuthenticationFailureHandler defaultLoginFailureHandler; | ||||
@Autowired | @Autowired | ||||
@Qualifier(value = "passwordLoginUserDetailService") | |||||
private UserDetailsService passwordLoginUserDetailService; | |||||
@Qualifier(value = "credentialLoginUserDetailService") | |||||
private UserDetailsService credentialLoginUserDetailService; | |||||
@Autowired | @Autowired | ||||
private PasswordEncoder passwordEncoder; | private PasswordEncoder passwordEncoder; | ||||
@@ -41,20 +42,26 @@ public class UsernamePasswordAuthSecurityConfig | |||||
private AuthenticationManager authenticationManager; | private AuthenticationManager authenticationManager; | ||||
@Autowired | |||||
private ZwddAuthClient zwddAuthClient; | |||||
@Override | @Override | ||||
public void configure(HttpSecurity http) throws Exception { | public void configure(HttpSecurity http) throws Exception { | ||||
UsernamePasswordAuthFilter usernamePasswordAuthFilter = | |||||
new UsernamePasswordAuthFilter(authProperties.getPasswordLoginUrl()); | |||||
CredentialAuthFilter credentialAuthFilter = | |||||
new CredentialAuthFilter(authProperties.getPasswordLoginUrl()); | |||||
authenticationManager = http.getSharedObject(AuthenticationManager.class); | authenticationManager = http.getSharedObject(AuthenticationManager.class); | ||||
usernamePasswordAuthFilter.setAuthenticationManager(authenticationManager); | |||||
usernamePasswordAuthFilter.setAuthenticationSuccessHandler(defaultLoginSuccessHandler); | |||||
usernamePasswordAuthFilter.setAuthenticationFailureHandler(defaultLoginFailureHandler); | |||||
credentialAuthFilter.setAuthenticationManager(authenticationManager); | |||||
credentialAuthFilter.setAuthenticationSuccessHandler(defaultLoginSuccessHandler); | |||||
credentialAuthFilter.setAuthenticationFailureHandler(defaultLoginFailureHandler); | |||||
UsernamePasswordAuthProvider authenticationProvider = new UsernamePasswordAuthProvider(); | |||||
authenticationProvider.setUserDetailsService(passwordLoginUserDetailService); | |||||
CredentialAuthProvider authenticationProvider = new CredentialAuthProvider(); | |||||
authenticationProvider.setUserDetailsService(credentialLoginUserDetailService); | |||||
// 确保对密码进行加密的encoder和解密的encoder相同 | // 确保对密码进行加密的encoder和解密的encoder相同 | ||||
authenticationProvider.setPasswordEncoder(passwordEncoder); | authenticationProvider.setPasswordEncoder(passwordEncoder); | ||||
http.authenticationProvider(authenticationProvider).addFilterAfter(usernamePasswordAuthFilter, | |||||
// 传入浙政钉client | |||||
authenticationProvider.setZwddAuthClient(zwddAuthClient); | |||||
http.authenticationProvider(authenticationProvider).addFilterAfter(credentialAuthFilter, | |||||
UsernamePasswordAuthenticationFilter.class); | UsernamePasswordAuthenticationFilter.class); | ||||
} | } | ||||
@@ -1,5 +1,6 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.password; | |||||
package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | |||||
import org.springframework.security.authentication.AbstractAuthenticationToken; | import org.springframework.security.authentication.AbstractAuthenticationToken; | ||||
import org.springframework.security.core.GrantedAuthority; | import org.springframework.security.core.GrantedAuthority; | ||||
import org.springframework.security.core.SpringSecurityCoreVersion; | import org.springframework.security.core.SpringSecurityCoreVersion; | ||||
@@ -11,7 +12,7 @@ import java.util.Collection; | |||||
* @Date 2020/8/3 8:52 下午 | * @Date 2020/8/3 8:52 下午 | ||||
* @Version 1.0 | * @Version 1.0 | ||||
**/ | **/ | ||||
public class UsernamePasswordAuthToken extends AbstractAuthenticationToken { | |||||
public class CredentialAuthToken extends AbstractAuthenticationToken { | |||||
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; | private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; | ||||
@@ -19,16 +20,18 @@ public class UsernamePasswordAuthToken extends AbstractAuthenticationToken { | |||||
private final Object credentials; | private final Object credentials; | ||||
private final LoginTypeEnum loginTypeEnum; | |||||
/** | /** | ||||
* This constructor can be safely used by any code that wishes to create a | * This constructor can be safely used by any code that wishes to create a | ||||
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()} will return | * <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()} will return | ||||
* <code>false</code>. | * <code>false</code>. | ||||
*/ | */ | ||||
public UsernamePasswordAuthToken(String principal, String credentials) { | |||||
public CredentialAuthToken(String principal, String credentials, String loginTypeEnum) { | |||||
super(null); | super(null); | ||||
this.principal = principal; | this.principal = principal; | ||||
this.credentials = credentials; | this.credentials = credentials; | ||||
this.loginTypeEnum = LoginTypeEnum.valueOf(loginTypeEnum); | |||||
setAuthenticated(false); | setAuthenticated(false); | ||||
} | } | ||||
@@ -40,15 +43,20 @@ public class UsernamePasswordAuthToken extends AbstractAuthenticationToken { | |||||
* @param principal | * @param principal | ||||
* @param authorities | * @param authorities | ||||
*/ | */ | ||||
public UsernamePasswordAuthToken(Object principal, Object credentials, | |||||
Collection<? extends GrantedAuthority> authorities) { | |||||
public CredentialAuthToken(Object principal, Object credentials, | |||||
Collection<? extends GrantedAuthority> authorities) { | |||||
super(authorities); | super(authorities); | ||||
this.principal = principal; | this.principal = principal; | ||||
this.credentials = credentials; | this.credentials = credentials; | ||||
this.loginTypeEnum = null; | |||||
// must use super, as we override | // must use super, as we override | ||||
super.setAuthenticated(true); | super.setAuthenticated(true); | ||||
} | } | ||||
public LoginTypeEnum getLoginTypeEnum() { | |||||
return this.loginTypeEnum; | |||||
} | |||||
@Override | @Override | ||||
public Object getCredentials() { | public Object getCredentials() { | ||||
return this.credentials; | return this.credentials; |
@@ -0,0 +1,67 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | |||||
import com.ningdatech.pmapi.user.manage.UserAuthLoginManage; | |||||
import com.ningdatech.pmapi.user.security.auth.constants.UserDeatilsServiceConstant; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.springframework.security.core.userdetails.UserDetailsService; | |||||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.Objects; | |||||
/** | |||||
* @author LiuXinXin | |||||
* @date 2022/9/30 上午9:49 | |||||
*/ | |||||
@Service("credentialLoginUserDetailService") | |||||
@RequiredArgsConstructor | |||||
public class CredentialLoginUserDetailService implements UserDetailsService { | |||||
private final UserAuthLoginManage userAuthLoginManage; | |||||
@Override | |||||
public UserInfoDetails loadUserByUsername(String username) throws UsernameNotFoundException { | |||||
String[] split = username.split(UserDeatilsServiceConstant.USER_DETAILS_SERVICE_SEPARATOR); | |||||
username = split[0]; | |||||
String loginTypeStr = split[1]; | |||||
LoginTypeEnum loginTypeEnum = LoginTypeEnum.valueOf(loginTypeStr); | |||||
UserFullInfoDTO userFullInfoDTO = null; | |||||
switch (loginTypeEnum) { | |||||
case PHONE_VERIFICATION_CODE_LOGIN: { | |||||
userFullInfoDTO = userAuthLoginManage.queryUserInfoInPhoneNoAuth(username); | |||||
} | |||||
break; | |||||
case USERNAME_PASSWORD_LOGIN: { | |||||
userFullInfoDTO = userAuthLoginManage.queryUserInfoInPasswordAuth(username); | |||||
} | |||||
break; | |||||
case DING_QR_LOGIN: { | |||||
userFullInfoDTO = userAuthLoginManage.queryUserInfoInAccountIdAuth(username); | |||||
} | |||||
break; | |||||
default: { | |||||
throw new UsernameNotFoundException(String.format("%s user not exist", username)); | |||||
} | |||||
} | |||||
if (Objects.isNull(userFullInfoDTO)) { | |||||
throw new UsernameNotFoundException(String.format("%s user not exist", username)); | |||||
} | |||||
UserInfoDetails userInfoDetails = new UserInfoDetails(); | |||||
userInfoDetails.setUserId(userFullInfoDTO.getUserId()); | |||||
userInfoDetails.setUsername(userFullInfoDTO.getUsername()); | |||||
userInfoDetails.setRealName(userFullInfoDTO.getRealName()); | |||||
userInfoDetails.setRole(userFullInfoDTO.getRole()); | |||||
userInfoDetails.setRegionCode(userFullInfoDTO.getRegionCode()); | |||||
userInfoDetails.setCompanyId(userFullInfoDTO.getCompanyId()); | |||||
userInfoDetails.setIdentifier(userFullInfoDTO.getIdentifier()); | |||||
userInfoDetails.setPassword(userFullInfoDTO.getCredential()); | |||||
return userInfoDetails; | |||||
} | |||||
} |
@@ -1,71 +0,0 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.password; | |||||
import com.ningdatech.basic.exception.BizException; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.http.HttpMethod; | |||||
import org.springframework.security.authentication.AuthenticationServiceException; | |||||
import org.springframework.security.authentication.BadCredentialsException; | |||||
import org.springframework.security.authentication.InternalAuthenticationServiceException; | |||||
import org.springframework.security.core.Authentication; | |||||
import org.springframework.security.core.AuthenticationException; | |||||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | |||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; | |||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
/** | |||||
* @Author LiuXinXin | |||||
* @Date 2020/8/3 8:46 下午 | |||||
* @Version 1.0 | |||||
**/ | |||||
public class UsernamePasswordAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
private boolean postOnly = true; | |||||
private static final String USERNAME_PARAMETER = "username"; | |||||
private static final String PASSWORD_PARAMETER = "password"; | |||||
// ~ Constructors | |||||
// =================================================================================================== | |||||
public UsernamePasswordAuthFilter(String processingUrl) { | |||||
super(new AntPathRequestMatcher(processingUrl, HttpMethod.POST.name())); | |||||
} | |||||
// ~ Methods | |||||
// ======================================================================================================== | |||||
@Override | |||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) | |||||
throws AuthenticationException { | |||||
if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) { | |||||
throw new AuthenticationServiceException("请求方法错误"); | |||||
} | |||||
String username = request.getParameter(USERNAME_PARAMETER); | |||||
String password = request.getParameter(PASSWORD_PARAMETER); | |||||
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { | |||||
throw new UsernameNotFoundException("用户名或密码不能为空"); | |||||
} | |||||
username = username.trim(); | |||||
password = password.trim(); | |||||
try { | |||||
UsernamePasswordAuthToken authRequest = new UsernamePasswordAuthToken(username, password); | |||||
// Allow subclasses to set the "details" property | |||||
setDetails(request, authRequest); | |||||
return this.getAuthenticationManager().authenticate(authRequest); | |||||
} catch (AuthenticationException e) { | |||||
throw new BadCredentialsException("账号或密码错误"); | |||||
} catch (BizException e) { | |||||
throw new BadCredentialsException(e.getMessage()); | |||||
} catch (Exception e) { | |||||
throw new InternalAuthenticationServiceException("授权失败:", e); | |||||
} | |||||
} | |||||
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthToken authRequest) { | |||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | |||||
} | |||||
} |
@@ -1,65 +0,0 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.password; | |||||
import org.springframework.security.authentication.AuthenticationProvider; | |||||
import org.springframework.security.authentication.BadCredentialsException; | |||||
import org.springframework.security.authentication.InternalAuthenticationServiceException; | |||||
import org.springframework.security.core.Authentication; | |||||
import org.springframework.security.core.AuthenticationException; | |||||
import org.springframework.security.core.userdetails.UserDetails; | |||||
import org.springframework.security.core.userdetails.UserDetailsService; | |||||
import org.springframework.security.crypto.password.PasswordEncoder; | |||||
/** | |||||
* @Author LiuXinXin | |||||
* @Date 2020/8/3 8:55 下午 | |||||
* @Version 1.0 | |||||
**/ | |||||
public class UsernamePasswordAuthProvider implements AuthenticationProvider { | |||||
private UserDetailsService userDetailsService; | |||||
private PasswordEncoder passwordEncoder; | |||||
@Override | |||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException { | |||||
if (!(authentication instanceof UsernamePasswordAuthToken)) { | |||||
throw new RuntimeException("CustomAuthProvider 只支持 CustomAuthToken"); | |||||
} | |||||
UsernamePasswordAuthToken authenticationToken = (UsernamePasswordAuthToken) authentication; | |||||
UserDetails user = userDetailsService.loadUserByUsername((String) authenticationToken.getPrincipal()); | |||||
if (user == null) { | |||||
throw new InternalAuthenticationServiceException("can not get user info!"); | |||||
} | |||||
// TODO 开发使用暂时关闭账号密码验证 | |||||
// additionalAuthenticationChecks(user, authenticationToken); | |||||
// 校验用户是否有当前端的登陆权限 | |||||
// 将用户定义的user放入token中,这样可以在session中查询到所有自定义的用户信息 | |||||
return new UsernamePasswordAuthToken(user, user.getPassword(), user.getAuthorities()); | |||||
} | |||||
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthToken authentication) | |||||
throws AuthenticationException { | |||||
if (authentication.getCredentials() == null) { | |||||
throw new BadCredentialsException("login fail! password is null"); | |||||
} | |||||
String presentedPassword = authentication.getCredentials().toString(); | |||||
if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { | |||||
throw new BadCredentialsException("login fail! password is error"); | |||||
} | |||||
} | |||||
@Override | |||||
public boolean supports(Class<?> authentication) { | |||||
return UsernamePasswordAuthToken.class.isAssignableFrom(authentication); | |||||
} | |||||
public void setUserDetailsService(UserDetailsService userDetailsService) { | |||||
this.userDetailsService = userDetailsService; | |||||
} | |||||
public void setPasswordEncoder(PasswordEncoder passwordEncoder) { | |||||
this.passwordEncoder = passwordEncoder; | |||||
} | |||||
} |
@@ -3,6 +3,9 @@ package com.ningdatech.pmapi.user.util; | |||||
import com.ningdatech.basic.auth.AbstractLoginUserUtil; | import com.ningdatech.basic.auth.AbstractLoginUserUtil; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | ||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
/** | /** | ||||
* @Author liuxinxin | * @Author liuxinxin | ||||
@@ -15,4 +18,10 @@ public class LoginUserUtil extends AbstractLoginUserUtil { | |||||
return getLoginUserPrincipal(); | return getLoginUserPrincipal(); | ||||
} | } | ||||
public static List<Long> getRoleIdList() { | |||||
List<Long> roleIdList = new ArrayList<>(); | |||||
roleIdList.add(1L); | |||||
return roleIdList; | |||||
} | |||||
} | } |
@@ -153,16 +153,4 @@ sa-token: | |||||
# token风格 | # token风格 | ||||
token-style: uuid | token-style: uuid | ||||
# 是否输出操作日志 | # 是否输出操作日志 | ||||
is-log: false | |||||
#专有钉钉 | |||||
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 | |||||
is-log: false |
@@ -1,20 +1,12 @@ | |||||
#专有钉钉 | #专有钉钉 | ||||
integration: | integration: | ||||
zzd: | |||||
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-key: ls_rebuild-10c8n5X0707yFV7jURr | ||||
app-secret: gN8J3WazyXLMWKDuFmx6C4yaH5lFUY41x8rYLLo6 | app-secret: gN8J3WazyXLMWKDuFmx6C4yaH5lFUY41x8rYLLo6 | ||||
#专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | ||||
tenantId: 31141 | tenantId: 31141 | ||||
domain: openplatform.dg-work.cn | |||||
# integration.zzd.enabled=true | |||||
# #扫码 | |||||
# integration.zzd.app-auth-key=file-manage_dingoa-zte2LbiAfIj | |||||
# integration.zzd.app-auth-secret=H794aFZf271QbfUr50pbBpBTlXSrWIP71q9RTR34 | |||||
# integration.zzd.domain=openplatform.dg-work.cn | |||||
domain: openplatform.dg-work.cn |
@@ -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,7 @@ security: | |||||
auth: | auth: | ||||
auth-require-url: /api/v1/user/auth/auth-require | auth-require-url: /api/v1/user/auth/auth-require | ||||
invalid-session-url: /api/v1/user/auth/invalid-session | 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 | logout-url: /api/v1/user/auth/logout | ||||
ignore-auth-urls: | ignore-auth-urls: | ||||
- /v2/api-docs | - /v2/api-docs | ||||
@@ -2,7 +2,7 @@ security: | |||||
auth: | auth: | ||||
auth-require-url: /api/v1/user/auth/auth-require | auth-require-url: /api/v1/user/auth/auth-require | ||||
invalid-session-url: /api/v1/user/auth/invalid-session | 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 | logout-url: /api/v1/user/auth/logout | ||||
ignore-auth-urls: | ignore-auth-urls: | ||||
- /v2/api-docs | - /v2/api-docs | ||||
@@ -1,6 +1,7 @@ | |||||
package com.ningdatech.pmapi.organization; | package com.ningdatech.pmapi.organization; | ||||
import com.ningdatech.pmapi.AppTests; | import com.ningdatech.pmapi.AppTests; | ||||
//import com.ningdatech.pmapi.ding.task.EmployeeBatchGetTask; | |||||
import com.ningdatech.pmapi.ding.task.OrganizationBatchGetTask; | import com.ningdatech.pmapi.ding.task.OrganizationBatchGetTask; | ||||
import com.ningdatech.zwdd.client.ZwddAuthClient; | import com.ningdatech.zwdd.client.ZwddAuthClient; | ||||
import com.ningdatech.zwdd.client.ZwddClient; | import com.ningdatech.zwdd.client.ZwddClient; | ||||
@@ -23,9 +24,17 @@ class OrganizationTest extends AppTests { | |||||
@Autowired | @Autowired | ||||
private OrganizationBatchGetTask organizationBatchGetTask; | private OrganizationBatchGetTask organizationBatchGetTask; | ||||
// @Autowired | |||||
// private EmployeeBatchGetTask employeeBatchGetTask; | |||||
@Test | @Test | ||||
public void testBatchGetOrganization() { | public void testBatchGetOrganization() { | ||||
organizationBatchGetTask.batchGetOrganizationTask(); | organizationBatchGetTask.batchGetOrganizationTask(); | ||||
} | } | ||||
// @Test | |||||
// public void testEmployeeBatchGetTask(){ | |||||
// employeeBatchGetTask.batchGetEmployeeTask(); | |||||
// } | |||||
} | } |