Procházet zdrojové kódy

门户注册、找回密码

Gaosheng před 6 dny
rodič
revize
0530f261c1

+ 8 - 0
xinkeaboard-server/b2b2c-core/src/main/java/com/slodon/b2b2c/core/constant/RedisConst.java

@@ -78,6 +78,8 @@ public class RedisConst {
      */
     public static final String DRAW_PREFIX = "draw_";
 
+    public static final String SLD_PC_EMAIL_VERIFY_CODE_LIMIT="sld_pc_verify_code_limit:email::";
+
     /**
      * reids中保存邮箱用户注册,key=前缀+email
      */
@@ -98,6 +100,12 @@ public class RedisConst {
      */
     public static final long REGISTER_USER_AND_FORGETPWD_USER_EMAIL_LINK_EXPIRE_TIME = 60L * 10 * 6 * 24;
 
+
+    /**
+     * 用户注册、忘记密码验证码有效时间:5min
+     */
+    public static final long REGISTER_USER_AND_FORGETPWD_USER_EMAIL_VERIFICATION_CODE_EXPIRE_TIME = 60L * 5;
+
     /**
      * 单点登录链接有效时间:600秒即10分钟
      */

+ 9 - 0
xinkeaboard-server/b2b2c-core/src/main/java/com/slodon/b2b2c/core/util/AssertUtil.java

@@ -214,4 +214,13 @@ public class AssertUtil {
             throw new MallException("请输入正确的数字");
         }
     }
+
+    public static void passwordCheck(String password) {
+        String check = "^[a-zA-Z0-9!@#$%^&*()\\\\{\\\\}\\\\[\\\\]|\\\\\\\\:;'\\\",./?]{6,20}$";
+        Pattern regex = Pattern.compile(check);
+        Matcher matcher = regex.matcher(password);
+        if (!matcher.matches()) {
+            throw new MallException("请输入正确的密码");
+        }
+    }
 }

+ 10 - 0
xinkeaboard-server/b2b2c-core/src/main/resources/i18n_en.properties

@@ -1807,6 +1807,7 @@ admin账号不可删除=admin account can not be deleted
 更新直播和短视频设置表失败,请重试=Live updates and short video settings table failed, please try again
 退出成功=exit successfully
 用户名或密码错误=wrong user name or password
+会员邮箱或密码错误=wrong member email or password
 系统开小差了=System deserted
 账号已被冻结=Account has been frozen
 账号不可用=Account unavailable
@@ -2519,9 +2520,17 @@ pc端注册页面logo=
 榜单分类不存在=
 该邮箱已注册,请登录=This email has been registered, please log in
 邮件不能为空=Email cannot be empty
+验证码不能为空=Verification cannot be empty
+请勿频繁操作,请1分钟后重试=Please do not operate frequently, please retry in 1 minute
+验证码发送失败,请重试=Failed to send verification code, please try again
 发送验证邮件失败,请重试=Failed to send verification email, please try again
 发送验证邮件成功=Successfully sent the verification email
+验证码发送成功=Successfully sent the verification code
+验证码已过期,请重新获取=Verification code has expired, please get a new one
+验证码校验失败=Verification code verification failed
+验证码校验成功=Verification code verification successful
 注册链接不正确,请重新注册=The registration link is incorrect, please register again
+密码不一致,请重新输入=Passwords do not match. Please reenter
 会员邮箱不存在,请重新注册=Member email does not exist, please re register
 会员邮箱已激活,无需重复注册,请登录=Member email has been activated, no need to re register, please log in
 注册链接激活码已失效,请重新注册=The registration link activation code has expired, please re register
@@ -2537,6 +2546,7 @@ pc端注册页面logo=
 重置密码链接已失效,请重新获取=The reset password link has expired, please obtain it again
 亲爱的=Dear 
 感谢您申请注册=Thank you for applying for registration
+验证码=Verification code
 请点击或复制以下链接到浏览器激活账号=Please click or copy the following link to the browser to activate your account
 欢迎注册=Welcome to register 
 请验证您的邮箱=Please verify your email

+ 198 - 1
xinkeaboard-server/b2b2c-web/src/main/java/com/slodon/b2b2c/controller/member/front/advich/MemberEmailActiveController.java

@@ -22,7 +22,6 @@ import io.swagger.annotations.Api;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.util.CollectionUtils;
-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;
@@ -30,7 +29,10 @@ import org.springframework.web.bind.annotation.RestController;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author cyan
@@ -62,6 +64,13 @@ public class MemberEmailActiveController extends BaseController {
     @Resource
     private VendorModel vendorModel;
 
+    private static final Map<Integer, String> EMAIL_KEY_MAP = new HashMap<>();
+
+    static {
+        EMAIL_KEY_MAP.put(1, RedisConst.SLD_PC_NEW_REGISTER_USER_EMAIL);
+        EMAIL_KEY_MAP.put(2, RedisConst.SLD_PC_FORGET_PWD_USER_EMAIL);
+    }
+
 //    /**
 //     * @param request
 //     * @param email
@@ -140,6 +149,194 @@ public class MemberEmailActiveController extends BaseController {
         return SldResponse.success(Language.translate("发送验证邮件成功", Language.EN_LANGUAGE_TYPE));
     }
 
+
+    /**
+     * 发送注册或忘记密码验证码
+     *
+     * @param request
+     * @param email
+     * @param source
+     * @param type
+     * @return
+     */
+    @PostMapping("/verification/code")
+    public JsonResult<Object> getMemberEmailVerificationCode(HttpServletRequest request, String email, Integer source, Integer type) {
+        log.info("getMemberEmailVerificationCode - email:{},source:{},type:{}", email, source, type);
+        if (StringUtil.isEmpty(email)) {
+            return SldResponse.fail(Language.translate("邮件不能为空", Language.EN_LANGUAGE_TYPE));
+        }
+        AssertUtil.emailCheck(email);
+
+        // 1. 判断是否在1分钟内已发送过验证码
+        String redisKey = RedisConst.SLD_PC_EMAIL_VERIFY_CODE_LIMIT + email + "::" + type;
+        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(redisKey))) {
+            return SldResponse.fail(Language.translate("请勿频繁操作,请1分钟后重试", Language.EN_LANGUAGE_TYPE));
+        }
+
+        int count;
+        if (type == 1) {
+            count = memberRegisterActiveModel.sendRegisterUserEmailVerificationCode(email, source);
+            AssertUtil.isTrue((count == 0), Language.translate("验证码发送失败,请重试", Language.EN_LANGUAGE_TYPE));
+            AssertUtil.isTrue((count == 2), Language.translate("该邮箱已注册,请登录", Language.EN_LANGUAGE_TYPE));
+        } else {
+            count = memberRegisterActiveModel.checkMemberUserInfo(email, type);
+            AssertUtil.isTrue((count == 0), Language.translate("验证码发送失败,请重试", Language.EN_LANGUAGE_TYPE));
+            AssertUtil.isTrue((count == 2), Language.translate("该邮箱未激活,请先激活", Language.EN_LANGUAGE_TYPE));
+            AssertUtil.isTrue((count == 3), Language.translate("该邮箱未注册,请先注册", Language.EN_LANGUAGE_TYPE));
+        }
+        // 2. 设置 Redis 标记,1分钟内不可重复发送
+        stringRedisTemplate.opsForValue().set(redisKey, "1", 60, TimeUnit.SECONDS);
+        return SldResponse.success(Language.translate("验证码发送成功", Language.EN_LANGUAGE_TYPE));
+
+    }
+
+
+    /**
+     * 校验注册或忘记密码验证码
+     *
+     * @param request
+     * @param email
+     * @param type
+     * @param verificationCode
+     * @return
+     */
+    @PostMapping("/check/verification/code")
+    public JsonResult<Object> checkMemberEmailVerificationCode(HttpServletRequest request, String email, Integer type, String verificationCode) {
+        log.info("checkMemberEmailVerificationCode - email:{},type:{},verificationCode:{}", email, type, verificationCode);
+        if (StringUtil.isEmpty(email)) {
+            return SldResponse.fail(Language.translate("邮件不能为空", Language.EN_LANGUAGE_TYPE));
+        }
+        if (StringUtil.isEmpty(verificationCode)) {
+            return SldResponse.fail(Language.translate("验证码不能为空", Language.EN_LANGUAGE_TYPE));
+        }
+        AssertUtil.emailCheck(email);
+
+        String baseKey = EMAIL_KEY_MAP.get(type);
+        if (baseKey == null) {
+            return SldResponse.fail(Language.translate("验证码不能为空", Language.EN_LANGUAGE_TYPE));
+        }
+
+        String redisKey = baseKey + email;
+        if (!stringRedisTemplate.hasKey(redisKey)) {
+            return SldResponse.fail(Language.translate("验证码已过期,请重新获取", Language.EN_LANGUAGE_TYPE));
+        }
+
+        String storedCode = stringRedisTemplate.opsForValue().get(redisKey);
+        if (!verificationCode.equals(storedCode)) {
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("验证码校验失败", Language.EN_LANGUAGE_TYPE));
+        }
+        stringRedisTemplate.delete(redisKey);
+        return SldResponse.success(Language.translate("验证码校验成功", Language.EN_LANGUAGE_TYPE));
+    }
+
+
+    /**
+     * 注册
+     * @param request
+     * @param email
+     * @param nickName
+     * @param password
+     * @param confirmPassword
+     * @return
+     */
+    @PostMapping("/register")
+    public JsonResult<Object> activeMemberEmailInfo(HttpServletRequest request, String email, String nickName, String password,String confirmPassword) {
+        log.info("activeMemberEmailInfo - email:{},nickName:{},password:{},confirmPassword:{}", email, nickName, password,confirmPassword);
+        if (StringUtil.isEmpty(email)) {
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("邮件不能为空", Language.EN_LANGUAGE_TYPE));
+        }
+        if(!password.equals(confirmPassword)){
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("密码不一致,请重新输入", Language.EN_LANGUAGE_TYPE));
+        }
+        AssertUtil.passwordCheck(password);
+        MemberExample memberExample = new MemberExample();
+        memberExample.setMemberEmail(email.toLowerCase());
+        List<Member> memberList = memberReadMapper.listByExample(memberExample);
+        if (CollectionUtils.isEmpty(memberList)) {
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("会员邮箱不存在,请重新注册", Language.EN_LANGUAGE_TYPE));
+        }
+
+        Member memberInfo = memberList.get(0);
+        if (memberInfo.getIsEmailActive() != null && memberInfo.getIsEmailActive() == 1) {
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("会员邮箱已激活,无需重复注册,请登录", Language.EN_LANGUAGE_TYPE));
+        }
+
+        // 更新用户邮箱激活状态
+        Member memberNew = new Member();
+        memberNew.setMemberId(memberInfo.getMemberId());
+        memberNew.setIsEmailActive(1);
+        memberNew.setUpdateTime(new Date());
+        memberNew.setMemberNickName(nickName);
+        memberNew.setLoginPwd(Md5.getMd5String(password));
+        memberModel.updateMember(memberNew);
+
+        // 发送账户注册成功邮件
+        memberRegisterActiveModel.sendRegisterSuccessEmail(email, nickName);
+        return SldResponse.success(Language.translate("会员邮箱账户激活成功", Language.EN_LANGUAGE_TYPE));
+    }
+
+
+
+    /**
+     * 用户邮箱重置忘记密码
+     *
+     * @param request
+     * @param email
+     * @param verificationCode
+     * @param loginPwd
+     * @param confirmPassWord
+     * @return
+     */
+    @PostMapping("/email/reset/pwdNew")
+    public JsonResult<Object> emailResetPwdNew(HttpServletRequest request, String email, String verificationCode, String loginPwd, String confirmPassWord) {
+        log.info("emailResetPwd - email:{},verificationCode:{},loginPwd:{},confirmPassWord:{}", email, verificationCode, loginPwd, confirmPassWord);
+        if (StringUtil.isEmpty(email) ) {
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("邮件不能为空", Language.EN_LANGUAGE_TYPE));
+        }
+        MemberExample memberExample = new MemberExample();
+        memberExample.setMemberEmail(email.toLowerCase());
+        List<Member> memberList = memberReadMapper.listByExample(memberExample);
+
+        if (CollectionUtils.isEmpty(memberList)) {
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("该邮箱不存在,请先注册", Language.EN_LANGUAGE_TYPE));
+        }
+
+        Member memberInfo = memberList.get(0);
+        if (memberInfo.getIsEmailActive() != null && memberInfo.getIsEmailActive() == 0) {
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("该邮箱未激活,请先激活", Language.EN_LANGUAGE_TYPE));
+        }
+
+        if(!loginPwd.equals(confirmPassWord)){
+            return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("密码不一致,请重新输入", Language.EN_LANGUAGE_TYPE));
+        }
+
+        AssertUtil.passwordCheck(loginPwd);
+
+        String forgetPwdEmailKey = RedisConst.SLD_PC_FORGET_PWD_USER_EMAIL + email;
+        log.info("forgetPwdEmailKey:{}", forgetPwdEmailKey);
+        if (stringRedisTemplate.hasKey(forgetPwdEmailKey)) {
+            String verifyNumber = stringRedisTemplate.opsForValue().get(forgetPwdEmailKey);
+            log.info("verifyNumber:{}", verifyNumber);
+            if (!verificationCode.equals(verifyNumber)) {
+                return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("验证码校验失败", Language.EN_LANGUAGE_TYPE));
+            }
+
+            // 更新用户密码
+            Member memberNew = new Member();
+            memberNew.setMemberId(memberInfo.getMemberId());
+            memberNew.setLoginPwd(Md5.getMd5String(loginPwd));
+            memberNew.setUpdateTime(new Date());
+            memberModel.updateMember(memberNew);
+
+            stringRedisTemplate.delete(forgetPwdEmailKey);
+
+            return SldResponse.success(Language.translate("重置登录密码成功", Language.EN_LANGUAGE_TYPE));
+        }
+        return SldResponse.fail(ResponseConst.STATE_FAIL, Language.translate("验证码已过期,请重新获取", Language.EN_LANGUAGE_TYPE));
+    }
+
+
+
     /**
      * 用户邮箱链接激活
      *

+ 1 - 1
xinkeaboard-server/b2b2c-web/src/main/java/com/slodon/b2b2c/controller/sso/front/FrontAuthController.java

@@ -118,7 +118,7 @@ public class FrontAuthController {
                     // 检测gp系统用户是否存在
                     GpUserInfoDto gpUserInfoDto = oneClickLoginModel.checkGpSystemUserIsExist(request, username, password, "PC");
                     if (gpUserInfoDto == null) {
-                        AssertUtil.notEmpty(memberList, Language.translate("用户名或密码错误",Language.EN_LANGUAGE_TYPE));
+                        AssertUtil.notEmpty(memberList, Language.translate("会员邮箱或密码错误",Language.EN_LANGUAGE_TYPE));
                         AssertUtil.isTrue(!memberList.get(0).getLoginPwd().equals(Md5.getMd5String(password)), Language.translate("用户名或密码错误",Language.EN_LANGUAGE_TYPE));
                     } else {
                         memberList = memberModel.getMemberList(memberExample, null);

+ 93 - 0
xinkeaboard-server/b2b2c-web/src/main/java/com/slodon/b2b2c/model/member/advich/MemberRegisterActiveModel.java

@@ -5,6 +5,7 @@ import com.slodon.b2b2c.captcha.work.Producer;
 import com.slodon.b2b2c.core.config.DomainUrlUtil;
 import com.slodon.b2b2c.core.constant.RedisConst;
 import com.slodon.b2b2c.core.i18n.Language;
+import com.slodon.b2b2c.core.random.RandomUtil;
 import com.slodon.b2b2c.core.uid.GoodsIdGenerator;
 import com.slodon.b2b2c.core.util.StringUtil;
 import com.slodon.b2b2c.dao.read.member.MemberReadMapper;
@@ -269,4 +270,96 @@ public class MemberRegisterActiveModel {
         String subject = Language.translate("注册成功", Language.EN_LANGUAGE_TYPE) + " " + pcDomainUrl.toUpperCase();
         msgSendModel.sendHtmlMail(email, subject, emailMsgTpl.toString());
     }
+
+    public Integer sendRegisterUserEmailVerificationCode(String email, Integer source) {
+        int res = 0;
+        MemberExample example = new MemberExample();
+        example.setMemberEmail(email.toLowerCase());
+        List<Member> memberList = memberReadMapper.listByExample(example);
+        if (CollectionUtil.isNotEmpty(memberList)) {
+            Member memberInfo = memberList.get(0);
+            if (memberInfo.getIsEmailActive() == 0) {
+                sendEmailRegisterVerificationCode(email);
+                res = 1;
+            } else {
+                res = 2;
+            }
+        } else {
+            res = 1;
+            sendEmailRegisterVerificationCode(email);
+            saveEmailUserInfo(email, source);
+        }
+        return res;
+    }
+
+    private void sendEmailRegisterVerificationCode(String email) {
+        String pcDomainUrl = DomainUrlUtil.SLD_PC_URL.replace("http://", "").replace("https://", "");
+        String verifCode = "";
+        //邮件验证码过期时间,单位秒
+        long expireTime = RedisConst.REGISTER_USER_AND_FORGETPWD_USER_EMAIL_VERIFICATION_CODE_EXPIRE_TIME;
+        //将随机数存在redis中
+        String activeEmailKey = RedisConst.SLD_PC_NEW_REGISTER_USER_EMAIL + email;
+        if (stringRedisTemplate.hasKey(activeEmailKey)) {
+            stringRedisTemplate.delete(activeEmailKey);
+        } else {
+            verifCode = RandomUtil.randomNumber(4);
+            stringRedisTemplate.opsForValue().set(activeEmailKey, verifCode, expireTime, TimeUnit.SECONDS);
+        }
+
+        StringBuffer emailMsgTpl = new StringBuffer();
+        emailMsgTpl.append(Language.translate("感谢您申请注册", Language.EN_LANGUAGE_TYPE) + "\r\n");
+        emailMsgTpl.append(Language.translate("验证码", Language.EN_LANGUAGE_TYPE));
+        emailMsgTpl.append(":" + verifCode);
+
+        String subject = Language.translate("欢迎注册", Language.EN_LANGUAGE_TYPE) + pcDomainUrl.toUpperCase() + "," + Language.translate("请验证您的邮箱", Language.EN_LANGUAGE_TYPE);
+        msgSendModel.sendHtmlMail(email, subject, emailMsgTpl.toString());
+    }
+
+    public Integer checkMemberUserInfo(String email, Integer type) {
+        int res = 0;
+        MemberExample memberExample = new MemberExample();
+        memberExample.setMemberEmail(email);
+        List<Member> memberList = memberReadMapper.listByExample(memberExample);
+        if (CollectionUtil.isNotEmpty(memberList)) {
+            Member memberInfo = memberList.get(0);
+            if (memberInfo.getIsEmailActive() == 1) {
+                sendEmailForgetPasswordVerificationCode(email, memberInfo.getMemberNickName());
+                res = 1;
+            } else {
+                res = 2;
+            }
+        } else {
+            res = 3;
+        }
+        return res;
+    }
+
+    private void sendEmailForgetPasswordVerificationCode(String email, String nickName) {
+        String pcDomainUrl = DomainUrlUtil.SLD_PC_URL.replace("http://", "").replace("https://", "");
+        String verifCode = "";
+        //重置密码验证码过期时间,单位秒
+        long expireTime = RedisConst.REGISTER_USER_AND_FORGETPWD_USER_EMAIL_VERIFICATION_CODE_EXPIRE_TIME;
+        //将随机数存在redis中
+        String forgetPwdEmailKey = RedisConst.SLD_PC_FORGET_PWD_USER_EMAIL + email;
+        if (stringRedisTemplate.hasKey(forgetPwdEmailKey)) {
+            stringRedisTemplate.delete(forgetPwdEmailKey);
+        } else {
+            verifCode = RandomUtil.randomNumber(4);
+            stringRedisTemplate.opsForValue().set(forgetPwdEmailKey, verifCode, expireTime, TimeUnit.SECONDS);
+        }
+
+
+        StringBuffer emailMsgTpl = new StringBuffer(Language.translate("亲爱的", Language.EN_LANGUAGE_TYPE));
+        emailMsgTpl.append(StringUtil.isEmpty(nickName) ? email : nickName + ":" + "<br/>");
+        emailMsgTpl.append(Language.translate("验证码", Language.EN_LANGUAGE_TYPE));
+        emailMsgTpl.append(":" + verifCode);
+        emailMsgTpl.append("<br/>");
+        emailMsgTpl.append(Language.translate("如果您没有请求新密码,请忽略此邮件。", Language.EN_LANGUAGE_TYPE) + "<br/>");
+        emailMsgTpl.append(Language.translate("这是系统邮件,请不要回复。", Language.EN_LANGUAGE_TYPE) + "<br/>");
+        emailMsgTpl.append("<br/>");
+        emailMsgTpl.append(Language.translate("最好的问候", Language.EN_LANGUAGE_TYPE) + "<br/>");
+        emailMsgTpl.append(pcDomainUrl);
+        String subject = Language.translate("重设您的", Language.EN_LANGUAGE_TYPE) + pcDomainUrl.toUpperCase() + " " + Language.translate("帐户密码", Language.EN_LANGUAGE_TYPE);
+        msgSendModel.sendHtmlMail(email, subject, emailMsgTpl.toString());
+    }
 }