说明:

(1)本篇博客内容:继续开发【注册/登录】接口;

● 在【25:第三章:开发通行证服务:8:【注册/登录】接口:接收并校验“手机号和验证码”参数;】中,【注册/登录】接口,只开发了【校验验证码是否OK】;

● 本篇博客,继续完善【注册/登录】接口:验证码校验OK后,先根据手机号去查查该用户是否已存在,如果用户不存在就创建这个用户;

目录

一:继续完善【注册/登录】接口:验证码校验OK后,先根据手机号去查查该用户是否已存在,如果用户不存在就创建这个用户;

1.【user】用户微服务中,PassportController中的【注册/登录】接口:继续完善;

二: 创建Service层,并创建对应的方法;

1.在【user】用户微服务中,创建service包,UserService接口、impl包,UserServiceImpl实现类;

2.UserService接口:定义两个方法:【根据手机号,查询该用户是否已存在:queryMobileIsExist()】、【新增用户:createUser()】;

3.UserServiceImpl实现类:实现上面定义的两个方法:【根据手机号,查询该用户是否已存在:queryMobileIsExist()】、【新增用户:createUser()】;

(1)先看下app_user用户表的内容;

(2)【根据手机号,查询该用户是否已存在:queryMobileIsExist()】:利用tkmybatis的Example,自定义查询条件;然后,去查询数据库;

(3.1)【新增用户:createUser()】:这个方法是个非查询操作,我们使用了【@Transactional】注解去控制事务;

(3.2)【新增用户:createUser()】:创建工具类,去生成app_user表的主键;(使用IdWorker工具类,基于雪花算法)

(3.3)【新增用户:createUser()】:设置用户默认昵称的时候,我们选择使用【用户+18888888888】的形式;而为了保护用户隐私,防止手机号泄露,我们在【common】通用工程中创建【信息脱敏工具DesensitizationUtil工具类】,来设置成【用户+18******888】的形式;

(3.4)【新增用户:createUser()】:设置用户头像图片的地址;

(3.5)【新增用户:createUser()】:设置用户生日;(在【common】通用工程中,创建了DateUtil工具类,其可以把【符合格式的日期字符串】转成【对应的java.util.Date格式的日期】)

(3.6)【新增用户:createUser()】:设置用户性别;(性别,在数据库中使用【性别 1:男  0:女  2:保密】的数字来代表的;所以,对于这种数据,老套路,最好使用枚举类管理起来)(在【common】通用工程中,创建枚举类Sex)

(3.7)【新增用户:createUser()】:设置用户用户激活状态(用户刚创建用户的时候,其状态默认设为“未激活”);(和“性别”同理,用户激活状态也使用枚举类管理起来)(在【common】通用工程中,创建枚举类UserStatus)

(3.8)【新增用户:createUser()】:构建好AppUser对象后,调用Dao层方法,去新增用户;

三:效果;


一:继续完善【注册/登录】接口:验证码校验OK后,先根据手机号去查查该用户是否已存在,如果用户不存在就创建这个用户;

1.【user】用户微服务中,PassportController中的【注册/登录】接口:继续完善;

    /*** 【一键注册/登录,接口】* @param registLoginBo* @param result* @return*/@Overridepublic GraceJSONResult doLogin(@Valid RegistLoginBo registLoginBo, BindingResult result) {//0.判断BindingResult中是否保存了验证失败的错误信息,如果有,说明前端的输入是有问题的(手机号或者验证码,至少有一个没输入);// 那么,我们就获取这个错误信息,并构建一个GraceJSONResult统一返回对象,返回;if (result.hasErrors()) {Map<String, String> map = getErrorsFromBindingResult(result);return GraceJSONResult.errorMap(map);}//1.校验验证码是否匹配;//1.1 获取用户在前端输入的手机号和验证码;String mobile = registLoginBo.getMobile();String smsCode = registLoginBo.getSmsCode();//1.2 根据用户在前端输入的手机号,尝试去redis中获取对应的验证码;String redisSMSCode = redisOperator.get(MOBILE_SMSCODE + ":" + mobile);//1.3如果前端输入的验证码,在redis中不存在(说明:我们并没有针对【用户输入的这个手机号码】发送过验证码;// 或者说是用户在收到验证码短信后,过了30min后才使用,redis中存的验证码过期失效了),// 或者前端输入的验证码和redis中的不一样(说明:用户的验证码输错了);// 那么,就返回对应的,包含错误信息的GraceJSONResult统一返回对象;// 其中,这儿我们利用【org.apache.commons.lang3】中的StringUtils工具类的isBlank()方法来判空;if (StringUtils.isBlank(redisSMSCode) || !redisSMSCode.equals(smsCode)) {return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);}//2.利用手机号,查询数据库中,该用户是否已注册;AppUser user = userService.queryMobileIsExist(mobile);//2.1如果用户存在但是已经冻结;直接返回对应的(包含错误信息)的GraceJSONResult统一返回对象if ((user != null) && (user.getActiveStatus() == UserStatus.FROZEN.type)) {return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_FROZEN);} else if (user == null) {//2.2如果用户为空,我们就去注册这个用户user = userService.createUser(mobile);}return GraceJSONResult.ok(user);}

说明:

(1)完善内容;

(2)在后面我们调用,后面编写的Service层的方法;所以这儿我们需要注入UserService对象;

(3)逻辑说明,看注释;

(4)Service层的UserService和UserServiceImpl,在下面介绍;


二: 创建Service层,并创建对应的方法;

1.在【user】用户微服务中,创建service包,UserService接口、impl包,UserServiceImpl实现类;

2.UserService接口:定义两个方法:【根据手机号,查询该用户是否已存在:queryMobileIsExist()】、【新增用户:createUser()】;

package com.imooc.user.service;import com.imooc.pojo.AppUser;public interface UserService {/*** 查询【用户输入的手机号码】是否存在;即,查询用户是否存在;* 如果用户存在,返回user信息;* @param mobile* @return*/public AppUser queryMobileIsExist(String mobile);/*** 创建用户,新增用户记录到数据库;* @param mobile* @return*/public AppUser createUser(String mobile);}

说明:

(1)根据【注册/登录】接口的逻辑需求,在Service层这儿定义了两个方法:

● 一个是:根据用户手机号,查询该用户是否已存在;一个是:新增用户;

3.UserServiceImpl实现类:实现上面定义的两个方法:【根据手机号,查询该用户是否已存在:queryMobileIsExist()】、【新增用户:createUser()】;

package com.imooc.user.service.impl;import com.imooc.enums.Sex;
import com.imooc.enums.UserStatus;
import com.imooc.pojo.AppUser;
import com.imooc.user.mapper.AppUserMapper;
import com.imooc.user.service.UserService;
import com.imooc.utils.DateUtil;
import com.imooc.utils.DesensitizationUtil;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;import java.util.Date;@Service
public class UserServiceImpl implements UserService {@Autowiredpublic AppUserMapper appUserMapper;@Autowiredpublic Sid sid;//这儿,课程方给提供了三张用户头像图片;自己可以先用着;private static final String USER_FACE0 = "http://122.152.205.72:88/group1/M00/00/05/CpoxxFw_8_qAIlFXAAAcIhVPdSg994.png";private static final String USER_FACE1 = "http://122.152.205.72:88/group1/M00/00/05/CpoxxF6ZUySASMbOAABBAXhjY0Y649.png";private static final String USER_FACE2 = "http://122.152.205.72:88/group1/M00/00/05/CpoxxF6ZUx6ANoEMAABTntpyjOo395.png";/*** 查询【用户输入的手机号码】是否存在;即,查询用户是否存在;* 如果用户存在,返回user信息;* @param mobile* @return*/@Overridepublic AppUser queryMobileIsExist(String mobile) {//1.利用tkmybatis的Example,自定义查询条件;// 1.1先创建一个查询实例,这个实例,是针对APPUser作查询的;Example userExample = new Example(AppUser.class);//1.2给上面的查询实例,增加查询条件;Example.Criteria userCriteria = userExample.createCriteria();//第一个参数:AppUser实体类中的mobile;第二个参数:queryMobileIsExist这个方法的mobile参数;userCriteria.andEqualTo("mobile", mobile);//2.利用创建好的查询条件,调用方法,去查数据库;AppUser appUser = appUserMapper.selectOneByExample(userExample);return appUser;}/*** 创建用户,新增用户记录到数据库;* @param mobile* @return*/@Transactional@Overridepublic AppUser createUser(String mobile) {/*** 互联网项目都要考虑可扩展性;如果以后的业务激增,就需要考虑分库分表;* 那么,数据库表的主键必须要保证全局唯一;所以,主键ID就不能使用自增主键了;*/String userId = sid.nextShort();//调用,获取一个主键id;AppUser appUser = new AppUser();appUser.setId(userId);//设置主键idappUser.setMobile(mobile);//设置mobile手机号appUser.setNickname("用户" + DesensitizationUtil.commonDisplay(mobile));//设置昵称,这儿我们就用手机号设为其默认昵称了;(自然,我们也可以设置其他昵称;;比如百度账号的默认昵称是【baidu_38686yhjh67】这种)appUser.setFace(USER_FACE1);//设置用户头像图片的地址;appUser.setBirthday(DateUtil.stringToDate("2000-01-01"));//设置生日;appUser.setSex(Sex.secret.type);//设置性别,使用了枚举,默认未知appUser.setActiveStatus(UserStatus.INACTIVE.type);//设置用户激活状态,使用了枚举,默认未激活appUser.setTotalIncome(0);//设置用户收入,默认为0appUser.setCreatedTime(new Date());//创建时间,使用默认的当前时间appUser.setUpdatedTime(new Date());//更新时间,使用默认的当前时间appUserMapper.insert(appUser);return appUser;}
}

说明:

(1)先看下app_user用户表的内容;

(2)【根据手机号,查询该用户是否已存在:queryMobileIsExist()】:利用tkmybatis的Example,自定义查询条件;然后,去查询数据库;

● 首先,要引入Dao层的AppUserMapper接口的对象;然后,这儿我们需要在AppUserMapper接口上,增加一个@Repository注解(我们创建的时候,其默认是没有@Repository注解的);

● 利用tkmybatis的【Example】创建查询实例,【Example.Criteria】设置查询条件;去数据库中查询;

(3.1)【新增用户:createUser()】:这个方法是个非查询操作,我们使用了【@Transactional】注解去控制事务;

● 在【附加:Spring Boot项目,手动控制事务;(包括:总结了到目前为止,事务的所有内容;)】中我们总结了,至今为止遇到过的所有事务;;其中Spring中控制事务,就介绍了使用【@Transactional】注解去控制事务;

(3.2)【新增用户:createUser()】:创建工具类,去生成app_user表的主键;(使用IdWorker工具类,基于雪花算法)

● 互联网项目都要考虑可扩展性、可维护性;尤其是分布式微服务项目,我们在以后的业务激增,就需要考虑分库分表;那么,如果分库分表的话,主键id就不能使用自增主键了;自增主键的可维护性很差;所以,我们需要使用全局id,其可以保证数据库表的主键全局唯一;

● 为此,我们在【common】通用工程中,引入了一个第三方的主键生成的【idworker】;(其是基于雪花算法,生成唯一id的);

● 要想使用这个工具类,我们需要注入Sid对象;

● PS:因为【idworker】是写在了【org.n3r.idworker】这个包中,而在【user】的主启动类上,需要设置@ComponentScan,以让其能够扫描到【org.n3r.idworker】这个包;;;否则,上步注入Sid对象时,其在IoC容器中会找不到Sid对象;

(3.3)【新增用户:createUser()】:设置用户默认昵称的时候,我们选择使用【用户+18888888888】的形式;而为了保护用户隐私,防止手机号泄露,我们在【common】通用工程中创建【信息脱敏工具DesensitizationUtil工具类】,来设置成【用户+18******888】的形式;

(3.4)【新增用户:createUser()】:设置用户头像图片的地址;

(3.5)【新增用户:createUser()】:设置用户生日;(在【common】通用工程中,创建了DateUtil工具类,其可以把【符合格式的日期字符串】转成【对应的java.util.Date格式的日期】)

(3.6)【新增用户:createUser()】:设置用户性别;(性别,在数据库中使用【性别 1:男  0:女  2:保密】的数字来代表的;所以,对于这种数据,老套路,最好使用枚举类管理起来)(在【common】通用工程中,创建枚举类Sex)

● 有关枚举数据类型、枚举类,介绍过N次;枚举类的使用SOP也很明确,没什么好说的;如有需要可以参考【Spring Boot电商项目13:用户模块二:枚举类;】等很多其他相关文章;

(3.7)【新增用户:createUser()】:设置用户用户激活状态(用户刚创建用户的时候,其状态默认设为“未激活”);(和“性别”同理,用户激活状态也使用枚举类管理起来)(在【common】通用工程中,创建枚举类UserStatus)

(3.8)【新增用户:createUser()】:构建好AppUser对象后,调用Dao层方法,去新增用户;


三:效果;

(1)先全局install一下整个项目;

(2)运行【user】用户微服务的主启动类;

(3)我们在【http://localhost:8003/doc.html】Swagger2的页面上,去测试接口了;

……………………………………………………

PS:使用Swagger的时候,接口的接收参数的时候,最好使用@RequestParam等注解;(PS:这也是自己一直以来的习惯)

……………………………………………………

……………………………………………………

即,我们目前编写的逻辑是:对于新用户,我们去注册,然后返回用户信息;对于已注册,我们直接返回用户信息;

……………………………………………………

26:第三章:开发通行证服务:9:【注册/登录】接口:验证码校验OK后,先根据手机号去查查该用户是否已存在,如果用户不存在就创建这个用户;(tkmybatis查询构建查询条件,雪花算法,枚举类等等)相关推荐

  1. 33:第三章:开发通行证服务:16:使用Redis缓存用户信息;(以减轻数据库的压力)

    说明: (1)声明:这个其中的区别和相同点,要清楚: ● 在[32:第三章:开发通行证服务:15:浏览器存储介质,简介:]中,前端使用[把"用户基本信息"存到Session Sto ...

  2. 32:第三章:开发通行证服务:15:浏览器存储介质,简介;(cookie,Session Storage,Local Storage)

    说明: (1)简单介绍浏览器存储介质:cookie,Session Storage,Local Storage: (2)目前为止的.可以确定的几点: ● 这些存储介质都是浏览器的,我们要想使用这些存储 ...

  3. 微信小程序注册/登录接口开发

    文章目录 后端有关说明 前端有关说明 接口设计 小程序注册/登录接口 APP 注册/登录接口 PC Web 端的注册/登录接口 小程序注册/登录序列图 校验 token 后端有关说明 登录和注册的逻辑 ...

  4. 鸿蒙OS应用开发之——实现APP注册登录功能

    一.功能简介 注册登录页面作为基础模块,具体包括了注册.登录.登录后界面的策划设计. 1.1注册 注册包括用户名,密码,确认密码三个流程,密码现在是明码显示的方式.这个模块中设置了判断"确认 ...

  5. 数据库授予用户增删改查的权限的语句_mysql创建本地用户及赋予数据库权限的方法示例...

    前言 大家在安装 mysql 时通常会生成一个超级用户 root,很多人之后就一直沿用这一个用户,虽然这会很方便,但超级用户权限太大,在所有地方使用它通常是一个安全隐患. 这一点跟操作系统的用户管理也 ...

  6. 【MySQL】 # MySQL对用户权限的简单操作:(1)创建新用户(2)赋权限

    MySQL对用户权限操作的详细内容:MySQL权限操作 1. 创建新用户 一般使用 Navicat 直接登录 MySQL,也可以使用命令行 mysql -u root -p,然后输入密码即可. 1.1 ...

  7. 31:第三章:开发通行证服务:14:开发【获得用户基本信息,接口】;(需要根据前端对返回数据的要求,创建一个只包含非隐私信息的AppUserVO类,去包装返回给前端的数据)

    说明: (1)本篇博客内容:开发[获得用户基本信息,接口]: 目录 零:本篇博客合理性说明:(或者说是:[获得用户基本信息,接口]是什么) 一:正式开发: 1.在[api]接口工程的UserContr ...

  8. 20:第三章:开发通行证服务:3:在程序中,打通redis服务器;(仅仅是打通redis服务器,不涉及具体的业务开发)

    说明: (1)本篇博客需要注意的点: ● 本篇博客仅仅是打通redis服务(也就是我们的程序,可以操作redis服务器),不涉及[redis服务,在项目中的具体应用],也不涉及[具体业务的开发]: ● ...

  9. 毕业设计——第三章 开发方法及系统实现(6)(完结)

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

最新文章

  1. MVC框架内容-控制器
  2. Mysql存储引擎MyIsAM和InnoDB区别
  3. 【原创】大数据基础之Hive(2)Hive SQL执行过程之SQL解析过程
  4. Python 中关于 round 函数的小坑
  5. 系统架构设计师考试知识点整理-3:信号量与PV操作
  6. zookeeper做分布式锁
  7. vue:model和v-model的区别
  8. volatile与synchronized 同步原理基础讲解
  9. mybatis源码阅读(三):mybatis初始化(下)mapper解析
  10. 【X264系列】之编码YUV的内存流程
  11. NBA的字母哥如何拿到2415万美金年薪
  12. 荒神罪蜀山传 服务器未响应,《DOTA2》荒神罪蜀山传新手攻略
  13. Ubuntu 查看系统版本
  14. 服务器c盘满了怎么清理? 服务器c盘空间不足清理方法
  15. 零成本赚钱小项目,轻松操作,完整版笔记分享给你
  16. 产品经理考什么证书?考这个准没错
  17. 最好用的 20 款数据可视化工具
  18. 免费屏幕录制程序都不用
  19. devc++ value of xxx too large for field of 4 bytes at xxx 并且源文件未编译
  20. 微信发展简史:微信成功的必然和偶然

热门文章

  1. html5落叶效果,使用Html5实现树叶飘落的效果
  2. 解决图片间间距的几种方法
  3. ISO26262功能安全 故障分类
  4. 密码控晒稀奇密码大开眼界 文艺密码PK科学密码
  5. 计算机网络技术---万维网
  6. Android 开发被迫失业在家带娃,一个月后拿下百度Offer
  7. 西南财经大学接受计算机调剂吗,2018年西南财经大学EMBA关于接受考生调剂的公告...
  8. Forrester评出十佳移动体验品牌
  9. 亚马逊跟卖的跟卖原理以及跟卖所要注意的事项
  10. Python客户端开发总结