Vue+Springboot实现登录注册

3 篇文章 1 订阅

一、Vue登录注册页面内容

<template>
  <div id="login" v-loading="loading" element-loading-text="登录中...">
    <el-form class="container" :model="loginForm" status-icon :rules="rules"
             ref="loginForm" v-show="showLogin" label-width="100px">
      <h3 class="title">MyVue 系统用户登录</h3>
      <el-form-item label="用户名:" prop="username">
        <el-input type="username" v-model="loginForm.username" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="密码:" prop="password">
        <el-input type="password" v-model="loginForm.password" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="验证码:" prop="validCode" class="validCode">
        <el-input v-model.number="loginForm.validCode"></el-input>
        <el-image :src="codeUrl" @click="getValidCode" class="login-code"></el-image>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="login('loginForm')">登录</el-button>
        <el-button @click="resetForm('loginForm')">重置</el-button>
        <el-link type="primary" :underline="false" @click="showChange">-> 去注册</el-link>
      </el-form-item>
    </el-form>
    <el-form class="container" :model="registerForm" status-icon :rules="rules"
             ref="registerForm" v-show="!showLogin" label-width="100px">
      <h3 class="title">MyVue 系统用户注册</h3>
      <el-form-item label="用户名:" prop="username">
        <el-input type="username" v-model="registerForm.username" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="密码:" prop="password">
        <el-input type="password" v-model="registerForm.password" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="确认密码:" prop="rePassword">
        <el-input type="rePassword" v-model="registerForm.rePassword" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="验证码:" prop="validCode" class="validCode">
        <el-input v-model.number="registerForm.validCode"></el-input>
        <el-image :src="codeUrl" @click="getValidCode" class="login-code"></el-image>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="register('registerForm')">注册</el-button>
        <el-button @click="resetForm('registerForm')">重置</el-button>
<!--        #606266 #5cb6ff-->
        <el-link type="primary" :underline="false" @click="showChange">-> 去登录</el-link>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>

export default {
  name: 'Login',
  data () {
    var validateChkcode = (rule, value, callback) => {
      if (value === '') {
        return callback(new Error('请输入验证码!'))
      }
      callback()
    }
    var validateUsername = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入用户名!'))
      } else if (!this.showLogin) {
        // 异步原因,不会等待返回后再执行后面流程,而是直接执行else后面的语句
        this.$get('user/chkUsername', this.registerForm).then(retDate => {
          if (retDate === 1) {
            callback(new Error('该用户名已经存在!'))
          }
          callback()
        })
      } else {
        callback()
      }
    }
    var validatePassword = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入密码!'))
      }
      callback()
    }
    var validateRePassword = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请再次输入密码!'))
      } else if (value !== this.registerForm.password) {
        callback(new Error('两次输入密码不一致!'))
      }
      callback()
    }
    return {
      showLogin: true,
      loading: false,
      codeUrl: '',
      cookiePass: '',
      loginForm: {
        username: '',
        password: '',
        validCode: '',
        id: ''
      },
      registerForm: {
        username: '',
        password: '',
        rePassword: '',
        validCode: '',
        id: ''
      },
      rules: {
        username: [
          { validator: validateUsername, trigger: 'blur' }
        ],
        password: [
          { validator: validatePassword, trigger: 'blur' }
        ],
        validCode: [
          { validator: validateChkcode, trigger: 'blur' }
        ],
        rePassword: [
          { validator: validateRePassword, trigger: 'blur' }
        ]
      }
    }
  },
  created () {
    this.getValidCode()
  },
  methods: {
    showMessage (message) {
      this.$message.error(message)
    },
    login (formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.loading = true
          this.$post('user/login', this.loginForm).then(retDate => {
            if (retDate.ok) {
              this.$store.dispatch('setUser', retDate)
              this.$router.push({path: '/'})
            } else {
              this.showMessage(retDate.message)
              this.loading = false
            }
          })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    register (formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$post('user/register', this.registerForm).then(retDate => {
            if (retDate.ok) {
              this.$store.dispatch('setUser', retDate)
              // 注册成功跳转到首页
              this.$message.success(retDate.message)
              this.$router.push({path: '/'})
            } else {
              this.showMessage(retDate.message)
            }
          })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm (formName) {
      this.$refs[formName].resetFields()
    },
    getValidCode () {
      this.codeUrl = this.$global.baseURL + 'user/getCheckCode?' + new Date()
    },
    showChange () {
      this.showLogin = !this.showLogin
      this.getValidCode()
    }
  }
}
</script>

<style>
  #login {
    background:url("../assets/backImg.jpg") no-repeat;
    background-position: center;
    height: 100%;
    width: 100%;
    background-size: cover;
    position: fixed;
  }

  body{
    margin: 0px;
  }

  .container {
    border-radius: 15px;
    background-clip: padding-box;
    margin: 8% auto;
    width: 350px;
    padding: 35px 35px 15px 35px;
    background: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
  }

  .title {
    margin: 0px auto 40px auto;
    text-align: center;
    color: #505458;
  }

  .login-code {
    display: inline-block;
    height: 40px;
    float: right;
  }

  .validCode .el-input {
    float: left;
    width: 50%;
  }

  .el-link {
    margin-left: 25px;
  }

  img {
    float: right;
  }
</style>

二、后台controller文件内容:

package com.login.controller;

import com.login.util.DateUtil;
import com.login.util.Md5Util;
import com.login.util.StringUtil;
import com.login.util.VerifyCodeUtil;
import com.mydatasource.entity.User;
import com.mydatasource.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

/**
 * 文件描述: 用户登录,注册
 *
 * @author yuzonghao
 * @date 2020/05/22 14:43
 **/
@RestController
public class LoginController {
    private static Logger log = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private UserService userService;

    @RequestMapping("/register")
    public String register(HttpServletRequest request, @RequestBody User user){
        String verifyCode = (String) request.getSession().getAttribute("verifyCode");
        log.info("获取验证码的值为: {}",verifyCode);
        if (!user.getValidCode().equalsIgnoreCase(verifyCode)){
            user.setOk(false);
            user.setMessage("验证码输入错误!");
            return StringUtil.toJson(user);
        }
        user.setId(DateUtil.dataFormat(new Date(),DateUtil.DateTimeNum)
                + StringUtil.getRandomStr());
        user.setPassword(Md5Util.encoderByMd5(user.getPassword()));
        int num = userService.insertUser(user);
        if (num <= 0){
            user.setOk(false);
            user.setMessage("注册失败!");
            return StringUtil.toJson(user);
        }
        user.setMessage("注册成功!");
        return StringUtil.toJson(user);
    }

    @RequestMapping("/login")
    public String login(HttpServletRequest request, @RequestBody User user){
        String verifyCode = (String) request.getSession().getAttribute("verifyCode");
        log.info("获取验证码的值为: {}",verifyCode);
        if (!user.getValidCode().equalsIgnoreCase(verifyCode)){
            user.setOk(false);
            user.setMessage("验证码输入错误!");
            return StringUtil.toJson(user);
        }
        user = userService.selectUser(user.getUsername(), Md5Util.encoderByMd5(user.getPassword()));
        if (user == null){
            return StringUtil.toJson(new User(false,"账号或密码错误!"));
        }
        return StringUtil.toJson(user);
    }

    @GetMapping("/chkUsername")
    public String chkUsername(@RequestParam String username){
        if (userService.chkUsername(username)) return "1";
        return "0";
    }

    /**
     * description: 获取验证码图片
     * param [response, request]
     * author yuzonghao
     * createTime 2020/3/7 13:36
     **/
    @GetMapping("/getCheckCode")
    public void getCheckCode(HttpServletResponse response, HttpServletRequest request) {
        try {
            int width = 120;
            int height = 40;
            BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //生成对应宽高的初始图片
            String randomText = VerifyCodeUtil.drawRandomText(width, height, verifyImg);
            request.getSession().setAttribute("verifyCode", randomText);
//            request.getSession().setAttribute("startTime",new Date());
            response.setContentType("image/png");//必须设置响应内容类型为图片,否则前台不识别
            OutputStream os = response.getOutputStream(); //获取文件输出流
            ImageIO.write(verifyImg, "png", os);//输出图片流
            os.flush();
            os.close();//关闭流
        } catch (IOException e) {
            log.error("获取验证码图片失败!", e);
        }
    }

}

Md5Util

package com.example.myblog.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import java.security.MessageDigest;

/**
 * 文件描述:
 *
 * @author yuzonghao
 * @date 2020/05/27 14:19
 **/
public class Md5Util {
    private static Logger log = LoggerFactory.getLogger(Md5Util.class);

    public static String encoderByMd5(String str) {
        if (str == null) return null;
        try {
            //确定计算方法
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            BASE64Encoder base64en = new BASE64Encoder();
            //加密后的字符串
            return base64en.encode(md5.digest(str.trim().getBytes("utf-8")));
        } catch (Exception e) {
            log.error("字符串Md5加密失败,",e);
        }
        return null;
    }
}

VerifyCodeUtil

package com.example.myblog.util;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * @description: 生成验证码工具类
 * @projectName:personal
 * @author:yuzonghao
 * @createTime:2020/3/7 12:57
 */
public class VerifyCodeUtil {

    private static String baseNumLetter = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
    private static String font = "微软雅黑";

    /**
     * description: 绘制验证码图片,返回验证码文本内容
     * param [width, height, verifyImg]
     * author yuzonghao
     * createTime 2020/3/7 13:06
     **/
    public static  String drawRandomText(int width, int height, BufferedImage verifyImg) {

        Graphics2D graphics = (Graphics2D) verifyImg.getGraphics();
        graphics.setColor(Color.WHITE);//设置画笔颜色-验证码背景色
        graphics.fillRect(0, 0, width, height);//填充背景
        graphics.setFont(new Font(font, Font.BOLD, 30));

        StringBuffer sBuffer = new StringBuffer();
        int x = 10;  //旋转原点的 x 坐标
        String ch = "";
        Random random = new Random();
        for(int i = 0;i < 4;i++){
            graphics.setColor(getRandomColor());
            //设置字体旋转角度
            int degree = random.nextInt() % 10;  //角度小于10度
            int dot = random.nextInt(baseNumLetter.length());
            ch = baseNumLetter.charAt(dot) + "";
            sBuffer.append(ch);
            //正向旋转
            graphics.rotate(degree * Math.PI / 180, x, 30);
            graphics.drawString(ch, x, 30);
            //反向旋转
            graphics.rotate(-degree * Math.PI / 180, x, 30);
            x += 25;
        }

        //画干扰线
        for (int i = 0; i <15; i++) {
            // 设置随机颜色
            graphics.setColor(getRandomColor());
            // 随机画线
            graphics.drawLine(random.nextInt(width), random.nextInt(height),
                    random.nextInt(width), random.nextInt(height));

        }

        //添加噪点
        for(int i=0;i<15;i++){
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            graphics.setColor(getRandomColor());
            graphics.fillRect(x1, y1, 2,2);

        }
        return sBuffer.toString();
    }


    /**
     * description: 获取随机颜色
     * param []
     * author yuzonghao
     * createTime 2020/3/7 12:55
     **/
    private static Color getRandomColor(){
        Random ran = new Random();
        Color color = new Color(ran.nextInt(256),
                ran.nextInt(256),ran.nextInt(256));
        return color;
    }
}


三、效果图:

在这里插入图片描述
在这里插入图片描述

四、开发过程中的问题:

1)、跨域问题,解决方法参考该博客中的四
  • 8
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
VueSpringBoot打造假日旅社管理系统》课程,将讲解如何使用VueSpringBoot开发这个项目,手把手演示开发流程!附赠源码、文档、数据库脚本等全部资料,提供售后答疑。 课程简介本课程讲解的是《基于 VueSpringBoot 的假日旅社管理系统》,该系统支持民宿档案、民宿新闻、民宿预定、民宿评论这四大核心业务,适用于乡村民宿企业的民宿预定业务。系统给每个民宿档案提供一个唯一标识,对民宿预定、评论等各个环节进行快速批量的数据采集,确保游客及时掌握景区民宿的真实数据,方便游客进行民宿预定。另外系统还包括员工管理、组织机构管理、文件管理、权限管理功能,给旅社企业提供更个性化的民宿管理模式。假日旅社管理系统采用了基于角色的访问控制,角色和菜单关联,一个角色可以配置多个菜单权限;然后再将用户和角色关联,一位用户可以赋予多个角色。这样用户就可以根据角色拿到该有的菜单权限,更方便旅社企业的管理人员进行权限管控。   软件技术选型前端VueVue 是构建前端界面的核心框架,本系统采用 2.6.14 版本。View UI:基于 Vue.js2.0 的组件库,本系统采用 4.7.0 版本。后端Spring Boot:构建系统核心逻辑的后端框架,本系统采用 2.7.0 版本。MyBatis / MyBatis Plus:后端连接数据库的框架,本系统采用 3.5.2 版本。数据库MySQL:本项目的主数据库,本系统采用 8.0.29 版本。Redis:本系统采用基于 Windows 版本的 Redis,用于图形验证码和用户菜单权限的临时存储,采用了 5.0.14 版本。开发环境VsCode:项目前端的开发工具,使用版本为 1.68.0。IntelliJ IDEA :项目后端的开发工具,使用版本为 2021.3.2。Jdk:Java 的开发环境,使用版本为 17.0.3.1。Maven:后端项目的打包工具,使用版本为 3.6.2。NodeJs:前端项目的开发环境,使用版本为 16.13.0。 软件架构分析基于 VueSpringBoot 的假日旅社管理系统包括了系统基础模块、民宿档案模块、民宿新闻模块、民宿预定模块、民宿评论模块这五大功能模块,其架构如下图所示。  接下来,分别对五大模块进行详细介绍。系统基础模块系统基础模块,是用于支撑假日旅社管理系统的正常运行,这个模块包括了登陆注册模块、员工部门管理、菜单权限管理等。假日旅社管理系统支持用户使用账号、密码和图形验证码登陆,操作界面如下图所示。  假日旅社管理系统支持用户使用手机号、姓名、密码和图形验证码注册,操作界面如下图所示。 用户成功进入系统后,可进入到基于 VueSpringBoot 的假日旅社管理系统的首页,首页展示了当前登陆的地址、现在的时间和用户配置的常用模块,如下图所示。 接着用户点击左侧的用户管理,即可进入用户管理模块,用户管理模块的首页如下图所示。 用户可以在这个模块对系统登陆用户的档案进行维护,包括添加新用户、删除用户、编辑用户、根据姓名/部门查询用户。用户可以进入部门管理模块,管理旅社的部门数据,如下图所示。 同理用户可以进入到菜单管理模块,对系统的菜单进行管理,菜单管理模块的操作界面如下图所示。 民宿档案模块第二个模块是民宿档案模块,民宿档案就是用来管理民宿的数据,民宿档案包括民宿的名称、面积、房号、房间类型、早餐情况、价格、备注等,以下是民宿档案模块的主界面。用户可以点击顶部的“新增”按钮,进入民宿档案添加界面,添加民宿档案数据,如下图所示。 其中房间类型为下拉框单项选择,如下图所示。还有早餐情况也是下拉单选,如下图所示。 用户可以对现有的民宿档案数据进行编辑更新,只需点击每一行民宿档案数据的“编辑”按钮,即可进入民宿档案数据的编辑界面,如下图所示。 用户也可以对不需要的民宿数据进行删除操作,用户点击删除时,系统会弹出二次确认弹框,如下图所示。  民宿新闻模块第三个模块是民宿新闻模块,民宿新闻就是用来管理民宿的新闻资讯,包含的功能如下所示。 民宿新闻包括民宿的名称、面积、房号、房间类型、早餐情况、价格、备注等,以下是民宿新闻模块的主界面,其中的图片仅供测试样例使用。用户可以点击顶部的“新增”按钮,进入民宿新闻添加界面,添加民宿新闻数据,如下图所示。 新闻描述字段采用了 ueditor 富文本编辑器,这是由百度 web 前端研发部开发的所见即所得的开源富文本编辑器,具有轻量、可定制、用户体验优秀等特点,基于 MIT 开源协议,所有源代码可自由修改和使用。 用户可以对现有的民宿新闻数据进行编辑更新,只需点击每一行民宿新闻数据的“编辑”按钮,即可进入民宿新闻数据的编辑界面,如下图所示。 民宿预定模块第四个模块是民宿预定模块,旅客可以在民宿预定模块中预定民宿,达到旅客的住宿目的,民宿预定模块包含的功能如下所示。民宿预定包括了预定民宿 ID、预定民宿名称、预定日期、下单时间、下单人 ID、下单人姓名、价格、是否付款、下单备注等字段,旅客首先进入民宿档案模块,可以看到每一行民宿数据都有一个预约按钮,如下图所示。 如用户点击 1 幢 102 民宿的预约按钮后,会弹出预约确认框,需要输入预约的日期,日期表单默认选择今日,如下图所示。 旅客需要点击“确认预约”按钮,完成预约操作,系统给与“预约成功”提示,如下图所示。 预约成功后,旅客可以从民宿预定模块中进行查询,如下图所示。 最后旅客进行付款操作,点击每一行右侧的付款按钮,如下图所示。支付完成后,系统将预定单的支付状态改为付款,预定流程结束,如下图所示。 民宿评论模块 第五个模块是民宿预定模块,旅客可以在民宿预定结束后评论民宿,以帮助更多的人了解民宿,民宿评论模块包含的功能如下所示。 民宿评论包括了民宿名称、民宿 ID、评论时间、评论内容、评论人 ID、评论人姓名等字段,旅客首先进入民宿档案模块,可以看到每一行民宿数据都有一个评论按钮,如下图所示。 旅客点击评论后,系统给与弹框反馈,如下图所示。  用户输入评论内容后,点击确认评论按钮,即可完成评论操作,如下图所示。  旅客评论后,即可在民宿评论模块中查看此评论数据,如下图所示。 也可以在民宿模块中,双击民宿数据查看评论信息,如下图所示。 项目总结本软件是基于 VueSpringBoot 的假日旅社管理系统,包含了民宿档案、民宿新闻、民宿预定、民宿评论这四个功能模块。 开发本系统的目的,就是为了帮助旅游景点的民宿企业提高民宿管理效率,降低人力成本,让旅游景点的民宿企业获得更多的经济效益。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值