当前位置: 首页 > news >正文

【学生管理系统】用户管理之用户登录

目录

2. 用户管理

2.1 环境搭建

2.1.1 前端环境

2.1.2 后端环境(9000)

2.2 用户登录

2.2.1 需求

2.2.2 后端实现

2.2.3 前端实现

2.3 首页

2.3.1 需求

2.3.2 前端实现

2. 用户管理

2.1 环境搭建

2.1.1 前端环境

  • 编写默认布局

  • 编写自定义登陆布局

  • 编写登录页面,使用登录布局

  • 编写默认布局

     

  • 编写自定义登陆布局

     

    <template>
      <nuxt/>
    </template>
    ​
    <script>
    export default {
    ​
    }
    </script>
    ​
    <style>
    ​
    </style>

  • 编写登录页面,使用登录布局

     

    <template>
      <div>
        登录
      </div>
    </template>
    ​
    <script>
    export default {
      layout: 'user'
    }
    </script>
    ​
    <style>
    ​
    </style>

2.1.2 后端环境(9000)

  • 项目名:nacos-nuxt-student-service-user

  • pom文件

    ​
        <dependencies>
            <!--web起步依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- nacos 客户端 -->
            <dependency>
                <groupId>com.alibaba.nacos</groupId>
                <artifactId>nacos-client</artifactId>
            </dependency>
    ​
            <!-- nacos 服务发现 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
    ​
            <!--swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
            </dependency>
    ​
            <!-- feign 远程调用 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    ​
            <!--测试-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
    ​
            <!-- mybatis plus-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!--自定义项目-->
            <dependency>
                <groupId>com.czxy</groupId>
                <artifactId>nacos-nuxt-student-domain</artifactId>
            </dependency>
    ​
            <!-- redis 启动器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <!-- JavaMail 启动器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-mail</artifactId>
            </dependency>
            <!-- MQ 启动器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-amqp</artifactId>
            </dependency>
    ​
            <!-- fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
            </dependency>
    ​
            <!--开发者工具-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
    ​
            <!--jwt工具-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
            </dependency>
            <!--joda 时间工具类 -->
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
            </dependency>
            <!--JavaBean工具类,用于JavaBean数据封装-->
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
            </dependency>
    ​
        </dependencies>

  • yml文件

    # 服务端口号
    server:
      port: 9000
    # 服务名
    spring:
      application:
        name: user-service
      datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/cloud_es_user?useUnicode=true&characterEncoding=utf8
        username: root
        password: 1234
        druid:    #druid 连接池配置
          initial-size: 1       #初始化连接池大小
          min-idle: 1           #最小连接数
          max-active: 20        #最大连接数
          test-on-borrow: true  #获取连接时候验证,会影响性能
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848   #nacos服务地址
    ​
    #开启log4j打印SQL语句
    logging:
      level:
        com:
          czxy:
            user:
              mapper: debug
    ​
    # mp日志打印
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      global-config:
        db-config:
          logic-delete-value: 1
          logic-not-delete-value: 0
    ​
    sc:
      jwt:
        secret: sc@Login(Auth}*^31)&czxy% # 登录校验的密钥
        pubKeyPath: D:/rsa/rsa.pub # 公钥地址
        priKeyPath: D:/rsa/rsa.pri # 私钥地址
        expire: 360 # 过期时间,单位分钟

  • 启动类

    package com.czxy;
    ​
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     * @description
     */
    @SpringBootApplication      //spring boot
    @EnableDiscoveryClient      //服务发现
    @EnableFeignClients         //远程调用
    public class UserServiceApplication {
        public static void main(String[] args) {
            SpringApplication.run(UserServiceApplication.class, args);
        }
    }
    ​

  • 拷贝config

     

  • 基本结构:mapper、service、controller

     

    package com.czxy.user.mapper;
    ​
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.czxy.domain.TbUser;
    import org.apache.ibatis.annotations.Mapper;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     * @description
     */
    @Mapper
    public interface TbUserMapper extends BaseMapper<TbUser> {
    }
    ​
    package com.czxy.user.service;
    ​
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.czxy.domain.TbUser;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     * @description
     */
    public interface TbUserService extends IService<TbUser> {
    }
    ​
    package com.czxy.user.service.impl;
    ​
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.czxy.domain.TbUser;
    import com.czxy.user.mapper.TbUserMapper;
    import com.czxy.user.service.TbUserService;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     * @description
     */
    @Service
    @Transactional
    public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements TbUserService {
    }
    ​
    package com.czxy.user.controller;
    ​
    import com.czxy.user.service.TbUserService;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    ​
    import javax.annotation.Resource;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     * @description
     */
    @RestController
    @RequestMapping("/user")
    public class TbUserController {
        @Resource
        private TbUserService tbUserService;
    ​
    ​
    }
    ​

2.2 用户登录

2.2.1 需求

  • 基本校验:非空、长度

     

  • 异步校验:

 

  • 登录成功后,跳转到首页

2.2.2 后端实现

1)用户名校验

  • 需求:用户名不存在不能登录、用户存在可以登录

  • 编写service

  • 编写controller

  • 编写service

    • 接口

      package com.czxy.user.service;
      ​
      import com.baomidou.mybatisplus.extension.service.IService;
      import com.czxy.domain.TbUser;
      ​
      /**
       * @author 桐叔
       * @email liangtong@itcast.cn
       * @description
       */
      public interface TbUserService extends IService<TbUser> {
          TbUser findByUserName(String userName);
      }
      ​

    • 实现类

      public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements TbUserService {
          @Override
          public TbUser findByUserName(String userName) {
              //1 拼条件
              QueryWrapper<TbUser> queryWrapper = new QueryWrapper<>();
              queryWrapper.eq("user_name", userName);
      ​
              //2 查询
              TbUser findUser = baseMapper.selectOne(queryWrapper);
              return findUser;
          }
      }

  • 编写controller

    package com.czxy.user.controller;
    ​
    import com.czxy.domain.TbUser;
    import com.czxy.user.service.TbUserService;
    import com.czxy.vo.BaseResult;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    ​
    import javax.annotation.Resource;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     * @description
     */
    @RestController
    @RequestMapping("/user")
    public class TbUserController {
        @Resource
        private TbUserService tbUserService;
    ​
        /**
         * 用户登录的校验
         * @author 桐叔
         * @email liangtong@itcast.cn
         * @return
         */
        @PostMapping("/check")
        public BaseResult check(@RequestBody TbUser tbUser) {
            //1 查询:通用用户名查询
            TbUser findUser = tbUserService.findByUserName(tbUser.getUserName());
            //2 返回
            if(findUser != null) {
                return BaseResult.ok("可以登录");
            }
            return BaseResult.error("用户名不存在");
        }
    ​
    ​
    }
    ​

2)用户登录

  • 编写service

  • 编写controller

  • 编写service

    • 接口

      package com.czxy.user.service;
      ​
      import com.baomidou.mybatisplus.extension.service.IService;
      import com.czxy.domain.TbUser;
      ​
      /**
       * @author 桐叔
       * @email liangtong@itcast.cn
       * @description
       */
      public interface TbUserService extends IService<TbUser> {
      ​
          /**
           * 登录
           * @author 桐叔
           * @email liangtong@itcast.cn
           * @return
           */
          TbUser login(TbUser loginUser);
      }
      ​

    • 实现类

          @Override
          public TbUser login(TbUser loginUser) {
              //1 拼条件
              QueryWrapper<TbUser> queryWrapper = new QueryWrapper<>();
              queryWrapper.eq("user_name", loginUser.getUserName());
              queryWrapper.eq("password", loginUser.getPassword());
      ​
              //2 查询
              TbUser findUser = baseMapper.selectOne(queryWrapper);
              return findUser;
          }

  • 编写controller

    package com.czxy.user.controller;
    ​
    import com.czxy.domain.TbUser;
    import com.czxy.user.service.TbUserService;
    import com.czxy.vo.BaseResult;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    ​
    import javax.annotation.Resource;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     * @description
     */
    @RestController
    @RequestMapping("/user")
    public class TbUserController {
        @Resource
        private TbUserService tbUserService;
    ​
        /**
         * 登录
         * @author 桐叔
         * @email liangtong@itcast.cn
         * @return
         */
        @PostMapping("/login")
        public BaseResult login(@RequestBody TbUser tbUser) {
            //1 查询:通用用户名查询
            TbUser findUser = tbUserService.login(tbUser);
            //2 返回
            if(findUser != null) {
                return BaseResult.ok("登录成功");
            }
            return BaseResult.error("用户名或密码不匹配");
        }
    ​
    ​
    }
    ​

2.2.3 前端实现

1)绘制登录页面

<template>
  <div class="login">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <el-button type="text" icon="el-icon-s-home">传智专修学院</el-button>
      </div>
      <!-- 正文 -->
      <el-form :model="user" :rules="rules" ref="loginForm" label-width="80px" >
        <el-form-item label="用户名" prop="userName">
          <el-input v-model="user.userName"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="user.password" show-password></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" >登录</el-button>
          <el-button >取消</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>
​
<script>
export default {
  layout: 'user',
  data() {
    return {
      user: {},
      rules: {
        userName: [
            { required: true, message: '请输入用户名', trigger: 'blur' },
            { min: 3, max: 6, message: '长度在 3 到 6 个字符', trigger: 'blur' }
          ],
        password: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { min: 3, max: 6, message: '长度在 3 到 6 个字符', trigger: 'blur' }
          ]
      }
    }
  },
}
</script>
​
<style>
  .login {
​
  }
  .login .box-card {
    width: 500px;
  }
</style>

2)登录框居中

  • 扩展:登录框居中

    • 登录页面拷贝样式

       

        .login {
          height: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
        }

    • 登录布局页面拷贝样式

       

        html, body, #__nuxt, #__layout {
          height: 100%;
        }

3)登录

<template>
  <div class="login">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <el-button type="text" icon="el-icon-s-home">传智专修学院</el-button>
      </div>
      <!-- 正文 -->
      <el-form :model="user" :rules="rules" ref="loginForm" label-width="80px" >
        <el-form-item label="用户名" prop="userName">
          <el-input v-model="user.userName"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="user.password" show-password></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="login" >登录</el-button>
          <el-button >取消</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>
​
<script>
export default {
  layout: 'user',
  data() {
    return {
      user: {
        userName: 'jack',
        password: '1234'
      },
      rules: {
        userName: [
            { required: true, message: '请输入用户名', trigger: 'blur' },
            { min: 3, max: 6, message: '长度在 3 到 6 个字符', trigger: 'blur' }
          ],
        password: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { min: 3, max: 6, message: '长度在 3 到 6 个字符', trigger: 'blur' }
          ]
      }
    }
  },
  methods: {
    login() {
      // 校验
      //this.$refs['loginForm'].validate((valid) => {
      this.$refs.loginForm.validate(async (valid) => {
        if (valid) {
          // 校验通过后ajax登录
          let { data:baseResult } = await this.$axios.post('/user-service/user/login', this.user)
          if(baseResult.code == 20000) {
            // 成功
            this.$message.success(baseResult.message)
            // 跳转
            this.$router.push('/')
          } else {
            // 失败
            this.$message.error(baseResult.message)
          }
        } else {
          console.log('error submit!!');
          return false;
        }
      });
      
      
    }
  },
}
</script>
​
<style>
  .login {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .login .box-card {
    width: 500px;
  }
</style>

4)表单校验:内置校验

 

5)用户名校验:自定义校验

 

<template>
  <div class="login">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <el-button type="text" icon="el-icon-s-home">传智专修学院</el-button>
      </div>
      <!-- 正文 -->
      <el-form :model="user" :rules="rules" ref="loginForm" label-width="80px" >
        <el-form-item label="用户名" prop="userName">
          <el-input v-model="user.userName"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="user.password" show-password></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="login" >登录</el-button>
          <el-button >取消</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>
​
<script>
export default {
  layout: 'user',
  data() {
    // 自定义校验规则start
    var validateLoginCheck = async (rule, value, callback) => {
      // 校验通过:callback();
      // 校验未通过:callback(new Error('请输入密码'));
      // 发送ajax,进行用户名校验
      let user = {
        userName: value
      }
      let { data:baseResult } = await this.$axios.post(`/user-service/user/check`, user)
      if(baseResult.code == 20000) {
        // 成功
        callback();
      } else {
        // 失败
        callback(new Error(baseResult.message));
      }
    };
    // 自定义校验规则end
    return {
      user: {
        userName: 'jack',
        password: '1234'
      },
      rules: {
        userName: [
            { required: true, message: '请输入用户名', trigger: 'blur' },
            { min: 3, max: 6, message: '长度在 3 到 6 个字符', trigger: 'blur' },
            { validator: validateLoginCheck, trigger: 'blur' }
          ],
        password: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { min: 3, max: 6, message: '长度在 3 到 6 个字符', trigger: 'blur' }
          ]
      }
    }
  },
  methods: {
    login() {
      // 校验
      //this.$refs['loginForm'].validate((valid) => {
      this.$refs.loginForm.validate(async (valid) => {
        if (valid) {
          // 校验通过后ajax登录
          let { data:baseResult } = await this.$axios.post('/user-service/user/login', this.user)
          if(baseResult.code == 20000) {
            // 成功
            this.$message.success(baseResult.message)
            // 跳转
            this.$router.push('/')
          } else {
            // 失败
            this.$message.error(baseResult.message)
          }
        } else {
          console.log('error submit!!');
          return false;
        }
      });
      
      
    }
  },
}
</script>
​
<style>
  .login {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .login .box-card {
    width: 500px;
  }
</style>

2.3 首页

2.3.1 需求

 

2.3.2 前端实现

  • 将element ui布局内容编写nuxt的默认布局

    • 编写布局

    • 左侧垂直菜单

    • 头像+弹出提示

  • 设置reset.css(优化)

  • 将element ui布局内容编写nuxt的默认布局

    • 编写布局

    • 左侧垂直菜单

    • 头像+弹出提示

     

    <template>
      <el-container>
        <el-header>
          <el-row>
            <el-col :span="22" class="title">
              学生管理系统(SMS)
            </el-col>
            <el-col :span="2">
    ​
              <!-- <el-popover
                placement="top-start"
                width="200"
                trigger="hover"
                content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。">
                <el-avatar slot="reference" size="large" src="/5.jpg"></el-avatar>
                <div class="avatarItem">用户详情</div>
                <div class="avatarItem">修改密码</div>
                <div class="avatarItem">退出登录</div>
              </el-popover> -->
              <el-dropdown>
                <span class="el-dropdown-link">
                  <el-avatar :size="50" src="/5.jpg"></el-avatar>
                </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item>用户详情</el-dropdown-item>
                  <el-dropdown-item>修改密码</el-dropdown-item>
                  <el-dropdown-item>退出登录</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </el-col>
          </el-row>
        </el-header>
        <el-container>
          <el-aside width="200px">
            <!-- 菜单start -->
            <el-menu
              :default-active="$route.path"
              router
              background-color="#545c64"
              text-color="#fff"
              active-text-color="#ffd04b">
              <el-menu-item index="/">
                <i class="el-icon-menu"></i>
                <span slot="title">首页</span>
              </el-menu-item>
              <el-submenu index="/classes">
                <template slot="title">
                  <i class="el-icon-location"></i>
                  <span>班级管理</span>
                </template>
                <el-menu-item index="/classes/classesAdd">添加班级</el-menu-item>
                <el-menu-item index="/classes/classesList">班级列表</el-menu-item>
              </el-submenu>
              <el-submenu index="/student">
                <template slot="title">
                  <span>学生管理</span>
                </template>
                <el-menu-item index="/student/studentList">学生列表</el-menu-item>
              </el-submenu>
             
            </el-menu>
            <!-- 菜单end -->
          </el-aside>
          <el-main>
            <!-- 视图显示 -->
            <nuxt/>
          </el-main>
        </el-container>
        <el-footer>传智专修学院</el-footer>
      </el-container>
    </template>
    ​
    <script>
    export default {
    ​
    }
    </script>
    ​
    <style>
      html, body, #__nuxt, #__layout, .el-container {
        height: 100%;
      }
      body {
        margin: 0;
      }
      .avatarItem {
        width: 100px;
        display: inline-block;
        margin: 5px 0;
      }
      .title {
        font-size: 30px;
        font-weight: bold;
      }
      .el-header, .el-footer {
        background-color: #B3C0D1;
        color: #333;
        text-align: center;
        line-height: 60px;
      }
      
      .el-aside {
        background-color: #545c64;
        color: #fff;
      }
      
      .el-main {
        background-color: #E9EEF3;
        color: #333;
        text-align: center;
      }
    </style>

  • 设置reset.css(优化)--待定

相关文章:

  • FTP客户端Transmit 5 for Mac中文激活版
  • Git恢复至某一个提交的状态
  • JavaSE备忘录(未完)
  • JWT技术选型以及相关功能的实现
  • HTML合集
  • CSS transition和animation的用法和区别
  • Linux系统——Nginx拓展
  • 区块链智能合约开发
  • [LeetCode]143.重排链表
  • 校园微社区微信小程序源码/二手交易/兼职交友微信小程序源码
  • 51单片机-(定时/计数器)
  • Easy-Jmeter: 性能测试平台
  • 操作系统八股文03-内存管理
  • DRL经典文献阅读(一):策略梯度理论(Policy Gradient, PG)
  • 第26章 物联网软件系统测试
  • Xmake实战---libjpeg 开源库移植
  • 基于划分的聚类分析——K-means(机器学习)
  • 10.17复习
  • Python正则表达式详解
  • Day08-尚品汇-分页器动态展示
  • 基于图像处理技术的印刷电路板缺陷检测技术分析
  • Hello Word你真的理解了么?今天教我的表弟,有些感悟
  • 【NNDL作业】图像锐化后,为什么“蒙上了一层灰色”?
  • JDBC——使用Java语言操作数据库
  • 将华为地图套件集成到HarmonyOs可穿戴设备应用中
  • 基于OpenAPI(Swagger3)使用AOP技术,进行日志记录
  • JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数
  • 【PyTorch深度学习项目实战100例】—— 基于UNet实现血管瘤超声图像分割 | 第30例
  • 浅谈面向对象设计思想,以及在Linux内核中的体现
  • Mybatis——进阶
  • 简单上手_Kotlin,让开发更简洁
  • 机器学习——代价函数