node+MySQL+Express实现账户登录,注册,重置之登录篇

实现技术

node.js,MySQL5.7(8.0以上版本会报错)layui(前端框架)Express
notify(消息通知layui插件)

开发工具

编码:vscode
数据库:navicat

项目结构

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

效果图

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

app.js代码

在这里插入图片描述

// 引入express模块
const express = require('express');
const path = require('path');
const { app, pool } =require('./db')
const user = require('./router/account')
// 设置端口号
const port = process.env.PORT || 8080; // 设置默认端口号
// const port = 8080;//设置端口号


// 静态资源目录路径
const staticPath = path.join(__dirname, 'public');
// 登录相关页面基础路径
const loginBasePath = path.join(__dirname, 'views/login');

// 使用静态资源
app.use(express.static(staticPath));

// 页面路由处理
const sendPage = (route, filename) => app.get(route, (req, res) => res.sendFile(path.join(loginBasePath, filename)));

// 跳转到登录页面
sendPage('/', 'login.html');
// 跳转到注册页面
sendPage('/register', 'register.html');
// 跳转到重置密码页面
sendPage('/rest', 'restPassword.html');
//  跳转到首页
sendPage('/main', 'main.html');
//跳转到短信验证登录页面
sendPage('/sms', 'smsLogin.html');
// 用户相关路由
app.use('/user', user)

// 监听端口
app.listen(port, () => console.log(`服务器在端口 ${port} 上启动成功`));
db.js

在这里插入图片描述

const mysql = require('mysql2')
const express = require('express')
const app = express()
const router = express.Router();

// 解析参数
const bodyParser = require('body-parser')
// json请求
app.use(bodyParser.json())
// 表单请求
app.use(bodyParser.urlencoded({extended: false}))
/**
 * 配置mysql
 */
const option = {
    host: 'localhost',
    user: 'root',
    password: 'root',
    port: '3307',
    database: 'bookInfo',
    connectTimeout: 5000, //连接超时
    multipleStatements: false //是否允许一个query中包含多条sql语句
}
let pool;
repool()
function Res ({ code = 200, msg = '', data = {} }) {
    this.code = code;
    this.msg = msg;
    this.data = data;
}
function resJson (_res, result) {
    return _res.json(new Res(result))
}
// 断线重连机制
function repool() {
    // 创建连接池
    pool = mysql.createPool({
        ...option,
        waitForConnections: true, //当无连接池可用时,等待(true)还是抛错(false)
        connectionLimit: 100, //连接数限制
        queueLimit: 0 //最大连接等待数(0为不限制)
    })
    pool.on('error', err => {
        err.code === 'PROTOCOL_CONNECTION_LOST' && setTimeout(repool, 2000)
    })
    app.all('*', (_,__, next) => {
        pool.getConnection( err => {
            err && setTimeout(repool, 2000) || next()
        })
    })
}
module.exports = { app, pool, router, resJson }

router下的account.js

在这里插入图片描述

const { pool, router, resJson } = require('../db');
const userSQL = require('../db/account');
const path = require('path');


/**
 * 用户登录功能
 */
router.post('/login', (req, res) => {
    // 获取请求参数
    let user = {
        account: req.body.account,
        password: req.body.password
    };
    let _res = res;
    // 判断参数是否为空
    if (!user.account) {
        return resJson(_res, {
            code: -1,
            msg: '账户不能为空'
        });
    }
    // 判断参数是否为空
    if (!user.password) {
        return resJson(_res, {
            code: -1,
            msg: '密码不能为空'
        });
    }
    // 从连接池获取连接
    pool.getConnection((err, conn) => {
        conn.query(userSQL.queryByNamePassword, [user.account, user.password], (e, result) => {
            if (e) {
                return resJson(_res, { code: -1, msg: e });
            }
            // 通过用户名和密码索引查询数据有数据说明用户存在且密码正确
            if (result && result.length) {
               // 登录成功
               resJson(_res, {
                code: 0,
                msg: '登录成功!'
            });
            } else {
                // 账户或密码错误
                resJson(_res, {
                    code: -1,
                    msg: '账户或密码错误'
                });
            }
        });
        pool.releaseConnection(conn); // 释放连接池,等待别的连接使用
    });
});

module.exports = router;
db下的account.js

在这里插入图片描述

const accountSQL = {
    queryByNamePassword: 'select * from  tb_account where account=? and password=?',  // 通过账户和密码索引查询用户
}

module.exports = accountSQL
login.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>暖意书籍管理系统登录</title>
  <!-- 设置系统图标 -->
   <link rel="shortcut icon" href="../icon/login.ico" type="image/x-icon" />
  <!-- 引用layui文件中layui.css -->
   <link rel="stylesheet" href="../layui/css/layui.css"  media="all"></link>
</head>
<style>
  .login-container{width: 320px; margin: 241px auto 0;}
  body {
    background-image: url(../image/login_index.jpg);
    background-size: cover;
    background-repeat: repeat;
  }
  .register-link-container {
    text-align: right; /* 右对齐文本 */
  }
  </style>
<body>
<form class="layui-form">
  <div class="login-container">
    <div class="layui-form-item">
      <div class="layui-input-wrap">
        <div class="layui-input-prefix">
          <i class="layui-icon layui-icon-username"></i>
        </div>
        <input type="number" name="account"  lay-verify="required|phone" placeholder="账户" lay-reqtext="请先填写账户" lay-vertype="tips" autocomplete="off" class="layui-input" lay-affix="clear">
      </div>
    </div>
    <div class="layui-form-item">
      <div class="layui-input-wrap">
        <div class="layui-input-prefix">
          <i class="layui-icon layui-icon-password"></i>
        </div>
        <input type="password" name="password"  lay-verify="required" placeholder="密   码" lay-reqtext="请填写密码" lay-vertype="tips" autocomplete="off" class="layui-input" lay-affix="eye">
      </div>
    </div>
    <div class="layui-form-item">
      <input type="checkbox" name="remember" lay-skin="primary" title="记住密码">
      <a href="/rest" style="float: right; margin-top: 7px;color: #435594;">忘记密码?</a>
    </div>
    <div class="layui-form-item">
      <button class="layui-btn layui-btn-fluid layui-bg-black" lay-submit lay-filter="loginBtn">&nbsp;&nbsp;&nbsp;&nbsp;</button>
    </div>
    <div class="layui-form-item">
      <a href="/sms" style="position: fixed;color: #435594;">短信快捷登录</a>
      <div class="register-link-container">
        <a href="/register" style="color: #435594;">注册帐号</a>
      </div>
    </div>
  </div>
</form>
  
<!-- 请勿在项目正式环境中引用该 layui.js 地址 -->
<script src="../layui/layui.js"></script> 
<script src="../notify/notify.js"></script>
<script>
  layui.use(['notify'],function(){
    var $ = layui.$;
  var form = layui.form;
  var layer = layui.layer;
  var util = layui.util;
  var notify = layui.notify;
    
    /* 方法1:利用layui的form模块的进行表单提交事件
       form.on('submit(loginBtn)', function(data){
        var field = data.field; // 获取表单字段值
        var loadIndex = layer.msg('验证登录中,请稍后...', {
          icon: 16,
          shade: 0.01
        });;
        setTimeout(function(){
          layer.close(loadIndex);
          $.ajax({
          url: 'http://localhost:3000/user/login',
          type: 'post',
          data: {account:field.account,
                password:field.password
          }, // 数据转换为JSON字符串
          success: function(res) {
            if(res.code == 0){
              layer.msg(res.msg);
              setTimeout(function(){
                location.href = 'http://localhost:3000/main';
              }, 1000);
            }else{
              layer.msg(res.msg);
            }
          }
        })
        }, 2000);
        // 阻止表单跳转
        return false; 
      });
    */

  // 方法2: 引用第三方消息通知组件进行表单提交事件
  form.on('submit(loginBtn)', function(data){
      var field = data.field; // 获取表单字段值
      if(field.password.length < 6){
        notify.info({msg:'密码长度不能小于6位',position:'vcenter',shadow:true, closable:false,duration:1000});
        return false;
      }
      /*
      加载提示:用法 notify.info({
                     msg:"提示",//提示信息
                    closable:true,//是否显示关闭按钮 默认是true
                    position:'vcenter',// 指定弹出位置:默认topCenter,可选值:bottomRight|bottomLeft|topRight|topLeft|topCenter|bottomCenter|vcenter"
                    shadow:true,//  是否显示阴影默认是false
                    duration:2000,//显示时间默认3000,为 0 时不自动关闭
                });
      */
      notify.loading({msg:'验证登录中,请稍后...',position:'vcenter',shadow:true, closable:false});//显示加载中
      setTimeout(function(){
        notify.destroyAll();//关闭所有通知
        $.ajax({
        url: 'http://localhost:8080/user/login',
        type: 'post',
        data: {account:field.account,
              password:field.password
        }, // 数据转换为JSON字符串
        success: function(res) {
          if(res.code == 0){
            //弹出成功提示
            notify.success({msg:res.msg,position:'vcenter',shadow:true, closable:false,duration:1000});
            //跳转到系统首页,延迟500毫秒
            setTimeout(function(){
              location.href = 'http://localhost:8080/main';
            }, 500);
          }else{
            //弹出错误提示
            notify.error({msg:res.msg,position:'vcenter',shadow:true, closable:false,duration:1000});
          }
        }
      })
      }, 2000);
      // 阻止表单跳转
      return false; //如果不加的话,表单不会跳转但不会进行登录操作
    });


  });
  </script>

 
</body>
</html>
数据库结构

在这里插入图片描述

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值