2.注册模块

注册页面主要实现的功能
① 验证vip: 非vip用户不得注册
② 用户头像上传并回显,默认显示默认头像
③ 验证用户的注册是否是第二次注册
④ 用户注册成功,添加登录日志
一. 验证vip: 用户在输入学号和姓名的时候,姓名输入框失去焦点触发axios请求,在数据库中的vip表查询是否存在该用户,如果存在返回true,否则返回false,返回false,弹出提示框提示信息,并在用户点击确定之前,清空刚才输入的信息,并重新将焦点定位到学号一栏
  • 页面显示
    在这里插入图片描述

  • 前端代码一, 验证是否存在该vip

    checkVip: function () {
          this.$http
            .post("http://localhost:8888/user/checkVip.do", this.registerForm)
            .then((res) => {
              if (res.data != true) {
    
                // 弹出提示框
                this.dialogVisible = true;  
              }
            });
        },
    

    其中在弹出框关闭前触发清空信息并重新定位光标的函数

        <!-- 没有该vip,弹出框提示信息 -->
        <el-dialog
          title="提示"
          :visible.sync="dialogVisible"
          width="30%"
          :before-close="clearInfo">
          <span>没有该vip用户,请重新输入</span>
          <span slot="footer" class="dialog-footer">
            <el-button type="primary" @click="clearInfo">确 定</el-button>
          </span>
        </el-dialog>
    
    clearInfo: function() {
      
      // 关闭弹出框
      this.dialogVisible = false;
    
      // 清空输入框
      this.registerForm = {};
    
      // 将光标重新定位到第一个input,该input需要指定一个ref,值为clickPosition
      this.$refs.clickPosition.focus();
    },
    
    
  • 后端代码一,controller层

    // 检查是否存在该vip用户
    @RequestMapping(value = "/checkVip.do", method = RequestMethod.POST)
    @ResponseBody
    @CrossOrigin
    public boolean checkVipService(@RequestBody CheckUser checkUser) {
    
        User user = userService.checkVip(Integer.valueOf(checkUser.getId()), checkUser.getName());
        if (user == null) {
            return false;
        }
    
        return true;
    }
    
  • 后端代码二,业务逻辑层

    package com.zhl.service;
    
    /**
     * @author ZhangHailong
     * @date 2022/2/23 - 13:45
     * @project_name
     */
    public interface UserService {
    
        // 检查是否有该vip
        User checkVip(Integer id, String name);
    
    }
    
    package com.zhl.service.impl;
    
    import com.zhl.dao.UserDao;
    import com.zhl.service.UserService;
    
    /**
     * @author ZhangHailong
     * @date 2022/2/23 - 13:48
     * @project_name
     */
    
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserDao userDao;
    
        @Override
        public User checkVip(Integer id, String name) {
    
            return userDao.checkVip(id, name);
        }
    }
    
    
  • 后端代码三,持久层

    package com.zhl.service.impl;
    
    import com.zhl.dao.UserDao;
    import com.zhl.service.UserService;
    
    /**
     * @author ZhangHailong
     * @date 2022/2/23 - 13:48
     * @project_name
     */
    
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserDao userDao;
    
        @Override
        public User checkVip(Integer id, String name) {
    
            return userDao.checkVip(id, name);
        }
    }
    
二. 用户头像上传并回显: 用户在上传头像以后,后台将此头像的绝对地址返回给前端,前端进行回显,在用户提交其他的注册信息到后端后,与头像的绝对地址一起,封装成新用户添加到数据库中
  • 参考博客: SpringMVC实现图片的上传

  • 配置

        <!--文件上传资源解析bean-->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 设置默认编码 -->
            <property name="defaultEncoding" value="utf-8"></property>
            <!-- 上传图片最大大小1M-->
            <property name="maxUploadSize" value="1048576"></property>
        </bean>
    
  • 前端代码

          <!-- 上传头像 -->
      <el-form-item label="上传头像">
        <el-upload
          class="upload-demo"
          action="http://localhost:8888/user/upload.do"
          :headers="headers"
          :on-success="handleUpload"
          >
          <el-button size="small" type="primary">点击上传</el-button>
          <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
        </el-upload>
      </el-form-item>
    
    // 上传头像成功以后,获取后台返回的头像的绝对路径,回显
    handleUpload: function(res) {
      // console.log(res);
      this.default_portrait = res; // default_portrait就是页面中头像部分绑定的值
    },
    
  • 后端代码,因为还是在本地开发阶段,没有购买服务器,所以上传的头像保存到本地的D:\portraits文件夹下,以protrait开头命名

    // 注册页面上传头像并回显
    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    @ResponseBody
    @CrossOrigin
    public String uploadService(MultipartFile file) {
    
        String filePath = "";
        if (file != null){
            // 原始文件名
            String originalFileName = file.getOriginalFilename();
            // 获取图片后缀
            String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));
            // 生成图片存储的名称,UUID 避免相同图片名冲突,并加上图片后缀
            String fileName = UUID.randomUUID().toString() + suffix;
            // 图片存储路径
            // 此时的"D:\\portraits\\portrait"就相当于服务器下的portrait文件夹,图片的名字是: portrait@1233131dslfjdofj.jpg
            filePath = "D:/portraits/portrait" + fileName;
            File saveFile = new File(filePath);
            try {
                // 将上传的文件保存到服务器文件系统
                file.transferTo(saveFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            // 将头像绝对路径放入数据库
            this.portrait = filePath;
    
        }
    
        // 将绝对路径返回,用于回显头像
        return filePath;
    }
    

    遇到的问题: 我一开始指定的filePath是D:/portraits,以为图片就保存到portraits文件夹下了,结果是保存到了D盘下,而且是以portraits为开头的,看了别人的博客,发现是MultipartFile中transferTo(File file)的路径问题, 参考博客: MultipartFile中transferTo(File file)的路径问题, 于是对路径进行了修改,最终效果如下
    在这里插入图片描述
    在购买服务器以后,将文件上传改为上传到OSS

    • 添加pom依赖

      <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
        <version>3.10.2</version>
      </dependency>
      <dependency>
        <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>1.3.2</version>
      </dependency>
      <dependency>
       <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.2.1</version>
      </dependency>
      
    • 修改Controller

      // 注册页面上传头像并回显
          @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
          @ResponseBody
          @CrossOrigin
          public String uploadService(MultipartFile file) {
      
              try {
      
                  String endpoint = "oss-cn-beijing.aliyuncs.com";
                  String accessKeyId = "****";
                  String accessKeySecret = "***";
      
                  // 创建OSSClient实例。
                  OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
      
                  // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
                  InputStream inputStream = file.getInputStream();
                  //获取上传的文件名
                  String filename = file.getOriginalFilename();
                  filename =  "skaters/"+ currentId +"/portrait/portrait" + new Date().getTime() + filename;
      
                  // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
                  ossClient.putObject("skaterdata", filename, inputStream);
      
                  // 关闭OSSClient。
                  ossClient.shutdown();
      
                  // https://qy145.oss-cn-hangzhou.aliyuncs.com/16388489433231.jpg
                  portrait = "https://skaterdata."+endpoint+"/"+filename;
      
              } catch (IOException e) {
                  e.printStackTrace();
              }
      
              return  portrait;
      
          }
      
三. 用户注册: 用户在提交信息以后,首先后台会去数据库中查找,是否已经存在了该用户,如果存在了,那么返回String对象"已经注册过了", 首次注册的话, 返回"注册成功", 前端根据返回信息进行下一步操作, 注册成功,sessionStorage将用户的id存储,并跳转到主页,已经注册了,询问用户是否跳转到登录页面,如果跳转,携带用户的id,自动填充到id框,用户进行登录操作,如果不跳转,那么清空用户之前填写的所有信息,并将光标重新定位到id一栏
  • 前端代码

    handleRegister: function () {
      this.$http
        .post("http://localhost:8888/user/registerUser.do", this.registerForm)
        .then((res) => {
          // console.log(res);
          if (res.data == "已经注册过了") {
            // 已经注册过了,显示弹出框询问用户是否跳转到登录页面
            this.dialogVisible2 = true;
    
          } else if (res.data == "注册成功") {
            // 注册成功,跳转到主页
            sessionStorage.setItem('userId', this.registerForm.id);
            this.$router.push({
              path: "/Home",
            });
          }
        });
    },
    
        <!-- 已经注册过了,询问用户是否跳转到登录页面 -->
        <el-dialog
          title="提示"
          :visible.sync="dialogVisible2"
          width="30%"
          :before-close="clearInfo2">
          <span>已经注册过了,是否跳转到登录页面?</span>
          <span slot="footer" class="dialog-footer">
            <el-button @click="clearInfo2">取 消</el-button>
            <el-button type="primary" @click="goToLoginPage">确 定</el-button>
          </span>
        </el-dialog>
    
  • 后端代码一, controller层

    // 注册用户
    @RequestMapping(value = "/registerUser.do", method = RequestMethod.POST)
    @ResponseBody
    @CrossOrigin
    public String registerUserService(@RequestBody User user, HttpServletRequest request) {
    
        // 在注册之前,验证该用户是否已注册
        User ifRegistered = userService.chkIfRegistered(user);
        if (ifRegistered != null) {
            // 已经注册过了
            return "已经注册过了";
        }
    
        user.setPortrait(this.portrait);
        String ipAddress = request.getRemoteAddr();
        userService.registerUser(user, ipAddress);
        return "注册成功";
    }
    
  • 后端代码二, 业务逻辑层代码

    package com.zhl.service;
    
    import com.zhl.entity.User;
    
    /**
     * @author ZhangHailong
     * @date 2022/2/23 - 13:45
     * @project_name
     */
    public interface UserService {
    
        // 添加新用户前检查该用户是否是二次注册
        User chkIfRegistered(User user);
    
        // 注册用户
        User registerUser(User user, String ipAddress);
    
    
    package com.zhl.service.impl;
    
    import com.zhl.dao.UserDao;
    import com.zhl.entity.User;
    import com.zhl.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * @author ZhangHailong
     * @date 2022/2/23 - 13:48
     * @project_name
     */
    
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserDao userDao;
    
        @Override
        public User chkIfRegistered(User user) {
            return userDao.chkIfRegistered(user);
        }
    
        @Override
        public User registerUser(User user, String ipAddress) {
        	// 因为持久层的插入操作返回的是作用的行数,但是在切面类中我还要用到这个用户,
        	// 所以在这里做一个判断,如果插入成功,将该注册用户返回
            if (userDao.insertUser == -1)
            	return null;
            return user;	
        }
    
    }
    
  • 后端代码三,持久层

    package com.zhl.dao;
    
    import com.zhl.entity.User;
    import org.apache.ibatis.annotations.Param;
    
    /**
     * @author ZhangHailong
     * @date 2022/2/23 - 13:37
     * @project_name
     */
    public interface UserDao {
    
        // 注册前验证是否已存在该用户
        User chkIfRegistered(User user);
    
        // 持久层添加用户
        int insertUser(User user);
    
    }
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.zhl.dao.UserDao">
    
        <!--select|insert|update|delete语句-->
    
        <!--检查是否是二次注册-->
        <select id="chkIfRegistered" resultType="com.zhl.entity.User">
            select * from user where id = #{id} and name = #{name}
        </select>
    
        <!--添加用户-->
        <insert id="insertUser">
            insert into user(id,name,nickName,password,lv,portrait,stance) values(#{id},#{name},#{nickName},#{password},#{lv},#{portrait},#{stance})
        </insert>
    
    </mapper>
    
    四. 用户注册成功后,跳转到主页,这时通过AOP切面类添加登录日志,方式与登录的登录日志相同,这里不多赘述
  • 后端代码

    package com.zhl.aspect;
    
    import com.zhl.dao.LoginLogDao;
    import com.zhl.entity.LoginLog;
    import com.zhl.entity.User;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.util.Date;
    
    /**
     * @author ZhangHailong
     * @date 2022/3/11 - 19:38
     * @project_name
     */
    
    @Aspect
    @Component
    public class LoginLogAspect {
    
        @Autowired
        private LoginLogDao loginLogDao;
    
    
        // 注册成功以后,添加登录日志
        @AfterReturning(value = "execution(* *..UserServiceImpl.registerUser(..))", returning = "result")
        public void addRegisterLog(JoinPoint jp,User result) {
    
            if (result != null) {
    
                LoginLog loginLog = new LoginLog();
                // 注册的id
                loginLog.setUserId(result.getId());
                // 注册时间
                loginLog.setLoginTime(new Date());
                // 获取registerUser方法的第二个参数,也就是注册的用户的ip,择取需要的填充到LoginLog对象中
                loginLog.setIpAddress(jp.getArgs()[1].toString());
    
                loginLogDao.insertLogDao(loginLog);
    
            }
    
        }
    
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值