新用户注册

news2024/11/29 11:56:30

在这里插入图片描述

业务实现

(一) 字段校验

  1. 检验用户名、密码、手机号、验证码
  2. 如果校验不通过则刷新页面,并显示字段校验失败信息

(二) 校验验证码

  1. 点击发送验证码,验证会保存一份到redis,并且会发送至手机
  2. 输入验证码与redis取出的验证码进行比对
  3. 如果验证码不存在则表示redis中验证码已失效,则刷新页面显示 “验证码已失效”
  4. 验证码存在则进行比较,失败则表示输入错误,刷新页面显示 “验证码不正确”

(三) 用户注册

  1. 如果验证码校验成功则调用会员服务进行注册
  2. 设置默认等级
  3. 判断用户名是否唯一、手机号是否唯一,不唯一则抛出异常
  4. 使用md5+盐值的方式加密用户密码

(四) 注册成功跳转至登陆页

代码

  1. 字段校验
@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;
}
  1. 将验证码存入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();

    }

  1. 验证码校验
//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";
        }

    }
  1. 用户注册
//注册会员
    @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);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/663978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大数据hive】hive 拉链表设计与实现

目录 一、前言 二、拉链表业务背景 2.1 数据同步引发的问题 2.1.1 解决方案1 2.1.2 解决方案2 2.1.3 解决方案3 三、拉链表设计与原理 3.1 功能与应用场景 3.2 实现步骤 3.2.1 Step1 3.2.2 Step2 3.2.3 Step3 3.3 操作演示 3.3.1 创建一张表并加载数据 3.3.2 模…

高级数据分析师工作的基本职责(合集)

高级数据分析师工作的基本职责1 职责&#xff1a; 1. 负责出行平台层面司乘用户分析&#xff0c;给平台相关业务及策略建设输入洞察和方法; 2. 形成天、周和月度的分析报告&#xff0c;传递给公司管理层并进行定期汇报; 3. 可独立完成针对特定问题的分析解读&#xff0c;支持临…

【数据分享】2023年全国范围的1km分辨率高新技术企业数量栅格数据

企业是经济活动的参与主体。一个城市的企业数量决定了这个城市的经济发展水平&#xff01;比如一个城市的金融企业较多&#xff0c;那这个城市的金融产业肯定比较发达&#xff1b;一个城市的制造业企业较多&#xff0c;那这个城市的制造业肯定比较发达。 目前&#xff0c;在城…

插件 - 一份配置,离插件机制只有一步之遥

文章目录 Pre优化方案流程图优点缺点举例论证CodePre 插件 - 通过SPI方式实现插件管理 中我们提到了缺点 无法保证唯一实现:在SPI机制中,同一个服务接口可能会有多个提供者实现,而无法明确指定使用哪一个。依赖于配置文件:配置文件是发现和加载提供者的关键,如果配置文件…

Java泛型中的T、E、K、V、?通配符,你确定都了解吗?

目录 前言 泛型带来的好处 泛型中通配符 小结 前言 Java 泛型&#xff08;generics&#xff09;是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制&#xff0c;该机制允许开发者在编译时检测到非法的类型。 泛型的本质是参数化类型&#xff0c;也就是说所操…

7.controller部署neutron服务

Neutron 为整个 openstack 提供虚拟化的网络支持&#xff0c;主要功能包括二层交换、三层路由、防火墙、VPN &#xff0c;以及负载均衡等。 neutron数据库配置 controller节点 在安装和配置 neutron 服务之前&#xff0c;必须创建服务对应的数据库用于存储相关数据 &#xff0…

多模态简介

1. 多模态定义 多模式深度学习是一个机器学习子领域&#xff0c;旨在训练人工智能模型来处理和发现不同类型数据&#xff08;模式&#xff09;之间的关系——通常是图像、视频、音频和文本。通过结合不同的模态&#xff0c;深度学习模型可以更普遍地理解其环境&#xff0c;因为…

【C++】I/O流类库

I/O 数据的输入和输出&#xff08;input/output简写为I/O&#xff09;&#xff0c;对标准输入设备和标准输出设备的输入输出简称为标准I/O。对在外存磁盘上的文件输入输出简称为文件I/O。对内存中指定的字符串存储空间的输入输出简称为串I/O。 流 数据输入输出的过程&#x…

边缘智能:边缘计算和人工智能的深度融合

摘要 随着通信技术的飞速发展和移动设备使用的激增&#xff0c;一种全新的计算范式——边缘计算正在迅速普及。与此同时&#xff0c;随着深度学习的突破和硬件架构的许多改进&#xff0c;人工智能(AI)应用正在蓬勃发展。在网络边缘产生数十亿字节的数据&#xff0c;对数据处理…

也聊聊BLDC 电机的 10 大热门应用---【其利天下技术分享】

近年来&#xff0c;随着全球提出的低碳&#xff0c;高能效的概念提出&#xff0c;作为高效动力来源的BLDC技术&#xff0c;越来越受到各界的追捧。 大家都知道&#xff0c;BLDC的发展史也就短短几十年的时间&#xff0c;随着近年来&#xff0c;新磁性材料的运用、微电子技术和…

基于大模型的虚拟数字人__虚拟主播实例

基于大模型的虚拟数字人__虚拟主播实例 本文目录&#xff1a; 一、技术的背景&#xff1a; 二、创意名称&#xff1a; 三、创意背景 四、创意目标 五、创意设计 六、技术实现路径 七、完整代码实现 八、创意总结 九、人工智能虚拟人物的一些优秀代表作品及其特点 十、…

河道水位标尺识别预警 yolov7

河道水位标尺识别预警系统通过pythonyolov7网络模型技术&#xff0c;河道水位标尺识别预警算法对河道水位标尺进行实时监测&#xff0c;当河道水位出现异常情况时&#xff0c;河道水位标尺识别预警算法将自动发出警报提示后台管理人员及时采取措施。YOLO系列算法是一类典型的on…

【工具篇】SpringBoot基于assembly的服务化打包方案

简介 最近项目中&#xff0c;使用插件式开发方式&#xff0c;将多个Web应用打成一个FatJar程序包部署运行。但考虑到原始裸Jar包方式交付&#xff0c;有很多不便之处&#xff0c;比如启动命令过长&#xff08;JVM参数配置、Spring环境配置等&#xff09;、配置无法修改等问题会…

基于OpenMV的自动驾驶智能小车模拟系统

一、项目简介 基于机器视觉模块OpenMV采集车道、红绿灯、交通标志等模拟路况信息&#xff0c;实现一辆能车道保持、红绿灯识别、交通标志识别、安全避障以及远程WiFi控制的多功能无人驾驶小车。 赛道规格&#xff1a; 1、编程所需软件&#xff1a; OpenMV&#xff1a;使用Op…

cuda pyinstall cvs 使用记录

1.pip 换源 pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/2.安装匹配cuda的pytorch 官网&#xff1a;PyTorch pip3 install torch torchvision torchaudio查看能否使用cuda: import torch torch.cuda.is_available()获得以下反馈&#xff1a; 意思…

CSS基础学习--22 图像透明/不透明

一、透明度属性 CSS3中属性的透明度是 opacity 正常的图像 相同的图像带有透明度&#xff1a; img {opacity:0.4;filter:alpha(opacity40); /* IE8 及其更早版本 */ } 备注&#xff1a;Opacity属性值从0.0 - 1.0。值越小&#xff0c;使得元素更加透明。 IE8和早期版本使用滤…

【MySQL】库和表结构的增删查改

目录 一、库的操作 1、创建数据库 2、数据库所使用的编码 2.1查询编码集和校验集 2.2查看数据库的字符集和校验集 2.3创建数据库指定字符集和校验集 2.4不同的校验集所筛选的数据结果不一样 3、查看数据库 4、修改数据库 5、删除数据库 6、数据库的备份和恢复 6.1备…

【Spring MVC】获取 @RequsetBody 标识的对象,使用适配器模式增加代码可读性

1. 前言 一个技术需求引发的思考和实践&#xff1a; 思考 用 AOP 把校验代码 实践 用 Spring MVC 的 RequestBodyAdvice 做AOP逻辑继承 RequestBodyAdviceAdapter 实现自己的 适配器用自己的适配器让代码可读性增加熟悉 Spring MVC 、Java 反射的一些实践 本文内容 澄清一个A…

Mysql 调优

前言 硬件层面&#xff1a;使用固态硬盘、扩大内存、加大带宽等等 架构层面&#xff1a;主从复制实现读写分离【一主一 或 双主双从】 表结构层面&#xff1a;对表结构进行垂直拆分、水平分表、分库分表。常用的数据库中间件有&#xff1a;MySQL Proxy、MyCat以及ShardingSphe…

电脑C盘的清理 | 微信QQ缓存信息

记录一下我处理C盘爆满时的几个方法&#xff0c;基本上都是可以日常使用的。 一、磁盘清理 链接 二、查看具体哪些文件占内存 win图标右击 -----> 点击“系统&#xff08;Y&#xff09;” 点击查看具体是哪些文件夹哪些app占用了大量的内存&#xff0c;并选择删除部分…