Loading

学生管理系统(Nodejs)

一、项目介绍

①使用nodejs+bootstrap开发

②对文件进行合理的模块化

③实现基本的增删改查功能

二、思路

①处理模块,处理模块,配置开发静态资源,配置模块引擎

②路由设计,提取路由模块

③单独的文件用于封装一些方法:查找学生数据,保存学生数据,更新学生数据,删除学生数据

④单独的路由模块实现具体功能:通过路由接收请求,调用数据操作API处理数据,发送操作结果给客户端

三、功能实现

①目录

②npm安装的包

③代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>管理系统</title>
    <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
    <nav class="navbar navbar-expand navbar-dark bg-dark fixed-top">
        <a class="navbar-brand" href="#">学生管理系统</a>
    </nav>
    <main class="container mt-5">
        <h1 class="alert-heading">学生管理
            <a class="btn btn-link btn-sm" href="/students/new">添加学生</a>
        </h1>
        <table class="table table-hover">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>性别</th>
                    <th>年龄</th>
                    <th>爱好</th>
                    <th class="text-center" width="140">操作</th>
                </tr>
            </thead>
            <tbody>
                {{each students}}
                <tr>
                  <td>{{$value.id}}</td>
                  <td>{{$value.name}}</td>
                  <td>{{$value.gender}}</td>
                  <td>{{$value.age}}</td>
                  <td>{{$value.hobbies}}</td>
                  <td>
                    <a href="/students/edit?id={{$value.id}}">编辑</a>
                    <a href="/students/delete?id={{$value.id}}">删除</a>
                  </td>
                </tr>
                {{/each}}
            </tbody>
        </table>
        <ul class="pagination justify-content-center">
            <li class="page-item"><a class="page-link" href="#">&laquo;</a></li>
            <li class="page-item"><a class="page-link" href="#">1</a></li>
            <li class="page-item"><a class="page-link" href="#">2</a></li>
            <li class="page-item"><a class="page-link" href="#">3</a></li>
            <li class="page-item"><a class="page-link" href="#">&raquo;</a></li>
        </ul>
    </main>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加学生</title>
    <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
    <nav class="navbar navbar-expand navbar-dark bg-dark fixed-top">
        <a href="#" class="navbar-brand">学生管理系统</a>
    </nav>
    <main class="container mt-5">
        <h1 class="alert-heading">添加学生</h1>
        <form action="/students/new" method="post" autocomplete="off">
            <div class="form-group">
                <label for="name">姓名</label>
                <input type="text" name="name" id="name" class="form-control">
            </div>
            <div class="form-group">
                <label for="gender" class="radio-inline">性别</label><br>
                <input type="radio" name="gender" value="0" id="gender">&nbsp;&nbsp;&nbsp;
                <input type="radio" name="gender" value="1" id="gender"></div>
            <div class="form-group">
                <label for="age">年龄</label>
                <input type="number" name="age" id="age" class="form-control">
            </div>
            <div class="form-group">
                    <label for="hobbies">爱好</label>
                    <input type="text" name="hobbies" id="hobbies" class="form-control">
            </div>
            <button class="btn btn-primary">保存</button>
        </form>
    </main>
</body>
</html>
new.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加学生</title>
    <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
    <nav class="navbar navbar-expand navbar-dark bg-dark fixed-top">
        <a href="#" class="navbar-brand">学生管理系统</a>
    </nav>
    <main class="container mt-5">
        <h1 class="alert-heading">添加学生</h1>
        <form action="/students/edit" method="post" autocomplete="off">
            <div class="form-group">
                <label for="id"></label>
                <input type="hidden" name="id" id="id" class="form-control" value="{{student.id}}">
            </div>
            <div class="form-group">
                <label for="name">姓名</label>
                <input type="text" name="name" id="name" class="form-control" value="{{student.name}}" >
            </div>
            <div class="form-group">
                <label for="gender" class="radio-inline">性别</label><br>
                <input type="radio" name="gender" value="0" id="gender">&nbsp;&nbsp;&nbsp;
                <input type="radio" name="gender" value="1" id="gender"></div>
            <div class="form-group">
                <label for="age">年龄</label>
                <input type="number" name="age" id="age" class="form-control" value="{{student.age}}">
            </div>
            <div class="form-group">
                    <label for="hobbies">爱好</label>
                    <input type="text" name="hobbies" id="hobbies" class="form-control" value="{{student.hobbies}}">
            </div>
            <button class="btn btn-primary">保存</button>
        </form>
    </main>
</body>
</html>
edit.html
{
    "students": [{
        "id": 1,
        "name": "赵一",
        "gender": 0,
        "age": 18,
        "hobbies": "足球"
    }, {
        "id": 2,
        "name": "孙二",
        "gender": 1,
        "age": 20,
        "hobbies": "篮球"
    }, {
        "id": 3,
        "name": "张三",
        "gender": 0,
        "age": 30,
        "hobbies": "彩票"
    }, {
        "id": 4,
        "name": "李四",
        "gender": 1,
        "age": 25,
        "hobbies": "代码"
    }, {
        "id": 5,
        "name": "王五",
        "gender": 0,
        "age": 10,
        "hobbies": "游戏"
    }]
}
db.json
/**
 * app.js入口模块:
 * 1.创建服务,
 * 2.服务相关配置:模板引擎,body-parser配置,静态服务资源,挂载路由
 * 3.监听端口启动服务
 */
//npm安装并加载express
var express=require('express');
var app=express();
// 加载路由模块
var router=require('./router');
// npm安装并加载body-parser
var bodyParser=require('body-parser');
//公开node_modules和public目录
app.use('/node_modules/',express.static('./node_modules/'));
app.use('/public/',express.static('./public/'));
// npm安装art-template和express-art-template并配置express-art-template(需要在挂载路由之前)
app.engine('html',require('express-art-template'));
// 配置body-parser(需要在挂载路由之前)
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
// 挂载路由
app.use(router);
// 绑定端口
app.listen(3000,function(){
    console.log('server is running at port 3000...')
});
app.js
/**
 * router.js路由模块:
 * 处理路由,根据不同的请求方法或者请求路径设置具体的返回数据
 */
// 加载相关模块
var fs=require('fs');
var express=require('express');
var Student=require('./student');
// 创建一个路由容器
var router=express.Router();
/** 路由设计:
 * 请求方法 ==== 请求路径 ==== 参数  =====备注 
 * GET ==== /students ==== 参数无 ====渲染首页
 * GET ==== /students/new ===== 参数无 ======渲染添加学生页面
 * POST ==== /students/new ===== 参数name,age,gender,hobbies ======添加学生页面提交表单
 * GET ==== /students/edit ===== 参数id ======渲染编辑页面
 * POST ==== /students/edit ===== 参数id,name,age,gender,hobbies ======编辑学生页面表单提交
 * GET ==== /students/delete ===== 参数id ======处理删除请求
 */
// 处理路由:把路由都挂载到路由容器
router.get('/students',function(req,res){
    Student.find(function(err,students){
        if(err){
            return res.status(500).send('server error')
        }
        res.render('index.html',{
            students:students
        })
    });
});
router.get('/students/new',function(req,res){
    res.render('new.html')
});
router.post('/students/new',function(req,res){
    // 获取表单数据-->处理(保存到db.json)-->发送响应
    Student.save(req.body,function(err){
        if(err){
            return res.status(500).send('server error')
        }
        res.redirect('/students')
    })
});
router.get('/students/edit',function(req,res){
    Student.findById(parseInt(req.query.id),function(err,student){
        if(err){
            return res.status(500).send('server error')
        }
        res.render('edit.html',{
            student:student
        });
    });
});
router.post('/students/edit',function(req,res){
    Student.updateById(req.body,function(err){
        if(err){
            return res.status(500).send('server error')
        }
        res.redirect('/students')
    })
});
router.get('/students/delete',function(req,res){
    Student.deleateById(req.query.id,function(err){
        if(err){
            return res.status(500).send('server error')
        }
        res.redirect('/students')
    });
});
// 把路由导出
module.exports=router;
router.js
/**
 * student.js模块:
 * 用于数据操作,只处理数据,不关心业务
 */
// 加载相关模块
var fs=require('fs');
var dbPath='./db.json';
// 获取所有学生数据列表
exports.find=function(callback){
    // callback有两个参数:第一个是err,第二个是data
    fs.readFile(dbPath,'utf8',function(err,data){
        if(err){
            return(callback(err))
        }
        callback(null,JSON.parse(data).students)
    });
};
// 根据id获取学生信息对象
exports.findById=function(id,callback){
    fs.readFile(dbPath,'utf8',function(err,data){
        if(err){
            return callback(err)
        }
        var students=JSON.parse(data).students;
        var ret=students.find(function(item){
            return item.id===parseInt(id)
        });
        callback(null,ret)
    });
}
// 添加保存学生数据列表
exports.save=function(student,callback){
    fs.readFile(dbPath,'utf8',function(err,data){
        if(err){
            return callback(err)
        }
        var students=JSON.parse(data).students
        // 处理id唯一的,不重复
        student.id=students[students.length-1].id+1
        // 保存到数组
        students.push(student)
        // 转为字符串
        var fileDate=JSON.stringify({students:students})
        // 保存到文件
        fs.writeFile(dbPath,fileDate,function(err){
            if(err){
                return callback(err)
            }
            callback(null)
        })
    });
};
// 更新学生数据列表
exports.updateById=function(student,callback){
    fs.readFile(dbPath,'utf8',function(err,data){
        if(err){
            return callback(err)
        }
        var students=JSON.parse(data).students;
        student.id=parseInt(student.id);
        // find 是ecmascript6的方法
        var stu=students.find(function(item){
            return item.id===student.id
        });
        // 遍历拷贝对象
        for(var key in student){
            stu[key]=student[key]
        }
        // 把对象数据转为字符串
        var fileDate=JSON.stringify({
            students:students
        });
        // 保存到文件
        fs.writeFile(dbPath,fileDate,function(err){
            if(err){
                return callback(err)
            }
            callback(null)
        });
    });
};
// 删除学生数据
exports.deleateById = function(id,callback){
    fs.readFile(dbPath,'utf8',function(err,data){
        if(err){
            return callback(err)
        }
        var students=JSON.parse(data).students;
        var deleteId=students.findIndex(function(item){
            return item.id===parseInt(id)
        });
        students.splice(deleteId,1);
        var fileDate=JSON.stringify({students:students});
        fs.writeFile(dbPath,fileDate,function(err){
            if(err){
                return callback(err)
            }
            callback(null)
        });
    })
}
student.js
{
  "name": "Code",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "art-template": "^4.12.2",
    "body-parser": "^1.18.3",
    "bootstrap": "^4.1.1",
    "express": "^4.16.3",
    "express-art-template": "^1.0.1"
  }
}
package.json

③效果展示

posted @ 2018-07-12 02:02  澎湃_L  阅读(2034)  评论(0编辑  收藏  举报