Files
pkAssistant/src/main/java/vvpkassistant/User/service/UserServiceImpl.java

256 lines
10 KiB
Java
Raw Normal View History

2025-08-04 21:58:55 +08:00
package vvpkassistant.User.service;
import cn.dev33.satoken.stp.StpUtil;
2025-08-05 15:16:03 +08:00
import cn.dev33.satoken.temp.SaTempUtil;
2025-08-04 21:58:55 +08:00
import cn.hutool.core.bean.BeanUtil;
2025-08-05 21:15:01 +08:00
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
2025-08-04 21:58:55 +08:00
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
2025-08-05 21:15:01 +08:00
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.zxing.WriterException;
import lombok.extern.slf4j.Slf4j;
2025-08-04 21:58:55 +08:00
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import vvpkassistant.Data.WxChatParam;
import vvpkassistant.Tools.BcryptUtils;
2025-08-05 21:15:01 +08:00
import vvpkassistant.Tools.QRCodeUtil;
2025-08-04 21:58:55 +08:00
import vvpkassistant.Tools.VVTools;
import vvpkassistant.User.mapper.UserDao;
2025-08-05 21:15:01 +08:00
import vvpkassistant.User.model.*;
import vvpkassistant.User.model.DTO.LoginInfoDTO;
import vvpkassistant.User.model.DTO.ScanInfoDTO;
2025-08-04 21:58:55 +08:00
import vvpkassistant.User.model.DTO.UserModelDTO;
2025-08-05 21:15:01 +08:00
import vvpkassistant.User.model.enumeration.LoginStatusEnum;
2025-08-04 21:58:55 +08:00
import vvpkassistant.common.ErrorCode;
import vvpkassistant.exception.BusinessException;
2025-08-05 15:16:03 +08:00
import vvpkassistant.mail.service.MailService;
2025-08-04 21:58:55 +08:00
import javax.annotation.Resource;
2025-08-05 21:15:01 +08:00
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
2025-08-04 21:58:55 +08:00
/*
* @author: ziin
* @date: 2025/8/4 16:19
*/
@Service
2025-08-05 21:15:01 +08:00
@Slf4j
2025-08-04 21:58:55 +08:00
public class UserServiceImpl extends ServiceImpl<UserDao, UserModel> implements UserService {
@Resource
private UserDao userDao;
@Resource
private WxChatParam wxChatParam;
2025-08-05 15:16:03 +08:00
@Autowired
private MailService mailService;
2025-08-04 21:58:55 +08:00
2025-08-05 21:15:01 +08:00
private final Cache<String, LoginInfoDTO> qrcodeCache = Caffeine.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES)
.build();
2025-08-04 21:58:55 +08:00
@Override
public UserModelVO loginWithMail(UserModelDTO model) {
LambdaQueryWrapper<UserModel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(UserModel::getEmail,model.getEmail())
.in(UserModel::getStatus, 0,2);
UserModel userModel = userDao.selectOne(lambdaQueryWrapper);
if (userModel == null) {
throw new BusinessException(ErrorCode.USER_DOES_NOT_EXIST);
}
String password = userModel.getPassword();
UserModelVO userModelVO = BeanUtil.copyProperties(userModel, UserModelVO.class);
if (BcryptUtils.matchPassword(password, model.getPassword())) {
StpUtil.login(userModel.getId());
userModelVO.setToken(StpUtil.getTokenValue());
userModelVO.setChatInfo(wxChatParam);
return userModelVO;
}else {
throw new BusinessException(ErrorCode.PASSWORD_ERROR);
}
}
@Override
public UserModelVO updateUserInfo(UserModelDTO userModelDTO) {
UserModel userInfo = userDao.selectById(userModelDTO.getId());
if (userInfo == null) {
throw new BusinessException(ErrorCode.USER_DOES_NOT_EXIST);
}
// 用户没有密码的情况下设置密码
if (userInfo.getPassword() == null) {
if (!userModelDTO.getNewPassword().isEmpty()){
if (userModelDTO.getNewPassword().length()<6){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码长度不能小于 6 位");
}
userModelDTO.setPassword(BcryptUtils.encryptPassword(userModelDTO.getNewPassword()));
}
}
if (userModelDTO.getEmail() != null) {
mailService.sendVerificationMail(userModelDTO.getEmail(), userModelDTO.getId());
}
2025-08-04 21:58:55 +08:00
// 用户有密码的情况下重新设置密码
if (userInfo.getPassword() != null && userModelDTO.getOldPassword() != null) {
if (BcryptUtils.matchPassword(userModelDTO.getOldPassword(), userInfo.getPassword())) {
userModelDTO.setPassword(BcryptUtils.encryptPassword(userModelDTO.getNewPassword()));
}else {
throw new BusinessException(ErrorCode.PASSWORD_ERROR,"旧密码不正确");
}
}
UserModel userModel = new UserModel();
BeanUtil.copyProperties(userModelDTO, userModel);
int i = userDao.updateById(userModel);
// 返回结果
userDao.selectById(userModel.getId());
UserModelVO userModelVO = BeanUtil.copyProperties(userModel, UserModelVO.class);
userModelVO.setNewAccount(false);
if (i == 1){
return userModelVO;
}else {
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
}
}
@Override
2025-08-05 15:16:03 +08:00
public UserModelVO addUserWithMail(UserModelDTO userModelDTO) {
2025-08-04 21:58:55 +08:00
LambdaQueryWrapper<UserModel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
2025-08-05 15:16:03 +08:00
lambdaQueryWrapper.eq(UserModel::getEmail,userModelDTO.getEmail());
2025-08-04 21:58:55 +08:00
UserModel userModel = userDao.selectOne(lambdaQueryWrapper);
if (userModel != null) {
throw new BusinessException(ErrorCode.MAIL_ALREADY_EXIST);
}
2025-08-05 15:16:03 +08:00
if (userModelDTO.getPassword().length() < 6 ){
2025-08-04 21:58:55 +08:00
throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码长度不能小于 6 位");
}
2025-08-05 15:16:03 +08:00
userModelDTO.setPassword(BcryptUtils.encryptPassword(userModelDTO.getPassword()));
userModelDTO.setCreateTime(VVTools.currentTimeStamp());
//设置状态为待验证
userModelDTO.setStatus(2);
2025-08-04 21:58:55 +08:00
//设置积分为0
2025-08-05 15:16:03 +08:00
userModelDTO.setPoints(0);
UserModel userModelEntity = BeanUtil.copyProperties(userModelDTO, UserModel.class);
userModelEntity.setMailVerification(1);
2025-08-05 15:16:03 +08:00
if ( userDao.insert(userModelEntity) != 1){
throw new BusinessException(ErrorCode.ADD_FAILED,"用户注册失败");
}
mailService.sendMail(userModelDTO.getEmail(),userModelEntity.getId());
2025-08-04 21:58:55 +08:00
// 判断用户是否为邀请用户
2025-08-05 15:16:03 +08:00
if (userModelDTO.getInviterId() != null) {
UserModel oldUser = userDao.selectById(userModelDTO.getInviterId());
2025-08-04 21:58:55 +08:00
oldUser.setPoints(oldUser.getPoints() + 10);
userDao.updateById(oldUser);
}
2025-08-05 15:16:03 +08:00
UserModelVO userModelVO = BeanUtil.copyProperties(userModelEntity, UserModelVO.class);
2025-08-04 21:58:55 +08:00
userModelVO.setNewAccount(true);
userModelVO.setChatInfo(wxChatParam);
return userModelVO;
}
2025-08-05 15:16:03 +08:00
@Override
public Boolean activateAccount(String token) {
Integer userId = SaTempUtil.parseToken(token, Integer.class);
UserModel userModel = userDao.selectById(userId);
if (userModel == null) {
throw new BusinessException(ErrorCode.USER_DOES_NOT_EXIST);
}
userModel.setStatus(0);
userModel.setMailVerification(0);
2025-08-05 15:16:03 +08:00
if (userDao.updateById(userModel) == 1){
return true;
}else {
throw new BusinessException(ErrorCode.UPDATE_FAILED,"激活失败");
}
}
@Override
public Boolean verificationMail(String token) {
Integer userId = SaTempUtil.parseToken(token, Integer.class);
UserModel userModel = userDao.selectById(userId);
userModel.setMailVerification(0);
if (userDao.updateById(userModel) == 1){
return true;
}
throw new BusinessException(ErrorCode.SYSTEM_ERROR,"邮箱验证失败");
}
2025-08-05 21:15:01 +08:00
@Override
public QrcodeVO generatedQrcode() {
String uuid = UUID.randomUUID().toString();
QrcodeEntity qrcodeEntity = new QrcodeEntity();
qrcodeEntity.setUuid(uuid);
qrcodeEntity.setType("qrcdoe");
String base64QR = null;
try {
base64QR = QRCodeUtil.generateQRCode(JSONUtil.toJsonStr(qrcodeEntity), 200, 200);
} catch (WriterException | IOException e) {
log.error(e.getMessage());
throw new BusinessException(ErrorCode.SYSTEM_ERROR,"二维码生成失败");
}
LoginInfoDTO loginInfoDTO = new LoginInfoDTO();
loginInfoDTO.setStatus(LoginStatusEnum.UNSCANNED.name());
loginInfoDTO.setUuid(uuid);
// 二维码uuid绑定存入缓存
qrcodeCache.put(uuid,loginInfoDTO);
// 返回生成的二维码信息
QrcodeVO vo = QrcodeVO.builder().uuid(uuid).qrcode("data:image/png;base64," + base64QR).build();
log.info("-------生成二维码成功:{}-------", uuid);
return vo;
}
@Override
public Object checkQrcode(String uuid) {
LoginInfoDTO loginInfoDTO = qrcodeCache.getIfPresent(uuid);
if (loginInfoDTO == null) {
throw new BusinessException(ErrorCode.QRCODE_EXPIRED);
}
if (Objects.equals(loginInfoDTO.getStatus(), LoginStatusEnum.SCANNED.name())) {
return loginInfoDTO;
}
if (LoginStatusEnum.CONFIRMED.name().equals(loginInfoDTO.getStatus())) {
UserModel userModel = userDao.selectById(loginInfoDTO.getUserId());
StpUtil.login(userModel.getId());
UserModelVO userModelVO = BeanUtil.copyProperties(userModel, UserModelVO.class);
userModelVO.setToken(StpUtil.getTokenValue());
userModelVO.setChatInfo(wxChatParam);
return userModelVO;
}
return null;
}
@Override
public void scanQrcode(ScanInfoDTO scanInfoDTO) {
LoginInfoDTO loginInfoDTO = qrcodeCache.getIfPresent(scanInfoDTO.getUuid());
if (loginInfoDTO != null) {
loginInfoDTO.setStatus(LoginStatusEnum.SCANNED.name());
}
if (loginInfoDTO != null) {
qrcodeCache.put(scanInfoDTO.getUuid(),loginInfoDTO);
}
log.info("-------扫码成功uuid:{}-------", scanInfoDTO.getUuid());
}
@Override
public void confirm(ScanInfoDTO scanInfoDTO) {
LoginInfoDTO loginInfoDTO = qrcodeCache.getIfPresent(scanInfoDTO.getUuid());
if (loginInfoDTO != null) {
loginInfoDTO.setStatus(LoginStatusEnum.CONFIRMED.name());
loginInfoDTO.setUserId(scanInfoDTO.getUserId());
qrcodeCache.put(scanInfoDTO.getUuid(),loginInfoDTO);
}
log.info("-------确认登录成功uuid:{}-------", scanInfoDTO.getUuid());
}
2025-08-04 21:58:55 +08:00
}