构建学生管理系统-1

 

  • 首先我们在命令行中新建文件夹和相应的文件
  • 具体步骤如下图所示
  • 然后我们编写index.js里面的内容,并将它暴露出来

  • 代码如下
  • const express = require('express')
    //构建express框架
    const router = express.Router()
    //设置router下的index.js 实现路由功能
    
    
    module.exports = router;
    //对外暴漏router里面的index.js

     

  • 然后我们编写app.js里面的代码
  • const express=require('express')
    //构建express框架
    const router = require('/router')
    //我们自己构建的index.js模块 必须用 ./ 或者 ../开头  以便我们运行app.js的时候顺带运行router下的index.js
    const app = express();
    //设置app.js
    
    app.engine('html',require('express-art-template'))
    //引入express-art-template,用于解析html文件
    
    //接下来就该开放静态资源了
    app.use('/public',express.static('public'))
    //开放public文件夹,以便在后端打开时,app.js能够调用public里面的(js,css,img)
    app.use('/node_modules',express.static('node_modules'))
    //开放node_modules文件夹,以便我们调用jquery和boostrap
    
    
    //然后我们开始配置body-parser
    //现在较高版本的body-parser都内嵌在了express里面
    //必须配置body-parser,否则无法收到前端post的内容
    express.use(express.urlencoded({extend:false}))
    express.use(express.json)
    
    app.use(router)
    //用于app.js 和 index.js的连接
    app.listen(3000,()=>console.log("app is running"))
    //设置监听

    随后我们开始编写admin-log.html 一个首页登录的界面

  • 首先我们登录到boostrap中文网站    
    • https://v3.bootcss.com/css/#forms
  • 我们找到我们所需的css样式        如图所示
  •  

     我们复制他的代码到我们的admin-login.html中

  • 编写我们的admin-login.html     

我们考虑首先我们在编写login.js的时候会判断账号是否符合格式并且判断账号是否在后端数据库中是否存在

所以,我们在页面上是要写如以下代码并设置他的class属性为hidden

代码如下

           <p class="text-danger hidden" id="p1" >账号格式不正确</p>
           <p class="text-danger hidden" id="p2" >账号未注册</p>
  • 总代码如下
  • <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>welcome administrator login!</title>
        <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
        <!--我们链入这个我们在npm社区里面下载好的bootstrap.min.css-->
        <style>
            body{
                background: rgb(235,238,244);
            }
            header{
                background: #fff;
                border-bottom: 10px solid rgb(235,238,244);
            }
            #loginInput{
                background: #fff;
                height: 600px;
                padding-top: 100px;
            }
        </style>
    </head>
    <body>
    <header class="container-fluid">
        <div class="container">
            <div class="row">
                <h1 class="col-xs-12">Welcome Administrator Login!</h1>
            </div>
        </div>
    
    </header>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2" id="loginInput">
                <form class="form-horizontal" action="/admin-login" method="post">
                    <!--            //post=>body    get =>query-->
    
    
                    <div class="form-group">
                        <label for="account" class="col-sm-2 control-label">Account</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control"name="account" id="account" placeholder="Account">
                            <p class="text-danger hidden" id="p1" >账号格式不正确</p>
                            <p class="text-danger hidden" id="p2" >账号未注册</p>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="password" class="col-sm-2 control-label">Password</label>
                        <div class="col-sm-10">
                            <input type="password" class="form-control"name="password" id="password" placeholder="Password">
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <div class="checkbox">
                                <label>
                                    <input type="checkbox"> Remember me
                                </label>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-default">Sign in</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
    
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="../node_modules/jquery/dist/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
    <!--链入判断账号格式的login.js-->
    <script src="../public/js/login.js"></script>
    </body>
    </html>

     

  • 我们在data文件里面新建admins.json文件
  • 代码如下
  • [
      {
        "id": 0,
        "name": "王二小",
        "gender": 1,
        "account": 13312341234,
        "password": "000000",
      },
      {
        "id": 1,
        "name": "张三",
        "gender": 1,
        "account":18343214321,
        "password": "000000",
      }
    ]

     

  • 根据这个登录页面,我们编写相应的验证账户的login.js

  • 第一我么做这个项目,这个输入框的验证
  • 是当我们输入好了以后
  • 当鼠标失去焦点的时候我们就开始验证一系列操作所以我们先写入失去焦点的代码
  • $('#account').blur(test_account)

    让我们的一系列的函数,当失去焦点的时候,开始生效。

  • 首先:我们验证此账户的手机号位数是否合法
  • 我们用正则表达式来解决这个问题
  • 我们在       https://regexper.com/    来查找
  • 代码如下     
    /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
  • 验证手机号是否合法
  • 正则表达式.test(在这里我们用jquery实现判断)
  • .val() 返回这个输入的值判断是否一致
  • 代码如下
  •  if (reg_phone.test($('#account').val())){
    
    }

    如果是合法的我们

  • 将之间在html界面设置的p1标签的class属性为hidden
  • 代码如下
  •    $('#p1').addClass('hidden')

     

  • 同样如果不合法的话我们将去除p1标签的class属性hidden
  • 代码如下
  •  $('#p1').removeClass('hidden')

     

  • 但是这样会导致一个bug
  • 就是我么这样会让p2的
  • 通过get方法,向'/test-account'路径发送信息{account: $('#account').val()},

  • 判断数据库data文件下是否存在这个账户
  • 代码如下
  • $.get('/test-account', {account: $('#account').val()}, data => {
    
    }

    如果后端返回了数据,即account为true时,此账号已经注册,那么我们用jquery让p2的class名为hidden,如果在数据库中不存在的话,我们加上class属性hidden

  • 代码如下
  •  if (data) {
                    islogin.account = true
                    $('#p2').addClass('hidden')
                    return
                }
                islogin.account = false
                $('#p2').removeClass('hidden')

    全部代码如下图所示

  • const test_account = () => {
        const reg_phone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
        if (reg_phone.test($('#account').val())) {
            $('#p1').addClass('hidden')
                $.get('/test-account', {account: $('#account').val()}, data => {
                if (data) {
                    islogin.account = true
                    $('#p2').addClass('hidden')
                    return
                }
                islogin.account = false
                $('#p2').removeClass('hidden')
            })
            return
        }
        $('#p1').removeClass('hidden')
        $('#p2').addClass('hidden')
        islogin.account = false
    }
    $('#account').blur(test_account)

    这样我们就能够实现用户的账号是否符合格式,并且在后端数据库中是否存在

  • 那我们避免不了我们不小心输错账号和密码
  • 所以我们设置输错账号和密码的提醒
  • 首先我们在html界面中加入以下代码
  •        {{if isNotLogin}}
                <p class="text-danger">账号或密码错误</p>
                {{/if}}

    在login.js的最后加入这行代码

  • $('form').submit(()=>{
        test_account()
        return islogin.account
    })

    当我们提交的时候执行text_account()这个函数,来做判断我们的账号和密码是否正确

  • 这样的话我们基本的功能就实现了

然后我们做信息展示平台

  • 我们构思一下,一个大体的框架大概是这样的,如图所示
  •  

     

          左面应该是一个根据登录者的权限而显示的选项

总共是四个权限,分别是 1.查看学生 2.添加学生 3.查看管理员 4.添加管理员

超级管理员:四个权限都具备

普通管理员:只能查看学生和添加学生

首先我们该如何判断呢       我们在data中建立jurisdiction.json文件

然后我们通过index.js调用jurisdiction.json文件做判断

首先jurisdiction.json代码如下

{
  "adminJurisdiction": [
    {
      "id": 0,
      "name": "查看学生",
      "path": "/a"
    },{
      "id": 1,
      "name": "添加学生",
      "path": "/b"
    }
  ],
  "SuperAdminJurisdiction": [
    {
      "id": 2,
      "name": "查看管理员",
      "path": "/c"
    },{
      "id": 3,
      "name": "添加管理员",
      "path": "/d"
    }
  ]
}

同样的html界面我们做这样的处理

  {{each result.jurisdiction_result}}
<!--                //each循环每一个后端数据-->
                <li><a href="{{$value.path}}">{{$value.name}}</a></li>
                {{/each}}

同样nav的地方我们也是这样处理

  欢迎尊贵{{result.admin.isSuperAdmin?"超级":""}}管理员登录

在admin.json文件中

第一个设置为超级管理员

第二个设置普通管理员

代码如下

    "isSuperAdmin":true

    "isSuperAdmin":false

 

然后学生的信息部分html代码如下

 {{each result.students}}
                <tr>
                    <td>{{$value.name}}</td>
                    <td>{{$value.gender==1?"男":"女"}}</td>
                    <td>{{$value.birth}}</td>
                    <td>{{$value.account}}</td>
                    <td>¥{{$value.salary}}</td>
                    <td>
                        <a href="/edit?id={{$value.id}}" class="bg-warning">编辑</a>
                        <a href="" class="bg-danger">删除</a>
                    </td>
                </tr>
                {{/each}}

 

同样我们设置students.json文件,在后端录入信息

代码如下

[
  {
    "id": 0,
    "name": "阿伟",
    "gender": 1,
    "birth": 952494401000,
    "account": 15512341234,
    "password": 123456,
    "salary": 5000
  },
  {
    "id": 1,
    "name": "阿花",
    "gender": 0,
    "birth": 952404401000,
    "account": 15500001234,
    "password": 123456,
    "salary": 4500
  },
  {
    "id": 2,
    "name": "小鹿",
    "gender": 1,
    "birth": 952492401000,
    "account": 15512340000,
    "password": 123456,
    "salary": 4000
  },
  {
    "id": 3,
    "name": "小和",
    "gender": 0,
    "birth": 952494121000,
    "account": 15510041234,
    "password": 123456,
    "salary": 5500
  },
  {
    "id": 4,
    "name": "小马",
    "gender": 1,
    "birth": 952294401010,
    "account": 15512341004,
    "password": 123456,
    "salary": 4500
  }
]

完整的show-students.html

代码如下

<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Welcome Administrator Login</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" href=../node_modules/bootstrap/dist/css/bootstrap.min.css>
    <link rel="stylesheet" href="../public/css/public.css">


</head>
<body>

<header class="container-fluid">
    <div class="container">
        <div class="row">
            <h1 class="col-xs-12">
                欢迎尊贵{{result.admin.isSuperAdmin?"超级":""}}管理员登录

            </h1>
        </div>
    </div>
</header>

<div class="container">
    <div class="row">
        <div class="col-sm-2 bg-warning">
            <ul>
                {{each result.jurisdiction_result}}
<!--                //each循环每一个后端数据-->
                <li><a href="{{$value.path}}">{{$value.name}}</a></li>
                {{/each}}
            </ul>
        </div>
        <div class="col-sm-10 bg-danger">
            <table class="table table-bordered table-hover table-responsive">
                <thead>
                <tr>
                    <th>姓名</th>
                    <th>性别</th>
                    <th>年龄</th>
                    <th>手机号</th>
                    <th>期望薪资</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {{each result.students}}
                <tr>
                    <td>{{$value.name}}</td>
                    <td>{{$value.gender==1?"男":"女"}}</td>
                    <td>{{$value.birth}}</td>
                    <td>{{$value.account}}</td>
                    <td>¥{{$value.salary}}</td>
                    <td>
                        <a href="/edit?id={{$value.id}}" class="bg-warning">编辑</a>
                        <a href="" class="bg-danger">删除</a>
                    </td>
                </tr>
                {{/each}}
                </tbody>
            </table>

        </div>
    </div>
</div>


<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
</body>
</html>

然后我们在index.js里面就可以做判断了

接下来我们编写index.js

一开始我们已经编写了初始的 index.js

代码如下

const express = require('express')
//构建express框架
const router = express.Router()
//设置router下的index.js 实现路由功能


module.exports = router;
//对外暴漏router里面的index.js

然后我们继续编写

首先我们于admin-login.html建立连接并且渲染admin-login.html

代码如下

router.get('/admin-login.html', (req, res) => {
    res.render('admin-login.html')
})  

然后我们判断他是否为管理员

用get方法  获取'/test-account'路径

fs.readFile读取data下的admins.json

看后端数据和前端输入的数据是否相同

代码如下

router.get('/test-account', (req, res) => {
    fs.readFile('data/admins.json', (err, data) => {
        if (err) throw err
        res.send(Boolean(JSON.parse(data).find(value => value.account == req.query.account)))
    })
})

我们在前端登录页面判断他的账号和密码是否正确

首先我们post到admin-login.html页面上

然后我们读取admins.json

判断他的账号和密码是否正确

符合条件的我们将他定义为admin

以便下一步我们分配不同的权限

 

代码如下

router.post('/admin-login', (req, res) => {
    console.log(req.body)
    fs.readFile('data/admins.json', (err, data) => {
        if (err) throw err
        const admin = JSON.parse(data).find(value => value.account == req.body.account)
        if (admin && admin.password == req.body.password) {
}

 然后我们读取用来判断是否为超级管理员的jurisdiction.json文件

我们声明jurisdictions=JSON.parse(data)

对jurisdiction.json文件中的数组进行转型

代码如下

fs.readFile('data/jurisdiction.json', (err, data) => {
                if (err) throw err
                const jurisdictions = JSON.parse(data)
                const jurisdiction_result = jurisdictions.adminJurisdiction
//默认将普通管理员的权限赋值给jurisdiction_result
}

接下来我们判断他是否为超级管理员,如果是的话我们将超级管理员那两个权限附加给他(push)

代码如下

if (admin.isSuperAdmin) {
jurisdiction_result.push(...jurisdictions.SuperAdminJurisdiction)
 }

因为我们是在前端做的判断,所以后端的数据会发送给前端,处于信息安全考虑我们删除发送到前端的代码

        delete admin.password;

其次我们开始弄右侧展示学生的代码

同样的我们读取

students.json文件

然后声明students并转型

其次我们循环输出学生的信息       并删除他们的密码

用.map()方法

代码如下

 fs.readFile('data/students.json',(err,data)=>{
                    if (err)throw err
                    const students = JSON.parse(data)
                    console.log(students)
                    students.map(value=>delete value.password)
                    console.log(students)
}

最后我们声明result

用于渲染页面附带在后段传入前端的admin jurisdiction students

代码如下

      const result = {admin, jurisdiction_result,students}
      res.render('show-students.html', {result})

 

完整的index.js代码如下

const express = require('express')
const fs = require('fs')

const router = express.Router()

router.get('/admin-login.html', (req, res) => {
    res.render('admin-login.html')
})

//管理员登录,验证手机号是否存在
router.get('/test-account', (req, res) => {
    //判断账号是否已注册
    fs.readFile('data/admins.json', (err, data) => {
        if (err) throw err
        res.send(Boolean(JSON.parse(data).find(value => value.account == req.query.account)))
    })
})
//管理员登录账号密码处理
router.post('/admin-login', (req, res) => {
    console.log(req.body)
    fs.readFile('data/admins.json', (err, data) => {
        //读文件,获取管理员数据库里的所有数据,是一个数组
        if (err) throw err
        //判断错误
        const admin = JSON.parse(data).find(value => value.account == req.body.account)
        //在数据库根据前端传过来的账号查找对应的账户,如果找到,admin是对应的账户(对象) 并进行数组转型
        //如果找不到,admin为undefined
        if (admin && admin.password == req.body.password) {
            //如果admin是查找的对应账户(不是undefined)
            //并且数据中的密码和前端传输过来的一致
            fs.readFile('data/jurisdiction.json', (err, data) => {
                //则继续读取权限数据库
                if (err) throw err
                const jurisdictions = JSON.parse(data)
                //声明管理员,并转型
                const jurisdiction_result = jurisdictions.adminJurisdiction
                //默认将普通管理员的权限赋值给jurisdiction_result
                if (admin.isSuperAdmin) {
                    //判断如果是超级管理员的话就在jurisdiction_result加上超级管理员所特有的两个权限
                    jurisdiction_result.push(...jurisdictions.SuperAdminJurisdiction)
                    // arrA.push(...arrB) 意为把数组B里面的每一个元素都按序push到数组A中
                }
                console.log(jurisdiction_result)
                delete admin.password;
                //删除传入前端的密码,
                fs.readFile('data/students.json',(err,data)=>{
                    if (err)throw err
                    const students = JSON.parse(data)
                    console.log(students)
                    students.map(value=>delete value.password)
                    console.log(students)
                    //.map类似于一个for循环,students是一个数组实现数组的循环
                    const result = {admin, jurisdiction_result,students}
                    //渲染页面时。顺便捎带的数据,必须是object
                    /*
                      const result = {admin, jurisdiction_result}
                    * 以上代码ES6新语法
                    等同于
                      const result = {
                      admin:admin,
                      jurisdiction_result:jurisdiction_result
                      }
                    * */
                    //result{是不是管理员或者超级管理员,左边是两个权限或者四个权限}
                    res.render('show-students.html', {result})
                    //渲染页面,并且便于将后端的数据传输得show—students.html中
                })

            })

        } else {
            res.render('admin-login.html', {isNotLogin: true})
        }
    })
})

module.exports = router

这样我们就实现了如图所示的效果

 

 

 

posted @ 2022-03-10 16:05  doudou帅  阅读(27)  评论(0)    收藏  举报