@@ -1,6 +1,7 @@ | |||||
package com.ningdatech.pmapi.todocenter.manage; | package com.ningdatech.pmapi.todocenter.manage; | ||||
import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||
import com.alibaba.fastjson.JSON; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.file.service.FileService; | import com.ningdatech.file.service.FileService; | ||||
@@ -15,8 +16,10 @@ import com.ningdatech.pmapi.projectdeclared.manage.DefaultDeclaredProjectManage; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectDraftSaveDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectDraftSaveDTO; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectApplicationDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
@@ -47,8 +50,11 @@ 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.HashMap; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
import java.util.Objects; | import java.util.Objects; | ||||
import java.util.stream.Collectors; | |||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant.*; | import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant.*; | ||||
@@ -198,6 +204,17 @@ public class HandlerManage { | |||||
ProjectDraftSaveDTO draftSaveDto = new ProjectDraftSaveDTO(); | ProjectDraftSaveDTO draftSaveDto = new ProjectDraftSaveDTO(); | ||||
ProjectDTO projectInfo = new ProjectDTO(); | ProjectDTO projectInfo = new ProjectDTO(); | ||||
BeanUtils.copyProperties(declaredProject,projectInfo); | BeanUtils.copyProperties(declaredProject,projectInfo); | ||||
// 查询出项目关联的应用信息 | |||||
List<ProjectApplication> applicationList = projectApplicationService.list(Wrappers.lambdaQuery(ProjectApplication.class) | |||||
.eq(ProjectApplication::getProjectId, declaredProject.getId())); | |||||
List<ProjectApplicationDTO> applicationDTOList = applicationList.stream().map(a -> { | |||||
ProjectApplicationDTO applicationDTO = new ProjectApplicationDTO(); | |||||
BeanUtils.copyProperties(a, applicationDTO); | |||||
return applicationDTO; | |||||
}).collect(Collectors.toList()); | |||||
projectInfo.setApplicationList(applicationDTOList); | |||||
HashMap<String,Object> dynamicMap = JSON.parseObject(declaredProject.getDynamicForm(), HashMap.class); | |||||
projectInfo.setDynamicForm(dynamicMap); | |||||
draftSaveDto.setProjectInfo(projectInfo); | draftSaveDto.setProjectInfo(projectInfo); | ||||
declaredProjectManage.saveToDraft(draftSaveDto); | declaredProjectManage.saveToDraft(draftSaveDto); | ||||
// 并删除项目库中该项目信息 | // 并删除项目库中该项目信息 | ||||
@@ -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 Liuxinxin | |||||
* @since 2023-01-05 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.user/user-role") | |||||
public class UserRoleController { | |||||
} |
@@ -74,6 +74,7 @@ public class UserInfoManage { | |||||
LambdaQueryWrapper<DingEmployeeInfo> wrapper = Wrappers.lambdaQuery(DingEmployeeInfo.class) | LambdaQueryWrapper<DingEmployeeInfo> wrapper = Wrappers.lambdaQuery(DingEmployeeInfo.class) | ||||
.eq(DingEmployeeInfo::getMainJob, "true") | .eq(DingEmployeeInfo::getMainJob, "true") | ||||
.eq(DingEmployeeInfo::getStatus, "A") | |||||
.eq(StringUtils.isNotBlank(orgCode), DingEmployeeInfo::getOrganizationCode, orgCode) | .eq(StringUtils.isNotBlank(orgCode), DingEmployeeInfo::getOrganizationCode, orgCode) | ||||
.like(StringUtils.isNotBlank(phoneNo), DingEmployeeInfo::getBindUserMobile, phoneNo) | .like(StringUtils.isNotBlank(phoneNo), DingEmployeeInfo::getBindUserMobile, phoneNo) | ||||
.like(StringUtils.isNotBlank(name), DingEmployeeInfo::getEmployeeName, name) | .like(StringUtils.isNotBlank(name), DingEmployeeInfo::getEmployeeName, name) | ||||
@@ -91,7 +92,7 @@ public class UserInfoManage { | |||||
Map<String, UserInfo> employeeCodeAvailableMap = new HashMap<>(16); | Map<String, UserInfo> employeeCodeAvailableMap = new HashMap<>(16); | ||||
if (CollUtil.isNotEmpty(employeeCodeList)) { | if (CollUtil.isNotEmpty(employeeCodeList)) { | ||||
employeeCodeAvailableMap = iUserInfoService.list(Wrappers.lambdaQuery(UserInfo.class) | employeeCodeAvailableMap = iUserInfoService.list(Wrappers.lambdaQuery(UserInfo.class) | ||||
.in(UserInfo::getEmployeeCode, employeeCodeList)) | |||||
.in(UserInfo::getEmployeeCode, employeeCodeList)) | |||||
.stream().collect(Collectors.toMap(UserInfo::getEmployeeCode, Function.identity())); | .stream().collect(Collectors.toMap(UserInfo::getEmployeeCode, Function.identity())); | ||||
} | } | ||||
List<String> orgCodeList = records.stream() | List<String> orgCodeList = records.stream() | ||||
@@ -168,7 +169,7 @@ public class UserInfoManage { | |||||
// TODO 这里过滤的非浙政钉用户的专家 后续需要增加补充逻辑 | // TODO 这里过滤的非浙政钉用户的专家 后续需要增加补充逻辑 | ||||
return iUserInfoService.list(Wrappers.lambdaQuery(UserInfo.class) | return iUserInfoService.list(Wrappers.lambdaQuery(UserInfo.class) | ||||
.in(UserInfo::getId, compliantUserIdList)) | |||||
.in(UserInfo::getId, compliantUserIdList)) | |||||
.stream().map(UserInfo::getEmployeeCode) | .stream().map(UserInfo::getEmployeeCode) | ||||
.filter(StringUtils::isNotBlank).collect(Collectors.toList()); | .filter(StringUtils::isNotBlank).collect(Collectors.toList()); | ||||
@@ -256,23 +257,11 @@ public class UserInfoManage { | |||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public void userInfoDetailEdit(ReqUserDetailEditPO reqUserDetailEditPO) { | public void userInfoDetailEdit(ReqUserDetailEditPO reqUserDetailEditPO) { | ||||
String employeeCode = reqUserDetailEditPO.getEmployeeCode(); | |||||
Long userId = generateUserId(reqUserDetailEditPO.getEmployeeCode()); | Long userId = generateUserId(reqUserDetailEditPO.getEmployeeCode()); | ||||
UserInfo userInfo = iUserInfoService.getById(userId); | UserInfo userInfo = iUserInfoService.getById(userId); | ||||
// 绑定用户手机号 | |||||
bandUserMobile(userInfo, reqUserDetailEditPO); | |||||
String mobile = userInfo.getMobile(); | |||||
if (StringUtils.isBlank(mobile)) { | |||||
String phoneNo = reqUserDetailEditPO.getPhoneNo(); | |||||
userInfo.setMobile(phoneNo); | |||||
// 更新浙政钉相关数据 | |||||
if (StringUtils.isNotBlank(phoneNo)) { | |||||
iDingEmployeeInfoService | |||||
.update(Wrappers.lambdaUpdate(DingEmployeeInfo.class) | |||||
.eq(DingEmployeeInfo::getMainJob, "true") | |||||
.eq(DingEmployeeInfo::getEmployeeCode, employeeCode) | |||||
.set(DingEmployeeInfo::getBindUserMobile, phoneNo)); | |||||
} | |||||
} | |||||
userInfo.setAvailable(reqUserDetailEditPO.getStatus()); | userInfo.setAvailable(reqUserDetailEditPO.getStatus()); | ||||
userInfo.setUpdateOn(LocalDateTime.now()); | userInfo.setUpdateOn(LocalDateTime.now()); | ||||
userInfo.setUpdateBy(LoginUserUtil.getUserId()); | userInfo.setUpdateBy(LoginUserUtil.getUserId()); | ||||
@@ -291,6 +280,39 @@ public class UserInfoManage { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* 绑定用户手机号 | |||||
* | |||||
* @param userInfo | |||||
* @param reqUserDetailEditPO | |||||
*/ | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void bandUserMobile(UserInfo userInfo, ReqUserDetailEditPO reqUserDetailEditPO) { | |||||
String employeeCode = reqUserDetailEditPO.getEmployeeCode(); | |||||
String mobile = userInfo.getMobile(); | |||||
Long userId = userInfo.getId(); | |||||
if (StringUtils.isBlank(mobile)) { | |||||
// 校验手机号是否重复 | |||||
UserInfo repeatMobileUserInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class) | |||||
.eq(UserInfo::getMobile, mobile).ne(UserInfo::getId, userId)); | |||||
if (Objects.nonNull(repeatMobileUserInfo)) { | |||||
throw new BizException("该手机号码已被绑定,请问重复绑定"); | |||||
} | |||||
String phoneNo = reqUserDetailEditPO.getPhoneNo(); | |||||
userInfo.setMobile(phoneNo); | |||||
// 更新浙政钉相关数据 | |||||
if (StringUtils.isNotBlank(phoneNo)) { | |||||
iDingEmployeeInfoService | |||||
.update(Wrappers.lambdaUpdate(DingEmployeeInfo.class) | |||||
.eq(DingEmployeeInfo::getMainJob, "true") | |||||
.eq(DingEmployeeInfo::getEmployeeCode, employeeCode) | |||||
.set(DingEmployeeInfo::getBindUserMobile, phoneNo)); | |||||
} | |||||
} | |||||
} | |||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public Long generateUserId(String employeeCode) { | public Long generateUserId(String employeeCode) { | ||||
UserInfo userInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class) | UserInfo userInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class) | ||||
@@ -53,7 +53,7 @@ public class AgentAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
setDetails(request, authRequest); | setDetails(request, authRequest); | ||||
return this.getAuthenticationManager().authenticate(authRequest); | return this.getAuthenticationManager().authenticate(authRequest); | ||||
} catch (AuthenticationException e) { | } catch (AuthenticationException e) { | ||||
throw new BadCredentialsException("账号或密码错误"); | |||||
throw new BadCredentialsException("用户id 不能为空"); | |||||
} catch (BizException e) { | } catch (BizException e) { | ||||
throw new BadCredentialsException(e.getMessage()); | throw new BadCredentialsException(e.getMessage()); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
@@ -2,6 +2,7 @@ package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | ||||
import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.springframework.http.HttpMethod; | import org.springframework.http.HttpMethod; | ||||
import org.springframework.security.authentication.AuthenticationServiceException; | import org.springframework.security.authentication.AuthenticationServiceException; | ||||
@@ -53,7 +54,6 @@ public class CredentialAuthFilter extends AbstractAuthenticationProcessingFilter | |||||
} | } | ||||
paramValid(identifier, credential, loginType); | paramValid(identifier, credential, loginType); | ||||
identifier = trim(identifier); | identifier = trim(identifier); | ||||
credential = trim(credential); | credential = trim(credential); | ||||
loginType = trim(loginType); | loginType = trim(loginType); | ||||
@@ -62,6 +62,10 @@ public class CredentialAuthFilter extends AbstractAuthenticationProcessingFilter | |||||
// Allow subclasses to set the "details" property | // Allow subclasses to set the "details" property | ||||
setDetails(request, authRequest); | setDetails(request, authRequest); | ||||
return this.getAuthenticationManager().authenticate(authRequest); | return this.getAuthenticationManager().authenticate(authRequest); | ||||
} catch (CommonLoginException e) { | |||||
throw new CommonLoginException(e.getMessage()); | |||||
} catch (BadCredentialsException e) { | |||||
throw new BadCredentialsException(e.getMessage()); | |||||
} catch (AuthenticationException e) { | } catch (AuthenticationException e) { | ||||
throw new BadCredentialsException("账号或密码错误"); | throw new BadCredentialsException("账号或密码错误"); | ||||
} catch (BizException e) { | } catch (BizException e) { | ||||
@@ -80,19 +84,19 @@ public class CredentialAuthFilter extends AbstractAuthenticationProcessingFilter | |||||
switch (loginTypeEnum) { | switch (loginTypeEnum) { | ||||
case DING_QR_LOGIN: { | case DING_QR_LOGIN: { | ||||
if (StringUtils.isBlank(credential)) { | if (StringUtils.isBlank(credential)) { | ||||
throw new BadCredentialsException("浙政钉扫码登陆 授权码 不能为空 credential"); | |||||
throw new CommonLoginException("浙政钉扫码登陆 授权码 不能为空 credential"); | |||||
} | } | ||||
} | } | ||||
break; | break; | ||||
case USERNAME_PASSWORD_LOGIN: { | case USERNAME_PASSWORD_LOGIN: { | ||||
if (StringUtils.isBlank(identifier) || StringUtils.isBlank(credential)) { | if (StringUtils.isBlank(identifier) || StringUtils.isBlank(credential)) { | ||||
throw new BadCredentialsException("账号密码登陆 账号密码不能为空 identifier credential"); | |||||
throw new CommonLoginException("账号密码登陆 账号密码不能为空 identifier credential"); | |||||
} | } | ||||
} | } | ||||
break; | break; | ||||
case PHONE_VERIFICATION_CODE_LOGIN: { | case PHONE_VERIFICATION_CODE_LOGIN: { | ||||
if (StringUtils.isBlank(identifier) || StringUtils.isBlank(credential)) { | if (StringUtils.isBlank(identifier) || StringUtils.isBlank(credential)) { | ||||
throw new BadCredentialsException("手机号验证码登陆 手机号或验证码不能为空 identifier credential"); | |||||
throw new CommonLoginException("手机号验证码登陆 手机号或验证码不能为空 identifier credential"); | |||||
} | } | ||||
} | } | ||||
break; | break; | ||||
@@ -6,6 +6,7 @@ import com.ningdatech.pmapi.user.manage.UserAuthLoginManage; | |||||
import com.ningdatech.pmapi.user.security.auth.constants.UserDeatilsServiceConstant; | 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.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | ||||
import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.springframework.security.core.userdetails.UserDetailsService; | import org.springframework.security.core.userdetails.UserDetailsService; | ||||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||
@@ -35,14 +36,23 @@ public class CredentialLoginUserDetailService implements UserDetailsService { | |||||
switch (loginTypeEnum) { | switch (loginTypeEnum) { | ||||
case PHONE_VERIFICATION_CODE_LOGIN: { | case PHONE_VERIFICATION_CODE_LOGIN: { | ||||
userFullInfoDTO = userAuthLoginManage.queryUserInfoInPhoneNoAuth(username); | userFullInfoDTO = userAuthLoginManage.queryUserInfoInPhoneNoAuth(username); | ||||
if (Objects.isNull(userFullInfoDTO)) { | |||||
throw new CommonLoginException("改手机号未绑定用户"); | |||||
} | |||||
} | } | ||||
break; | break; | ||||
case USERNAME_PASSWORD_LOGIN: { | case USERNAME_PASSWORD_LOGIN: { | ||||
userFullInfoDTO = userAuthLoginManage.queryUserInfoInPasswordAuth(username); | userFullInfoDTO = userAuthLoginManage.queryUserInfoInPasswordAuth(username); | ||||
if (Objects.isNull(userFullInfoDTO)) { | |||||
throw new UsernameNotFoundException(String.format("%s user not exist", username)); | |||||
} | |||||
} | } | ||||
break; | break; | ||||
case DING_QR_LOGIN: { | case DING_QR_LOGIN: { | ||||
userFullInfoDTO = userAuthLoginManage.queryUserInfoInAccountIdAuth(username); | userFullInfoDTO = userAuthLoginManage.queryUserInfoInAccountIdAuth(username); | ||||
if (Objects.isNull(userFullInfoDTO)) { | |||||
throw new CommonLoginException("浙政钉账号无法登陆"); | |||||
} | |||||
} | } | ||||
break; | break; | ||||
default: { | default: { | ||||
@@ -50,9 +60,6 @@ public class CredentialLoginUserDetailService implements UserDetailsService { | |||||
} | } | ||||
} | } | ||||
if (Objects.isNull(userFullInfoDTO)) { | |||||
throw new UsernameNotFoundException(String.format("%s user not exist", username)); | |||||
} | |||||
UserInfoDetails userInfoDetails = new UserInfoDetails(); | UserInfoDetails userInfoDetails = new UserInfoDetails(); | ||||
userInfoDetails.setUserId(userFullInfoDTO.getUserId()); | userInfoDetails.setUserId(userFullInfoDTO.getUserId()); | ||||
userInfoDetails.setUsername(userFullInfoDTO.getUsername()); | userInfoDetails.setUsername(userFullInfoDTO.getUsername()); | ||||
@@ -3,6 +3,7 @@ package com.ningdatech.pmapi.user.security.auth.handler; | |||||
import com.fasterxml.jackson.databind.ObjectMapper; | import com.fasterxml.jackson.databind.ObjectMapper; | ||||
import com.ningdatech.basic.model.ApiResponse; | import com.ningdatech.basic.model.ApiResponse; | ||||
import com.ningdatech.pmapi.user.security.auth.errorcode.AuthErrorCodeEnum; | import com.ningdatech.pmapi.user.security.auth.errorcode.AuthErrorCodeEnum; | ||||
import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException; | |||||
import org.springframework.security.authentication.BadCredentialsException; | import org.springframework.security.authentication.BadCredentialsException; | ||||
import org.springframework.security.core.AuthenticationException; | import org.springframework.security.core.AuthenticationException; | ||||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||
@@ -32,7 +33,10 @@ public class DefaultLoginFailureHandler extends SimpleUrlAuthenticationFailureHa | |||||
String errorMsg; | String errorMsg; | ||||
// 所有的认证异常都可以在这里添加,目前只支持用户名密码错误异常 | // 所有的认证异常都可以在这里添加,目前只支持用户名密码错误异常 | ||||
if (exception instanceof BadCredentialsException || exception instanceof UsernameNotFoundException) { | |||||
if (exception instanceof CommonLoginException) { | |||||
errorCode = 400; | |||||
errorMsg = exception.getMessage(); | |||||
} else if (exception instanceof BadCredentialsException || exception instanceof UsernameNotFoundException) { | |||||
errorCode = AuthErrorCodeEnum.USERNAME_OR_PASSWORD_ERROR.getCode(); | errorCode = AuthErrorCodeEnum.USERNAME_OR_PASSWORD_ERROR.getCode(); | ||||
errorMsg = exception.getMessage(); | errorMsg = exception.getMessage(); | ||||
} else { | } else { | ||||
@@ -0,0 +1,17 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.validate; | |||||
import org.springframework.security.core.AuthenticationException; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/3/24 上午11:47 | |||||
* 通用登陆错误 | |||||
*/ | |||||
public class CommonLoginException extends AuthenticationException { | |||||
public CommonLoginException(String message) { | |||||
super(message); | |||||
} | |||||
} |
@@ -1,10 +1,14 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.validate; | package com.ningdatech.pmapi.user.security.auth.validate; | ||||
import lombok.Data; | |||||
/** | /** | ||||
* @author liuxinxin | * @author liuxinxin | ||||
* @date 2023/3/24 上午11:47 | * @date 2023/3/24 上午11:47 | ||||
* 浙政钉扫码登陆错误 | |||||
*/ | */ | ||||
@Data | |||||
public class DingQrLoginException extends RuntimeException { | public class DingQrLoginException extends RuntimeException { | ||||
private Integer code; | private Integer code; | ||||