Compare commits

...

4 Commits

Author SHA1 Message Date
4808960491 【优化】代码格式 2025-11-25 16:35:41 +08:00
74d8c66a6e 【新增】忘记密码接口 2025-11-25 16:35:11 +08:00
fca95e1203 【新增】封装账号类型校验工具 2025-11-25 16:34:19 +08:00
b7d3e07d16 【改进】账号类型校验 2025-11-25 16:33:56 +08:00
9 changed files with 104 additions and 36 deletions

View File

@@ -24,8 +24,8 @@ public class SaTokenConfig implements WebMvcConfigurer {
registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin())) registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
// 拦截所有路由 // 拦截所有路由
.addPathPatterns("/**") .addPathPatterns("/**")
// 排除登录、注册、发送验证码接口 // 排除登录、注册、发送验证码, 忘记密码接口
.excludePathPatterns("/user/login", "/user/register", "/user/sendCode") .excludePathPatterns("/user/login", "/user/register", "/user/sendCode", "/user/forgetPassword")
// 排除后台管理登录接口 // 排除后台管理登录接口
.excludePathPatterns("/sys/user/login") .excludePathPatterns("/sys/user/login")
// 排除反馈接口(支持匿名提交) // 排除反馈接口(支持匿名提交)

View File

@@ -0,0 +1,19 @@
package com.corewing.app.dto.api;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ForgetPasswordRequest {
@NotBlank(message = "手机号或邮箱不能为空")
private String account;
@NotBlank(message = "验证码不能为空")
private String verificationCode;
@NotBlank(message = "密码不能为空")
private String password;
}

View File

@@ -17,7 +17,7 @@ public class SendCodeRequest {
private String account; private String account;
/** /**
* 验证码类型register-注册, login-登录, reset-重置密码 * 验证码类型register-注册, login-登录, reset-重置密码, forget-忘记密码
*/ */
@NotBlank(message = "验证码类型不能为空") @NotBlank(message = "验证码类型不能为空")
private String type; private String type;

View File

@@ -2,15 +2,14 @@ package com.corewing.app.modules.app;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import com.corewing.app.common.Result; import com.corewing.app.common.Result;
import com.corewing.app.dto.api.LoginRequest; import com.corewing.app.dto.api.*;
import com.corewing.app.dto.api.RegisterRequest; import com.corewing.app.dto.biz.user.ResetPasswordRequest;
import com.corewing.app.dto.api.SendCodeRequest;
import com.corewing.app.dto.api.UpdatePasswordRequest;
import com.corewing.app.entity.User; import com.corewing.app.entity.User;
import com.corewing.app.service.UserService; import com.corewing.app.service.UserService;
import com.corewing.app.service.VerifyCodeService; import com.corewing.app.service.VerifyCodeService;
import com.corewing.app.util.I18nUtil; import com.corewing.app.util.I18nUtil;
import com.corewing.app.util.IpUtil; import com.corewing.app.util.IpUtil;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -174,4 +173,14 @@ public class AppUserController {
return Result.error(e.getMessage()); return Result.error(e.getMessage());
} }
} }
/**
* 忘记密码
* @param request
* @return
*/
@PutMapping("/forgetPassword")
public Result<String> forgetPassword(@RequestBody ForgetPasswordRequest request) {
return Result.isBool(userService.forgetPassword(request));
}
} }

View File

@@ -2,12 +2,11 @@ package com.corewing.app.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.corewing.app.dto.biz.user.BizUserIdRequest; import com.corewing.app.dto.api.ForgetPasswordRequest;
import com.corewing.app.dto.biz.user.BizUserStatusRequest; import com.corewing.app.dto.biz.user.BizUserStatusRequest;
import com.corewing.app.dto.biz.user.ResetPasswordRequest; import com.corewing.app.dto.biz.user.ResetPasswordRequest;
import com.corewing.app.entity.User; import com.corewing.app.entity.User;
import java.util.List;
/** /**
* 应用用户 Service 接口 * 应用用户 Service 接口
@@ -115,4 +114,11 @@ public interface UserService extends IService<User> {
* @return * @return
*/ */
boolean batchStatus(BizUserStatusRequest bizUserStatusRequest); boolean batchStatus(BizUserStatusRequest bizUserStatusRequest);
/**
* 忘记密码
* @param request
* @return
*/
boolean forgetPassword(ForgetPasswordRequest request);
} }

View File

@@ -8,7 +8,6 @@ import com.corewing.app.entity.PrivacyPolicy;
import com.corewing.app.mapper.PrivacyPolicyMapper; import com.corewing.app.mapper.PrivacyPolicyMapper;
import com.corewing.app.service.PrivacyPolicyService; import com.corewing.app.service.PrivacyPolicyService;
import com.corewing.app.util.DateUtils; import com.corewing.app.util.DateUtils;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;

View File

@@ -3,11 +3,10 @@ package com.corewing.app.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.corewing.app.common.page.PageContext; import com.corewing.app.common.page.PageContext;
import com.corewing.app.dto.biz.user.BizUserIdRequest; import com.corewing.app.dto.api.ForgetPasswordRequest;
import com.corewing.app.dto.biz.user.BizUserStatusRequest; import com.corewing.app.dto.biz.user.BizUserStatusRequest;
import com.corewing.app.dto.biz.user.ResetPasswordRequest; import com.corewing.app.dto.biz.user.ResetPasswordRequest;
import com.corewing.app.entity.User; import com.corewing.app.entity.User;
@@ -16,14 +15,13 @@ import com.corewing.app.service.UserService;
import com.corewing.app.service.VerifyCodeService; import com.corewing.app.service.VerifyCodeService;
import com.corewing.app.util.I18nUtil; import com.corewing.app.util.I18nUtil;
import com.corewing.app.util.Ip2RegionUtil; import com.corewing.app.util.Ip2RegionUtil;
import com.corewing.app.util.RedisUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/** /**
* 应用用户 Service 实现类 * 应用用户 Service 实现类
@@ -34,11 +32,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
private final VerifyCodeService verifyCodeService; private final VerifyCodeService verifyCodeService;
private final Ip2RegionUtil ip2RegionUtil; private final Ip2RegionUtil ip2RegionUtil;
private final UserMapper userMapper; private final UserMapper userMapper;
private final RedisUtil redisUtil;
public UserServiceImpl(VerifyCodeService verifyCodeService, Ip2RegionUtil ip2RegionUtil, UserMapper userMapper) { public UserServiceImpl(VerifyCodeService verifyCodeService, Ip2RegionUtil ip2RegionUtil, UserMapper userMapper, RedisUtil redisUtil) {
this.verifyCodeService = verifyCodeService; this.verifyCodeService = verifyCodeService;
this.ip2RegionUtil = ip2RegionUtil; this.ip2RegionUtil = ip2RegionUtil;
this.userMapper = userMapper; this.userMapper = userMapper;
this.redisUtil = redisUtil;
} }
@Override @Override
@@ -255,4 +255,22 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
}); });
return true; return true;
} }
@Override
public boolean forgetPassword(ForgetPasswordRequest request) {
User user = getByAccount(request.getAccount());
if(user == null) {
throw new RuntimeException(I18nUtil.getMessage("error.user.not.found"));
}
String codeKey = String.format("verify_code:%s:%s", "forget", request.getAccount());
String checkCode = redisUtil.get(codeKey).toString();
if(!checkCode.equalsIgnoreCase(request.getVerificationCode())) {
throw new RuntimeException(I18nUtil.getMessage("error.verify.code.invalid"));
}
String encryptPassword = DigestUtils.md5DigestAsHex(request.getPassword().getBytes(StandardCharsets.UTF_8));
user.setPassword(encryptPassword);
return updateById(user);
}
} }

View File

@@ -1,16 +1,12 @@
package com.corewing.app.service.impl; package com.corewing.app.service.impl;
import com.corewing.app.service.VerifyCodeService; import com.corewing.app.service.VerifyCodeService;
import com.corewing.app.util.EmailUtil; import com.corewing.app.util.*;
import com.corewing.app.util.I18nUtil;
import com.corewing.app.util.RedisUtil;
import com.corewing.app.util.SmsBaoUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.Random; import java.util.Random;
import java.util.regex.Pattern;
/** /**
* 验证码服务实现类 * 验证码服务实现类
@@ -33,16 +29,6 @@ public class VerifyCodeServiceImpl implements VerifyCodeService {
*/ */
private static final int CODE_LENGTH = 6; private static final int CODE_LENGTH = 6;
/**
* 手机号正则
*/
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
/**
* 邮箱正则
*/
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
public VerifyCodeServiceImpl(RedisUtil redisUtil, SmsBaoUtil smsBaoUtil, EmailUtil emailUtil) { public VerifyCodeServiceImpl(RedisUtil redisUtil, SmsBaoUtil smsBaoUtil, EmailUtil emailUtil) {
this.redisUtil = redisUtil; this.redisUtil = redisUtil;
this.smsBaoUtil = smsBaoUtil; this.smsBaoUtil = smsBaoUtil;
@@ -59,11 +45,7 @@ public class VerifyCodeServiceImpl implements VerifyCodeService {
throw new RuntimeException(I18nUtil.getMessage("error.verify.type.empty")); throw new RuntimeException(I18nUtil.getMessage("error.verify.type.empty"));
} }
// 判断是手机号还是邮箱 if (!AccountUtil.isPhone(account) && !AccountUtil.isEmail(account)) {
boolean isPhone = PHONE_PATTERN.matcher(account).matches();
boolean isEmail = EMAIL_PATTERN.matcher(account).matches();
if (!isPhone && !isEmail) {
throw new RuntimeException(I18nUtil.getMessage("error.account.format.invalid")); throw new RuntimeException(I18nUtil.getMessage("error.account.format.invalid"));
} }
@@ -77,7 +59,7 @@ public class VerifyCodeServiceImpl implements VerifyCodeService {
log.info("验证码已生成: account={}, type={}, code={}", account, type, code); log.info("验证码已生成: account={}, type={}, code={}", account, type, code);
// 发送验证码 // 发送验证码
if (isPhone) { if (AccountUtil.isPhone(account)) {
// 发送短信验证码 // 发送短信验证码
boolean success = smsBaoUtil.sendVerifyCode(account, code); boolean success = smsBaoUtil.sendVerifyCode(account, code);
if (!success) { if (!success) {

View File

@@ -0,0 +1,35 @@
package com.corewing.app.util;
import java.util.regex.Pattern;
public class AccountUtil {
/**
* 手机号正则
*/
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
/**
* 邮箱正则
*/
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
/**
* 校验是否是手机号
* @param email
* @return
*/
public static boolean isEmail(String email) {
return EMAIL_PATTERN.matcher(email).matches();
}
/**
* 校验是否是手机
* @param phoneNumber
* @return
*/
public static boolean isPhone(String phoneNumber) {
return PHONE_PATTERN.matcher(phoneNumber).matches();
}
}