sxwz2.0/src/main/java/com/kexue/skills/service/impl/SysUserServiceImpl.java
wangzhiwei 83fc577186 feat(redis): 集成 Redisson 并统一配置管理
- 添加 Redisson 依赖并配置自动装配
- 创建 application-common.yml 统一管理 Redis 配置
- 在 application.yml 中引入公共配置文件
- 修改生产环境配置以引用公共 Redis 配置
- 替换原生 RedisTemplate 为 Redisson 客户端
- 实现基于 Redisson 的分布式锁和缓存功能
2026-01-28 14:45:36 +08:00

823 lines
28 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.kexue.skills.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.alicp.jetcache.anno.CacheInvalidate;
import com.alicp.jetcache.anno.CachePenetrationProtect;
import com.alicp.jetcache.anno.Cached;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kexue.skills.common.Assert;
import com.kexue.skills.common.CacheManager;
import com.kexue.skills.common.Const;
import com.kexue.skills.config.CaptchaConfig;
import com.kexue.skills.entity.*;
import com.kexue.skills.entity.dto.ContentPurchaseDto;
import com.kexue.skills.entity.dto.SysUserDto;
import com.kexue.skills.entity.request.*;
import com.kexue.skills.mapper.*;
import com.kexue.skills.service.SysUserService;
import com.kexue.skills.utils.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import java.util.Random;
/**
* (SysUser)表服务实现类
*
* @author 王志维
* @since 2025-02-21 23:01:48
*/
@Service("sysUserService")
@Slf4j
public class SysUserServiceImpl implements SysUserService {
@Resource
private SysUserMapper sysUserMapper;
@Resource
private org.springframework.data.redis.core.RedisTemplate<String, String> redisTemplate;
@Resource
private RedissonClient redissonClient;
@Resource
private CaptchaConfig captchaConfig;
@Resource
private PointsAccountMapper pointsAccountMapper;
@Resource
private AccountMapper accountMapper;
@Resource
private SysUserRoleMapper sysUserRoleMapper;
@Resource
private ContentPurchaseMapper contentPurchaseMapper;
@Resource
private CmsContentLikeMapper cmsContentLikeMapper;
@Resource
private CmsContentViewMapper cmsContentViewMapper;
@Resource
private CmsContentMapper cmsContentMapper;
/**
* 分页查询数据
*
* @param queryDto
* @return 数据分页列表
*/
@Override
public PageInfo<SysUser> getPageList(SysUserDto queryDto) {
int pageNum = queryDto.getPageNum()==null?PAGENUM:queryDto.getPageNum();
int pageSize = queryDto.getPageSize()==null? PAGESIZE :queryDto.getPageSize();
PageHelper.startPage(pageNum,pageSize);
List<SysUser> dataList = sysUserMapper.getPageList(queryDto);
// 将所有返回的用户密码设置为null
dataList.forEach(user -> user.setPwd(null));
return new PageInfo<>(dataList);
}
/**
* 通过ID查询单条数据
*
* @param userId 主键
* @return 实例对象
*/
@Override
@Cached(name = "sysUser:", key = "#userId", expire = 3600, cacheType = com.alicp.jetcache.anno.CacheType.BOTH)
@CachePenetrationProtect
public SysUser queryById(Long userId) {
SysUser sysUser = sysUserMapper.queryById(userId);
sysUser.setPwd(null);
return sysUser;
}
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
@Override
public List<SysUser> queryAllByLimit(int offset, int limit) {
List<SysUser> sysUsers = sysUserMapper.queryAllByLimit(offset, limit);
// 将所有返回的用户密码设置为null
sysUsers.forEach(user -> user.setPwd(null));
return sysUsers;
}
/**
* 新增数据
*
* @param sysUser 实例对象
* @return 实例对象
*/
@Override
public SysUser insert(SysUser sysUser) {
SysUser byUsername = getByUsername(sysUser.getUserName());
Assert.isNull(byUsername, "用户名已存在");
sysUser.setEnable(Const.USER_STATUS_NORMAL);
sysUser.setDeleteFlag(Const.DELETE_FLAG_NO);
//写一个salt生成方法
sysUser.setSalt(System.currentTimeMillis()+"");
try {
String md5Pwd = MD5Util.encryptToHex(sysUser.getPwd()+sysUser.getSalt());
sysUser.setPwd(md5Pwd);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
// 插入用户信息
sysUserMapper.insert(sysUser);
// 初始化账户(余额账户)
Account account = new Account();
account.setUserId(sysUser.getUserId());
account.setUserName(sysUser.getUserName());
account.setBalance(BigDecimal.ZERO); // 初始余额为0
account.setFrozenAmount(BigDecimal.ZERO); // 初始冻结金额为0
account.setDeleteFlag(Const.DELETE_FLAG_NO); // 初始未删除
accountMapper.insert(account);
// 初始化积分账户
PointsAccount pointsAccount = new PointsAccount();
pointsAccount.setUserId(sysUser.getUserId());
pointsAccount.setUserName(sysUser.getUserName());
pointsAccount.setTotalPoints(0); // 初始总积分为0
pointsAccount.setAvailablePoints(0); // 初始可用积分为0
pointsAccount.setFrozenPoints(0); // 初始冻结积分为0
pointsAccount.setDeleteFlag(Const.DELETE_FLAG_NO); // 初始未删除
pointsAccountMapper.insert(pointsAccount);
// 将返回的用户密码设置为null
sysUser.setPwd(null);
return sysUser;
}
/**
* 修改数据
*
* @param sysUser 实例对象
* @return 实例对象
*/
@Override
@CacheInvalidate(name = "sysUser:", key = "#sysUser.userId")
@CacheInvalidate(name = "sysUser:username:", key = "#sysUser.userName")
public SysUser update(SysUser sysUser) {
if (Objects.nonNull(sysUser.getUserId())){
// 校验用户名是否已经存在
if (sysUser.getUserName() != null && !sysUser.getUserName().isEmpty()) {
SysUser existingUser = sysUserMapper.getByUsername(sysUser.getUserName());
Assert.isTrue(existingUser == null || existingUser.getUserId().equals(sysUser.getUserId()), "用户名已存在");
}
sysUserMapper.update(sysUser);
}else {
insert(sysUser);
}
return queryById(sysUser.getUserId());
}
/**
* 通过主键删除数据
*
* @param userId 主键
* @return 是否成功
*/
@Override
@CacheInvalidate(name = "sysUser:", key = "#userId")
public boolean deleteById(Long userId) {
SysUser sysUser = queryById(userId);
//管理员不允许删除
Assert.isFalse(Const.ADMIN_USER_LIST.contains(sysUser.getUserName().toLowerCase()), "该用户是管理员,不能删除");
// 删除用户名缓存
redisTemplate.delete("sysUser:username:" + sysUser.getUserName());
return sysUserMapper.deleteById(userId) > 0;
}
@Override
public LoginUserDto login(LoginDto loginDto) {
// 参数验证
validateLoginParams(loginDto);
// 验证码验证
validateCaptcha(loginDto);
// 查询用户
SysUser sysUser = getUserByUsername(loginDto.getUsername());
// 密码验证
validatePassword(loginDto.getPassword(), sysUser);
// 生成token
String token = generateToken(sysUser.getUserId());
// 构建登录用户信息
LoginUser loginUser = buildLoginUser(sysUser, token);
// 存储登录信息到Redis
saveLoginUserToRedis(token, loginUser);
// 构建返回对象
LoginUserDto sysUserDto = buildLoginUserDto(loginUser);
log.info("用户:{}登录成功token{}", loginDto.getUsername(), token);
return sysUserDto;
}
/**
* 参数验证
*
* @param loginDto 登录请求参数
*/
private void validateLoginParams(LoginDto loginDto) {
Assert.notNull(loginDto.getUsername(), "用户名不能位空");
Assert.notNull(loginDto.getPassword(), "密码不能位空");
}
/**
* 验证码验证
*
* @param loginDto 登录请求参数
*/
private void validateCaptcha(LoginDto loginDto) {
if (captchaConfig.isEnabled()) {
Assert.notNull(loginDto.getCaptchaId(), "验证码不能为空");
Assert.notNull(loginDto.getCaptchaValue(), "验证码不能为空");
String captchaKey = "captcha:" + loginDto.getCaptchaId();
String captchaText = redisTemplate.opsForValue().get(captchaKey);
Assert.notNull(captchaText, "验证码已过期");
Assert.equals(captchaText, loginDto.getCaptchaValue().toLowerCase(), "验证码错误");
redisTemplate.delete(captchaKey);
}
}
/**
* 根据用户名查询用户
*
* @param username 用户名
* @return 用户对象
*/
private SysUser getUserByUsername(String username) {
SysUser sysUser = sysUserMapper.getByUsername(username);
Assert.notNull(sysUser, "用户名不存在");
return sysUser;
}
/**
* 密码验证
*
* @param password 密码
* @param sysUser 用户对象
*/
private void validatePassword(String password, SysUser sysUser) {
try {
// 假设客户端已经对密码进行了一次MD5加密服务端使用双重加密验证
String encryptedPwd = MD5Util.doubleEncrypt(password, sysUser.getSalt());
Assert.equals(encryptedPwd, sysUser.getPwd(), "密码不正确");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 生成token
*
* @param userId 用户ID
* @return token
*/
private String generateToken(Long userId) {
cn.dev33.satoken.stp.StpUtil.login(userId);
return cn.dev33.satoken.stp.StpUtil.getTokenValue();
}
/**
* 构建登录用户信息
*
* @param sysUser 用户对象
* @param token token
* @return 登录用户信息
*/
private LoginUser buildLoginUser(SysUser sysUser, String token) {
LoginUser loginUser = new LoginUser();
// 设置用户基本信息
sysUser.setPwd(null);
loginUser.setUserInfo(sysUser);
// 查询并设置用户角色列表
loginUser.setRoles(queryUserRoles(sysUser.getUserId()));
// 查询并设置用户已购买的内容ID列表
loginUser.setPurchasedContentIds(queryPurchasedContentIds(sysUser.getUserId()));
// 查询并设置用户账户信息
loginUser.setAccount(queryUserAccount(sysUser.getUserId()));
// 查询并设置用户积分信息
loginUser.setPointsAccount(queryUserPointsAccount(sysUser.getUserId()));
// 查询并设置用户最近点赞记录
loginUser.setFavorites(queryRecentFavorites(sysUser.getUserId()));
// 查询并设置用户最近查看记录
loginUser.setHistory(queryRecentViews(sysUser.getUserId()));
// 查询并设置用户最近创建记录
loginUser.setCreate(queryRecentCreatedContent(sysUser.getUserId()));
// 查询并设置用户最近购买记录
loginUser.setHas(queryRecentPurchases(sysUser.getUserId()));
// 设置token
loginUser.setToken(token);
return loginUser;
}
/**
* 查询用户角色列表
*
* @param userId 用户ID
* @return 角色列表
*/
private List<String> queryUserRoles(Long userId) {
List<String> roles = new java.util.ArrayList<>();
try {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(userId);
List<SysUserRole> userRoles = sysUserRoleMapper.queryAll(userRole);
for (SysUserRole ur : userRoles) {
roles.add("ROLE_" + ur.getRoleId());
}
} catch (Exception e) {
log.error("查询用户角色列表失败:{}", e.getMessage());
roles = java.util.Collections.emptyList();
}
return roles;
}
/**
* 查询用户已购买的内容ID列表
*
* @param userId 用户ID
* @return 内容ID列表
*/
private List<Long> queryPurchasedContentIds(Long userId) {
List<Long> purchasedContentIds = new java.util.ArrayList<>();
try {
ContentPurchaseDto purchaseDto = new ContentPurchaseDto();
purchaseDto.setUserId(userId);
List<ContentPurchase> purchases = contentPurchaseMapper.getList(purchaseDto);
for (ContentPurchase purchase : purchases) {
purchasedContentIds.add(purchase.getContentId());
}
} catch (Exception e) {
log.error("查询用户已购买内容列表失败:{}", e.getMessage());
purchasedContentIds = java.util.Collections.emptyList();
}
return purchasedContentIds;
}
/**
* 查询用户账户信息
*
* @param userId 用户ID
* @return 账户信息
*/
private Account queryUserAccount(Long userId) {
return accountMapper.queryByUserId(userId);
}
/**
* 查询用户积分信息
*
* @param userId 用户ID
* @return 积分信息
*/
private PointsAccount queryUserPointsAccount(Long userId) {
return pointsAccountMapper.queryByUserId(userId);
}
/**
* 查询用户最近点赞记录
*
* @param userId 用户ID
* @return 最近点赞记录
*/
private List<Long> queryRecentFavorites(Long userId) {
try {
return cmsContentLikeMapper.queryRecentLikesByUserId(userId, 20);
} catch (Exception e) {
log.error("查询用户最近点赞记录失败:{}", e.getMessage());
return java.util.Collections.emptyList();
}
}
/**
* 查询用户最近查看记录
*
* @param userId 用户ID
* @return 最近查看记录
*/
private List<Long> queryRecentViews(Long userId) {
try {
return cmsContentViewMapper.queryRecentViewsByUserId(userId, 20);
} catch (Exception e) {
log.error("查询用户最近查看记录失败:{}", e.getMessage());
return java.util.Collections.emptyList();
}
}
/**
* 查询用户最近创建记录
*
* @param userId 用户ID
* @return 最近创建记录
*/
private List<Long> queryRecentCreatedContent(Long userId) {
try {
return cmsContentMapper.queryRecentCreatedByUserId(userId, 20);
} catch (Exception e) {
log.error("查询用户最近创建记录失败:{}", e.getMessage());
return java.util.Collections.emptyList();
}
}
/**
* 查询用户最近购买记录
*
* @param userId 用户ID
* @return 最近购买记录
*/
private List<Long> queryRecentPurchases(Long userId) {
List<Long> has = new java.util.ArrayList<>();
try {
ContentPurchaseDto purchaseDto = new ContentPurchaseDto();
purchaseDto.setUserId(userId);
List<ContentPurchase> purchases = contentPurchaseMapper.getList(purchaseDto);
if (purchases != null && !purchases.isEmpty()) {
java.util.LinkedHashSet<Long> contentIdSet = new java.util.LinkedHashSet<>();
for (ContentPurchase purchase : purchases) {
if (contentIdSet.size() < 20) {
contentIdSet.add(purchase.getContentId());
} else {
break;
}
}
has.addAll(contentIdSet);
}
} catch (Exception e) {
log.error("查询用户最近购买记录失败:{}", e.getMessage());
has = java.util.Collections.emptyList();
}
return has;
}
/**
* 存储登录信息到Redis
*
* @param token token
* @param loginUser 登录用户信息
*/
private void saveLoginUserToRedis(String token, LoginUser loginUser) {
redisTemplate.opsForValue().set(
"loginUser:" + token,
cn.hutool.json.JSONUtil.toJsonStr(loginUser),
3600,
java.util.concurrent.TimeUnit.SECONDS
);
}
/**
* 构建登录用户返回对象
*
* @param loginUser 登录用户信息
* @return 登录用户返回对象
*/
private LoginUserDto buildLoginUserDto(LoginUser loginUser) {
LoginUserDto sysUserDto = new LoginUserDto();
BeanUtil.copyProperties(loginUser.getUserInfo(), sysUserDto);
sysUserDto.setToken(loginUser.getToken());
sysUserDto.setFavorites(loginUser.getFavorites());
sysUserDto.setHistory(loginUser.getHistory());
sysUserDto.setCreate(loginUser.getCreate());
sysUserDto.setHas(loginUser.getHas());
return sysUserDto;
}
@Override
public boolean resetPassword(ResetPasswordDto resetPasswordDto) {
Assert.notNull(resetPasswordDto.getUserName(), "用户名不能位空");
Assert.notNull(resetPasswordDto.getOldPassword(), "旧密码不能位空");
Assert.notNull(resetPasswordDto.getNewPassword(), "新密码不能位空");
SysUser sysUser = sysUserMapper.getByUsername(resetPasswordDto.getUserName());
Assert.notNull(sysUser, "用户名不存在");
try {
String oldMd5Pwd = MD5Util.encryptToHex(resetPasswordDto.getOldPassword() + sysUser.getSalt());
Assert.equals(oldMd5Pwd, sysUser.getPwd(), "旧密码不正确");
String newMd5Pwd = MD5Util.encryptToHex(resetPasswordDto.getNewPassword() + sysUser.getSalt());
sysUser.setPwd(newMd5Pwd);
sysUserMapper.update(sysUser);
// 清除旧的token
CacheManager.removeTokenFromCache(resetPasswordDto.getUserName());
return true;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean resetPasswordByAdmin(ResetPasswordDto resetPasswordDto) {
Assert.notNull(resetPasswordDto.getUserName(), "用户名不能位空");
Assert.notNull(resetPasswordDto.getNewPassword(), "新密码不能位空");
SysUser sysUser = sysUserMapper.getByUsername(resetPasswordDto.getUserName());
Assert.notNull(sysUser, "用户名不存在");
try {
String newMd5Pwd = MD5Util.encryptToHex(resetPasswordDto.getNewPassword() + sysUser.getSalt());
sysUser.setPwd(newMd5Pwd);
sysUserMapper.update(sysUser);
// 清除旧的token
CacheManager.removeTokenFromCache(resetPasswordDto.getUserName());
return true;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
@Override
@Cached(name = "sysUser:username:", key = "#username", expire = 3600, cacheType = com.alicp.jetcache.anno.CacheType.BOTH)
@CachePenetrationProtect
public SysUser getByUsername(String username) {
if (Objects.nonNull(username)){
SysUser sysUser = sysUserMapper.getByUsername(username);
if (sysUser != null) {
sysUser.setPwd(null);
}
return sysUser;
}
return null;
}
@Override
public boolean resetPwd(Long userId, String newPassword, String operator) {
// 检查操作人是否为管理员
Assert.isTrue(Const.ADMIN_USER_LIST.contains(operator.toLowerCase()), "只有管理员才能执行此操作");
// 查询用户是否存在
SysUser sysUser = sysUserMapper.queryById(userId);
Assert.notNull(sysUser, "用户不存在");
try {
// 生成新的加密密码
String newMd5Pwd = MD5Util.encryptToHex(newPassword + sysUser.getSalt());
sysUser.setPwd(newMd5Pwd);
// 更新用户密码
sysUserMapper.update(sysUser);
// 清除旧的token
CacheManager.removeTokenFromCache(sysUser.getUserName());
return true;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 发送手机验证码
*
* @param phone 手机号
* @return 是否发送成功
*/
@Override
public boolean sendSmsCode(String phone) {
try {
// 参数校验
Assert.notBlank(phone, "手机号不能为空");
// 生成6位随机验证码
String code = generateSmsCode();
// 存储验证码到Redis有效期5分钟
redissonClient.getBucket("sms_code:" + phone).set(code, 300, java.util.concurrent.TimeUnit.SECONDS);
// 获取默认的短信发送器
SmsBlend sms = SmsFactory.getSmsBlend();
Assert.notNull(sms, "短信服务未正确配置");
log.info("获取短信发送器成功");
// 发送验证码 - 使用模板方式发送,避免直接文本发送可能导致的参数缺失
LinkedHashMap<String, String> params = new LinkedHashMap<>();
params.put("code", code); // 参数名需要与阿里云模板中的变量名匹配
// 发送短信,使用配置文件中定义的模板
// 根据API文档和用户需求使用单个手机号发送的方法sendMessage(String phone, Map<String, String> params)
// 系统会自动从配置中读取template-id
sms.sendMessage(phone, params);
log.info("向手机号 {} 发送验证码:{}", phone, code);
return true;
} catch (Exception e) {
log.error("向手机号 {} 发送验证码失败:{}", phone, e.getMessage());
log.error("详细错误信息:", e);
// 如果短信服务不可用可以记录错误并返回false而不是抛出异常
// 或者根据业务需求决定是否继续
Assert.isTrue(false, "发送验证码失败:" + e.getMessage());
}
return false;
}
/**
* 生成6位随机验证码
*
* @return 6位随机验证码
*/
private String generateSmsCode() {
Random random = new Random();
return String.format("%06d", random.nextInt(1000000));
}
/**
* 手机号登录
*
* @param phoneLoginDto 手机号登录信息
* @return 登录结果
*/
@Override
public LoginUserDto phoneLogin(PhoneLoginDto phoneLoginDto) {
String phone = phoneLoginDto.getPhone();
String code = phoneLoginDto.getCode();
Assert.notBlank(phone, "手机号不能为空");
Assert.notBlank(code, "验证码不能为空");
// 验证验证码
String cachedCode = redisTemplate.opsForValue().get("sms_code:" + phone);
Assert.notNull(cachedCode, "验证码已过期");
Assert.equals(cachedCode, code, "验证码错误");
// 验证成功后,删除验证码
redisTemplate.delete("sms_code:" + phone);
// 查询用户是否存在
SysUser sysUser = sysUserMapper.getByTel(phone);
// 如果用户不存在,自动创建账号
if (sysUser == null) {
sysUser = createUserByPhone(phone);
}
// 使用Sa-Token登录生成token
cn.dev33.satoken.stp.StpUtil.login(sysUser.getUserId());
// 获取生成的token
String token = cn.dev33.satoken.stp.StpUtil.getTokenValue();
// 创建LoginUser对象
LoginUser loginUser = new LoginUser();
// 设置用户基本信息
sysUser.setPwd(null);
loginUser.setUserInfo(sysUser);
// 查询用户角色列表
List<String> roles = new java.util.ArrayList<>();
try {
// 创建查询条件,查询用户的角色关联记录
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
List<SysUserRole> userRoles = sysUserRoleMapper.queryAll(userRole);
// 遍历角色关联记录,获取角色名称
for (SysUserRole ur : userRoles) {
roles.add("ROLE_" + ur.getRoleId());
}
} catch (Exception e) {
log.error("查询用户角色列表失败:{}", e.getMessage());
roles = java.util.Collections.emptyList();
}
loginUser.setRoles(roles);
// 查询用户已购买的内容ID列表
List<Long> purchasedContentIds = new java.util.ArrayList<>();
try {
// 创建查询条件,查询用户的购买记录
ContentPurchaseDto purchaseDto = new ContentPurchaseDto();
purchaseDto.setUserId(sysUser.getUserId());
List<ContentPurchase> purchases = contentPurchaseMapper.getList(purchaseDto);
// 遍历购买记录获取内容ID
for (ContentPurchase purchase : purchases) {
purchasedContentIds.add(purchase.getContentId());
}
} catch (Exception e) {
log.error("查询用户已购买内容列表失败:{}", e.getMessage());
purchasedContentIds = java.util.Collections.emptyList();
}
loginUser.setPurchasedContentIds(purchasedContentIds);
// 查询用户账户信息
Account account = accountMapper.queryByUserId(sysUser.getUserId());
loginUser.setAccount(account);
// 查询用户积分信息
PointsAccount pointsAccount = pointsAccountMapper.queryByUserId(sysUser.getUserId());
loginUser.setPointsAccount(pointsAccount);
// 查询并设置用户最近点赞记录
loginUser.setFavorites(queryRecentFavorites(sysUser.getUserId()));
// 查询并设置用户最近查看记录
loginUser.setHistory(queryRecentViews(sysUser.getUserId()));
// 查询并设置用户最近创建记录
loginUser.setCreate(queryRecentCreatedContent(sysUser.getUserId()));
// 查询并设置用户最近购买记录
loginUser.setHas(queryRecentPurchases(sysUser.getUserId()));
// 设置token
loginUser.setToken(token);
// 将LoginUser对象存储到Redis缓存中使用token作为key
redisTemplate.opsForValue().set("loginUser:" + token, cn.hutool.json.JSONUtil.toJsonStr(loginUser), 3600, java.util.concurrent.TimeUnit.SECONDS);
// 创建LoginUserDto返回对象
LoginUserDto sysUserDto = buildLoginUserDto(loginUser);
log.info("用户:{} 手机号登录成功token{}", phone, token);
return sysUserDto;
}
/**
* 根据手机号创建用户
*
* @param phone 手机号
* @return 创建的用户对象
*/
private SysUser createUserByPhone(String phone) {
SysUser sysUser = new SysUser();
// 设置用户名(使用手机号作为用户名)
sysUser.setUserName(phone);
sysUser.setTel(phone);
// 生成随机密码
String randomPassword = generateRandomPassword();
sysUser.setPwd(randomPassword);
// 调用insert方法创建用户
return insert(sysUser);
}
/**
* 生成随机密码
*
* @return 随机密码
*/
private String generateRandomPassword() {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder(12);
for (int i = 0; i < 12; i++) {
sb.append(characters.charAt(random.nextInt(characters.length())));
}
return sb.toString();
}
}