天天看点

项目前期准备--了解项目的数据处理流程及注册功能(2)

当抽象方法已经设计好了,就应该在实现类中实现以上抽象方法:

@Autowired
ClassInfoMapper classInfoMapper;
@Autowired
UserMapper userMapper;

public void registerStudent(User user, String inviteCode) {
    // 【由于当前项目设计的规则是“学生账号通过手机号码注册、登录”,必须保证手机号码唯一】
    // 调用ClassInfoMapper对象的selectOne()方法,根据参数inviteCode邀请码,查询class_info表
    // 判断查询结果是否为空
    // 是:表示没有找到有效的邀请码,不允许注册,抛出InviteCodeException
    
    // 从以上查询到的班级信息中取出enabled,判断是否为0
    // 是:表示该班级已禁用,不允许注册该班级的学生账号,抛出ClassDisabledException
    
    // 从参数user中取出手机号码
    // 调用UserMapper对象的selectOne()方法,根据手机号码查询学生账号信息
    // 判断查询结果是否不为null
    // 是:找到了学生信息,表示手机号码已经被占用,则不允许注册,抛出PhoneDuplicateException
    
    // 没有找到学生信息,表示手机号码没有被占用,则允许注册……
    // 确保参数user中的数据全部是有效的
    // - 取出参数user中的密码,调用私有的encode()方法进行加密,并将加密后的密码封装回到user中
    // - classId:此前验证邀请码时得到的结果
    // - createdTime:当前时间,LocalDateTime.now()
    // - enabled:1,允许使用
    // - locked:0,不锁定
    // - type:0,表示学生
    
    // 调用UserMapper对象的insert()方法,根据参数user插入数据,获取返回值
    // 判断返回值(受影响的行数)是否不为1
    // 是:受影响的行数不是1,则插入用户数据失败,抛出InsertException
}

@Autowired
PasswordEncoder passwordEncoder;

// 将密码进行加密的方法
private String encode(String rawPassword) {
    String encodePassword = passwordEncoder.encode(rawPassword);
    return encodePassword;
}

      

在编写业务代码时,尽量根据“能够抛出异常”或其它能够使得方法运行结束为标准来写if语句的判断条件,以避免出现太多的if嵌套!

具体实现代码为:

package cn.tedu.straw.portal.service.impl;

import cn.tedu.straw.portal.mapper.ClassInfoMapper;
import cn.tedu.straw.portal.mapper.UserMapper;
import cn.tedu.straw.portal.model.ClassInfo;
import cn.tedu.straw.portal.model.User;
import cn.tedu.straw.portal.service.IUserService;
import cn.tedu.straw.portal.service.ex.ClassDisabledException;
import cn.tedu.straw.portal.service.ex.InsertException;
import cn.tedu.straw.portal.service.ex.InviteCodeException;
import cn.tedu.straw.portal.service.ex.PhoneDuplicateException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author tedu.cn
 * @since 2020-07-14
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private ClassInfoMapper classInfoMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void registerStudent(User user, String inviteCode) {
        // 【由于当前项目设计的规则是“学生账号通过手机号码注册、登录”,必须保证手机号码唯一】
        // 调用ClassInfoMapper对象的selectOne()方法,根据参数inviteCode邀请码,查询class_info表
        QueryWrapper<ClassInfo> classQueryWrapper = new QueryWrapper<>();
        classQueryWrapper.eq("invite_code", inviteCode);
        ClassInfo classInfo = classInfoMapper.selectOne(classQueryWrapper);
        // 判断查询结果是否为空
        if (classInfo == null) {
            // 是:表示没有找到有效的邀请码,不允许注册,抛出InviteCodeException
            throw new InviteCodeException();
        }

        // 从以上查询到的班级信息中取出enabled,判断是否为0
        if (classInfo.getEnabled() == 0) {
            // 是:表示该班级已禁用,不允许注册该班级的学生账号,抛出ClassDisabledException
            throw new ClassDisabledException();
        }

        // 从参数user中取出手机号码
        String phone = user.getPhone();
        // 调用UserMapper对象的selectOne()方法,根据手机号码查询学生账号信息
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("phone", user.getPhone());
        User result = userMapper.selectOne(userQueryWrapper);
        // 判断查询结果是否不为null
        if (result != null) {
            // 是:找到了学生信息,表示手机号码已经被占用,则不允许注册,抛出PhoneDuplicateException
            throw new PhoneDuplicateException();
        }

        // 没有找到学生信息,表示手机号码没有被占用,则允许注册……
        // 确保参数user中的数据全部是有效的
        // - 取出参数user中的密码,调用私有的encode()方法进行加密,并将加密后的密码封装回到user中
        String rawPassword = user.getPassword();
        String encodePassword = encode(rawPassword);
        user.setPassword(encodePassword);
        // - classId:此前验证邀请码时得到的结果
        user.setClassId(classInfo.getId());
        // - createdTime:当前时间,LocalDateTime.now()
        user.setCreatedTime(LocalDateTime.now());
        // - enabled:1,允许使用
        user.setEnabled(1);
        // - locked:0,不锁定
        user.setLocked(0);
        // - type:0,表示学生
        user.setType(0);

        // 调用UserMapper对象的insert()方法,根据参数user插入数据,获取返回值
        int rows = userMapper.insert(user);
        // 判断返回值(受影响的行数)是否不为1
        if (rows != 1) {
            // 是:受影响的行数不是1,则插入用户数据失败,抛出InsertException
            throw new InsertException();
        }
    }

    /**
     * 执行密码加密
     *
     * @param rawPassword 原密码
     * @return 根据原密码执行加密得到的密文
     */
    private String encode(String rawPassword) {
        String encodePassword = passwordEncoder.encode(rawPassword);
        return encodePassword;
    }

}

      

然后,调整控制器中处理请求的方法:

package cn.tedu.straw.portal.controller;


import cn.tedu.straw.portal.model.User;
import cn.tedu.straw.portal.service.IUserService;
import cn.tedu.straw.portal.service.ex.ClassDisabledException;
import cn.tedu.straw.portal.service.ex.InsertException;
import cn.tedu.straw.portal.service.ex.InviteCodeException;
import cn.tedu.straw.portal.service.ex.PhoneDuplicateException;
import cn.tedu.straw.portal.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author tedu.cn
 * @since 2020-07-14
 */
@RestController
@RequestMapping("/portal/user")
public class UserController {

    @Autowired
    private IUserService userService;

    // http://localhost:8080/portal/user/student/register?inviteCode=JSD2003-111111&nickname=Hello&phone=13800138002&password=1234
    @RequestMapping("/student/register")
    public R studentRegister(User user, String inviteCode) {
        try {
            userService.registerStudent(user, inviteCode);
            return new R().setState(1).setMessage("注册成功!");
        } catch (InviteCodeException e) {
            return new R().setState(2).setMessage("注册失败!邀请码错误!");
        } catch (ClassDisabledException e) {
            return new R().setState(3).setMessage("注册失败!班级已经被禁用!");
        } catch (PhoneDuplicateException e) {
            return new R().setState(4).setMessage("注册失败! 手机号码已经被注册!");
        } catch (InsertException e) {
            return new R().setState(5).setMessage("注册失败!服务器忙,请稍后再次尝试!");
        }
    }

}

      

完成后,重启项目,打开浏览器,登录后,通过以上URL进行测试。

继续阅读