• Reggie外卖项目 —— 后台系统登录功能


    03、后台系统登录功能

    3.1、需求分析

    1、页面原型展示

    在这里插入图片描述

    2、登录页面展示

    在这里插入图片描述

    3、数据模型employee表)

    在这里插入图片描述

    3.2、代码开发

    3.2.1、页面开发

    login.html

    DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>瑞吉外卖管理端title>
      <link rel="shortcut icon" href="../../favicon.ico">
      
      <link rel="stylesheet" href="../../plugins/element-ui/index.css" />
      <link rel="stylesheet" href="../../styles/common.css">
      <link rel="stylesheet" href="../../styles/login.css">
      <link rel="stylesheet" href="../../styles/icon/iconfont.css" />
      <style>
        .body{
          min-width: 1366px;
        }
      style>
    head> 
    
    <body>
      <div class="login" id="login-app">
        <div class="login-box">
          <img src="../../images/login/login-l.png" alt="">
          <div class="login-form">
            <el-form ref="loginForm" :model="loginForm" :rules="loginRules" >
              <div class="login-form-title">
                <img src="../../images/login/logo.png" style="width:139px;height:42px;" alt="" />
              div>
              <el-form-item prop="username">
                <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号" maxlength="20"
                  prefix-icon="iconfont icon-user" />
              el-form-item>
              <el-form-item prop="password">
                <el-input v-model="loginForm.password" type="password" placeholder="密码" prefix-icon="iconfont icon-lock" maxlength="20"
                  @keyup.enter.native="handleLogin" />
              el-form-item>
              <el-form-item style="width:100%;">
                <el-button :loading="loading" class="login-btn" size="medium" type="primary" style="width:100%;"
                  @click.native.prevent="handleLogin">
                  <span v-if="!loading">登录span>
                  <span v-else>登录中...span>
                el-button>
              el-form-item>
            el-form>
          div>
        div>
      div>
    
      
      <script src="../../plugins/vue/vue.js">script>
      
      <script src="../../plugins/element-ui/index.js">script>
      
      <script src="../../plugins/axios/axios.min.js">script>
      <script src="../../js/request.js">script>
      <script src="../../js/validate.js">script>
      <script src="../../api/login.js">script>
    
      <script>
        new Vue({
          el: '#login-app',
          data() {
            return {
              loginForm:{
                username: 'admin',
                password: '123456'
              },
              loading: false
            }
          },
          computed: {
            loginRules() {
              const validateUsername = (rule, value, callback) => {
                if (value.length < 1 ) {
                  callback(new Error('请输入用户名'))
                } else {
                  callback()
                }
              }
              const validatePassword = (rule, value, callback) => {
                if (value.length < 6) {
                  callback(new Error('密码必须在6位以上'))
                } else {
                  callback()
                }
              }
              return {
                'username': [{ 'validator': validateUsername, 'trigger': 'blur' }],
                'password': [{ 'validator': validatePassword, 'trigger': 'blur' }]
              }
            }
          },
          created() {
          },
          methods: {
            async handleLogin() {
              this.$refs.loginForm.validate(async (valid) => {
                if (valid) {
                  this.loading = true
                  let res = await loginApi(this.loginForm)
                  if (String(res.code) === '1') {//1表示登录成功
                    localStorage.setItem('userInfo',JSON.stringify(res.data))
                    window.location.href= '/backend/index.html'
                  } else {
                    this.$message.error(res.msg)
                    this.loading = false
                  }
                }
              })
            }
          }
        })
      script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117

    login.js

    function loginApi(data) {
      return $axios({
        'url': '/employee/login',
        'method': 'post',
        data
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.2.2、后端开发

    1、创建实体类Employee,和employee表进行映射

    /**
     * 员工实体
     */
    @Data
    public class Employee implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private Long id;
    
        private String username;
    
        private String name;
    
        private String password;
    
        private String phone;
    
        private String sex;
    
        private String idNumber;//身份证号码
    
        private Integer status;
    
        private LocalDateTime createTime;
    
        private LocalDateTime updateTime;
    
        @TableField(fill = FieldFill.INSERT)
        private Long createUser;
    
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Long updateUser;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2、创建controllerservicemapper

    EmployeeMapper.java

    @Mapper
    public interface EmployeeMapper extends BaseMapper<Employee> {
    }
    
    • 1
    • 2
    • 3

    EmployeeService.java

    public interface EmployeeService extends IService<Employee> {
    }
    
    • 1
    • 2

    EmployeeServiceImpl.java

    @Service
    public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
    }
    
    • 1
    • 2
    • 3

    EmployeeController.java

    @Slf4j
    @RestController
    @RequestMapping("/employee")
    public class EmployeeController {
    
        @Autowired
        private EmployeeService employeeService;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、返回结果类

    此类是一个通用结果类,服务端响应的所有结果最终都会包装成此种类型返回给前端页面

    /**
     * 通用返回结果类,服务端响应的数据最终都会封装成此对象
     * @param 
     */
    @Data
    public class R<T> {
    
        private Integer code; //编码:1成功,0和其它数字为失败
    
        private String msg; //错误信息
    
        private T data; //数据
    
        private Map map = new HashMap(); //动态数据
    
        public static <T> R<T> success(T object) {
            R<T> r = new R<T>();
            r.data = object;
            r.code = 1;
            return r;
        }
    
        public static <T> R<T> error(String msg) {
            R r = new R();
            r.msg = msg;
            r.code = 0;
            return r;
        }
    
        public R<T> add(String key, Object value) {
            this.map.put(key, value);
            return this;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    4、在controller中创建登录方法

    处理逻辑如下:

    • 将页面提交的密码password进行md5加密处理
    • 根据页面提交的用户名username查询数据库
    • 如果没有查询到则返回登录失败结果
    • 密码比对,如果不一致则返回登录失败结果
    • 查看员工状态,如果为已禁用状态,则返回员工已禁用结果
    • 登录成功,将员工id存入session并返回登录成功结果

    在这里插入图片描述

    3.3、功能测试

    EmployeeController.java

    /**
     * 员工登录
     * @param request
     * @param employee 将前端页面请求的用户名、密码封装成employee实体类
     * @return
     */
    @PostMapping("/login")
    public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
        //1、将页面提交的密码password进行md5加密处理
        String password = employee.getPassword();
        password = DigestUtils.md5DigestAsHex(password.getBytes());
    
        //2、根据页面提交的用户名username查询数据库
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getUsername, employee.getUsername());
        Employee emp = employeeService.getOne(queryWrapper);//username在数据库中是唯一的
    
        //3、如果没有查询到则返回登录失败结果
        if (emp == null) {
            return R.error("登录失败,无此用户!");
        }
    
        //4、密码比对,如果不一致则返回登录失败结果
        if (!emp.getPassword().equals(password)) {
            return R.error("登录失败,密码输入错误!");
        }
    
        //5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
        if (emp.getStatus() == 0) {
            return R.error("登录失败,该账号已禁用!");
        }
    
        //6、登录成功,将员工id存入session并返回登录成功结果
        request.getSession().setAttribute("employee", emp.getId());
        return R.success(emp);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

  • 相关阅读:
    小程序授权获取昵称
    Unity 使用StateMachineBehaviour让动画控制器状态自动关闭跳出
    字节码进阶之java Instrumentation原理详解
    html在线阅读小说网页制作模板 小说书籍网页设计 大学生静态HTML网页源码 dreamweaver网页作业 简单网页课程成品
    年薪百万的offer从何入手?P8的《Spring 5高级编程》看了吗
    【C++入门篇】引用&&内联函数&&auto&&范围for&&nullptr
    MySQL审计插件介绍
    表单中输入框中输入的内容自动存入localStorage中,并在刷新页面后显示出来。
    maven聚合工程的创建
    阿里云 腾讯云 配置二级域名并解析指向非80端口操作指南
  • 原文地址:https://blog.csdn.net/kuaixiao0217/article/details/126691680