mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
refactor(user): update user information retrieval to use UserDTO and improve method documentation
This commit is contained in:
1 parent
3a53fb5677
commit
d3770993ce
54 files changed
+810
-813
No files matched your search
+3
-10
@@ -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<Boolean> 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);
|
||||
}
|
||||
|
||||
|
||||
+140
-59
@@ -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<AppUserMapper, AppUser> 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.<AppUserRole>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<AppUserRole> 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<AppUserExcelVO> listUser(AppUserDTO appUser) {
|
||||
// 查询所有用户
|
||||
List<AppUser> appUsers = baseMapper.selectList(null);
|
||||
// 将用户实体转换为Excel视图对象
|
||||
List<AppUserExcelVO> 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<Long> roleIds = appRoleService.findRolesByUserId(user.getUserId())
|
||||
.stream()
|
||||
.map(AppRole::getRoleId)
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
info.setRoles(ArrayUtil.toArray(roleIds, Long.class));
|
||||
|
||||
// 设置权限列表(menu.permission)
|
||||
// 设置权限列表(暂为空)
|
||||
Set<String> 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.<AppUserRole>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<AppUser> appUserList = baseMapper
|
||||
.selectList(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getPhone, appUser.getPhone()));
|
||||
|
||||
@@ -230,17 +300,19 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> 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<AppUserMapper, AppUser> impl
|
||||
}
|
||||
|
||||
/**
|
||||
* @param excelVOList
|
||||
* @param bindingResult
|
||||
* @return
|
||||
* 导入用户(从Excel导入)
|
||||
* @param excelVOList Excel数据列表
|
||||
* @param bindingResult 数据校验结果
|
||||
* @return 导入结果
|
||||
*/
|
||||
@Override
|
||||
public R importUser(List<AppUserExcelVO> excelVOList, BindingResult bindingResult) {
|
||||
// 通用校验获取失败的数据
|
||||
// 获取通用校验失败的数据
|
||||
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
|
||||
|
||||
// 执行数据插入操作 组装 UserDto
|
||||
for (AppUserExcelVO excel : excelVOList) {
|
||||
// 个性化校验逻辑
|
||||
List<AppUser> userList = this.list();
|
||||
List<AppRole> roleList = appRoleService.list();
|
||||
// 获取现有用户和角色列表,用于校验
|
||||
List<AppUser> userList = this.list();
|
||||
List<AppRole> roleList = appRoleService.list();
|
||||
|
||||
// 遍历Excel数据进行处理
|
||||
for (AppUserExcelVO excel : excelVOList) {
|
||||
Set<String> errorMsg = new HashSet<>();
|
||||
// 校验用户名是否存在
|
||||
|
||||
// 校验用户名是否已存在
|
||||
boolean exsitUserName = userList.stream()
|
||||
.anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()));
|
||||
|
||||
@@ -272,47 +346,54 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
|
||||
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
|
||||
}
|
||||
|
||||
// 判断输入的角色名称列表是否合法
|
||||
// 校验角色名称是否合法
|
||||
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
|
||||
List<AppRole> 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<AppRole> 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<Long> roleIdList = roleCollList.stream().map(AppRole::getRoleId).collect(Collectors.toList());
|
||||
|
||||
// 获取角色ID列表
|
||||
List<Long> roleIdList = roleCollList.stream().map(AppRole::getRoleId).toList();
|
||||
userDTO.setRole(roleIdList);
|
||||
// 插入用户
|
||||
|
||||
// 保存用户
|
||||
this.saveUser(userDTO);
|
||||
}
|
||||
|
||||
}
|
||||
+5
-11
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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<String, Object> 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<String> keys = redisTemplate.keys(searchKey);
|
||||
Set<String> keys = RedisUtils.keys(searchKey);
|
||||
|
||||
// 分页处理
|
||||
List<String> 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);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+66
-68
@@ -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<String, String[]> 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<String, String[]> 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));
|
||||
}
|
||||
|
||||
}
|
||||
+105
-109
@@ -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));
|
||||
}
|
||||
}
|
||||
+8
-6
@@ -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<Long>) 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);
|
||||
|
||||
+2
-4
@@ -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<OAuth2AccessTokenResponse> 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<String, Object> 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)
|
||||
|
||||
+7
-11
@@ -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<String, Object> 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) {
|
||||
+20
-31
@@ -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<String, Object> 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<String> keys = redisTemplate.keys(tokenUsernameKey);
|
||||
Set<String> keys = RedisUtils.keys(tokenUsernameKey);
|
||||
if (CollUtil.isEmpty(keys)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Object> tokenList = redisTemplate.opsForValue().multiGet(keys);
|
||||
List<String> 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);
|
||||
}
|
||||
+4
-1
@@ -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;
|
||||
|
||||
/**
|
||||
* 短信发送
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+20
-19
@@ -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<String> permissions = new ArrayList<>();
|
||||
|
||||
}
|
||||
+2
-2
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+7
-1
@@ -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 {
|
||||
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
+2
-4
@@ -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());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+10
-12
@@ -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
|
||||
* <p>
|
||||
* 容器启动后保存配置文件里面的路由信息到Redis
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@@ -56,8 +55,6 @@ import java.util.Map;
|
||||
@ConditionalOnDiscoveryEnabled
|
||||
public class DynamicRouteInitRunner implements InitializingBean {
|
||||
|
||||
private final RedisTemplate<String, String> 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<String, String, RouteDefinitionVo> 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<Void>) connection -> {
|
||||
connection.publish(CacheConstants.ROUTE_JVM_RELOAD_TOPIC.getBytes(), "路由信息,网关缓存更新".getBytes());
|
||||
return null;
|
||||
});
|
||||
log.debug("初始化网关路由结束 ");
|
||||
}
|
||||
|
||||
|
||||
+13
-8
@@ -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")
|
||||
|
||||
+8
-17
@@ -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;
|
||||
|
||||
/**
|
||||
* 公共参数
|
||||
|
||||
+14
-6
@@ -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<String, Object> 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<Void>) 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<Void>) 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<Void>) connection -> {
|
||||
connection.publish(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC.getBytes(), "刷新敏感词缓存".getBytes());
|
||||
return null;
|
||||
});
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
+5
-7
@@ -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<String, String> redisTemplate;
|
||||
|
||||
/**
|
||||
* 缓存监控
|
||||
* @return R<Object>
|
||||
*/
|
||||
@GetMapping("/cache")
|
||||
public R cache() {
|
||||
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) RedisServerCommands::info);
|
||||
Properties commandStats = (Properties) redisTemplate
|
||||
.execute((RedisCallback<Object>) connection -> connection.serverCommands().info("commandstats"));
|
||||
Object dbSize = redisTemplate.execute((RedisCallback<Object>) RedisServerCommands::dbSize);
|
||||
Properties info = RedisUtils.execute((RedisCallback<Properties>) RedisServerCommands::info);
|
||||
Properties commandStats = RedisUtils.execute((RedisCallback<Properties>)
|
||||
connection -> connection.serverCommands().info("commandstats"));
|
||||
Object dbSize = RedisUtils.execute((RedisCallback<Object>) RedisServerCommands::dbSize);
|
||||
|
||||
if (commandStats == null) {
|
||||
return R.failed("获取异常");
|
||||
|
||||
+10
-20
@@ -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.<SysUser>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.<SysUser>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<UserInfo> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+13
-8
@@ -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.<SysUser>query().lambda().eq(SysUser::getUsername, username));
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.setUsername(username);
|
||||
|
||||
if (user == null) {
|
||||
R<UserInfo> userInfoR = sysUserService.getUserInfo(userDTO);
|
||||
|
||||
if (userInfoR.getData() == null) {
|
||||
log.info("CAS 不存在用户:{}", username);
|
||||
return null;
|
||||
}
|
||||
return sysUserService.findUserInfo(user);
|
||||
|
||||
return userInfoR.getData();
|
||||
}
|
||||
|
||||
}
|
||||
+69
-61
@@ -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
|
||||
*
|
||||
* <p>
|
||||
* 钉钉登录
|
||||
*/
|
||||
@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
|
||||
* <p>
|
||||
* 通过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
|
||||
* <p>
|
||||
* 通过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.<SysUser>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<UserInfo> 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;
|
||||
}
|
||||
|
||||
}
|
||||
+14
-8
@@ -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.<SysUser>query().lambda().eq(SysUser::getGiteeLogin, identify));
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.setGiteeLogin(identify);
|
||||
|
||||
if (user == null) {
|
||||
log.info("码云未绑定:{}", identify);
|
||||
R<UserInfo> userInfoR = sysUserService.getUserInfo(userDTO);
|
||||
|
||||
if (userInfoR.getData() == null) {
|
||||
log.info("微信 不存在用户:{}", identify);
|
||||
return null;
|
||||
}
|
||||
return sysUserService.findUserInfo(user);
|
||||
|
||||
return userInfoR.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+13
-8
@@ -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.<SysUser>query().lambda().eq(SysUser::getMiniOpenid, openId));
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.setMiniOpenid(openId);
|
||||
|
||||
if (user == null) {
|
||||
log.info("微信小程序未绑定:{}", openId);
|
||||
R<UserInfo> userInfoR = sysUserService.getUserInfo(userDTO);
|
||||
|
||||
if (userInfoR.getData() == null) {
|
||||
log.info("小程序不存在用户:{}", openId);
|
||||
return null;
|
||||
}
|
||||
return sysUserService.findUserInfo(user);
|
||||
|
||||
return userInfoR.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+66
-59
@@ -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
|
||||
* <p>
|
||||
* 通过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
|
||||
* <p>
|
||||
* 通过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<String, Object> params = new HashMap<>(8);
|
||||
Map<String, Object> 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.<SysUser>query().lambda().eq(SysUser::getOscId, identify));
|
||||
R<UserInfo> 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;
|
||||
}
|
||||
|
||||
}
|
||||
+14
-8
@@ -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.<SysUser>query().lambda().eq(SysUser::getPhone, identify));
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.setPhone(identify);
|
||||
|
||||
if (user == null) {
|
||||
log.info("手机号未注册:{}", identify);
|
||||
R<UserInfo> userInfoR = sysUserService.getUserInfo(userDTO);
|
||||
|
||||
if (userInfoR.getData() == null) {
|
||||
log.info("手机号 不存在用户:{}", identify);
|
||||
return null;
|
||||
}
|
||||
return sysUserService.findUserInfo(user);
|
||||
|
||||
return userInfoR.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-107
@@ -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
|
||||
* <p>
|
||||
* 通过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.<SysUser>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;
|
||||
}
|
||||
|
||||
}
|
||||
+13
-9
@@ -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.<SysUser>query().lambda().eq(SysUser::getWxCpUserid, openId));
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.setWxCpUserid(openId);
|
||||
|
||||
if (user == null) {
|
||||
log.info("企业微信未绑定:{}", openId);
|
||||
R<UserInfo> userInfoR = sysUserService.getUserInfo(userDTO);
|
||||
|
||||
if (userInfoR.getData() == null) {
|
||||
log.info("企业微信 不存在用户:{}", openId);
|
||||
return null;
|
||||
}
|
||||
return sysUserService.findUserInfo(user);
|
||||
|
||||
return userInfoR.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-8
@@ -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.<SysUser>query().lambda().eq(SysUser::getWxOpenid, openId));
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.setWxOpenid(openId);
|
||||
|
||||
if (user == null) {
|
||||
log.info("微信未绑定:{}", openId);
|
||||
R<UserInfo> userInfoR = sysUserService.getUserInfo(userDTO);
|
||||
|
||||
if (userInfoR.getData() == null) {
|
||||
log.info("微信 不存在用户:{}", openId);
|
||||
return null;
|
||||
}
|
||||
return sysUserService.findUserInfo(user);
|
||||
|
||||
return userInfoR.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+35
-30
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author lengleng
|
||||
* @since 2017-10-29
|
||||
* @date 2025/06/30
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysUserMapper extends PigxBaseMapper<SysUser> {
|
||||
|
||||
/**
|
||||
* 通过用户名查询用户信息(含有角色信息)
|
||||
* @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<UserVO> getUserVosPage(Page page, @Param("query") UserDTO userDTO, DataScope dataScope);
|
||||
/**
|
||||
* 分页查询用户信息(含角色)
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param userDTO 用户查询参数
|
||||
* @param dataScope 数据权限范围
|
||||
* @return 分页用户信息列表
|
||||
*/
|
||||
IPage<UserVO> 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<UserVO> selectVoListByScope(@Param("query") UserDTO userDTO, @Param("ids") Long[] ids, DataScope dataScope);
|
||||
/**
|
||||
* 根据数据权限查询用户列表
|
||||
*
|
||||
* @param userDTO 查询条件
|
||||
* @param ids 用户ID数组
|
||||
* @param dataScope 数据权限声明
|
||||
* @return 用户VO列表
|
||||
*/
|
||||
List<UserVO> selectVoListByScope(@Param("query") UserDTO userDTO, @Param("ids") Long[] ids, DataScope dataScope);
|
||||
|
||||
}
|
||||
+3
-3
@@ -42,10 +42,10 @@ public interface SysUserService extends IService<SysUser> {
|
||||
/**
|
||||
* 查询用户信息
|
||||
*
|
||||
* @param sysUser 用户
|
||||
* @return userInfo
|
||||
* @param userDTO 用户数据传输对象
|
||||
* @return 用户信息对象
|
||||
*/
|
||||
UserInfo findUserInfo(SysUser sysUser);
|
||||
R<UserInfo> getUserInfo(UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* 分页查询用户信息(含有角色信息)
|
||||
|
||||
+4
-6
@@ -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<SysMessageMapper, SysMess
|
||||
|
||||
private final SysMessageRelationMapper relationMapper;
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
private final SysUserMapper userMapper;
|
||||
|
||||
private final SysFileMapper fileMapper;
|
||||
@@ -259,7 +257,7 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
|
||||
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
|
||||
}
|
||||
|
||||
String codeObj = redisTemplate.opsForValue().get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile);
|
||||
String codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile);
|
||||
|
||||
if (StrUtil.isNotBlank(codeObj)) {
|
||||
log.info("手机号验证码未过期:{},{}", mobile, codeObj);
|
||||
@@ -268,7 +266,7 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
|
||||
|
||||
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
|
||||
log.info("手机号生成验证码成功:{},{}", mobile, code);
|
||||
redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
|
||||
RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME);
|
||||
|
||||
// 发送
|
||||
return this.sendSms(MessageSmsDTO.builder().mobile(mobile).biz(SmsBizCodeEnum.SMS_NORMAL_CODE.getCode()).param(code).build());
|
||||
|
||||
+6
-4
@@ -9,8 +9,9 @@ import com.pig4cloud.pigx.admin.api.entity.SysSensitiveWordEntity;
|
||||
import com.pig4cloud.pigx.admin.mapper.SysSensitiveWordMapper;
|
||||
import com.pig4cloud.pigx.admin.service.SysSensitiveWordService;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@@ -25,8 +26,6 @@ import java.util.List;
|
||||
@RequiredArgsConstructor
|
||||
public class SysSensitiveWordServiceImpl extends ServiceImpl<SysSensitiveWordMapper, SysSensitiveWordEntity> implements SysSensitiveWordService {
|
||||
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 查询敏感词
|
||||
*
|
||||
@@ -59,7 +58,10 @@ public class SysSensitiveWordServiceImpl extends ServiceImpl<SysSensitiveWordMap
|
||||
});
|
||||
}
|
||||
|
||||
redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存");
|
||||
RedisUtils.execute((RedisCallback<Void>) connection -> {
|
||||
connection.publish(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC.getBytes(), "刷新敏感词缓存".getBytes());
|
||||
return null;
|
||||
});
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -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.*;
|
||||
|
||||
/**
|
||||
* 租户
|
||||
* 租户服务实现类
|
||||
* <p>
|
||||
* 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<SysTenantMapper, SysTenant
|
||||
|
||||
private final SysTenantUserMapper tenantUserMapper;
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 获取正常状态租户
|
||||
* <p>
|
||||
@@ -302,9 +300,9 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
}
|
||||
|
||||
// 清空指定租户的菜单权限缓存
|
||||
Set keys = redisTemplate.keys(String.format("%s:%s::*", tenantDTO.getId(), CacheConstants.MENU_DETAILS));
|
||||
Set<String> 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;
|
||||
}
|
||||
|
||||
+18
-21
@@ -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<SysUserMapper, SysUser> impl
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户全部信息,包括角色和权限
|
||||
* 根据用户信息查询用户全部信息,包括角色和权限
|
||||
*
|
||||
* @param sysUser 用户信息
|
||||
* @param userDTO 用户信息DTO
|
||||
* @return 包含用户角色和权限的用户信息对象
|
||||
*/
|
||||
@Override
|
||||
public UserInfo findUserInfo(SysUser sysUser) {
|
||||
UserInfo userInfo = new UserInfo();
|
||||
userInfo.setSysUser(sysUser);
|
||||
public R<UserInfo> 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<Long> roleIds = sysRoleService.findRolesByUserId(sysUser.getUserId())
|
||||
UserInfo userInfo = new UserInfo();
|
||||
BeanUtils.copyProperties(dbUser, userInfo);
|
||||
// 设置权限列表(menu.permission)
|
||||
List<String> 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<String> permissions = new HashSet<>();
|
||||
roleIds.forEach(roleId -> {
|
||||
List<String> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<result column="password_expire_flag" property="passwordExpireFlag"/>
|
||||
<result column="password_modify_time" property="passwordModifyTime"/>
|
||||
<result column="del_flag" property="delFlag"/>
|
||||
<result column="tenant_id" property="tenantId"/>
|
||||
<collection property="deptList" ofType="com.pig4cloud.pigx.admin.api.entity.SysDept"
|
||||
select="com.pig4cloud.pigx.admin.mapper.SysDeptMapper.listDeptsByUserId"
|
||||
column="{userId=user_id, tenantId=tenant_id}">
|
||||
@@ -65,12 +66,35 @@
|
||||
u.update_time
|
||||
</sql>
|
||||
|
||||
<select id="getUserVoByUsername" resultMap="baseResultMap">
|
||||
<select id="getUserVo" resultMap="baseResultMap">
|
||||
SELECT
|
||||
<include refid="userColumns"/>
|
||||
FROM
|
||||
sys_user u
|
||||
WHERE u.username = #{username} and u.del_flag = '0'
|
||||
FROM sys_user u
|
||||
WHERE u.del_flag = '0'
|
||||
<if test="query.username != null and query.username != ''">
|
||||
AND u.username = #{query.username}
|
||||
</if>
|
||||
<if test="query.oscId != null and query.oscId != ''">
|
||||
AND u.osc_id = #{query.oscId}
|
||||
</if>
|
||||
<if test="query.phone != null and query.phone != ''">
|
||||
AND u.phone = #{query.phone}
|
||||
</if>
|
||||
<if test="query.wxCpUserid != null and query.wxCpUserid != ''">
|
||||
AND u.wx_cp_userid = #{query.wxCpUserid}
|
||||
</if>
|
||||
<if test="query.wxDingUserid != null and query.wxDingUserid != ''">
|
||||
AND u.wx_ding_userid = #{query.wxDingUserid}
|
||||
</if>
|
||||
<if test="query.giteeLogin != null and query.giteeLogin != ''">
|
||||
AND u.gitee_login = #{query.giteeLogin}
|
||||
</if>
|
||||
<if test="query.wxOpenid != null and query.wxOpenid != ''">
|
||||
AND u.wx_openid = #{query.wxOpenid}
|
||||
</if>
|
||||
<if test="query.miniOpenid != null and query.miniOpenid != ''">
|
||||
AND u.mini_openid = #{query.miniOpenid}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUserVoById" resultMap="baseResultMap">
|
||||
|
||||
+12
-17
@@ -16,11 +16,9 @@
|
||||
|
||||
package com.pig4cloud.pigx.mp.config;
|
||||
|
||||
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
|
||||
import me.chanjar.weixin.common.enums.TicketType;
|
||||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
@@ -36,16 +34,13 @@ public class WxMpInRedisConfigStorage extends WxMpDefaultConfigImpl {
|
||||
|
||||
private final static String CARDAPI_TICKET_KEY = "wechat:cardapi_ticket_";
|
||||
|
||||
private final RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
private String accessTokenKey;
|
||||
|
||||
private String jsapiTicketKey;
|
||||
|
||||
private String cardapiTicketKey;
|
||||
|
||||
public WxMpInRedisConfigStorage(RedisTemplate redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
public WxMpInRedisConfigStorage() {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,52 +57,52 @@ public class WxMpInRedisConfigStorage extends WxMpDefaultConfigImpl {
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
return redisTemplate.opsForValue().get(this.accessTokenKey);
|
||||
return RedisUtils.get(this.accessTokenKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessTokenExpired() {
|
||||
return redisTemplate.getExpire(accessTokenKey) < 2L;
|
||||
return RedisUtils.getExpire(accessTokenKey) < 2L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
|
||||
redisTemplate.opsForValue().set(accessTokenKey, accessToken, expiresInSeconds - 200, TimeUnit.SECONDS);
|
||||
RedisUtils.set(accessTokenKey, accessToken, expiresInSeconds - 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAccessToken() {
|
||||
redisTemplate.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);
|
||||
RedisUtils.expire(this.accessTokenKey, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsapiTicket() {
|
||||
return redisTemplate.opsForValue().get(this.jsapiTicketKey);
|
||||
return RedisUtils.get(this.jsapiTicketKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCardApiTicket() {
|
||||
return redisTemplate.opsForValue().get(cardapiTicketKey);
|
||||
return RedisUtils.get(cardapiTicketKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTicket(TicketType type) {
|
||||
return redisTemplate.opsForValue().get(getTicketRedisKey(type));
|
||||
return RedisUtils.get(getTicketRedisKey(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTicketExpired(TicketType type) {
|
||||
return redisTemplate.getExpire(this.getTicketRedisKey(type)) < 2;
|
||||
return RedisUtils.getExpire(this.getTicketRedisKey(type)) < 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateTicket(TicketType type, String jsapiTicket, int expiresInSeconds) {
|
||||
redisTemplate.opsForValue().set(getTicketRedisKey(type), jsapiTicket, expiresInSeconds - 200, TimeUnit.SECONDS);
|
||||
RedisUtils.set(getTicketRedisKey(type), jsapiTicket, expiresInSeconds - 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireTicket(TicketType type) {
|
||||
redisTemplate.expire(getTicketRedisKey(type), 0, TimeUnit.SECONDS);
|
||||
RedisUtils.expire(getTicketRedisKey(type), 0);
|
||||
}
|
||||
|
||||
private String getTicketRedisKey(TicketType type) {
|
||||
|
||||
+1
-4
@@ -20,7 +20,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.listener.ChannelTopic;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
@@ -83,8 +82,6 @@ public class WxMpInitConfigRunner {
|
||||
|
||||
private final ScanHandler scanHandler;
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
@Async
|
||||
@Order
|
||||
@EventListener({ ApplicationReadyEvent.class })
|
||||
@@ -105,7 +102,7 @@ public class WxMpInitConfigRunner {
|
||||
// @formatter:on
|
||||
|
||||
mpServices = accountList.stream().map(a -> {
|
||||
WxMpInRedisConfigStorage configStorage = new WxMpInRedisConfigStorage(redisTemplate);
|
||||
WxMpInRedisConfigStorage configStorage = new WxMpInRedisConfigStorage();
|
||||
configStorage.setAppId(a.getAppid());
|
||||
configStorage.setSecret(a.getAppsecret());
|
||||
configStorage.setToken(a.getToken());
|
||||
|
||||
+8
-6
@@ -22,6 +22,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
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.log.annotation.SysLog;
|
||||
import com.pig4cloud.pigx.common.security.annotation.HasPermission;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpInitConfigRunner;
|
||||
@@ -30,7 +31,7 @@ import com.pig4cloud.pigx.mp.service.WxAccountService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
@@ -46,8 +47,6 @@ public class WxAccountController {
|
||||
|
||||
private final WxAccountService wxAccountService;
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param page 分页对象
|
||||
@@ -82,7 +81,8 @@ public class WxAccountController {
|
||||
@HasPermission("mp_wxaccount_add")
|
||||
public R save(@RequestBody WxAccount wxAccount) {
|
||||
wxAccountService.save(wxAccount);
|
||||
redisTemplate.convertAndSend(CacheConstants.MP_REDIS_RELOAD_TOPIC, "重新加载公众号配置");
|
||||
RedisUtils.execute((RedisCallback<Long>) connection ->
|
||||
connection.publish(CacheConstants.MP_REDIS_RELOAD_TOPIC.getBytes(), "重新加载公众号配置".getBytes()));
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@@ -96,7 +96,8 @@ public class WxAccountController {
|
||||
@HasPermission("mp_wxaccount_edit")
|
||||
public R updateById(@RequestBody WxAccount wxAccount) {
|
||||
wxAccountService.updateById(wxAccount);
|
||||
redisTemplate.convertAndSend(CacheConstants.MP_REDIS_RELOAD_TOPIC, "重新加载公众号配置");
|
||||
RedisUtils.execute((RedisCallback<Long>) connection ->
|
||||
connection.publish(CacheConstants.MP_REDIS_RELOAD_TOPIC.getBytes(), "重新加载公众号配置".getBytes()));
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@@ -110,7 +111,8 @@ public class WxAccountController {
|
||||
@HasPermission("mp_wxaccount_del")
|
||||
public R removeById(@PathVariable Long id) {
|
||||
wxAccountService.removeById(id);
|
||||
redisTemplate.convertAndSend(CacheConstants.MP_REDIS_RELOAD_TOPIC, "重新加载公众号配置");
|
||||
RedisUtils.execute((RedisCallback<Long>) connection ->
|
||||
connection.publish(CacheConstants.MP_REDIS_RELOAD_TOPIC.getBytes(), "重新加载公众号配置".getBytes()));
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user