SpringCloud用户微服务实战06 业务层代码实现

2022年7月13日 255点热度 0人点赞 0条评论

前言

大家好,我是张大鹏,今天继续给大家分享使用SpringCloud开发一个用户微服务实战项目的教程。这是一个系列的教学文章,如果没有看过前面几篇的同学,可以先通过公众号“张大鹏520”阅读前面的部分。

在上一篇教程中,我们实现了DAO接口的所有mybatis映射文件的编写,接下来就是业务层的实现和控制层的实现,也就是真正的接口的实现部分。

业务层接口

首先,我们来设计业务层的接口。根据之前的API接口设计,业务层的接口设计也只需要提供三个核心方法就可以了,具体设计如下:

package com.zhangdapeng520.user.service;

import com.zhangdapeng520.user.entity.BizException;
import com.zhangdapeng520.user.entity.GetSmsCodeReqVo;
import com.zhangdapeng520.user.entity.LoginByMobileReqVo;
import com.zhangdapeng520.user.entity.LoginByMobileResVo;
import com.zhangdapeng520.user.entity.LoginExitReqVo;


public interface UserService {

    // 获取短信验证码
    boolean getSmsCode(GetSmsCodeReqVo getSmsCodeReqVo);

    // 短信登录
    LoginByMobileResVo loginByMobile(LoginByMobileReqVo loginByMobileReqVo) throws BizException;

    // 登录退出
    boolean loginExit(LoginExitReqVo loginExitReqVo);

}

业务层实现代码

然后,我们来实现接口,实现真正的业务逻辑:

package com.zhangdapeng520.user.service.impl;

import com.zhangdapeng520.user.dao.UserInfoDao;
import com.zhangdapeng520.user.dao.UserSmsCodeDao;
import com.zhangdapeng520.user.entity.*;
import com.zhangdapeng520.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author joe
 */

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    UserSmsCodeDao userSmsCodeDao;

    @Autowired
    UserInfoDao userInfoDao;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public boolean getSmsCode(GetSmsCodeReqVo getSmsCodeReqVo) {
        // 随机生成6位短信验证码
        String smsCode = String.valueOf((int) (Math.random() * 100000 + 1));

        // todo 调用短信平台接口
        // 存储用户短信验证码信息至短信验证码信息表
        UserSmsCode userSmsCode = UserSmsCode.builder().mobileNo(getSmsCodeReqVo.getMobileNo()).smsCode(smsCode)
                .sendTime(new Timestamp(new Date().getTime())).createTime(new Timestamp(new Date().getTime()))
                .build();
        userSmsCodeDao.insert(userSmsCode);
        return true;
    }

    @Override
    public LoginByMobileResVo loginByMobile(LoginByMobileReqVo loginByMobileReqVo) throws BizException {
        // 1、验证短信验证码是否正确
        UserSmsCode userSmsCode = userSmsCodeDao.selectByMobileNo(loginByMobileReqVo.getMobileNo());
        if (userSmsCode == null) {
            throw new BizException(-1"验证码输入错误");
        } else if (!userSmsCode.getSmsCode().equals(loginByMobileReqVo.getSmsCode())) {
            throw new BizException(-1"验证码输入错误");
        }

        // 2、判断用户是否注册
        UserInfo userInfo = userInfoDao.selectByMobileNo(loginByMobileReqVo.getMobileNo());
        if (userInfo == null) {
            // 随机生成用户ID
            String userId = String.valueOf((int) (Math.random() * 100000 + 1));
            userInfo = UserInfo.builder().userId(userId).mobileNo(loginByMobileReqVo.getMobileNo()).isLogin("1")
                    .loginTime(new Timestamp(new Date().getTime())).createTime(new Timestamp(new Date().getTime()))
                    .build();

            // 完成系统默认注册流程
            userInfoDao.insert(userInfo);
        } else {
            userInfo.setIsLogin("1");
            userInfo.setLoginTime(new Timestamp(new Date().getTime()));
            userInfoDao.updateById(userInfo);
        }

        // 3、生成用户会话信息
        String accessToken = UUID.randomUUID().toString().toUpperCase().replaceAll("-""");

        // 将用户会话信息存储至Redis服务
        redisTemplate.opsForValue().set("accessToken", userInfo, 30, TimeUnit.DAYS);

        // 4、封装响应参数
        LoginByMobileResVo loginByMobileResVo = LoginByMobileResVo.builder().userId(userInfo.getUserId())
                .accessToken(accessToken).build();
        return loginByMobileResVo;
    }

    @Override
    public boolean loginExit(LoginExitReqVo loginExitReqVo) {
        try {
            redisTemplate.delete(loginExitReqVo.getAccessToken());
            return true;
        } catch (Exception e) {
            log.error(e.toString() + "_" + e);
            return false;
        }
    }
}

大家不要被这突然的一大堆代码吓到,我们来逐一分析一下。

获取短信验证码

获取短信验证码的核心代码如下:

@Override
public boolean getSmsCode(GetSmsCodeReqVo getSmsCodeReqVo) {
    // 随机生成6位短信验证码
    String smsCode = String.valueOf((int) (Math.random() * 100000 + 1));

    // todo 调用短信平台接口
    // 存储用户短信验证码信息至短信验证码信息表
    UserSmsCode userSmsCode = UserSmsCode.builder().mobileNo(getSmsCodeReqVo.getMobileNo()).smsCode(smsCode)
            .sendTime(new Timestamp(new Date().getTime())).createTime(new Timestamp(new Date().getTime()))
            .build();
    userSmsCodeDao.insert(userSmsCode);
    return true;
}

这里的逻辑比较简单,首先是生成一个随机的6位数的短信验证码。真正调用第三方短信平台发送短信的逻辑并没有实现,因为这个需要企业资质。然后就是将短信验证码存入到数据库中,之后返回一个true。

所以这个方法,并没有返回什么实质的东西,而是生成了短信验证码,然后存到数据库。

我们测试的时候,点击发送短信验证码,然后去数据库中查询最新的验证码,用来作为手机号登录的短信验证码。

根据手机号登录

接下来是最核心的一个方法,根据手机号登录:

@Override
public LoginByMobileResVo loginByMobile(LoginByMobileReqVo loginByMobileReqVo) throws BizException {
    // 1、验证短信验证码是否正确
    UserSmsCode userSmsCode = userSmsCodeDao.selectByMobileNo(loginByMobileReqVo.getMobileNo());
    if (userSmsCode == null) {
        throw new BizException(-1"验证码输入错误");
    } else if (!userSmsCode.getSmsCode().equals(loginByMobileReqVo.getSmsCode())) {
        throw new BizException(-1"验证码输入错误");
    }

    // 2、判断用户是否注册
    UserInfo userInfo = userInfoDao.selectByMobileNo(loginByMobileReqVo.getMobileNo());
    if (userInfo == null) {
        // 随机生成用户ID
        String userId = String.valueOf((int) (Math.random() * 100000 + 1));
        userInfo = UserInfo.builder().userId(userId).mobileNo(loginByMobileReqVo.getMobileNo()).isLogin("1")
                .loginTime(new Timestamp(new Date().getTime())).createTime(new Timestamp(new Date().getTime()))
                .build();

        // 完成系统默认注册流程
        userInfoDao.insert(userInfo);
    } else {
        userInfo.setIsLogin("1");
        userInfo.setLoginTime(new Timestamp(new Date().getTime()));
        userInfoDao.updateById(userInfo);
    }

    // 3、生成用户会话信息
    String accessToken = UUID.randomUUID().toString().toUpperCase().replaceAll("-""");

    // 将用户会话信息存储至Redis服务
    redisTemplate.opsForValue().set("accessToken", userInfo, 30, TimeUnit.DAYS);

    // 4、封装响应参数
    LoginByMobileResVo loginByMobileResVo = LoginByMobileResVo.builder().userId(userInfo.getUserId())
            .accessToken(accessToken).build();
    return loginByMobileResVo;
}

第一步是验证短信验证码是否正确。这里会校验客户端传过来的验证码,然后去数据库中查询验证码,进行一次比对。这是一个可以优化的地方,因为短信验证码这种实时性比较强的东西,我们可以考虑放在Redis数据库中。

第二步是判断用户是否注册,直接去数据库查询就行。如果注册了,则继续下一步,如果没有注册,则自动帮忙注册。

第三步是生成用户会话信息,也就是生成一个token。

第四步是将token存到Redis中。

最后是封装响应结果,返回给前端。

退出登录

退出登录的接口就比较简单了,如下:

@Override
public boolean loginExit(LoginExitReqVo loginExitReqVo) {
    try {
        redisTemplate.delete(loginExitReqVo.getAccessToken());
        return true;
    } catch (Exception e) {
        log.error(e.toString() + "_" + e);
        return false;
    }
}

最后

好了,今天的分享就到这里了,谢谢大家。

最后打一个小广告哈,是关于游戏的,不喜欢玩游戏的可以不用继续往下看了哈,如果你稍微喜欢玩游戏,则强烈推荐你下载看看,这个App真的不错,我自己用了五六年了,非常好用,里面经常会更新一些送Vip送红包送元宝的福利游戏。
图片

为啥推荐呢?
图片

都有什么游戏呢?
图片

下载地址(复制到浏览器打开):https://www.tsyule.cn/index.php/index/index/appid/7/tgid/ca0000500

通过这个地址下载一个手机App,苹果手机和安卓手机都可以下载哈。下载以后安装,然后注册一个账号登录就行了。里面有几千款游戏,特别是那种BT游戏,特别多。BT游戏就是只要你玩游戏,就会自动送你VIP,送你元宝,送你钻石的那种。打怪掉宝的几率也特别高,喜欢玩游戏的可以自行下载体会哈。

38660SpringCloud用户微服务实战06 业务层代码实现

这个人很懒,什么都没留下

文章评论