业务实现
(一) 字段校验
- 检验用户名、密码、手机号、验证码
- 如果校验不通过则刷新页面,并显示字段校验失败信息
(二) 校验验证码
- 点击发送验证码,验证会保存一份到redis,并且会发送至手机
- 输入验证码与redis取出的验证码进行比对
- 如果验证码不存在则表示redis中验证码已失效,则刷新页面显示 “验证码已失效”
- 验证码存在则进行比较,失败则表示输入错误,刷新页面显示 “验证码不正确”
(三) 用户注册
- 如果验证码校验成功则调用会员服务进行注册
- 设置默认等级
- 判断用户名是否唯一、手机号是否唯一,不唯一则抛出异常
- 使用md5+盐值的方式加密用户密码
(四) 注册成功跳转至登陆页
代码
- 字段校验
@Data
public class UserRegistVo {
@NotBlank(message = "用户名必须填写")
@Length(min = 6,max = 18,message = "用户名必须是6到18位字符")
private String userName;
@NotBlank(message = "密码必须填写")
@Length(min = 6,max = 18,message = "密码必须是6到18位字符")
private String password;
@NotBlank(message = "手机号必须填写")
@Pattern(regexp = "^[1]([3-9])[0-9]{9}$", message = "手机号格式不正确")
private String phone;
@NotBlank(message = "验证码必须填写")
private String code;
}
- 将验证码存入redis,然后发送验证码
/**
* 点击发送验证码
*/
@ResponseBody//thymeleaf异常,无法解析模版数据,
@GetMapping("/sms/sendcode")
public R sendCode(@RequestParam("phone") String phone){
//如果时间<60秒就稍后再试
String redisCode = redisTemplate.opsForValue().get(AuthServiceConstant.SMS_CODE_CACAHE_PRIFIX + phone);
if (!StringUtils.isEmpty(redisCode)){
Long time = Long.parseLong(redisCode.split("_")[1]);
if ((System.currentTimeMillis() - time) < 60000){
return R.error(BizCodeEnum.SMSCODE_EXCEPTIPN.getCode(),BizCodeEnum.SMSCODE_EXCEPTIPN.getMsg());
}
}
//存redis key-phone,value-code,过期时间:10分钟
//String code = UUID.randomUUID().toString().substring(0, 5);
String code = strCode();
String redisVal = code + "_" + System.currentTimeMillis();
redisTemplate.opsForValue().set(AuthServiceConstant.SMS_CODE_CACAHE_PRIFIX+phone,redisVal,10, TimeUnit.MINUTES);
//发送验证码
feignService.sms(phone,code);
return R.ok();
}
public String strCode(){
Random random = new Random();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 4; i++) {
int nextInt = random.nextInt(10);
stringBuilder.append(nextInt);
}
return stringBuilder.toString();
}
- 验证码校验
//TODO 重定向携带数据将数据存入Session ——> 分布式Session不共享问题?
@PostMapping("/regist")//点击立即注册发送请求
public String regist(@Valid UserRegistVo vo, BindingResult result, RedirectAttributes redirectAttributes){
//如果校验不通过,刷新页面,展示错误信息
if(result.hasErrors()) {
//1.取出校验失败结果,存入map
Map<String, String> errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
//2.向请求域传值
redirectAttributes.addFlashAttribute("errors", errors);
//3.校验出现错误——>重定向页面到注册页
return "redirect:http://auth.gulimall.com/reg.html";
}
//校验通过
//1111_15171284192
String redisVal = redisTemplate.opsForValue().get(AuthServiceConstant.SMS_CODE_CACAHE_PRIFIX + vo.getPhone());
if (!StringUtils.isEmpty(redisVal)){
String phone = redisVal.split("_")[0];
if (vo.getCode().equals(phone)){
//验证码通过,调用member服务注册会员
R r = memberFeignService.regist(vo);
if (r.getCode() == 0){
//用户注册成功,跳转到登陆页
return "redirect:http://auth.gulimall.com/login.html";
}else {
//用户注册失败,用户名已存在或手机号已存在
Map<String, String> map = new HashMap<>();
String msg = (String)r.getMsg(new TypeReference<String>() {});
if (r.getCode().equals(BizCodeEnum.USERNAME_EXIST_EXCEPTION.getCode())){
map.put("userName",msg);
}
if (r.getCode().equals(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode())){
map.put("phone",msg);
}
redirectAttributes.addFlashAttribute("errors",map);
return "redirect:http://auth.gulimall.com/reg.html";
}
}else {
//验证码不正确
Map<String, String> map = new HashMap<>();
map.put("code","验证码不正确");
redirectAttributes.addFlashAttribute("errors",map);
return "redirect:http://auth.gulimall.com/reg.html";
}
}else {
//验证码不存在,已失效
Map<String, String> map = new HashMap<>();
map.put("code","验证码已失效");
redirectAttributes.addFlashAttribute("errors",map);
return "redirect:http://auth.gulimall.com/reg.html";
}
}
- 用户注册
//注册会员
@Transactional()
@Override
public void regist(MemberUserRegistVo vo) {
MemberEntity memberEntity = new MemberEntity();
//默认等级
MemberLevelEntity memberLevelEntity = this.baseMapper.selectLevel();
memberEntity.setLevelId(memberLevelEntity.getId());
//判断用户名、手机号是否唯一
Integer usernameCount = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", vo.getUserName()));
if (usernameCount > 0){
throw new UserNameException();
}
memberEntity.setUsername(vo.getUserName());
Integer phoneCount = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", vo.getPhone()));
if (phoneCount > 0){
throw new PhoneException();
}
memberEntity.setMobile(vo.getPhone());
//密码md5盐值加密
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode = bCryptPasswordEncoder.encode(vo.getPassword());
memberEntity.setPassword(encode);
memberEntity.setGender(0);
memberEntity.setCreateTime(new Date());
this.baseMapper.insert(memberEntity);
}