From d3770993ceb6055feb3c06a8c7bcd63aaeae4bf0 Mon Sep 17 00:00:00 2001 From: PIG AI Date: Mon, 30 Jun 2025 13:22:19 +0800 Subject: [PATCH] refactor(user): update user information retrieval to use UserDTO and improve method documentation --- .../service/impl/AppMobileServiceImpl.java | 13 +- .../app/service/impl/AppUserServiceImpl.java | 199 +++++++++++----- .../endpoint/CaptchaCacheServiceProvider.java | 16 +- .../pigx/auth/endpoint/ImageCodeEndpoint.java | 9 +- .../pigx/auth/endpoint/PigxTokenEndpoint.java | 8 +- ...sourceOwnerBaseAuthenticationProvider.java | 2 +- .../support/filter/PasswordDecoderFilter.java | 134 ++++++----- .../support/filter/ValidateCodeFilter.java | 214 +++++++++--------- ...PigxAuthenticationFailureEventHandler.java | 14 +- ...PigxAuthenticationSuccessEventHandler.java | 6 +- ...edisOAuth2AuthorizationConsentService.java | 18 +- .../PigxRedisOAuth2AuthorizationService.java | 51 ++--- .../pigx/admin/api/dto/MessageEmailDTO.java | 5 +- .../pigx/admin/api/dto/SysLogDTO.java | 2 +- .../pigx/admin/api/dto/UserInfo.java | 39 ++-- .../pigx/admin/api/entity/SysDept.java | 4 +- .../api/entity/SysOauthClientDetails.java | 2 +- .../pigx/admin/api/entity/SysPost.java | 4 +- .../pigx/admin/api/entity/SysRole.java | 4 +- .../api/entity/SysSensitiveWordEntity.java | 3 +- .../api/entity/SysSystemConfigEntity.java | 2 +- .../pigx/admin/api/vo/CpUserExcelVo.java | 2 +- .../pigx/admin/api/vo/DeptExcelVO.java | 2 +- .../pigx/admin/api/vo/DingUserExcelVo.java | 8 +- .../pigx/admin/api/vo/PostExcelVO.java | 4 +- .../pigx/admin/api/vo/RoleExcelVO.java | 2 +- .../admin/config/ClientDetailsInitRunner.java | 6 +- .../admin/config/DynamicRouteInitRunner.java | 22 +- .../admin/controller/ConnectController.java | 21 +- .../controller/SysPublicParamController.java | 25 +- .../SysSensitiveWordController.java | 20 +- .../controller/SysSystemInfoController.java | 12 +- .../admin/controller/SysUserController.java | 30 +-- .../pigx/admin/handler/CasLoginHandler.java | 21 +- .../admin/handler/DingTalkLoginHandler.java | 130 ++++++----- .../pigx/admin/handler/GiteeLoginHandler.java | 22 +- .../admin/handler/MiniAppLoginHandler.java | 21 +- .../admin/handler/OscChinaLoginHandler.java | 125 +++++----- .../pigx/admin/handler/SmsLoginHandler.java | 22 +- .../admin/handler/TencentLoginHandler.java | 107 --------- .../admin/handler/WeChatCPLoginHandler.java | 22 +- .../admin/handler/WeChatLoginHandler.java | 22 +- .../pigx/admin/mapper/SysAreaMapper.java | 2 +- .../admin/mapper/SysSensitiveWordMapper.java | 2 +- .../pigx/admin/mapper/SysUserMapper.java | 65 +++--- .../pigx/admin/service/SysUserService.java | 6 +- .../service/impl/SysMessageServiceImpl.java | 10 +- .../impl/SysSensitiveWordServiceImpl.java | 10 +- .../service/impl/SysTenantServiceImpl.java | 14 +- .../service/impl/SysUserServiceImpl.java | 39 ++-- .../main/resources/mapper/SysUserMapper.xml | 32 ++- .../mp/config/WxMpInRedisConfigStorage.java | 29 +-- .../pigx/mp/config/WxMpInitConfigRunner.java | 5 +- .../mp/controller/WxAccountController.java | 14 +- 54 files changed, 810 insertions(+), 813 deletions(-) rename {pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service => pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store}/PigxRedisOAuth2AuthorizationConsentService.java (73%) rename {pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service => pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store}/PigxRedisOAuth2AuthorizationService.java (77%) delete mode 100644 pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/TencentLoginHandler.java diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java index 641404543..18a96639b 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java @@ -27,13 +27,11 @@ import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; -import java.util.concurrent.TimeUnit; - /** * @author lengleng * @date 2018/11/14 @@ -45,8 +43,6 @@ import java.util.concurrent.TimeUnit; @AllArgsConstructor public class AppMobileServiceImpl implements AppMobileService { - private final StringRedisTemplate redisTemplate; - /** * 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端 * @param mobile mobile @@ -54,8 +50,7 @@ public class AppMobileServiceImpl implements AppMobileService { */ @Override public R sendSmsCode(String mobile) { - String codeObj = redisTemplate.opsForValue() - .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile); + String codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile); if (StrUtil.isNotBlank(codeObj)) { log.info("手机号验证码未过期:{},{}", mobile, codeObj); @@ -64,9 +59,7 @@ public class AppMobileServiceImpl implements AppMobileService { String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE)); log.debug("手机号生成验证码成功:{},{}", mobile, code); - redisTemplate.opsForValue() - .set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, - SecurityConstants.CODE_TIME, TimeUnit.SECONDS); + RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME); return R.ok(Boolean.TRUE); } diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java index c4def9ed2..4381f7617 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java @@ -42,6 +42,7 @@ import com.pig4cloud.pigx.common.core.constant.enums.UserTypeEnum; import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.excel.vo.ErrorMessage; import com.pig4cloud.pigx.common.security.service.PigxUser; import com.pig4cloud.pigx.common.security.util.SecurityUtils; @@ -51,7 +52,6 @@ import org.springframework.beans.BeanUtils; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CacheEvict; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -60,10 +60,9 @@ import org.springframework.validation.BindingResult; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; /** - * app用户表 + * app用户表服务实现类 * * @author aeizzz * @date 2022-12-07 09:52:03 @@ -73,156 +72,227 @@ import java.util.stream.Collectors; @Slf4j public class AppUserServiceImpl extends ServiceImpl implements AppUserService { + /** + * 密码编码器,用于密码加密 + */ private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder(); + /** + * 用户角色关联服务 + */ private final AppUserRoleService appUserRoleService; - private final StringRedisTemplate redisTemplate; - + /** + * 角色服务 + */ private final AppRoleService appRoleService; + /** + * 缓存管理器 + */ private final CacheManager cacheManager; + /** - * 更新用户 - * @param userDTO - * @return + * 更新用户信息 + * @param userDTO 用户数据传输对象 + * @return 更新结果 */ @Override @CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username") public Boolean updateUser(AppUserDTO userDTO) { + // 创建用户实体并复制属性 AppUser appUser = new AppUser(); BeanUtils.copyProperties(userDTO, appUser); + + // 如果密码不为空,进行加密处理 if (StrUtil.isNotBlank(userDTO.getPassword())) { appUser.setPassword(ENCODER.encode(userDTO.getPassword())); } + // 更新用户基本信息 this.updateById(appUser); + // 删除用户与角色的关联关系 appUserRoleService.remove(Wrappers.lambdaQuery().eq(AppUserRole::getUserId, appUser.getUserId())); + // 重新建立用户与角色的关联关系 userDTO.getRole().forEach(roleId -> { AppUserRole appUserRole = new AppUserRole(); appUserRole.setRoleId(roleId); appUserRole.setUserId(userDTO.getUserId()); appUserRole.insert(); }); + + // 清除以手机号为key的用户缓存 + AppUser appUserInfo = baseMapper.selectById(userDTO.getUserId()); + cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(appUserInfo.getPhone()); return Boolean.TRUE; } /** * 新增用户 - * @param userDTO - * @return + * @param userDTO 用户数据传输对象 + * @return 保存结果 */ @Override public Boolean saveUser(AppUserDTO userDTO) { + // 创建用户实体并复制属性 AppUser appUser = new AppUser(); BeanUtils.copyProperties(userDTO, appUser); + // 设置删除标志为正常状态 appUser.setDelFlag(CommonConstants.STATUS_NORMAL); + // 对密码进行加密 appUser.setPassword(ENCODER.encode(userDTO.getPassword())); + // 插入用户记录 baseMapper.insert(appUser); - // 如果角色为空,赋默认角色 + + // 如果角色列表不为空,建立用户与角色的关联关系 if (CollUtil.isNotEmpty(userDTO.getRole())) { List userRoleList = userDTO.getRole().stream().map(roleId -> { AppUserRole userRole = new AppUserRole(); userRole.setUserId(appUser.getUserId()); userRole.setRoleId(roleId); return userRole; - }).collect(Collectors.toList()); + }).toList(); + // 批量保存用户角色关联 appUserRoleService.saveBatch(userRoleList); } return Boolean.TRUE; } /** - * 查询全部的用户 - * @param appUser - * @return + * 查询全部用户(用于Excel导出) + * @param appUser 查询条件 + * @return 用户Excel视图对象列表 */ @Override public List listUser(AppUserDTO appUser) { + // 查询所有用户 List appUsers = baseMapper.selectList(null); + // 将用户实体转换为Excel视图对象 List appUserExcelVOS = appUsers.stream().map(item -> { AppUserExcelVO appUserExcelVO = new AppUserExcelVO(); BeanUtils.copyProperties(item, appUserExcelVO); return appUserExcelVO; - }).collect(Collectors.toList()); + }).toList(); return appUserExcelVOS; } + /** + * 分页查询用户(包含角色信息) + * @param page 分页参数 + * @param appUserDTO 查询条件 + * @return 分页结果 + */ @Override public IPage getUsersWithRolePage(Page page, AppUserDTO appUserDTO) { return baseMapper.getUserVosPage(page, appUserDTO); } + /** + * 查询用户详细信息(包含角色和权限) + * @param user 用户对象 + * @return 用户信息对象 + */ @Override public AppUserInfo findUserInfo(AppUser user) { + // 创建用户信息对象 AppUserInfo info = new AppUserInfo(); info.setAppUser(user); - // 设置角色列表 (ID) + + // 设置角色列表(ID数组) List roleIds = appRoleService.findRolesByUserId(user.getUserId()) .stream() .map(AppRole::getRoleId) - .collect(Collectors.toList()); + .toList(); info.setRoles(ArrayUtil.toArray(roleIds, Long.class)); - // 设置权限列表(menu.permission) + // 设置权限列表(暂为空) Set permissions = new HashSet<>(); info.setPermissions(ArrayUtil.toArray(permissions, String.class)); return info; } + /** + * 更新用户个人信息 + * @param userDTO 用户数据传输对象 + * @return 操作结果 + */ @Override - @CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDto.username") - public R updateUserInfo(AppUserDTO userDto) { - // C端客户修改手机号需要判断验证码是否正确 + @CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username") + public R updateUserInfo(AppUserDTO userDTO) { + // 获取当前登录用户 PigxUser user = SecurityUtils.getUser(); - if (UserTypeEnum.TOC.getStatus().equals(user.getUserType()) && StrUtil.isNotBlank(userDto.getPhone())) { - String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT - + userDto.getPhone(); - String codeObj = redisTemplate.opsForValue().get(key); - if (!userDto.getMobileCode().equals(codeObj)) { + // C端客户修改手机号需要验证短信验证码 + if (UserTypeEnum.TOC.getStatus().equals(user.getUserType()) && StrUtil.isNotBlank(userDTO.getPhone())) { + // 构建验证码缓存key + String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + + userDTO.getPhone(); + // 获取缓存中的验证码 + String codeObj = RedisUtils.get(key); + + // 验证码不匹配,返回错误 + if (!userDTO.getMobileCode().equals(codeObj)) { return R.failed("验证码错误"); } } - // 更新密码 - if (StrUtil.isNotBlank(userDto.getPassword())) { - userDto.setPassword(ENCODER.encode(userDto.getPassword())); + // 更新密码(如果提供了新密码) + if (StrUtil.isNotBlank(userDTO.getPassword())) { + userDTO.setPassword(ENCODER.encode(userDTO.getPassword())); } - AppUser appUser = baseMapper.selectById(userDto.getUserId()); - BeanUtils.copyProperties(userDto, appUser); + // 获取原用户信息并更新 + AppUser appUser = baseMapper.selectById(userDTO.getUserId()); + BeanUtils.copyProperties(userDTO, appUser); + + // 清除以手机号为key的用户缓存 + cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(user.getPhone()); return R.ok(this.updateById(appUser)); } + /** + * 根据用户ID查询用户视图对象 + * @param userId 用户ID + * @return 用户视图对象 + */ @Override public AppUserVO selectUserVoById(Long userId) { return baseMapper.getUserVoById(userId); } /** - * 删除user用户同时删除user-role关系表 - * @param ids userIds + * 批量删除用户 + * @param ids 用户ID数组 + * @return 删除结果 */ @Override public Boolean deleteAppUserByIds(Long[] ids) { + // 获取缓存对象 Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS_MINI); + // 清除用户缓存 for (AppUser appUser : baseMapper.selectByIds(CollUtil.toList(ids))) { cache.evict(appUser.getUsername()); } - // 删除用户关联表 + + // 删除用户角色关联关系 this.appUserRoleService .remove(Wrappers.lambdaQuery().in(AppUserRole::getUserId, CollUtil.toList(ids))); + // 删除用户记录 this.removeBatchByIds(CollUtil.toList(ids)); return Boolean.TRUE; - } + /** + * 注册APP用户 + * @param appUser 用户数据传输对象 + * @return 操作结果 + */ @Override public R registerAppUser(AppUserDTO appUser) { + // 检查手机号是否已被注册 List appUserList = baseMapper .selectList(Wrappers.lambdaQuery().eq(AppUser::getPhone, appUser.getPhone())); @@ -230,17 +300,19 @@ public class AppUserServiceImpl extends ServiceImpl impl return R.failed("手机号已注册,请使用验证码直接登录"); } + // 验证短信验证码 String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + appUser.getPhone(); - String codeObj = redisTemplate.opsForValue().get(key); + String codeObj = RedisUtils.get(key); if (!appUser.getMobileCode().equals(codeObj)) { return R.failed("验证码错误"); } + // 创建用户并保存 AppUser app = new AppUser(); BeanUtils.copyProperties(appUser, app); - appUser.setUsername(app.getPhone()); + appUser.setUsername(app.getPhone()); // 默认使用手机号作为用户名 appUser.setDelFlag(CommonConstants.STATUS_NORMAL); appUser.setPassword(ENCODER.encode(appUser.getPassword())); baseMapper.insert(appUser); @@ -248,23 +320,25 @@ public class AppUserServiceImpl extends ServiceImpl impl } /** - * @param excelVOList - * @param bindingResult - * @return + * 导入用户(从Excel导入) + * @param excelVOList Excel数据列表 + * @param bindingResult 数据校验结果 + * @return 导入结果 */ @Override public R importUser(List excelVOList, BindingResult bindingResult) { - // 通用校验获取失败的数据 + // 获取通用校验失败的数据 List errorMessageList = (List) bindingResult.getTarget(); - // 执行数据插入操作 组装 UserDto - for (AppUserExcelVO excel : excelVOList) { - // 个性化校验逻辑 - List userList = this.list(); - List roleList = appRoleService.list(); + // 获取现有用户和角色列表,用于校验 + List userList = this.list(); + List roleList = appRoleService.list(); + // 遍历Excel数据进行处理 + for (AppUserExcelVO excel : excelVOList) { Set errorMsg = new HashSet<>(); - // 校验用户名是否存在 + + // 校验用户名是否已存在 boolean exsitUserName = userList.stream() .anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername())); @@ -272,47 +346,54 @@ public class AppUserServiceImpl extends ServiceImpl impl errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername())); } - // 判断输入的角色名称列表是否合法 + // 校验角色名称是否合法 List roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA); List roleCollList = roleList.stream() .filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name))) - .collect(Collectors.toList()); + .toList(); if (roleCollList.size() != roleNameList.size()) { errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList())); } - // 数据合法情况 + + // 数据合法时执行插入 if (CollUtil.isEmpty(errorMsg)) { insertExcelUser(excel, roleCollList); } else { - // 数据不合法情况 + // 记录不合法数据的错误信息 errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); } - } + // 存在错误信息时返回失败 if (CollUtil.isNotEmpty(errorMessageList)) { return R.failed(errorMessageList); } return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED)); - } + /** + * 插入Excel导入的用户数据 + * @param excel Excel用户数据 + * @param roleCollList 角色列表 + */ private void insertExcelUser(AppUserExcelVO excel, List roleCollList) { + // 创建用户DTO并设置基本信息 AppUserDTO userDTO = new AppUserDTO(); userDTO.setUsername(excel.getUsername()); userDTO.setPhone(excel.getPhone()); userDTO.setNickname(excel.getNickname()); userDTO.setName(excel.getName()); userDTO.setEmail(excel.getEmail()); - // 批量导入初始密码为手机号 + // 批量导入时初始密码设置为手机号 userDTO.setPassword(userDTO.getPhone()); - // 根据角色名称查询角色ID - List roleIdList = roleCollList.stream().map(AppRole::getRoleId).collect(Collectors.toList()); + + // 获取角色ID列表 + List roleIdList = roleCollList.stream().map(AppRole::getRoleId).toList(); userDTO.setRole(roleIdList); - // 插入用户 + + // 保存用户 this.saveUser(userDTO); } - } diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/CaptchaCacheServiceProvider.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/CaptchaCacheServiceProvider.java index 10ba8248d..9f35ddc22 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/CaptchaCacheServiceProvider.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/CaptchaCacheServiceProvider.java @@ -1,10 +1,7 @@ package com.pig4cloud.pigx.auth.endpoint; import com.anji.captcha.service.CaptchaCacheService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.StringRedisTemplate; - -import java.util.concurrent.TimeUnit; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; /** * @author lengleng @@ -16,27 +13,24 @@ public class CaptchaCacheServiceProvider implements CaptchaCacheService { private static final String REDIS = "redis"; - @Autowired - private StringRedisTemplate stringRedisTemplate; - @Override public void set(String key, String value, long expiresInSeconds) { - stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS); + RedisUtils.set(key, value, expiresInSeconds); } @Override public boolean exists(String key) { - return stringRedisTemplate.hasKey(key); + return RedisUtils.hasKey(key); } @Override public void delete(String key) { - stringRedisTemplate.delete(key); + RedisUtils.delete(key); } @Override public String get(String key) { - return stringRedisTemplate.opsForValue().get(key); + return RedisUtils.get(key); } @Override diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/ImageCodeEndpoint.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/ImageCodeEndpoint.java index 5d9126868..f50b9ad13 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/ImageCodeEndpoint.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/ImageCodeEndpoint.java @@ -8,19 +8,17 @@ import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import io.springboot.captcha.ArithmeticCaptcha; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.concurrent.TimeUnit; - /** * 验证码相关的接口 * @@ -36,8 +34,6 @@ public class ImageCodeEndpoint { private static final Integer DEFAULT_IMAGE_HEIGHT = 40; - private final StringRedisTemplate redisTemplate; - /** * 创建图形验证码 */ @@ -53,8 +49,7 @@ public class ImageCodeEndpoint { return; } - redisTemplate.opsForValue() - .set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result, SecurityConstants.CODE_TIME, TimeUnit.SECONDS); + RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result, SecurityConstants.CODE_TIME); // 转换流信息写出 captcha.out(response.getOutputStream()); } diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java index a21a13702..ae057bc36 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java @@ -32,6 +32,7 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.core.util.RetOps; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.common.security.annotation.Inner; import com.pig4cloud.pigx.common.security.util.OAuth2ErrorCodesExpand; @@ -42,7 +43,6 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.CacheManager; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.server.ServletServerHttpResponse; @@ -77,8 +77,6 @@ public class PigxTokenEndpoint { private final RemoteClientDetailsService clientDetailsService; - private final RedisTemplate redisTemplate; - private final RemoteTenantService tenantService; private final CacheManager cacheManager; @@ -213,7 +211,7 @@ public class PigxTokenEndpoint { // 根据是否有username参数选择不同的查询key String searchKey = StrUtil.isNotBlank(username) ? usernameKey : key; - Set keys = redisTemplate.keys(searchKey); + Set keys = RedisUtils.keys(searchKey); // 分页处理 List pages = keys.stream().skip((current - 1) * size).limit(size).toList(); @@ -234,7 +232,7 @@ public class PigxTokenEndpoint { tokenVo.setId(keyParts[5]); tokenVo.setAccessToken(keyParts[5]); // 获取TTL作为过期时间 - Long ttl = redisTemplate.getExpire(keyName); + Long ttl = RedisUtils.getExpire(keyName); // TTL是秒数,转换为过期时间 long expiresAtMillis = System.currentTimeMillis() + (ttl * 1000); String expiresAt = TemporalAccessorUtil.format(java.time.Instant.ofEpochMilli(expiresAtMillis), DatePattern.NORM_DATETIME_PATTERN); diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/base/OAuth2ResourceOwnerBaseAuthenticationProvider.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/base/OAuth2ResourceOwnerBaseAuthenticationProvider.java index 3e747f7de..c5227243a 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/base/OAuth2ResourceOwnerBaseAuthenticationProvider.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/base/OAuth2ResourceOwnerBaseAuthenticationProvider.java @@ -2,8 +2,8 @@ package com.pig4cloud.pigx.auth.support.base; import cn.hutool.core.util.BooleanUtil; import cn.hutool.extra.spring.SpringUtil; +import com.pig4cloud.pigx.auth.support.store.PigxRedisOAuth2AuthorizationService; import com.pig4cloud.pigx.common.core.constant.CommonConstants; -import com.pig4cloud.pigx.common.security.service.PigxRedisOAuth2AuthorizationService; import com.pig4cloud.pigx.common.security.util.OAuth2ErrorCodesExpand; import com.pig4cloud.pigx.common.security.util.ScopeException; import lombok.extern.slf4j.Slf4j; diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/PasswordDecoderFilter.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/PasswordDecoderFilter.java index ef3fbf8d3..59ba72e6a 100755 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/PasswordDecoderFilter.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/PasswordDecoderFilter.java @@ -30,13 +30,13 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.EncFlagTypeEnum; import com.pig4cloud.pigx.common.core.util.RepeatBodyRequestWrapper; import com.pig4cloud.pigx.common.core.util.WebUtils; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -55,85 +55,83 @@ import java.util.Map; @RequiredArgsConstructor public class PasswordDecoderFilter extends OncePerRequestFilter { - private final AuthSecurityConfigProperties authSecurityConfigProperties; + private static final String PASSWORD = "password"; + private static final String KEY_ALGORITHM = "AES"; - private final StringRedisTemplate redisTemplate; + static { + // 关闭hutool 强制关闭Bouncy Castle库的依赖 + SecureUtil.disableBouncyCastle(); + } - private static final String PASSWORD = "password"; + private final AuthSecurityConfigProperties authSecurityConfigProperties; - private static final String KEY_ALGORITHM = "AES"; + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + // 不是登录请求,直接向下执行 + if (!StrUtil.containsAnyIgnoreCase(request.getRequestURI(), SecurityConstants.OAUTH_TOKEN_URL)) { + chain.doFilter(request, response); + return; + } - static { - // 关闭hutool 强制关闭Bouncy Castle库的依赖 - SecureUtil.disableBouncyCastle(); - } + // 2. 刷新token类型,直接向下执行 + String grantType = request.getParameter("grant_type"); + if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) { + chain.doFilter(request, response); + return; + } - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - // 不是登录请求,直接向下执行 - if (!StrUtil.containsAnyIgnoreCase(request.getRequestURI(), SecurityConstants.OAUTH_TOKEN_URL)) { - chain.doFilter(request, response); - return; - } + // 3. 判断客户端是否需要解密,明文传输直接向下执行 + if (!isEncClient(request)) { + chain.doFilter(request, response); + return; + } - // 2. 刷新token类型,直接向下执行 - String grantType = request.getParameter("grant_type"); - if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) { - chain.doFilter(request, response); - return; - } + // 将请求流转换为可多次读取的请求流 + RepeatBodyRequestWrapper requestWrapper = new RepeatBodyRequestWrapper(request); + Map parameterMap = requestWrapper.getParameterMap(); - // 3. 判断客户端是否需要解密,明文传输直接向下执行 - if (!isEncClient(request)) { - chain.doFilter(request, response); - return; } + // 构建前端对应解密AES 因子 + AES aes = new AES(Mode.CFB, Padding.NoPadding, + new SecretKeySpec(authSecurityConfigProperties.getEncodeKey().getBytes(), KEY_ALGORITHM), + new IvParameterSpec(authSecurityConfigProperties.getEncodeKey().getBytes())); - // 将请求流转换为可多次读取的请求流 - RepeatBodyRequestWrapper requestWrapper = new RepeatBodyRequestWrapper(request); - Map parameterMap = requestWrapper.getParameterMap(); + parameterMap.forEach((k, v) -> { + String[] values = parameterMap.get(k); + if (!PASSWORD.equals(k) || ArrayUtil.isEmpty(values)) { + return; + } - // 构建前端对应解密AES 因子 - AES aes = new AES(Mode.CFB, Padding.NoPadding, - new SecretKeySpec(authSecurityConfigProperties.getEncodeKey().getBytes(), KEY_ALGORITHM), - new IvParameterSpec(authSecurityConfigProperties.getEncodeKey().getBytes())); + // 解密密码 + String decryptPassword = aes.decryptStr(values[0]); + parameterMap.put(k, new String[]{decryptPassword}); + }); + chain.doFilter(requestWrapper, response); + } - parameterMap.forEach((k, v) -> { - String[] values = parameterMap.get(k); - if (!PASSWORD.equals(k) || ArrayUtil.isEmpty(values)) { - return; - } + /** + * 根据请求的clientId 查询客户端配置是否是加密传输 + * + * @param request 请求上下文 + * @return true 加密传输 、 false 原文传输 + */ + private boolean isEncClient(HttpServletRequest request) { + String header = request.getHeader(HttpHeaders.AUTHORIZATION); + String clientId = WebUtils.extractClientId(header).orElse(null); + // 获取租户拼接区分租户的key + String tenantId = request.getHeader(CommonConstants.TENANT_ID); + String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId, + CacheConstants.CLIENT_FLAG, clientId); - // 解密密码 - String decryptPassword = aes.decryptStr(values[0]); - parameterMap.put(k, new String[]{decryptPassword}); - }); - chain.doFilter(requestWrapper, response); - } + String val = RedisUtils.get(key); - /** - * 根据请求的clientId 查询客户端配置是否是加密传输 - * - * @param request 请求上下文 - * @return true 加密传输 、 false 原文传输 - */ - private boolean isEncClient(HttpServletRequest request) { - String header = request.getHeader(HttpHeaders.AUTHORIZATION); - String clientId = WebUtils.extractClientId(header).orElse(null); - // 获取租户拼接区分租户的key - String tenantId = request.getHeader(CommonConstants.TENANT_ID); - String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId, - CacheConstants.CLIENT_FLAG, clientId); + // 当配置不存在时,默认需要解密 + if (val == null) { + return true; + } - String val = redisTemplate.opsForValue().get(key); - - // 当配置不存在时,默认需要解密 - if (val == null) { - return true; - } - - JSONObject information = JSONUtil.parseObj(val); - return !StrUtil.equals(EncFlagTypeEnum.NO.getType(), information.getStr(CommonConstants.ENC_FLAG)); - } + JSONObject information = JSONUtil.parseObj(val); + return !StrUtil.equals(EncFlagTypeEnum.NO.getType(), information.getStr(CommonConstants.ENC_FLAG)); + } } diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java index 5995ddaf5..4dba5d9b1 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java @@ -19,13 +19,13 @@ import com.pig4cloud.pigx.common.core.constant.enums.CaptchaFlagTypeEnum; import com.pig4cloud.pigx.common.core.exception.ValidateCodeException; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; import com.pig4cloud.pigx.common.core.util.WebUtils; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.HttpHeaders; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; @@ -45,135 +45,131 @@ import java.io.IOException; @RequiredArgsConstructor public class ValidateCodeFilter extends OncePerRequestFilter { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { - private final StringRedisTemplate redisTemplate; + String requestUrl = request.getServletPath(); + // 不是登录URL 请求直接跳过 + if (!SecurityConstants.OAUTH_TOKEN_URL.equals(requestUrl)) { + filterChain.doFilter(request, response); + return; + } - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { + // 如果登录URL 但是刷新token的请求,直接向下执行 + String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); + if (StrUtil.containsAny(grantType, SecurityConstants.REFRESH_TOKEN)) { + filterChain.doFilter(request, response); + return; + } - String requestUrl = request.getServletPath(); + // mobile模式, 如果请求不包含mobile 参数直接 + String mobile = request.getParameter(SecurityConstants.GRANT_MOBILE); + if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && StrUtil.isBlank(mobile)) { + throw new OAuth2AuthenticationException(SecurityConstants.GRANT_MOBILE); + } - // 不是登录URL 请求直接跳过 - if (!SecurityConstants.OAUTH_TOKEN_URL.equals(requestUrl)) { - filterChain.doFilter(request, response); - return; - } + // mobile模式, 社交登录模式不校验验证码直接跳过 + if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && !StrUtil.contains(mobile, "SMS")) { + filterChain.doFilter(request, response); + return; + } - // 如果登录URL 但是刷新token的请求,直接向下执行 - String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); - if (StrUtil.containsAny(grantType, SecurityConstants.REFRESH_TOKEN)) { - filterChain.doFilter(request, response); - return; - } + // 判断客户端是否跳过检验 + if (!isCheckCaptchaClient(request)) { + filterChain.doFilter(request, response); + return; + } - // mobile模式, 如果请求不包含mobile 参数直接 - String mobile = request.getParameter(SecurityConstants.GRANT_MOBILE); - if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && StrUtil.isBlank(mobile)) { - throw new OAuth2AuthenticationException(SecurityConstants.GRANT_MOBILE); - } + // 校验验证码 1. 客户端开启验证码 2. 短信模式 + try { + checkCode(); + filterChain.doFilter(request, response); + } catch (ValidateCodeException validateCodeException) { + throw new OAuth2AuthenticationException(validateCodeException.getMessage()); + } + } - // mobile模式, 社交登录模式不校验验证码直接跳过 - if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && !StrUtil.contains(mobile, "SMS")) { - filterChain.doFilter(request, response); - return; - } + /** + * 校验验证码 + */ + private void checkCode() throws ValidateCodeException { + HttpServletRequest request = WebUtils.getRequest(); + String code = request.getParameter("code"); - // 判断客户端是否跳过检验 - if (!isCheckCaptchaClient(request)) { - filterChain.doFilter(request, response); - return; - } + if (StrUtil.isBlank(code)) { + throw new ValidateCodeException("验证码不能为空"); + } - // 校验验证码 1. 客户端开启验证码 2. 短信模式 - try { - checkCode(); - filterChain.doFilter(request, response); - } catch (ValidateCodeException validateCodeException) { - throw new OAuth2AuthenticationException(validateCodeException.getMessage()); - } - } + String randomStr = request.getParameter("randomStr"); - /** - * 校验验证码 - */ - private void checkCode() throws ValidateCodeException { - HttpServletRequest request = WebUtils.getRequest(); - String code = request.getParameter("code"); + // https://gitee.com/log4j/pig/issues/IWA0D + String mobile = request.getParameter("mobile"); + if (StrUtil.isNotBlank(mobile)) { + randomStr = mobile; + } - if (StrUtil.isBlank(code)) { - throw new ValidateCodeException("验证码不能为空"); - } + // 若是滑块登录 + if (CommonConstants.IMAGE_CODE_TYPE.equalsIgnoreCase(randomStr)) { + CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class); + CaptchaVO vo = new CaptchaVO(); + vo.setCaptchaVerification(code); + vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE); + if (!captchaService.verification(vo).isSuccess()) { + throw new ValidateCodeException("验证码不能为空"); + } + return; + } - String randomStr = request.getParameter("randomStr"); + String key = CacheConstants.DEFAULT_CODE_KEY + randomStr; + if (!RedisUtils.hasKey(key)) { + throw new ValidateCodeException("验证码不合法"); + } - // https://gitee.com/log4j/pig/issues/IWA0D - String mobile = request.getParameter("mobile"); - if (StrUtil.isNotBlank(mobile)) { - randomStr = mobile; - } + String codeObj = RedisUtils.get(key); - // 若是滑块登录 - if (CommonConstants.IMAGE_CODE_TYPE.equalsIgnoreCase(randomStr)) { - CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class); - CaptchaVO vo = new CaptchaVO(); - vo.setCaptchaVerification(code); - vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE); - if (!captchaService.verification(vo).isSuccess()) { - throw new ValidateCodeException("验证码不能为空"); - } - return; - } + if (codeObj == null) { + throw new ValidateCodeException("验证码不合法"); + } + String saveCode = codeObj; + if (StrUtil.isBlank(saveCode)) { + RedisUtils.delete(key); + throw new ValidateCodeException("验证码不合法"); + } - String key = CacheConstants.DEFAULT_CODE_KEY + randomStr; - if (Boolean.FALSE.equals(redisTemplate.hasKey(key))) { - throw new ValidateCodeException("验证码不合法"); - } + if (!StrUtil.equals(saveCode, code)) { + RedisUtils.delete(key); + throw new ValidateCodeException("验证码不合法"); + } - Object codeObj = redisTemplate.opsForValue().get(key); + RedisUtils.delete(key); + } - if (codeObj == null) { - throw new ValidateCodeException("验证码不合法"); - } + /** + * 是否需要校验客户端,根据client 查询客户端配置 + * + * @param request 请求 + * @return true 需要校验, false 不需要校验 + */ + private boolean isCheckCaptchaClient(HttpServletRequest request) { + String header = request.getHeader(HttpHeaders.AUTHORIZATION); + String clientId = WebUtils.extractClientId(header).orElse(null); + // 获取租户拼接区分租户的key + String tenantId = request.getHeader(CommonConstants.TENANT_ID); + String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId, + CacheConstants.CLIENT_FLAG, clientId); - String saveCode = codeObj.toString(); - if (StrUtil.isBlank(saveCode)) { - redisTemplate.delete(key); - throw new ValidateCodeException("验证码不合法"); - } + String val = RedisUtils.get(key); - if (!StrUtil.equals(saveCode, code)) { - redisTemplate.delete(key); - throw new ValidateCodeException("验证码不合法"); - } + // 当配置不存在时,不用校验 + if (val == null) { + return false; + } - redisTemplate.delete(key); - } + JSONObject information = JSONUtil.parseObj(val); + return !StrUtil.equals(CaptchaFlagTypeEnum.OFF.getType(), information.getStr(CommonConstants.CAPTCHA_FLAG)); + } - /** - * 是否需要校验客户端,根据client 查询客户端配置 - * - * @param request 请求 - * @return true 需要校验, false 不需要校验 - */ - private boolean isCheckCaptchaClient(HttpServletRequest request) { - String header = request.getHeader(HttpHeaders.AUTHORIZATION); - String clientId = WebUtils.extractClientId(header).orElse(null); - // 获取租户拼接区分租户的key - String tenantId = request.getHeader(CommonConstants.TENANT_ID); - String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId, - CacheConstants.CLIENT_FLAG, clientId); - - String val = redisTemplate.opsForValue().get(key); - - // 当配置不存在时,不用校验 - if (val == null) { - return false; - } - - JSONObject information = JSONUtil.parseObj(val); - return !StrUtil.equals(CaptchaFlagTypeEnum.OFF.getType(), information.getStr(CommonConstants.CAPTCHA_FLAG)); - } } diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationFailureEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationFailureEventHandler.java index 56663494e..f564f579d 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationFailureEventHandler.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationFailureEventHandler.java @@ -25,6 +25,7 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.util.KeyStrResolver; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.core.util.WebUtils; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.data.resolver.ParamResolver; import com.pig4cloud.pigx.common.log.event.SysLogEvent; import com.pig4cloud.pigx.common.log.util.LogTypeEnum; @@ -35,7 +36,7 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.RedisCallback; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -48,7 +49,6 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand import org.springframework.stereotype.Component; import java.io.IOException; -import java.util.concurrent.TimeUnit; /** * @author lengleng @@ -61,8 +61,6 @@ public class PigxAuthenticationFailureEventHandler implements AuthenticationFail private static final MappingJackson2HttpMessageConverter errorHttpResponseConverter = new MappingJackson2HttpMessageConverter(); - private final StringRedisTemplate redisTemplate; - private final ApplicationEventPublisher publisher; private final KeyStrResolver tenantKeyStrResolver; @@ -135,11 +133,15 @@ public class PigxAuthenticationFailureEventHandler implements AuthenticationFail private void recordLoginFailureTimes(String username) { String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, username); Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L); - Long times = redisTemplate.opsForValue().increment(key); + + // 使用 RedisUtils 执行原生 Redis 命令进行递增操作 + Long times = RedisUtils.execute((RedisCallback) connection -> + connection.incr(key.getBytes()) + ); // 自动过期时间 Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L); - redisTemplate.expire(key, deltaTime, TimeUnit.HOURS); + RedisUtils.expire(key, deltaTime * 3600); // 转换为秒 if (deltaTimes <= times) { userService.lockUser(username); diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationSuccessEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationSuccessEventHandler.java index 7fd52be27..f354bf77c 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationSuccessEventHandler.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/handler/PigxAuthenticationSuccessEventHandler.java @@ -23,6 +23,7 @@ import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.util.KeyStrResolver; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.log.event.SysLogEvent; import com.pig4cloud.pigx.common.log.util.LogTypeEnum; import com.pig4cloud.pigx.common.log.util.SysLogUtils; @@ -32,7 +33,6 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.security.core.Authentication; @@ -62,8 +62,6 @@ public class PigxAuthenticationSuccessEventHandler implements AuthenticationSucc private static final HttpMessageConverter accessTokenHttpResponseConverter = new OAuth2AccessTokenResponseHttpMessageConverter(); - private final StringRedisTemplate redisTemplate; - private final ApplicationEventPublisher publisher; private final KeyStrResolver tenantKeyStrResolver; @@ -132,7 +130,7 @@ public class PigxAuthenticationSuccessEventHandler implements AuthenticationSucc private void clearLoginFailureTimes(Map map) { String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, MapUtil.getStr(map, SecurityConstants.DETAILS_USERNAME)); - redisTemplate.delete(key); + RedisUtils.delete(key); } private void sendAccessTokenResponse(HttpServletResponse response, Authentication authentication) diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxRedisOAuth2AuthorizationConsentService.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store/PigxRedisOAuth2AuthorizationConsentService.java similarity index 73% rename from pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxRedisOAuth2AuthorizationConsentService.java rename to pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store/PigxRedisOAuth2AuthorizationConsentService.java index 9af1825f5..d2f8f8225 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxRedisOAuth2AuthorizationConsentService.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store/PigxRedisOAuth2AuthorizationConsentService.java @@ -1,41 +1,37 @@ -package com.pig4cloud.pigx.common.security.service; +package com.pig4cloud.pigx.auth.support.store; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import lombok.RequiredArgsConstructor; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; +import org.springframework.stereotype.Service; import org.springframework.util.Assert; -import java.util.concurrent.TimeUnit; - +@Service @RequiredArgsConstructor public class PigxRedisOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService { - private final RedisTemplate redisTemplate; - private final static Long TIMEOUT = 10L; @Override public void save(OAuth2AuthorizationConsent authorizationConsent) { Assert.notNull(authorizationConsent, "authorizationConsent cannot be null"); - redisTemplate.opsForValue() - .set(buildKey(authorizationConsent), authorizationConsent, TIMEOUT, TimeUnit.MINUTES); + RedisUtils.set(buildKey(authorizationConsent), authorizationConsent, TIMEOUT * 60); } @Override public void remove(OAuth2AuthorizationConsent authorizationConsent) { Assert.notNull(authorizationConsent, "authorizationConsent cannot be null"); - redisTemplate.delete(buildKey(authorizationConsent)); + RedisUtils.delete(buildKey(authorizationConsent)); } @Override public OAuth2AuthorizationConsent findById(String registeredClientId, String principalName) { Assert.hasText(registeredClientId, "registeredClientId cannot be empty"); Assert.hasText(principalName, "principalName cannot be empty"); - return (OAuth2AuthorizationConsent) redisTemplate.opsForValue() - .get(buildKey(registeredClientId, principalName)); + return RedisUtils.get(buildKey(registeredClientId, principalName)); } private static String buildKey(String registeredClientId, String principalName) { diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxRedisOAuth2AuthorizationService.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store/PigxRedisOAuth2AuthorizationService.java similarity index 77% rename from pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxRedisOAuth2AuthorizationService.java rename to pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store/PigxRedisOAuth2AuthorizationService.java index 2d26c0205..d3dd201f3 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxRedisOAuth2AuthorizationService.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/store/PigxRedisOAuth2AuthorizationService.java @@ -1,10 +1,10 @@ -package com.pig4cloud.pigx.common.security.service; +package com.pig4cloud.pigx.auth.support.store; import cn.hutool.core.collection.CollUtil; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; +import com.pig4cloud.pigx.common.security.service.PigxUser; import lombok.RequiredArgsConstructor; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.lang.Nullable; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -15,6 +15,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; +import org.springframework.stereotype.Service; import org.springframework.util.Assert; import java.security.Principal; @@ -23,12 +24,14 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.concurrent.TimeUnit; /** + * 基于Redis实现的OAuth2授权服务类,提供授权信息的存储、查询和删除功能 + * * @author lengleng - * @date 2022/5/27 + * @date 2025/06/30 */ +@Service @RequiredArgsConstructor public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationService { @@ -36,8 +39,6 @@ public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationS private static final String AUTHORIZATION = "token"; - private final RedisTemplate redisTemplate; - private static boolean isState(OAuth2Authorization authorization) { return Objects.nonNull(authorization.getAttribute("state")); } @@ -62,9 +63,7 @@ public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationS if (isState(authorization)) { String token = authorization.getAttribute("state"); - redisTemplate.setValueSerializer(RedisSerializer.java()); - redisTemplate.opsForValue() - .set(buildKey(OAuth2ParameterNames.STATE, token), authorization, TIMEOUT, TimeUnit.MINUTES); + RedisUtils.set(buildKey(OAuth2ParameterNames.STATE, token), authorization, TIMEOUT * 60); } if (isCode(authorization)) { @@ -73,28 +72,20 @@ public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationS OAuth2AuthorizationCode authorizationCodeToken = authorizationCode.getToken(); long between = ChronoUnit.MINUTES.between(authorizationCodeToken.getIssuedAt(), authorizationCodeToken.getExpiresAt()); - redisTemplate.setValueSerializer(RedisSerializer.java()); - redisTemplate.opsForValue() - .set(buildKey(OAuth2ParameterNames.CODE, authorizationCodeToken.getTokenValue()), authorization, - between, TimeUnit.MINUTES); + RedisUtils.set(buildKey(OAuth2ParameterNames.CODE, authorizationCodeToken.getTokenValue()), authorization, + (int) (between * 60)); } if (isRefreshToken(authorization)) { OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken(); long between = ChronoUnit.SECONDS.between(refreshToken.getIssuedAt(), refreshToken.getExpiresAt()); - redisTemplate.setValueSerializer(RedisSerializer.java()); - redisTemplate.opsForValue() - .set(buildKey(OAuth2ParameterNames.REFRESH_TOKEN, refreshToken.getTokenValue()), authorization, between, - TimeUnit.SECONDS); + RedisUtils.set(buildKey(OAuth2ParameterNames.REFRESH_TOKEN, refreshToken.getTokenValue()), authorization, (int) between); } if (isAccessToken(authorization)) { OAuth2AccessToken accessToken = authorization.getAccessToken().getToken(); long between = ChronoUnit.SECONDS.between(accessToken.getIssuedAt(), accessToken.getExpiresAt()); - redisTemplate.setValueSerializer(RedisSerializer.java()); - redisTemplate.opsForValue() - .set(buildKey(OAuth2ParameterNames.ACCESS_TOKEN, accessToken.getTokenValue()), authorization, between, - TimeUnit.SECONDS); + RedisUtils.set(buildKey(OAuth2ParameterNames.ACCESS_TOKEN, accessToken.getTokenValue()), authorization, (int) between); UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = authorization.getAttribute(Principal.class.getName()); @@ -102,7 +93,7 @@ public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationS // 扩展记录 access-token 、username 的关系 token::username::admin::tenantId::xxx String tokenUsername = String.format("%s::%s::%s::%s::%s::%s", AUTHORIZATION, SecurityConstants.DETAILS_USERNAME, authorization.getPrincipalName(), authorization.getRegisteredClientId(), pigxUser.getTenantId(), accessToken.getTokenValue()); - redisTemplate.opsForValue().set(tokenUsername, accessToken.getTokenValue(), between, TimeUnit.SECONDS); + RedisUtils.set(tokenUsername, accessToken.getTokenValue(), (int) between); } } } @@ -139,7 +130,7 @@ public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationS keys.add(key); } - redisTemplate.delete(keys); + RedisUtils.delete(keys.toArray(new String[0])); } @Override @@ -152,9 +143,7 @@ public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationS @Nullable public OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType) { Assert.hasText(token, "token cannot be empty"); - redisTemplate.setValueSerializer(RedisSerializer.java()); - return (OAuth2Authorization) redisTemplate.opsForValue() - .get(buildKey(Objects.requireNonNullElse(tokenType, OAuth2TokenType.ACCESS_TOKEN).getValue(), token)); + return RedisUtils.get(buildKey(Objects.requireNonNullElse(tokenType, OAuth2TokenType.ACCESS_TOKEN).getValue(), token)); } private String buildKey(String type, String id) { @@ -173,16 +162,16 @@ public class PigxRedisOAuth2AuthorizationService implements OAuth2AuthorizationS // 扩展记录 access-token 、username 的关系 1::token::username::admin::xxx String tokenUsernameKey = String.format("%s::%s::%s::*", AUTHORIZATION, SecurityConstants.DETAILS_USERNAME, authenticationName); - Set keys = redisTemplate.keys(tokenUsernameKey); + Set keys = RedisUtils.keys(tokenUsernameKey); if (CollUtil.isEmpty(keys)) { return; } - List tokenList = redisTemplate.opsForValue().multiGet(keys); + List tokenList = RedisUtils.multiGet(keys.stream().toList()); - for (Object token : tokenList) { + for (String token : tokenList) { // 根据token 查询存储的 OAuth2Authorization - OAuth2Authorization authorization = this.findByToken((String) token, OAuth2TokenType.ACCESS_TOKEN); + OAuth2Authorization authorization = this.findByToken(token, OAuth2TokenType.ACCESS_TOKEN); // 根据 OAuth2Authorization 删除相关令牌 this.remove(authorization); } diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/MessageEmailDTO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/MessageEmailDTO.java index 8d4e1fc9d..e6760e3e7 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/MessageEmailDTO.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/MessageEmailDTO.java @@ -5,7 +5,10 @@ import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.experimental.FieldNameConstants; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 短信发送 diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java index 275a81b0e..54f45bc31 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java @@ -1,9 +1,9 @@ package com.pig4cloud.pigx.admin.api.dto; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; import lombok.Data; -import jakarta.validation.constraints.NotBlank; import java.time.LocalDateTime; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/UserInfo.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/UserInfo.java index cb00fd84d..1e17dfa84 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/UserInfo.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/UserInfo.java @@ -19,42 +19,43 @@ package com.pig4cloud.pigx.admin.api.dto; -import com.pig4cloud.pigx.admin.api.entity.SysUser; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.pig4cloud.pigx.admin.api.vo.UserVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; /** + * Spring Security 用户信息实体类,继承自UserVO并实现Serializable接口 + * * @author lengleng - * @date 2017/11/11 + * @date 2025/06/30 */ @Data @Schema(description = "用户信息") -public class UserInfo implements Serializable { +@EqualsAndHashCode(callSuper = true) +public class UserInfo extends UserVO implements Serializable { /** - * 用户基本信息 + * 密码 */ - @Schema(description = "用户基本信息") - private SysUser sysUser; + @JsonIgnore(value = false) + private String password; + + /** + * 随机盐 + */ + @JsonIgnore(value = false) + private String salt; /** * 权限标识集合 */ @Schema(description = "权限标识集合") - private String[] permissions; - - /** - * 角色集合 - */ - @Schema(description = "角色标识集合") - private Long[] roles; - - /** - * 部门ID - */ - @Schema(description = "用户所属部门id") - private Long deptId; + private List permissions = new ArrayList<>(); } diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java index b0d2405b5..2a63dbd0d 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java @@ -23,11 +23,11 @@ import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.pig4cloud.pigx.common.core.util.TenantTable; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java index 7acc2c1ba..ef920e120 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java @@ -23,10 +23,10 @@ import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.pig4cloud.pigx.common.core.util.TenantTable; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.NotBlank; import java.time.LocalDateTime; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java index 37f08fdbb..a60da91ae 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java @@ -21,11 +21,11 @@ import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.pig4cloud.pigx.common.core.util.TenantTable; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java index ad25fb83f..5d1c28cbe 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java @@ -23,11 +23,11 @@ import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.pig4cloud.pigx.common.core.util.TenantTable; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSensitiveWordEntity.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSensitiveWordEntity.java index d1834ffac..7370fabd1 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSensitiveWordEntity.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSensitiveWordEntity.java @@ -2,10 +2,11 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.pig4cloud.pigx.common.core.util.TenantTable; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -import com.pig4cloud.pigx.common.core.util.TenantTable; + import java.time.LocalDateTime; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSystemConfigEntity.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSystemConfigEntity.java index 13e3174c1..65dab12c6 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSystemConfigEntity.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSystemConfigEntity.java @@ -2,10 +2,10 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.pig4cloud.pigx.common.core.util.TenantTable; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -import com.pig4cloud.pigx.common.core.util.TenantTable; import lombok.experimental.FieldNameConstants; import java.time.LocalDateTime; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/CpUserExcelVo.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/CpUserExcelVo.java index 4fbe6351d..b46a680a3 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/CpUserExcelVo.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/CpUserExcelVo.java @@ -3,9 +3,9 @@ package com.pig4cloud.pigx.admin.api.vo; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.pig4cloud.pigx.common.excel.annotation.ExcelLine; +import jakarta.validation.constraints.NotBlank; import lombok.Data; -import jakarta.validation.constraints.NotBlank; import java.io.Serializable; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DeptExcelVO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DeptExcelVO.java index ef4e8ce2a..02f989d80 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DeptExcelVO.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DeptExcelVO.java @@ -3,9 +3,9 @@ package com.pig4cloud.pigx.admin.api.vo; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.pig4cloud.pigx.common.excel.annotation.ExcelLine; +import jakarta.validation.constraints.NotBlank; import lombok.Data; -import jakarta.validation.constraints.NotBlank; import java.io.Serializable; /** diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DingUserExcelVo.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DingUserExcelVo.java index 2506d9a26..155876899 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DingUserExcelVo.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/DingUserExcelVo.java @@ -3,11 +3,17 @@ package com.pig4cloud.pigx.admin.api.vo; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.pig4cloud.pigx.common.excel.annotation.ExcelLine; +import jakarta.validation.constraints.NotBlank; import lombok.Data; -import jakarta.validation.constraints.NotBlank; import java.io.Serializable; +/** + * 钉钉用户Excel导入导出VO + * + * @author lengleng + * @date 2025/06/30 + */ @Data public class DingUserExcelVo implements Serializable { diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java index a618d4d42..480af3c88 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java @@ -4,10 +4,10 @@ import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.pig4cloud.pigx.common.excel.annotation.ExcelLine; -import lombok.Data; - import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import lombok.Data; + import java.io.Serializable; import java.time.LocalDateTime; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/RoleExcelVO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/RoleExcelVO.java index 5dd720b81..06a7ef67d 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/RoleExcelVO.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/RoleExcelVO.java @@ -4,9 +4,9 @@ import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.pig4cloud.pigx.common.excel.annotation.ExcelLine; +import jakarta.validation.constraints.NotBlank; import lombok.Data; -import jakarta.validation.constraints.NotBlank; import java.io.Serializable; import java.time.LocalDateTime; diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/ClientDetailsInitRunner.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/ClientDetailsInitRunner.java index 776c0f5f7..f6060d14f 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/ClientDetailsInitRunner.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/ClientDetailsInitRunner.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil; import com.pig4cloud.pigx.admin.service.SysOauthClientDetailsService; import com.pig4cloud.pigx.admin.service.SysTenantService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.data.tenant.TenantBroker; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -12,7 +13,6 @@ import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.event.EventListener; import org.springframework.core.annotation.Order; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.scheduling.annotation.Async; @@ -37,8 +37,6 @@ public class ClientDetailsInitRunner implements InitializingBean { private final SysTenantService tenantService; - private final StringRedisTemplate redisTemplate; - /** * WebServerInitializedEvent 使用 TransactionalEventListener 时启动时无法获取到事件 */ @@ -65,7 +63,7 @@ public class ClientDetailsInitRunner implements InitializingBean { // 3. 拼接key 1:client_config_flag:clinetId String key = String.format("%s:%s:%s", tenantId, CacheConstants.CLIENT_FLAG, client.getClientId()); // 4. hashkey clientId 保存客户端信息 - redisTemplate.opsForValue().set(key, client.getAdditionalInformation()); + RedisUtils.set(key, client.getAdditionalInformation()); }); }); }); diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java index 56c9e0440..745585c41 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java @@ -21,6 +21,7 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; import com.pig4cloud.pigx.admin.service.SysRouteConfService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.gateway.support.DynamicRouteInitEvent; import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo; import lombok.RequiredArgsConstructor; @@ -33,11 +34,9 @@ import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; import org.springframework.core.annotation.Order; -import org.springframework.data.redis.core.HashOperations; -import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; -import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.scheduling.annotation.Async; import org.springframework.transaction.event.TransactionalEventListener; @@ -45,10 +44,10 @@ import java.net.URI; import java.util.Map; /** + * 动态路由初始化运行器:容器启动后保存配置文件里面的路由信息到Redis + * * @author lengleng * @date 2018/10/31 - *

- * 容器启动后保存配置文件里面的路由信息到Redis */ @Slf4j @Configuration @@ -56,8 +55,6 @@ import java.util.Map; @ConditionalOnDiscoveryEnabled public class DynamicRouteInitRunner implements InitializingBean { - private final RedisTemplate redisTemplate; - private final SysRouteConfService routeConfService; private final RedisMessageListenerContainer listenerContainer; @@ -76,7 +73,7 @@ public class DynamicRouteInitRunner implements InitializingBean { @Order @TransactionalEventListener({DynamicRouteInitEvent.class}) public void initRoute() { - redisTemplate.delete(CacheConstants.ROUTE_KEY); + RedisUtils.delete(CacheConstants.ROUTE_KEY); log.info("开始初始化网关路由"); routeConfService.list().forEach(route -> { @@ -93,13 +90,14 @@ public class DynamicRouteInitRunner implements InitializingBean { vo.setMetadata(JSONUtil.toBean(route.getMetadata(), Map.class)); log.info("加载路由ID:{},{}", route.getRouteId(), vo); - redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class)); - HashOperations stringStringValueOperations = redisTemplate.opsForHash(); - stringStringValueOperations.put(CacheConstants.ROUTE_KEY, route.getRouteId(), vo); + RedisUtils.hset(CacheConstants.ROUTE_KEY, route.getRouteId(), vo); }); // 通知网关重置路由 - redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "路由信息,网关缓存更新"); + RedisUtils.execute((RedisCallback) connection -> { + connection.publish(CacheConstants.ROUTE_JVM_RELOAD_TOPIC.getBytes(), "路由信息,网关缓存更新".getBytes()); + return null; + }); log.debug("初始化网关路由结束 "); } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/ConnectController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/ConnectController.java index 3f8645f4b..803fbbf69 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/ConnectController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/ConnectController.java @@ -31,8 +31,9 @@ public class ConnectController { private final SysDeptService deptService; /** - * 同步钉钉用户 - * @return + * 同步钉钉用户信息 + * + * @return 操作结果 */ @PostMapping("/sync/ding/user") @HasPermission("sys_connect_sync") @@ -44,8 +45,10 @@ public class ConnectController { } /** - * 同步钉钉部门 - * @return + * 同步钉钉部门信息 + * + * @return 同步操作结果 + * @see R */ @PostMapping("/sync/ding/dept") @HasPermission("sys_connect_sync") @@ -54,8 +57,9 @@ public class ConnectController { } /** - * 同步企微用户 - * @return + * 同步企业微信用户信息 + * + * @return 同步操作结果 */ @PostMapping("/sync/cp/user") @HasPermission("sys_connect_sync") @@ -64,8 +68,9 @@ public class ConnectController { } /** - * 同步企微部门 - * @return + * 同步企业微信部门信息 + * + * @return 包含同步结果的响应对象 */ @PostMapping("/sync/cp/dept") @HasPermission("sys_connect_sync") diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java index db069c6d8..0215ffd99 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java @@ -17,19 +17,9 @@ package com.pig4cloud.pigx.admin.controller; -import java.util.List; - -import org.springdoc.core.annotations.ParameterObject; -import org.springframework.http.HttpHeaders; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -40,14 +30,15 @@ import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel; import com.pig4cloud.pigx.common.log.annotation.SysLog; import com.pig4cloud.pigx.common.security.annotation.HasPermission; import com.pig4cloud.pigx.common.security.annotation.Inner; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.StrUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.*; + +import java.util.List; /** * 公共参数 diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSensitiveWordController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSensitiveWordController.java index 84a6a8298..22bc041cb 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSensitiveWordController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSensitiveWordController.java @@ -10,6 +10,7 @@ import com.pig4cloud.pigx.admin.api.entity.SysSensitiveWordEntity; import com.pig4cloud.pigx.admin.service.SysSensitiveWordService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel; import com.pig4cloud.pigx.common.log.annotation.SysLog; import com.pig4cloud.pigx.common.security.annotation.HasPermission; @@ -19,7 +20,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springdoc.core.annotations.ParameterObject; -import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.RedisCallback; import org.springframework.http.HttpHeaders; import org.springframework.web.bind.annotation.*; @@ -40,8 +41,6 @@ public class SysSensitiveWordController { private final SysSensitiveWordService sysSensitiveWordService; - private final RedisTemplate redisTemplate; - /** * 分页查询 * @@ -107,7 +106,10 @@ public class SysSensitiveWordController { @HasPermission("admin_sysSensitiveWord_edit") public R updateById(@RequestBody SysSensitiveWordEntity sysSensitiveWord) { sysSensitiveWordService.updateById(sysSensitiveWord); - redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存"); + RedisUtils.execute((RedisCallback) connection -> { + connection.publish(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC.getBytes(), "刷新敏感词缓存".getBytes()); + return null; + }); return R.ok(); } @@ -137,7 +139,10 @@ public class SysSensitiveWordController { @HasPermission("admin_sysSensitiveWord_del") public R removeById(@RequestBody Long[] ids) { sysSensitiveWordService.removeBatchByIds(CollUtil.toList(ids)); - redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存"); + RedisUtils.execute((RedisCallback) connection -> { + connection.publish(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC.getBytes(), "刷新敏感词缓存".getBytes()); + return null; + }); return R.ok(); } @@ -165,7 +170,10 @@ public class SysSensitiveWordController { @GetMapping("/refresh") @HasPermission("admin_sysSensitiveWord_del") public R refresh() { - redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存"); + RedisUtils.execute((RedisCallback) connection -> { + connection.publish(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC.getBytes(), "刷新敏感词缓存".getBytes()); + return null; + }); return R.ok(); } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java index bfe181b78..1ce1760a7 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java @@ -1,13 +1,13 @@ package com.pig4cloud.pigx.admin.controller; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.data.redis.connection.RedisServerCommands; import org.springframework.data.redis.core.RedisCallback; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpHeaders; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -22,18 +22,16 @@ import java.util.*; @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class SysSystemInfoController { - private final RedisTemplate redisTemplate; - /** * 缓存监控 * @return R */ @GetMapping("/cache") public R cache() { - Properties info = (Properties) redisTemplate.execute((RedisCallback) RedisServerCommands::info); - Properties commandStats = (Properties) redisTemplate - .execute((RedisCallback) connection -> connection.serverCommands().info("commandstats")); - Object dbSize = redisTemplate.execute((RedisCallback) RedisServerCommands::dbSize); + Properties info = RedisUtils.execute((RedisCallback) RedisServerCommands::info); + Properties commandStats = RedisUtils.execute((RedisCallback) + connection -> connection.serverCommands().info("commandstats")); + Object dbSize = RedisUtils.execute((RedisCallback) RedisServerCommands::dbSize); if (commandStats == null) { return R.failed("获取异常"); diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java index 47fc193e7..464943e5b 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java @@ -28,10 +28,7 @@ import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.api.vo.UserExcelVO; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.CommonConstants; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; -import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; -import com.pig4cloud.pigx.common.data.tenant.TenantBroker; import com.pig4cloud.pigx.common.excel.annotation.RequestExcel; import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel; import com.pig4cloud.pigx.common.log.annotation.SysLog; @@ -73,12 +70,9 @@ public class SysUserController { @Inner @GetMapping("/info/{username}") public R info(@PathVariable String username) { - SysUser user = TenantBroker.noneAs(() -> userService.getOne(Wrappers.query().lambda().eq(SysUser::getUsername, username), false)); - if (user == null) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, username)); - } - - return TenantBroker.applyAs(user.getTenantId(), tenantId -> R.ok(userService.findUserInfo(user))); + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(username); + return userService.getUserInfo(userDTO); } /** @@ -89,18 +83,14 @@ public class SysUserController { @GetMapping(value = {"/info"}) public R info() { String username = SecurityUtils.getUser().getUsername(); - SysUser user = TenantBroker.noneAs(() -> userService.getOne(Wrappers.query().lambda().eq(SysUser::getUsername, username), false)); - if (user == null) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR)); + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(username); + // 获取用户信息,不返回数据库密码字段 + R userInfoR = userService.getUserInfo(userDTO); + if (userInfoR.getData() != null) { + userInfoR.getData().setPassword(null); } - - - return TenantBroker.applyAs(user.getTenantId(), tenantId -> { - // UserInfo 是复用对象,不能通过设置 @jsonIgnore 来忽略密码字段 - UserInfo userInfo = userService.findUserInfo(user); - userInfo.getSysUser().setPassword(null); - return R.ok(userInfo); - }); + return userInfoR; } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java index 6c7241be5..7d6d10190 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java @@ -18,13 +18,13 @@ package com.pig4cloud.pigx.admin.handler; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; -import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; +import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -65,19 +65,24 @@ public class CasLoginHandler extends AbstractLoginHandler { } /** - * username 获取用户信息 - * @param username - * @return + * 根据用户名获取用户信息 + * + * @param username 用户名 + * @return 用户信息对象,如果用户不存在则返回null */ @Override public UserInfo info(String username) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getUsername, username)); + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(username); - if (user == null) { + R userInfoR = sysUserService.getUserInfo(userDTO); + + if (userInfoR.getData() == null) { log.info("CAS 不存在用户:{}", username); return null; } - return sysUserService.findUserInfo(user); + + return userInfoR.getData(); } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java index 5a0cb243f..a331f8aa8 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java @@ -21,13 +21,14 @@ import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; +import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -35,7 +36,7 @@ import org.springframework.stereotype.Component; /** * @author lengleng * @date 2023-10-14 - * + *

* 钉钉登录 */ @Slf4j @@ -43,71 +44,78 @@ import org.springframework.stereotype.Component; @AllArgsConstructor public class DingTalkLoginHandler extends AbstractLoginHandler { - private final SysUserService sysUserService; + private final SysUserService sysUserService; - private final SysSocialDetailsMapper sysSocialDetailsMapper; + private final SysSocialDetailsMapper sysSocialDetailsMapper; - /** - * QQ登录传入code - *

- * 通过code 调用qq 获取唯一标识 - * @param code - * @return - */ - @Override - public String identify(String code) { - SysSocialDetails condition = new SysSocialDetails(); - condition.setType(LoginTypeEnum.DINGTALK.getType()); - SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); + /** + * QQ登录传入code + *

+ * 通过code 调用qq 获取唯一标识 + * + * @param code + * @return + */ + @Override + public String identify(String code) { + SysSocialDetails condition = new SysSocialDetails(); + condition.setType(LoginTypeEnum.DINGTALK.getType()); + SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); - String getAccessTokenUrl = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"; - String accessTokenResult = HttpUtil.post(getAccessTokenUrl, - JSONUtil.createObj() - .set("clientId", socialDetails.getAppId()) - .set("clientSecret", socialDetails.getAppSecret()) - .set("grantType", "authorization_code") - .set("code", code) - .toString()); - log.debug("获取钉钉Token响应报文:{}", accessTokenResult); - String accessToken = JSONUtil.parseObj(accessTokenResult).getStr("accessToken"); - String getUserIdUrl = "https://api.dingtalk.com/v1.0/contact/users/me"; + String getAccessTokenUrl = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"; + String accessTokenResult = HttpUtil.post(getAccessTokenUrl, + JSONUtil.createObj() + .set("clientId", socialDetails.getAppId()) + .set("clientSecret", socialDetails.getAppSecret()) + .set("grantType", "authorization_code") + .set("code", code) + .toString()); + log.debug("获取钉钉Token响应报文:{}", accessTokenResult); + String accessToken = JSONUtil.parseObj(accessTokenResult).getStr("accessToken"); + String getUserIdUrl = "https://api.dingtalk.com/v1.0/contact/users/me"; - String userResult = HttpRequest.get(getUserIdUrl) - .header("x-acs-dingtalk-access-token", accessToken) - .execute() - .body(); - log.debug("获取钉钉UserId响应报文:{}", userResult); - // 企微唯一标识 - return JSONUtil.parseObj(userResult).getStr("openId"); - } + String userResult = HttpRequest.get(getUserIdUrl) + .header("x-acs-dingtalk-access-token", accessToken) + .execute() + .body(); + log.debug("获取钉钉UserId响应报文:{}", userResult); + // 企微唯一标识 + return JSONUtil.parseObj(userResult).getStr("openId"); + } - /** - * openId 获取用户信息 - * @param openId - * @return - */ - @Override - public UserInfo info(String openId) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getWxDingUserid, openId)); + /** + * 根据openId获取用户信息 + * + * @param openId 用户openId + * @return 用户信息,不存在时返回null + */ + @Override + public UserInfo info(String openId) { + UserDTO userDTO = new UserDTO(); + userDTO.setWxDingUserid(openId); - if (user == null) { - log.info("钉钉未绑定:{}", openId); - return null; - } - return sysUserService.findUserInfo(user); - } + R userInfoR = sysUserService.getUserInfo(userDTO); - /** - * 绑定逻辑 - * @param user 用户实体 - * @param identify 渠道返回唯一标识 - * @return - */ - @Override - public Boolean bind(SysUser user, String identify) { - user.setWxDingUserid(identify); - sysUserService.updateById(user); - return true; - } + if (userInfoR.getData() == null) { + log.info("钉钉不存在用户:{}", openId); + return null; + } + + return userInfoR.getData(); + } + + /** + * 绑定逻辑 + * + * @param user 用户实体 + * @param identify 渠道返回唯一标识 + * @return + */ + @Override + public Boolean bind(SysUser user, String identify) { + user.setWxDingUserid(identify); + sysUserService.updateById(user); + return true; + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java index e442d5c88..084ec3c10 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java @@ -22,7 +22,7 @@ import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; import com.pig4cloud.pigx.admin.api.entity.SysUser; @@ -30,6 +30,7 @@ import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; +import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -80,20 +81,25 @@ public class GiteeLoginHandler extends AbstractLoginHandler { } /** - * identify 获取用户信息 - * @param identify identify - * @return + * 根据标识获取用户信息 + * + * @param identify 用户标识 + * @return 用户信息,未找到时返回null */ @Override public UserInfo info(String identify) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getGiteeLogin, identify)); + UserDTO userDTO = new UserDTO(); + userDTO.setGiteeLogin(identify); - if (user == null) { - log.info("码云未绑定:{}", identify); + R userInfoR = sysUserService.getUserInfo(userDTO); + + if (userInfoR.getData() == null) { + log.info("微信 不存在用户:{}", identify); return null; } - return sysUserService.findUserInfo(user); + + return userInfoR.getData(); } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java index 6d7192c80..bc74ae9a6 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java @@ -21,7 +21,7 @@ import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; import com.pig4cloud.pigx.admin.api.entity.SysUser; @@ -30,6 +30,7 @@ import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; import com.pig4cloud.pigx.common.core.exception.CheckedException; +import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -79,20 +80,24 @@ public class MiniAppLoginHandler extends AbstractLoginHandler { } /** - * openId 获取用户信息 + * 根据openId获取用户信息 * - * @param openId - * @return + * @param openId 用户openId + * @return 用户信息对象,未找到时返回null */ @Override public UserInfo info(String openId) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getMiniOpenid, openId)); + UserDTO userDTO = new UserDTO(); + userDTO.setMiniOpenid(openId); - if (user == null) { - log.info("微信小程序未绑定:{}", openId); + R userInfoR = sysUserService.getUserInfo(userDTO); + + if (userInfoR.getData() == null) { + log.info("小程序不存在用户:{}", openId); return null; } - return sysUserService.findUserInfo(user); + + return userInfoR.getData(); } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java index 4e450bb9f..2e4c00b91 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java @@ -21,7 +21,7 @@ import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; import com.pig4cloud.pigx.admin.api.entity.SysUser; @@ -29,6 +29,7 @@ import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; +import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -47,75 +48,81 @@ import java.util.Map; @AllArgsConstructor public class OscChinaLoginHandler extends AbstractLoginHandler { - private final SysSocialDetailsMapper sysSocialDetailsMapper; + private final SysSocialDetailsMapper sysSocialDetailsMapper; - private final SysUserService sysUserService; + private final SysUserService sysUserService; - /** - * 开源中国传入code - *

- * 通过code 调用qq 获取唯一标识 - * @param code - * @return - */ - @Override - public String identify(String code) { - SysSocialDetails condition = new SysSocialDetails(); - condition.setType(LoginTypeEnum.OSC.getType()); - SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); + /** + * 开源中国传入code + *

+ * 通过code 调用qq 获取唯一标识 + * + * @param code + * @return + */ + @Override + public String identify(String code) { + SysSocialDetails condition = new SysSocialDetails(); + condition.setType(LoginTypeEnum.OSC.getType()); + SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); - Map params = new HashMap<>(8); + Map params = new HashMap<>(8); - params.put("client_id", socialDetails.getAppId()); - params.put("client_secret", socialDetails.getAppSecret()); - params.put("grant_type", "authorization_code"); - params.put("redirect_uri", socialDetails.getRedirectUrl()); - params.put("code", code); - params.put("dataType", "json"); + params.put("client_id", socialDetails.getAppId()); + params.put("client_secret", socialDetails.getAppSecret()); + params.put("grant_type", "authorization_code"); + params.put("redirect_uri", socialDetails.getRedirectUrl()); + params.put("code", code); + params.put("dataType", "json"); - String result = HttpUtil.post(SecurityConstants.OSC_AUTHORIZATION_CODE_URL, params); - log.debug("开源中国响应报文:{}", result); + String result = HttpUtil.post(SecurityConstants.OSC_AUTHORIZATION_CODE_URL, params); + log.debug("开源中国响应报文:{}", result); - String accessToken = JSONUtil.parseObj(result).getStr("access_token"); + String accessToken = JSONUtil.parseObj(result).getStr("access_token"); - String url = String.format(SecurityConstants.OSC_USER_INFO_URL, accessToken); - String resp = HttpUtil.get(url); - log.debug("开源中国获取个人信息返回报文{}", resp); + String url = String.format(SecurityConstants.OSC_USER_INFO_URL, accessToken); + String resp = HttpUtil.get(url); + log.debug("开源中国获取个人信息返回报文{}", resp); - JSONObject userInfo = JSONUtil.parseObj(resp); - // 开源中国唯一标识 - String id = userInfo.getStr("id"); - return id; - } + JSONObject userInfo = JSONUtil.parseObj(resp); + // 开源中国唯一标识 + String id = userInfo.getStr("id"); + return id; + } - /** - * identify 获取用户信息 - * @param identify 开源中国表示 - * @return - */ - @Override - public UserInfo info(String identify) { + /** + * 根据开源中国标识获取用户信息 + * + * @param identify 开源中国用户标识 + * @return 用户信息对象,未找到时返回null + */ + @Override + public UserInfo info(String identify) { + UserDTO userDTO = new UserDTO(); + userDTO.setOscId(identify); - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getOscId, identify)); + R userInfoR = sysUserService.getUserInfo(userDTO); - if (user == null) { - log.info("开源中国未绑定:{}", identify); - return null; - } - return sysUserService.findUserInfo(user); - } + if (userInfoR.getData() == null) { + log.info("开源中国 不存在用户:{}", identify); + return null; + } - /** - * 绑定逻辑 - * @param user 用户实体 - * @param identify 渠道返回唯一标识 - * @return - */ - @Override - public Boolean bind(SysUser user, String identify) { - user.setOscId(identify); - sysUserService.updateById(user); - return true; - } + return userInfoR.getData(); + } + + /** + * 绑定逻辑 + * + * @param user 用户实体 + * @param identify 渠道返回唯一标识 + * @return + */ + @Override + public Boolean bind(SysUser user, String identify) { + user.setOscId(identify); + sysUserService.updateById(user); + return true; + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java index 19deb1898..589dbecb6 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java @@ -17,10 +17,11 @@ package com.pig4cloud.pigx.admin.handler; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.service.SysUserService; +import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -47,19 +48,24 @@ public class SmsLoginHandler extends AbstractLoginHandler { } /** - * 通过mobile 获取用户信息 - * @param identify - * @return + * 通过手机号获取用户信息 + * + * @param identify 手机号标识 + * @return 用户信息,未找到时返回null */ @Override public UserInfo info(String identify) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getPhone, identify)); + UserDTO userDTO = new UserDTO(); + userDTO.setPhone(identify); - if (user == null) { - log.info("手机号未注册:{}", identify); + R userInfoR = sysUserService.getUserInfo(userDTO); + + if (userInfoR.getData() == null) { + log.info("手机号 不存在用户:{}", identify); return null; } - return sysUserService.findUserInfo(user); + + return userInfoR.getData(); } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/TencentLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/TencentLoginHandler.java deleted file mode 100644 index 19ea6ec29..000000000 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/TencentLoginHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - */ - -package com.pig4cloud.pigx.admin.handler; - -import cn.hutool.http.HttpUtil; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.pig4cloud.pigx.admin.api.dto.UserInfo; -import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; -import com.pig4cloud.pigx.admin.api.entity.SysUser; -import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper; -import com.pig4cloud.pigx.admin.service.SysUserService; -import com.pig4cloud.pigx.common.core.constant.SecurityConstants; -import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -/** - * @author lengleng - * @date 2018/11/18 - */ -@Slf4j -@Component("QQ") -@AllArgsConstructor -public class TencentLoginHandler extends AbstractLoginHandler { - - private final SysUserService sysUserService; - - private final SysSocialDetailsMapper sysSocialDetailsMapper; - - /** - * QQ登录传入code - *

- * 通过code 调用qq 获取唯一标识 - * @param code - * @return - */ - @Override - public String identify(String code) { - SysSocialDetails condition = new SysSocialDetails(); - condition.setType(LoginTypeEnum.QQ.getType()); - SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); - - String url = String.format(SecurityConstants.QQ_AUTHORIZATION_CODE_URL, socialDetails.getAppId(), - socialDetails.getAppSecret(), code); - String result = HttpUtil.get(url); - log.debug("QQ响应报文:{}", result); - - String accessToken = JSONUtil.parseObj(result).getStr("access_token"); - String userUrl = String.format(SecurityConstants.QQ_USER_INFO_URL, accessToken); - String resp = HttpUtil.get(userUrl); - log.debug("QQ获取个人信息返回报文{}", resp); - - JSONObject userInfo = JSONUtil.parseObj(resp); - // QQ唯一标识 - String openid = userInfo.getStr("openid"); - return openid; - } - - /** - * openId 获取用户信息 - * @param openId - * @return - */ - @Override - public UserInfo info(String openId) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getQqOpenid, openId)); - - if (user == null) { - log.info("QQ未绑定:{}", openId); - return null; - } - return sysUserService.findUserInfo(user); - } - - /** - * 绑定逻辑 - * @param user 用户实体 - * @param identify 渠道返回唯一标识 - * @return - */ - @Override - public Boolean bind(SysUser user, String identify) { - user.setQqOpenid(identify); - sysUserService.updateById(user); - return true; - } - -} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java index 855c578ca..dd3b743d4 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java @@ -20,14 +20,14 @@ package com.pig4cloud.pigx.admin.handler; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; -import lombok.AllArgsConstructor; +import com.pig4cloud.pigx.common.core.util.R; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -75,20 +75,24 @@ public class WeChatCPLoginHandler extends AbstractLoginHandler { } /** - * openId 获取用户信息 + * 根据openId获取用户信息 * - * @param openId - * @return + * @param openId 用户openId + * @return 用户信息对象,未找到时返回null */ @Override public UserInfo info(String openId) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getWxCpUserid, openId)); + UserDTO userDTO = new UserDTO(); + userDTO.setWxCpUserid(openId); - if (user == null) { - log.info("企业微信未绑定:{}", openId); + R userInfoR = sysUserService.getUserInfo(userDTO); + + if (userInfoR.getData() == null) { + log.info("企业微信 不存在用户:{}", openId); return null; } - return sysUserService.findUserInfo(user); + + return userInfoR.getData(); } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java index c661f0d42..aa19da01b 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java @@ -20,7 +20,7 @@ package com.pig4cloud.pigx.admin.handler; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; import com.pig4cloud.pigx.admin.api.entity.SysUser; @@ -28,6 +28,7 @@ import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; +import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -68,19 +69,24 @@ public class WeChatLoginHandler extends AbstractLoginHandler { } /** - * openId 获取用户信息 - * @param openId - * @return + * 根据微信openId获取用户信息 + * + * @param openId 微信openId + * @return 用户信息,未找到时返回null */ @Override public UserInfo info(String openId) { - SysUser user = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getWxOpenid, openId)); + UserDTO userDTO = new UserDTO(); + userDTO.setWxOpenid(openId); - if (user == null) { - log.info("微信未绑定:{}", openId); + R userInfoR = sysUserService.getUserInfo(userDTO); + + if (userInfoR.getData() == null) { + log.info("微信 不存在用户:{}", openId); return null; } - return sysUserService.findUserInfo(user); + + return userInfoR.getData(); } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAreaMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAreaMapper.java index 10a703556..a56ea2d7a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAreaMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAreaMapper.java @@ -1,7 +1,7 @@ package com.pig4cloud.pigx.admin.mapper; -import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper; import com.pig4cloud.pigx.admin.api.entity.SysAreaEntity; +import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper; import org.apache.ibatis.annotations.Mapper; @Mapper diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSensitiveWordMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSensitiveWordMapper.java index d479b6e49..47a0e6b21 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSensitiveWordMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSensitiveWordMapper.java @@ -1,7 +1,7 @@ package com.pig4cloud.pigx.admin.mapper; -import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper; import com.pig4cloud.pigx.admin.api.entity.SysSensitiveWordEntity; +import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper; import org.apache.ibatis.annotations.Mapper; @Mapper diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java index 2924e63cf..9297dd60e 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java @@ -19,6 +19,7 @@ package com.pig4cloud.pigx.admin.mapper; +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.admin.api.dto.UserDTO; @@ -32,45 +33,49 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - *

* 用户表 Mapper 接口 - *

* * @author lengleng - * @since 2017-10-29 + * @date 2025/06/30 */ @Mapper public interface SysUserMapper extends PigxBaseMapper { - /** - * 通过用户名查询用户信息(含有角色信息) - * @param username 用户名 - * @return userVo - */ - UserVO getUserVoByUsername(String username); + /** + * 通过用户DTO查询用户信息(包含角色信息) + * + * @param userDTO 用户查询DTO + * @return 包含角色信息的用户VO + */ + @InterceptorIgnore(tenantLine = "true") + UserVO getUserVo(@Param("query") UserDTO userDTO); - /** - * 分页查询用户信息(含角色) - * @param page 分页 - * @param userDTO 查询参数 - * @param dataScope - * @return list - */ - IPage getUserVosPage(Page page, @Param("query") UserDTO userDTO, DataScope dataScope); + /** + * 分页查询用户信息(含角色) + * + * @param page 分页对象 + * @param userDTO 用户查询参数 + * @param dataScope 数据权限范围 + * @return 分页用户信息列表 + */ + IPage getUserVosPage(Page page, @Param("query") UserDTO userDTO, DataScope dataScope); - /** - * 通过ID查询用户信息 - * @param id 用户ID - * @return userVo - */ - UserVO getUserVoById(Long id); + /** + * 通过ID查询用户信息 + * + * @param id 用户ID + * @return 用户信息VO对象 + */ + UserVO getUserVoById(Long id); - /** - * 查询用户列表 - * @param userDTO 查询条件 - * @param dataScope 数据权限声明 - * @return - */ - List selectVoListByScope(@Param("query") UserDTO userDTO, @Param("ids") Long[] ids, DataScope dataScope); + /** + * 根据数据权限查询用户列表 + * + * @param userDTO 查询条件 + * @param ids 用户ID数组 + * @param dataScope 数据权限声明 + * @return 用户VO列表 + */ + List selectVoListByScope(@Param("query") UserDTO userDTO, @Param("ids") Long[] ids, DataScope dataScope); } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java index 4cbe743b1..9a9c13d32 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java @@ -42,10 +42,10 @@ public interface SysUserService extends IService { /** * 查询用户信息 * - * @param sysUser 用户 - * @return userInfo + * @param userDTO 用户数据传输对象 + * @return 用户信息对象 */ - UserInfo findUserInfo(SysUser sysUser); + R getUserInfo(UserDTO userDTO); /** * 分页查询用户信息(含有角色信息) diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java index 69da40c74..604ae0d14 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java @@ -42,6 +42,7 @@ import com.pig4cloud.pigx.common.core.exception.CheckedException; import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.common.file.core.FileTemplate; import com.pig4cloud.pigx.common.log.util.JacksonSensitiveFieldUtil; @@ -76,7 +77,6 @@ import org.dromara.sms4j.unisms.config.UniConfig; import org.dromara.sms4j.yunpian.config.YunpianConfig; import org.dromara.sms4j.zhutong.config.ZhutongConfig; import org.springframework.beans.BeanUtils; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -85,7 +85,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.concurrent.TimeUnit; + /** * 站内信息 @@ -109,8 +109,6 @@ public class SysMessageServiceImpl extends ServiceImpl implements SysSensitiveWordService { - private final RedisTemplate redisTemplate; - /** * 查询敏感词 * @@ -59,7 +58,10 @@ public class SysSensitiveWordServiceImpl extends ServiceImpl) connection -> { + connection.publish(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC.getBytes(), "刷新敏感词缓存".getBytes()); + return null; + }); return Boolean.TRUE; } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java index 503b2a094..eadbe8bb5 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java @@ -33,6 +33,7 @@ import com.pig4cloud.pigx.admin.service.*; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; +import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.data.datascope.DataScopeTypeEnum; import com.pig4cloud.pigx.common.data.resolver.ParamResolver; import com.pig4cloud.pigx.common.data.tenant.TenantBroker; @@ -43,7 +44,6 @@ import lombok.SneakyThrows; import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -54,12 +54,12 @@ import java.time.LocalDateTime; import java.util.*; /** - * 租户 + * 租户服务实现类 *

- * mybatis-plus 3.4.3.3 特殊处理 https://github.com/baomidou/mybatis-plus/pull/3592 + * 提供租户相关的业务逻辑实现,包括租户的增删改查及初始化操作 * * @author lengleng - * @date 2019-05-15 15:55:41 + * @date 2025/06/30 */ @Service @AllArgsConstructor @@ -89,8 +89,6 @@ public class SysTenantServiceImpl extends ServiceImpl @@ -302,9 +300,9 @@ public class SysTenantServiceImpl extends ServiceImpl keys = RedisUtils.keys(String.format("%s:%s::*", tenantDTO.getId(), CacheConstants.MENU_DETAILS)); if (CollUtil.isNotEmpty(keys)) { - redisTemplate.delete(keys); + RedisUtils.delete(keys.toArray(new String[0])); } return Boolean.TRUE; } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java index f9c6e0a77..0793f4eee 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java @@ -20,7 +20,6 @@ package com.pig4cloud.pigx.admin.service.impl; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -165,34 +164,32 @@ public class SysUserServiceImpl extends ServiceImpl impl } /** - * 查询用户全部信息,包括角色和权限 + * 根据用户信息查询用户全部信息,包括角色和权限 * - * @param sysUser 用户信息 + * @param userDTO 用户信息DTO * @return 包含用户角色和权限的用户信息对象 */ @Override - public UserInfo findUserInfo(SysUser sysUser) { - UserInfo userInfo = new UserInfo(); - userInfo.setSysUser(sysUser); + public R getUserInfo(UserDTO userDTO) { + UserVO dbUser = baseMapper.getUserVo(userDTO); + + if (dbUser == null) { + return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, userDTO.getUsername())); + } + // 设置角色列表 (ID) - List roleIds = sysRoleService.findRolesByUserId(sysUser.getUserId()) + UserInfo userInfo = new UserInfo(); + BeanUtils.copyProperties(dbUser, userInfo); + // 设置权限列表(menu.permission) + List permissions = dbUser.getRoleList() .stream() .map(SysRole::getRoleId) + .flatMap(roleId -> sysMenuService.findMenuByRoleId(roleId).stream()) + .filter(menu -> StrUtil.isNotEmpty(menu.getPermission())) + .map(SysMenu::getPermission) .toList(); - userInfo.setRoles(ArrayUtil.toArray(roleIds, Long.class)); - - // 设置权限列表(menu.permission) - Set permissions = new HashSet<>(); - roleIds.forEach(roleId -> { - List permissionList = sysMenuService.findMenuByRoleId(roleId) - .stream() - .filter(menu -> StrUtil.isNotEmpty(menu.getPermission())) - .map(SysMenu::getPermission) - .toList(); - permissions.addAll(permissionList); - }); - userInfo.setPermissions(ArrayUtil.toArray(permissions, String.class)); - return userInfo; + userInfo.setPermissions(permissions); + return R.ok(userInfo); } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml index 843688beb..420dccd1a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml +++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml @@ -25,6 +25,7 @@ + @@ -65,12 +66,35 @@ u.update_time - SELECT - FROM - sys_user u - WHERE u.username = #{username} and u.del_flag = '0' + FROM sys_user u + WHERE u.del_flag = '0' + + AND u.username = #{query.username} + + + AND u.osc_id = #{query.oscId} + + + AND u.phone = #{query.phone} + + + AND u.wx_cp_userid = #{query.wxCpUserid} + + + AND u.wx_ding_userid = #{query.wxDingUserid} + + + AND u.gitee_login = #{query.giteeLogin} + + + AND u.wx_openid = #{query.wxOpenid} + + + AND u.mini_openid = #{query.miniOpenid} +