@@ -1,6 +1,5 @@ | |||||
package com.ningdatech.pmapi.common.handler; | package com.ningdatech.pmapi.common.handler; | ||||
import cn.hutool.json.JSONUtil; | |||||
import com.ningdatech.basic.model.ApiResponse; | import com.ningdatech.basic.model.ApiResponse; | ||||
import org.springframework.core.MethodParameter; | import org.springframework.core.MethodParameter; | ||||
import org.springframework.http.MediaType; | import org.springframework.http.MediaType; | ||||
@@ -24,7 +23,9 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; | |||||
"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", | ||||
"com.ningdatech.pmapi.expert.controller" | |||||
"com.ningdatech.pmapi.meeting.controller", | |||||
"com.ningdatech.pmapi.expert.controller", | |||||
"com.ningdatech.pmapi.sms.controller" | |||||
}) | }) | ||||
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> { | public class GlobalResponseHandler implements ResponseBodyAdvice<Object> { | ||||
@@ -17,8 +17,8 @@ import java.time.LocalDateTime; | |||||
* @author Liuxinxin | * @author Liuxinxin | ||||
* @since 2023-02-22 | * @since 2023-02-22 | ||||
*/ | */ | ||||
@TableName("nd_expert_user_full_info") | |||||
@Data | @Data | ||||
@TableName("nd_expert_user_full_info") | |||||
@ApiModel(value = "NdExpertUserFullInfo对象", description = "") | @ApiModel(value = "NdExpertUserFullInfo对象", description = "") | ||||
public class ExpertUserFullInfo implements Serializable { | public class ExpertUserFullInfo implements Serializable { | ||||
@@ -60,13 +60,12 @@ public class ExpertManage { | |||||
* | * | ||||
* @param request | * @param request | ||||
*/ | */ | ||||
@Transactional(rollbackFor = Exception.class) | |||||
public void expertBasicInfoSubmit(ExpertUserBasicInfoSubmitRequest request) { | public void expertBasicInfoSubmit(ExpertUserBasicInfoSubmitRequest request) { | ||||
// 用户id | // 用户id | ||||
// Long userId = LoginUserUtil.getUserId(); | |||||
ExpertBasicInfo basicInfo = request.getBasicInfo(); | ExpertBasicInfo basicInfo = request.getBasicInfo(); | ||||
Long userId = generateOrGetUserId(basicInfo); | Long userId = generateOrGetUserId(basicInfo); | ||||
// 校验区域编码合法性 校验履职意向编码合法性 | // 校验区域编码合法性 校验履职意向编码合法性 | ||||
ExpertRegionInfo expertRegionInfo = basicInfo.getExpertRegionInfo(); | ExpertRegionInfo expertRegionInfo = basicInfo.getExpertRegionInfo(); | ||||
expertManageHelper.expertRegionInfoCheck(expertRegionInfo); | expertManageHelper.expertRegionInfoCheck(expertRegionInfo); | ||||
@@ -99,13 +98,13 @@ public class ExpertManage { | |||||
List<DictionaryFieldInfo> recommendedWay = recommendInfo.getRecommendedWay(); | List<DictionaryFieldInfo> recommendedWay = recommendInfo.getRecommendedWay(); | ||||
// 推荐方式 | // 推荐方式 | ||||
List<FileBasicInfo> recommendProofFile = recommendInfo.getRecommendationProofFile(); | List<FileBasicInfo> recommendProofFile = recommendInfo.getRecommendationProofFile(); | ||||
expertRecommendProofSubmit(recommendedWay, recommendProofFile); | |||||
expertRecommendProofSubmit(recommendedWay, recommendProofFile, userId); | |||||
} | } | ||||
public void expertRecommendProofSubmit(List<DictionaryFieldInfo> recommendedWay, List<FileBasicInfo> recommendProofFile) { | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void expertRecommendProofSubmit(List<DictionaryFieldInfo> recommendedWay, List<FileBasicInfo> recommendProofFile, Long expertUserId) { | |||||
// 用户id | // 用户id | ||||
Long expertUserId = LoginUserUtil.getUserId(); | |||||
ExpertUserFullInfo expertUserFullInfo = iExpertUserFullInfoService.getByUserId(expertUserId); | ExpertUserFullInfo expertUserFullInfo = iExpertUserFullInfoService.getByUserId(expertUserId); | ||||
// 判断专家状态,是否可以进行证明材料提交 | // 判断专家状态,是否可以进行证明材料提交 | ||||
if (Objects.isNull(expertUserFullInfo) | if (Objects.isNull(expertUserFullInfo) | ||||
@@ -158,6 +157,7 @@ public class ExpertManage { | |||||
.realName(basicInfo.getName()) | .realName(basicInfo.getName()) | ||||
// .employeeCode(dingEmployeeInfo.getEmployeeCode()) | // .employeeCode(dingEmployeeInfo.getEmployeeCode()) | ||||
.available(UserAvailableEnum.DISABLE.name()) | .available(UserAvailableEnum.DISABLE.name()) | ||||
.mobile(phoneNo) | |||||
.createBy(LoginUserUtil.getUserId()) | .createBy(LoginUserUtil.getUserId()) | ||||
.updateBy(LoginUserUtil.getUserId()) | .updateBy(LoginUserUtil.getUserId()) | ||||
.createOn(LocalDateTime.now()) | .createOn(LocalDateTime.now()) | ||||
@@ -79,6 +79,7 @@ public class ExpertReviewManage { | |||||
review.setContent(JSONUtil.toJsonStr(req.getReviewTemplateOptions())); | review.setContent(JSONUtil.toJsonStr(req.getReviewTemplateOptions())); | ||||
review.setProjectId(req.getProjectId()); | review.setProjectId(req.getProjectId()); | ||||
review.setTemplateId(req.getTemplateId()); | review.setTemplateId(req.getTemplateId()); | ||||
review.setMeetingId(req.getMeetingId()); | |||||
review.setOtherAdvice(req.getOtherAdvice()); | review.setOtherAdvice(req.getOtherAdvice()); | ||||
review.setAttachFileId(req.getAttachFileId()); | review.setAttachFileId(req.getAttachFileId()); | ||||
review.setIsFinal(req.getIsFinal()); | review.setIsFinal(req.getIsFinal()); | ||||
@@ -30,6 +30,9 @@ public class ExpertReview implements Serializable { | |||||
@ApiModelProperty("项目ID") | @ApiModelProperty("项目ID") | ||||
private Long projectId; | private Long projectId; | ||||
@ApiModelProperty("会议ID") | |||||
private Long meetingId; | |||||
@ApiModelProperty("评审模版配置ID") | @ApiModelProperty("评审模版配置ID") | ||||
private Long templateId; | private Long templateId; | ||||
@@ -28,6 +28,10 @@ public class ExpertReviewDetailReq { | |||||
@NotNull(message = "项目ID不能为空") | @NotNull(message = "项目ID不能为空") | ||||
private Long projectId; | private Long projectId; | ||||
@ApiModelProperty("会议ID") | |||||
@NotNull(message = "会议ID不能为空") | |||||
private Long meetingId; | |||||
@Valid | @Valid | ||||
@ApiModelProperty("配置模版") | @ApiModelProperty("配置模版") | ||||
@NotEmpty(message = "配置不能为空") | @NotEmpty(message = "配置不能为空") | ||||
@@ -0,0 +1,51 @@ | |||||
package com.ningdatech.pmapi.irs.config; | |||||
import lombok.Data; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.stereotype.Component; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/3/16 下午6:03 | |||||
*/ | |||||
@Component | |||||
@Data | |||||
public class IrsSealPlatformProperties { | |||||
public static String projectId; | |||||
public static String projectSecret; | |||||
public static String accessKey; | |||||
public static String secretKey; | |||||
public static String apiUrl; | |||||
@Value("${irs.seal-platform.project-id}") | |||||
public void setProjectId(String projectId) { | |||||
IrsSealPlatformProperties.projectId = projectId; | |||||
} | |||||
@Value("${irs.seal-platform.project-secret}") | |||||
public void setProjectSecret(String projectSecret) { | |||||
IrsSealPlatformProperties.projectSecret = projectSecret; | |||||
} | |||||
@Value("${irs.seal-platform.access-key}") | |||||
public void setAccessKey(String accessKey) { | |||||
IrsSealPlatformProperties.accessKey = accessKey; | |||||
} | |||||
@Value("${irs.seal-platform.secret-key}") | |||||
public void setSecretKey(String secretKey) { | |||||
IrsSealPlatformProperties.secretKey = secretKey; | |||||
} | |||||
@Value("${irs.seal-platform.api-url}") | |||||
public void setApiUrl(String apiUrl) { | |||||
IrsSealPlatformProperties.apiUrl = apiUrl; | |||||
} | |||||
} |
@@ -8,6 +8,7 @@ import com.ningdatech.pmapi.meeting.entity.dto.ReviewProjectDTO; | |||||
import com.ningdatech.pmapi.meeting.entity.req.*; | import com.ningdatech.pmapi.meeting.entity.req.*; | ||||
import com.ningdatech.pmapi.meeting.entity.vo.*; | import com.ningdatech.pmapi.meeting.entity.vo.*; | ||||
import com.ningdatech.pmapi.meeting.manage.MeetingManage; | import com.ningdatech.pmapi.meeting.manage.MeetingManage; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | |||||
import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
@@ -168,8 +169,14 @@ public class MeetingController { | |||||
@GetMapping("/listReviewProject") | @GetMapping("/listReviewProject") | ||||
@ApiOperation("评审会议列表") | @ApiOperation("评审会议列表") | ||||
public PageVo<ReviewProjectDTO> listReviewProject(ReviewProjectListReq req){ | |||||
public PageVo<ReviewProjectDTO> listReviewProject(ReviewProjectListReq req) { | |||||
return meetingManage.pageReviewProject(req); | return meetingManage.pageReviewProject(req); | ||||
} | } | ||||
@GetMapping("/option/project") | |||||
@ApiOperation("项目列表(创建会议添加项目)") | |||||
public PageVo<ProjectLibListItemVO> projectList(MeetingOptionProjectReq req) { | |||||
return meetingManage.optionProject(req); | |||||
} | |||||
} | } |
@@ -0,0 +1,21 @@ | |||||
package com.ningdatech.pmapi.meeting.entity.req; | |||||
import com.ningdatech.basic.model.PagePo; | |||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
/** | |||||
* <p> | |||||
* MeetingOptionProjectReq | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 11:50 2023/3/16 | |||||
*/ | |||||
@Data | |||||
@EqualsAndHashCode | |||||
public class MeetingOptionProjectReq extends PagePo { | |||||
private String meetingType; | |||||
} |
@@ -77,6 +77,7 @@ public class ExpertInviteManage { | |||||
.select(ExpertUserFullInfo::getUserId, | .select(ExpertUserFullInfo::getUserId, | ||||
ExpertUserFullInfo::getId, | ExpertUserFullInfo::getId, | ||||
ExpertUserFullInfo::getCompany, | ExpertUserFullInfo::getCompany, | ||||
ExpertUserFullInfo::getExpertName, | |||||
ExpertUserFullInfo::getPhoneNo) | ExpertUserFullInfo::getPhoneNo) | ||||
.eq(ExpertUserFullInfo::getExpertAccountStatus, ExpertAccountStatusEnum.AVAILABLE.getKey()); | .eq(ExpertUserFullInfo::getExpertAccountStatus, ExpertAccountStatusEnum.AVAILABLE.getKey()); | ||||
} | } | ||||
@@ -281,7 +282,7 @@ public class ExpertInviteManage { | |||||
LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | ||||
query.notIn(!tmpAvoidCompany.isEmpty(), ExpertUserFullInfo::getCompany, tmpAvoidCompany); | query.notIn(!tmpAvoidCompany.isEmpty(), ExpertUserFullInfo::getCompany, tmpAvoidCompany); | ||||
if (avoidCompany) { | if (avoidCompany) { | ||||
query.notExists("select 1 from expert_avoid_company eac where eac.user_id = expert_user_full_info.user_id" + | |||||
query.notExists("select 1 from expert_avoid_company eac where eac.user_id = nd_expert_user_full_info.user_id" + | |||||
" and company_name in ({0})", CollUtils.joinByComma(avoidRule.getAvoidUnitIdList())); | " and company_name in ({0})", CollUtils.joinByComma(avoidRule.getAvoidUnitIdList())); | ||||
} | } | ||||
// 处理专家层级 | // 处理专家层级 | ||||
@@ -357,7 +358,7 @@ public class ExpertInviteManage { | |||||
} | } | ||||
LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | ||||
query.notIn(ExpertUserFullInfo::getCompany, avoidRule.getAvoidUnitIdList()); | query.notIn(ExpertUserFullInfo::getCompany, avoidRule.getAvoidUnitIdList()); | ||||
query.notExists("select 1 from expert_avoid_company eac where eac.user_id = expert_user_full_info.user_id" + | |||||
query.notExists("select 1 from expert_avoid_company eac where eac.user_id = nd_expert_user_full_info.user_id" + | |||||
" and company_name in ({0})", CollUtils.joinByComma(avoidRule.getAvoidOrgIdList())); | " and company_name in ({0})", CollUtils.joinByComma(avoidRule.getAvoidOrgIdList())); | ||||
// 处理专家层级 | // 处理专家层级 | ||||
@@ -25,6 +25,7 @@ import com.ningdatech.pmapi.meeting.entity.domain.*; | |||||
import com.ningdatech.pmapi.meeting.entity.dto.*; | import com.ningdatech.pmapi.meeting.entity.dto.*; | ||||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | ||||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteTypeEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteTypeEnum; | ||||
import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingReviewTypeEnum; | |||||
import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum; | ||||
import com.ningdatech.pmapi.meeting.entity.req.*; | import com.ningdatech.pmapi.meeting.entity.req.*; | ||||
import com.ningdatech.pmapi.meeting.entity.vo.*; | import com.ningdatech.pmapi.meeting.entity.vo.*; | ||||
@@ -35,7 +36,9 @@ import com.ningdatech.pmapi.meeting.service.*; | |||||
import com.ningdatech.pmapi.meeting.task.ExpertInviteTask; | import com.ningdatech.pmapi.meeting.task.ExpertInviteTask; | ||||
import com.ningdatech.pmapi.meta.helper.DictionaryCache; | import com.ningdatech.pmapi.meta.helper.DictionaryCache; | ||||
import com.ningdatech.pmapi.meta.helper.TagCache; | import com.ningdatech.pmapi.meta.helper.TagCache; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.sys.model.dto.RegionDTO; | import com.ningdatech.pmapi.sys.model.dto.RegionDTO; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | ||||
@@ -702,4 +705,49 @@ public class MeetingManage { | |||||
return PageVo.of(page.getRecords(), page.getTotal()); | return PageVo.of(page.getRecords(), page.getTotal()); | ||||
} | } | ||||
public PageVo<ProjectLibListItemVO> optionProject(MeetingOptionProjectReq req) { | |||||
String meetingType = req.getMeetingType(); | |||||
LambdaQueryWrapper<Project> query = Wrappers.lambdaQuery(Project.class); | |||||
switch (MeetingReviewTypeEnum.getByCode(meetingType)) { | |||||
case PRELIMINARY_SCHEME_REVIEW: | |||||
buildOptionProjectQuery(query, meetingType, ProjectStatusEnum.PRE_APPLYING); | |||||
break; | |||||
case CONSTRUCTION_SCHEME_REVIEW: | |||||
buildOptionProjectQuery(query, meetingType, ProjectStatusEnum.SCHEME_UNDER_REVIEW); | |||||
break; | |||||
case ACCEPTANCE_SCHEME_REVIEW: | |||||
query.eq(Project::getStatus, ProjectStatusEnum.FINAL_ACCEPTANCE_IS_UNDER_REVIEW); | |||||
break; | |||||
case DEPT_JOIN_REVIEW: | |||||
query.eq(Project::getStatus, ProjectStatusEnum.DEPARTMENT_JOINT_REVIEW); | |||||
break; | |||||
default: | |||||
return PageVo.empty(); | |||||
} | |||||
Page<Project> page = projectService.page(req.page(), query); | |||||
PageVo<ProjectLibListItemVO> result = PageVo.of(null, page.getTotal()); | |||||
if (result.getTotal() > 0) { | |||||
List<ProjectLibListItemVO> projects = CollUtils.convert(page.getRecords(), | |||||
w -> ProjectLibListItemVO | |||||
.builder() | |||||
.id(w.getId()) | |||||
.projectName(w.getProjectName()) | |||||
.declaredAmount(w.getDeclareAmount()) | |||||
.projectType(w.getProjectType()) | |||||
.projectYear(w.getProjectYear()) | |||||
.buildOrg(w.getBuildOrgName()) | |||||
.build()); | |||||
result.setRecords(projects); | |||||
} | |||||
return result; | |||||
} | |||||
private void buildOptionProjectQuery(LambdaQueryWrapper<Project> query, String meetingType, ProjectStatusEnum status) { | |||||
String sql = String.format("select 1 from meeting m inner join meeting_inner_project mip on" + | |||||
" m.is_inner_project = true and m.id = mip.meeting_id and m.type = %s and m.status != 3", meetingType); | |||||
query.eq(Project::getStatus, status.getCode()); | |||||
query.and(q1 -> q1.notExists(sql)).or(q2 -> q2.exists(sql + " inner join nd_expert_review ner " + | |||||
"on ner.meeting_id = m.id and ner.is_final = true and review_result in (2, 3)")); | |||||
} | |||||
} | } |
@@ -87,7 +87,8 @@ public class ExpertInviteTask { | |||||
} | } | ||||
private CacheHashKey getCacheKey(Long meetingId) { | private CacheHashKey getCacheKey(Long meetingId) { | ||||
return new CacheHashKey(MEETING_ID_INVITE_RANDOM, meetingId, EXPIRE_TIME); | |||||
String meetingIdStr = meetingId == null ? null : meetingId.toString(); | |||||
return new CacheHashKey(MEETING_ID_INVITE_RANDOM, meetingIdStr, EXPIRE_TIME); | |||||
} | } | ||||
@PostConstruct | @PostConstruct | ||||
@@ -4,7 +4,9 @@ import com.fasterxml.jackson.annotation.JsonFormat; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | ||||
import io.swagger.annotations.ApiModel; | import io.swagger.annotations.ApiModel; | ||||
import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||
import lombok.Builder; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.experimental.Tolerate; | |||||
import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
@@ -20,9 +22,14 @@ import java.util.Optional; | |||||
* @since 15:13 2023/2/1 | * @since 15:13 2023/2/1 | ||||
*/ | */ | ||||
@Data | @Data | ||||
@Builder | |||||
@ApiModel("项目库列表视图") | @ApiModel("项目库列表视图") | ||||
public class ProjectLibListItemVO { | public class ProjectLibListItemVO { | ||||
@Tolerate | |||||
public ProjectLibListItemVO() { | |||||
} | |||||
@ApiModelProperty("项目ID") | @ApiModelProperty("项目ID") | ||||
private Long id; | private Long id; | ||||
@@ -67,8 +74,8 @@ public class ProjectLibListItemVO { | |||||
private String projectTypeName; | private String projectTypeName; | ||||
public String getProjectTypeName(){ | |||||
if(Objects.nonNull(this.projectType)){ | |||||
public String getProjectTypeName() { | |||||
if (Objects.nonNull(this.projectType)) { | |||||
Optional.ofNullable(ProjectTypeEnum.getDesc(this.projectType)) | Optional.ofNullable(ProjectTypeEnum.getDesc(this.projectType)) | ||||
.ifPresent(desc -> this.projectTypeName = desc); | .ifPresent(desc -> this.projectTypeName = desc); | ||||
} | } | ||||
@@ -23,6 +23,7 @@ import org.springframework.util.Assert; | |||||
import java.time.Duration; | import java.time.Duration; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Objects; | |||||
/** | /** | ||||
* @author liuxinxin | * @author liuxinxin | ||||
@@ -81,8 +82,9 @@ public class SmsManage { | |||||
cachePlusOps.set(new CacheKey(cacheKey, Duration.ofMinutes(verificationCodeTypeEnum.getExpireTime())), cache); | cachePlusOps.set(new CacheKey(cacheKey, Duration.ofMinutes(verificationCodeTypeEnum.getExpireTime())), cache); | ||||
String limitKey = SmsRedisKeyUtils.smsSendLimitKey(verificationCodeTypeEnum, request.getMobile()); | String limitKey = SmsRedisKeyUtils.smsSendLimitKey(verificationCodeTypeEnum, request.getMobile()); | ||||
if (StringUtils.isNotBlank(cachePlusOps.get(limitKey))) { | |||||
long limitCount = cachePlusOps.incr(new CacheKey(limitKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon()))); | |||||
if (Objects.nonNull(cachePlusOps.get(limitKey))) { | |||||
Integer limitCount = cachePlusOps.get(limitKey); | |||||
cachePlusOps.set(new CacheKey(limitKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())), limitCount++); | |||||
// 超出单日发送次数之后直接锁定 | // 超出单日发送次数之后直接锁定 | ||||
if (limitCount >= verificationCodeTypeEnum.getSendTimesByDay().longValue()) { | if (limitCount >= verificationCodeTypeEnum.getSendTimesByDay().longValue()) { | ||||
cachePlusOps.set(new CacheKey(lockKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())), request.getMobile()); | cachePlusOps.set(new CacheKey(lockKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())), request.getMobile()); | ||||
@@ -19,8 +19,8 @@ public class ReqVerificationCodePO implements Serializable { | |||||
@NotBlank(message = "手机号不能为空") | @NotBlank(message = "手机号不能为空") | ||||
private String mobile; | private String mobile; | ||||
@ApiModelProperty(value = "短信类型", allowableValues = "LOGIN,RECOMMENDATION_PROOF_FILE_SUBMIT") | |||||
@ApiModelProperty(value = "短信类型", allowableValues = "LOGIN") | |||||
@NotBlank(message = "短信类型不能为空") | @NotBlank(message = "短信类型不能为空") | ||||
private String verificationType; | private String verificationType; | ||||
} | |||||
} |
@@ -0,0 +1,29 @@ | |||||
package com.ningdatech.pmapi.sms.task; | |||||
import com.ningdatech.yxt.client.YxtContext; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.springframework.scheduling.annotation.Scheduled; | |||||
import org.springframework.stereotype.Component; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2022/8/9 下午3:58 | |||||
* 音信通定时检查电话结果 | |||||
*/ | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class YxtPollingTask { | |||||
private final YxtContext yxtContext; | |||||
/** | |||||
* 校验音信通结果数据 | |||||
* 每5分钟执行一次 | |||||
*/ | |||||
@Scheduled(cron = "0 */1 * * * ?") | |||||
// @Scheduled(cron = "${cron-expression.sms-msg-result-check-cron}") | |||||
public void smsMsgResultCheck() { | |||||
yxtContext.smsMsgResultCheck(); | |||||
} | |||||
} |
@@ -16,20 +16,22 @@ public class SmsRedisKeyUtils { | |||||
private SmsRedisKeyUtils() { | private SmsRedisKeyUtils() { | ||||
} | } | ||||
private static final String PROJECT_NAME = "ls_pm:"; | |||||
private static final String SMS_CODE_VERIFY_PREFIX = "sms:verify:"; | private static final String SMS_CODE_VERIFY_PREFIX = "sms:verify:"; | ||||
private static final String SMS_SEND_LIMIT = "sms:limit:"; | private static final String SMS_SEND_LIMIT = "sms:limit:"; | ||||
private static final String SMS_SEND_LOCK = "sms:lock:"; | private static final String SMS_SEND_LOCK = "sms:lock:"; | ||||
public static String smsCodeVerifyKey(VerificationCodeType type, String mobile) { | public static String smsCodeVerifyKey(VerificationCodeType type, String mobile) { | ||||
return SMS_CODE_VERIFY_PREFIX + StrPool.COLON + type.name() + StrPool.COLON + mobile; | |||||
return PROJECT_NAME + SMS_CODE_VERIFY_PREFIX + StrPool.COLON + type.name() + StrPool.COLON + mobile; | |||||
} | } | ||||
public static String smsSendLimitKey(VerificationCodeType type, String mobile) { | public static String smsSendLimitKey(VerificationCodeType type, String mobile) { | ||||
return SMS_SEND_LIMIT + StrPool.COLON + type.name() + StrPool.COLON + mobile; | |||||
return PROJECT_NAME + SMS_SEND_LIMIT + StrPool.COLON + type.name() + StrPool.COLON + mobile; | |||||
} | } | ||||
public static String smsSendLockKey(VerificationCodeType type, String mobile) { | public static String smsSendLockKey(VerificationCodeType type, String mobile) { | ||||
return SMS_SEND_LOCK + StrPool.COLON + type.name() + StrPool.COLON + mobile; | |||||
return PROJECT_NAME + SMS_SEND_LOCK + StrPool.COLON + type.name() + StrPool.COLON + mobile; | |||||
} | } | ||||
} | } |
@@ -81,4 +81,11 @@ public class UserAuthController { | |||||
response.getWriter().write(objectMapper.writeValueAsString(BizConst.UNAUTHENTICATED)); | response.getWriter().write(objectMapper.writeValueAsString(BizConst.UNAUTHENTICATED)); | ||||
} | } | ||||
@PostMapping(value = "/agent-login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) | |||||
@ApiOperation(value = "代登陆") | |||||
@ApiImplicitParams({ | |||||
@ApiImplicitParam(name = "userId", value = "账号", required = true, paramType = "form", dataType = "String")}) | |||||
public void agentLogin(@RequestParam(value = "userId", required = true) String userId) { | |||||
// 不实现任何内容,只是为了出api文档 | |||||
} | |||||
} | } |
@@ -59,10 +59,4 @@ public class UserInfoController { | |||||
return userInfoManage.currentUserInfo(); | return userInfoManage.currentUserInfo(); | ||||
} | } | ||||
@ApiOperation(value = "代登陆", notes = "代登陆") | |||||
@PostMapping("/generation-login") | |||||
public void generationLogin(@Valid @RequestBody ReqGenerationLoginPO reqGenerationLoginPO, HttpServletRequest httpServletRequest) { | |||||
userInfoManage.generationLogin(reqGenerationLoginPO); | |||||
} | |||||
} | } |
@@ -17,7 +17,10 @@ import com.ningdatech.pmapi.sys.service.IRoleService; | |||||
import com.ningdatech.pmapi.sys.service.IUserRoleService; | import com.ningdatech.pmapi.sys.service.IUserRoleService; | ||||
import com.ningdatech.pmapi.user.constant.UserAvailableEnum; | import com.ningdatech.pmapi.user.constant.UserAvailableEnum; | ||||
import com.ningdatech.pmapi.user.entity.UserInfo; | import com.ningdatech.pmapi.user.entity.UserInfo; | ||||
import com.ningdatech.pmapi.user.model.po.*; | |||||
import com.ningdatech.pmapi.user.model.po.ReqUserDetailEditPO; | |||||
import com.ningdatech.pmapi.user.model.po.ReqUserDetailPO; | |||||
import com.ningdatech.pmapi.user.model.po.ReqUserDisableOrEnablePO; | |||||
import com.ningdatech.pmapi.user.model.po.ReqUserInfoListPO; | |||||
import com.ningdatech.pmapi.user.model.vo.ResUserDetailVO; | 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 com.ningdatech.pmapi.user.model.vo.UserRoleVO; | import com.ningdatech.pmapi.user.model.vo.UserRoleVO; | ||||
@@ -25,7 +28,6 @@ import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||||
import com.ningdatech.pmapi.user.service.IUserInfoService; | import com.ningdatech.pmapi.user.service.IUserInfoService; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.springframework.security.core.userdetails.UserDetailsService; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
@@ -250,7 +252,7 @@ public class UserInfoManage { | |||||
} | } | ||||
resUserDetailVO.setUserRoleInfoList(userRoleInfoList); | resUserDetailVO.setUserRoleInfoList(userRoleInfoList); | ||||
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId); | UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId); | ||||
if(Objects.nonNull(userFullInfo)){ | |||||
if (Objects.nonNull(userFullInfo)) { | |||||
resUserDetailVO.setOrgCode(userFullInfo.getOrganizationCode()); | resUserDetailVO.setOrgCode(userFullInfo.getOrganizationCode()); | ||||
resUserDetailVO.setOrgName(userFullInfo.getOrganizationName()); | resUserDetailVO.setOrgName(userFullInfo.getOrganizationName()); | ||||
resUserDetailVO.setRegionCode(userFullInfo.getRegionCode()); | resUserDetailVO.setRegionCode(userFullInfo.getRegionCode()); | ||||
@@ -258,39 +260,4 @@ public class UserInfoManage { | |||||
return resUserDetailVO; | return resUserDetailVO; | ||||
} | } | ||||
public void generationLogin(ReqGenerationLoginPO reqGenerationLoginPO) { | |||||
Long userId = reqGenerationLoginPO.getUserId(); | |||||
UserInfo userInfo = iUserInfoService.getById(userId); | |||||
if (Objects.isNull(userInfo)) { | |||||
throw new BizException("该员工账号处于禁用状态中,无法使用"); | |||||
} | |||||
if (!UserAvailableEnum.ENABLE.name().equals(userInfo.getAvailable())) { | |||||
throw new BizException("该员工账号处于禁用状态中,无法使用"); | |||||
} | |||||
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId); | |||||
// ReqGenerationLoginPO reqGenerationLoginPO | |||||
} | |||||
// public void autoLogin(Long userId){ | |||||
// userDetailsService.loadUserByUsername(userId + UserDeatilsServiceConstant.USER_DETAILS_SERVICE_SEPARATOR + LoginTypeEnum.USERNAME_PASSWORD_LOGIN.name()); | |||||
// | |||||
// CredentialAuthToken token = new CredentialAuthToken(email, password); | |||||
// try { | |||||
// token.setDetails(new WebAuthenticationDetails(httpServletRequest)); | |||||
// UsernamePasswordAuthToken authenticatedUser = (UsernamePasswordAuthToken)usernamePasswordAuthSecurityConfig | |||||
// .getAuthenticationManager().authenticate(token); | |||||
// SecurityContextHolder.getContext().setAuthentication(authenticatedUser); | |||||
// httpServletRequest.getSession().setAttribute( | |||||
// HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); | |||||
// String sessionId = httpServletRequest.getSession().getId(); | |||||
// putSessionIdToCache(LoginUserUtil.getUserId(), sessionId); | |||||
// } catch ( | |||||
// AuthenticationException e) { | |||||
// throw new RuntimeException("autoLogIn Authentication failed!", e); | |||||
// } | |||||
// } | |||||
} | } |
@@ -29,6 +29,11 @@ public class AuthProperties { | |||||
private String passwordLoginUrl; | private String passwordLoginUrl; | ||||
/** | |||||
* 代登陆接口 | |||||
*/ | |||||
private String agentLoginUrl; | |||||
private String logoutUrl; | private String logoutUrl; | ||||
private List<String> ignoreAuthUrls; | private List<String> ignoreAuthUrls; | ||||
@@ -4,8 +4,9 @@ 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.CommonConst; | import com.ningdatech.pmapi.common.constant.CommonConst; | ||||
import com.ningdatech.pmapi.user.security.auth.handler.DefaultExpiredSessionStrategy; | |||||
import com.ningdatech.pmapi.user.security.auth.agent.AgentAuthSecurityConfig; | |||||
import com.ningdatech.pmapi.user.security.auth.credential.CredentialAuthSecurityConfig; | import com.ningdatech.pmapi.user.security.auth.credential.CredentialAuthSecurityConfig; | ||||
import com.ningdatech.pmapi.user.security.auth.handler.DefaultExpiredSessionStrategy; | |||||
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; | ||||
@@ -31,13 +32,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | |||||
private final CredentialAuthSecurityConfig credentialAuthSecurityConfig; | private final CredentialAuthSecurityConfig credentialAuthSecurityConfig; | ||||
private final LogoutSuccessHandler logoutSuccessHandler; | private final LogoutSuccessHandler logoutSuccessHandler; | ||||
private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy; | private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy; | ||||
private final AgentAuthSecurityConfig agentAuthSecurityConfig; | |||||
public WebSecurityConfig(AuthProperties authProperties, | public WebSecurityConfig(AuthProperties authProperties, | ||||
CredentialAuthSecurityConfig credentialAuthSecurityConfig, | CredentialAuthSecurityConfig credentialAuthSecurityConfig, | ||||
AgentAuthSecurityConfig agentAuthSecurityConfig, | |||||
@Qualifier(value = "defaultLogoutSuccessHandler") LogoutSuccessHandler logoutSuccessHandler, | @Qualifier(value = "defaultLogoutSuccessHandler") LogoutSuccessHandler logoutSuccessHandler, | ||||
DefaultExpiredSessionStrategy defaultExpiredSessionStrategy) { | DefaultExpiredSessionStrategy defaultExpiredSessionStrategy) { | ||||
this.authProperties = authProperties; | this.authProperties = authProperties; | ||||
this.credentialAuthSecurityConfig = credentialAuthSecurityConfig; | this.credentialAuthSecurityConfig = credentialAuthSecurityConfig; | ||||
this.agentAuthSecurityConfig = agentAuthSecurityConfig; | |||||
this.logoutSuccessHandler = logoutSuccessHandler; | this.logoutSuccessHandler = logoutSuccessHandler; | ||||
this.defaultExpiredSessionStrategy = defaultExpiredSessionStrategy; | this.defaultExpiredSessionStrategy = defaultExpiredSessionStrategy; | ||||
} | } | ||||
@@ -47,7 +51,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | |||||
assemblerPreAuthUrls(http); | assemblerPreAuthUrls(http); | ||||
http.formLogin() | http.formLogin() | ||||
.loginPage(authProperties.getAuthRequireUrl()) | .loginPage(authProperties.getAuthRequireUrl()) | ||||
.and().apply(credentialAuthSecurityConfig) | |||||
.and().apply(credentialAuthSecurityConfig).and().apply(agentAuthSecurityConfig) | |||||
.and() | .and() | ||||
.authorizeRequests().antMatchers(authProperties.getIgnoreAuthUrlsArray()).permitAll().anyRequest() | .authorizeRequests().antMatchers(authProperties.getIgnoreAuthUrlsArray()).permitAll().anyRequest() | ||||
.authenticated().and() | .authenticated().and() | ||||
@@ -0,0 +1,74 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.agent; | |||||
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.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 AgentAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
private boolean postOnly = true; | |||||
private static final String USER_ID_PARAMETER = "userId"; | |||||
// ~ Constructors | |||||
// =================================================================================================== | |||||
public AgentAuthFilter(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 userId = request.getParameter(USER_ID_PARAMETER); | |||||
if (StringUtils.isBlank(userId)) { | |||||
throw new BadCredentialsException("用户id 不能为空"); | |||||
} | |||||
userId = trim(userId); | |||||
try { | |||||
AgentAuthToken authRequest = new AgentAuthToken(userId, userId); | |||||
// 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, AgentAuthToken authRequest) { | |||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | |||||
} | |||||
private String trim(String trimStr) { | |||||
if (StringUtils.isNotBlank(trimStr)) { | |||||
return trimStr.trim(); | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.agent; | |||||
import org.springframework.security.authentication.AuthenticationProvider; | |||||
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; | |||||
/** | |||||
* @Author LiuXinXin | |||||
* @Date 2020/8/3 8:55 下午 | |||||
* @Version 1.0 | |||||
**/ | |||||
public class AgentAuthProvider implements AuthenticationProvider { | |||||
private UserDetailsService userDetailsService; | |||||
@Override | |||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException { | |||||
if (!(authentication instanceof AgentAuthToken)) { | |||||
throw new RuntimeException("CustomAuthProvider 只支持 CustomAuthToken"); | |||||
} | |||||
AgentAuthToken authenticationToken = (AgentAuthToken) authentication; | |||||
String principal = (String) authenticationToken.getPrincipal(); | |||||
UserDetails user = userDetailsService.loadUserByUsername(principal); | |||||
// 将用户定义的user放入token中,这样可以在session中查询到所有自定义的用户信息 | |||||
return new AgentAuthToken(user, user.getPassword(), user.getAuthorities()); | |||||
} | |||||
@Override | |||||
public boolean supports(Class<?> authentication) { | |||||
return AgentAuthToken.class.isAssignableFrom(authentication); | |||||
} | |||||
public void setUserDetailsService(UserDetailsService userDetailsService) { | |||||
this.userDetailsService = userDetailsService; | |||||
} | |||||
} |
@@ -0,0 +1,55 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.agent; | |||||
import com.ningdatech.pmapi.user.security.auth.AuthProperties; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.beans.factory.annotation.Qualifier; | |||||
import org.springframework.security.authentication.AuthenticationManager; | |||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter; | |||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | |||||
import org.springframework.security.core.userdetails.UserDetailsService; | |||||
import org.springframework.security.web.DefaultSecurityFilterChain; | |||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler; | |||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; | |||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | |||||
import org.springframework.stereotype.Component; | |||||
/** | |||||
* 账号密码登陆的认证配置 | |||||
*/ | |||||
@Component | |||||
public class AgentAuthSecurityConfig | |||||
extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> { | |||||
@Autowired | |||||
@Qualifier(value = "defaultLoginSuccessHandler") | |||||
protected AuthenticationSuccessHandler defaultLoginSuccessHandler; | |||||
@Autowired | |||||
@Qualifier(value = "defaultLoginFailureHandler") | |||||
protected AuthenticationFailureHandler defaultLoginFailureHandler; | |||||
@Autowired | |||||
@Qualifier(value = "agentLoginUserDetailService") | |||||
private UserDetailsService agentLoginUserDetailService; | |||||
@Autowired | |||||
private AuthProperties authProperties; | |||||
private AuthenticationManager authenticationManager; | |||||
@Override | |||||
public void configure(HttpSecurity http) throws Exception { | |||||
AgentAuthFilter agentAuthFilter = | |||||
new AgentAuthFilter(authProperties.getAgentLoginUrl()); | |||||
authenticationManager = http.getSharedObject(AuthenticationManager.class); | |||||
agentAuthFilter.setAuthenticationManager(authenticationManager); | |||||
agentAuthFilter.setAuthenticationSuccessHandler(defaultLoginSuccessHandler); | |||||
agentAuthFilter.setAuthenticationFailureHandler(defaultLoginFailureHandler); | |||||
AgentAuthProvider authenticationProvider = new AgentAuthProvider(); | |||||
authenticationProvider.setUserDetailsService(agentLoginUserDetailService); | |||||
http.authenticationProvider(authenticationProvider).addFilterAfter(agentAuthFilter, | |||||
UsernamePasswordAuthenticationFilter.class); | |||||
} | |||||
} |
@@ -0,0 +1,76 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.agent; | |||||
import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | |||||
import org.springframework.security.authentication.AbstractAuthenticationToken; | |||||
import org.springframework.security.core.GrantedAuthority; | |||||
import org.springframework.security.core.SpringSecurityCoreVersion; | |||||
import java.util.Collection; | |||||
/** | |||||
* @Author LiuXinXin | |||||
* @Date 2020/8/3 8:52 下午 | |||||
* @Version 1.0 | |||||
**/ | |||||
public class AgentAuthToken extends AbstractAuthenticationToken { | |||||
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; | |||||
private final Object principal; | |||||
private final Object credentials; | |||||
/** | |||||
* This constructor can be safely used by any code that wishes to create a | |||||
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()} will return | |||||
* <code>false</code>. | |||||
*/ | |||||
public AgentAuthToken(String principal, String credentials) { | |||||
super(null); | |||||
this.principal = principal; | |||||
this.credentials = credentials; | |||||
setAuthenticated(false); | |||||
} | |||||
/** | |||||
* This constructor should only be used by <code>AuthenticationManager</code> or <code>AuthenticationProvider</code> | |||||
* implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>) | |||||
* authentication token. | |||||
* | |||||
* @param principal | |||||
* @param authorities | |||||
*/ | |||||
public AgentAuthToken(Object principal, Object credentials, | |||||
Collection<? extends GrantedAuthority> authorities) { | |||||
super(authorities); | |||||
this.principal = principal; | |||||
this.credentials = credentials; | |||||
// must use super, as we override | |||||
super.setAuthenticated(true); | |||||
} | |||||
@Override | |||||
public Object getCredentials() { | |||||
return this.credentials; | |||||
} | |||||
@Override | |||||
public Object getPrincipal() { | |||||
return this.principal; | |||||
} | |||||
@Override | |||||
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { | |||||
if (isAuthenticated) { | |||||
throw new IllegalArgumentException( | |||||
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); | |||||
} | |||||
super.setAuthenticated(false); | |||||
} | |||||
@Override | |||||
public void eraseCredentials() { | |||||
super.eraseCredentials(); | |||||
} | |||||
} |
@@ -0,0 +1,48 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.agent; | |||||
import com.ningdatech.pmapi.user.manage.UserAuthLoginManage; | |||||
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("agentLoginUserDetailService") | |||||
@RequiredArgsConstructor | |||||
public class AgentLoginUserDetailService implements UserDetailsService { | |||||
private final UserAuthLoginManage userAuthLoginManage; | |||||
@Override | |||||
public UserInfoDetails loadUserByUsername(String username) throws UsernameNotFoundException { | |||||
final Long userId = Long.parseLong(username); | |||||
UserFullInfoDTO userFullInfoDTO = userAuthLoginManage.getUserFullInfo(userId); | |||||
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.setUserRoleList(userFullInfoDTO.getUserRoleList()); | |||||
userInfoDetails.setRegionCode(userFullInfoDTO.getRegionCode()); | |||||
userInfoDetails.setIdentifier(userFullInfoDTO.getIdentifier()); | |||||
userInfoDetails.setPassword(userFullInfoDTO.getCredential()); | |||||
userInfoDetails.setOrganizationCode(userFullInfoDTO.getOrganizationCode()); | |||||
userInfoDetails.setOrganizationName(userFullInfoDTO.getOrganizationName()); | |||||
return userInfoDetails; | |||||
} | |||||
} |
@@ -29,7 +29,7 @@ public class DefaultLoginSuccessHandler extends SavedRequestAwareAuthenticationS | |||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, | ||||
Authentication authentication) throws IOException { | Authentication authentication) throws IOException { | ||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE); | response.setContentType(MediaType.APPLICATION_JSON_VALUE); | ||||
response.getWriter().write(objectMapper.writeValueAsString(ApiResponse.ofSuccess())); | |||||
response.getWriter().write(objectMapper.writeValueAsString(ApiResponse.ofMessage(ApiResponse.SUCCESS_MSG))); | |||||
} | } | ||||
} | } |
@@ -3,6 +3,7 @@ security: | |||||
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-login-url: /api/v1/user/auth/login | ||||
agent-login-url: /api/v1/user/auth/agent-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 | ||||