路由设计
请求方式 |
url |
备注 |
GET |
/students |
获取所有学生 |
POST |
/students/addStu |
添加学生 |
POST |
/students/editStu |
编辑学生 |
GET |
/students/getStuById |
根据ID查找学生 |
GET |
/students/option |
学生管理操作 |
GET |
/students/delStu |
删除学生 |
目录结构
//views文件存储视图页面
//db.json用于持久化操作,用文件流操作,暂不使用数据库
//app.js主入口,启动服务器等
//route.js存放路由
//student.js 做增删改查处理数据
安装依赖包
//Express框架依赖
npm i express --save
npm i express-art-template --save
//模板引擎
npm i art-template --save
//Express框架用于解析请求体参数的依赖
npm i body-parser --save
文件详情
app.js
const express = require('express');
const app = express();
var router = require('./route.js');
var bodyParser = require('body-parser')
//配置模板引擎
app.engine('html', require('express-art-template'));
app.set('view engine', 'html');
//配置接受post请求参数的中间件
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: false
}))
// parse application/json
app.use(bodyParser.json())
app.use(router);
app.listen(3000, () => {
console.log('server is runnging and listen to 3000 port');
});
db.json
{
"students": [{
"id": 1,
"name": "zws",
"number": "13332111",
"gender": "1"
}]
}
route.js
const express = require('express');
let student = require('./student.js');
let router = express.Router();
//首页
router.get('/students', (req, res) => {
student.find((error, data) => {
if (error) {
return res.status(500).send('服务器错误');
}
res.render('index.html', {
students: data
});
});
});
//管理学生操作
router.get('/students/option', (req, res) => {
//如果有传id则是修改否则是增加
if (req.query.id) {
student.findStuById(req.query.id, (err, data) => {
if (err) {
return res.status(500).send('服务器错误');
}
res.render('option.html', {
returnUrl: '/students/editStu',
students: data
});
});
return;
}
return res.render('option.html', {
returnUrl: '/students/addStu',
students: {}
});
});
//添加学生
router.post('/students/addStu', (req, res) => {
student.addStu(req.body, (err) => {
if (err) {
return res.status(500).send('服务器错误');
}
res.redirect('/students');
});
});
//修改学生
router.post('/students/editStu', (req, res) => {
student.editStu(req.body, (err) => {
if (err) {
return res.status(500).send('服务器错误');
}
res.redirect('/students');
})
});
//删除学生
router.get('/students/delStu', (req, res) => {
student.delStu(req.query.id, (err) => {
if (err) {
return res.status(500).send('服务器错误');
}
res.redirect('/students');
});
});
module.exports = router;
student.js
const fs = require('fs');
//查找所有学生
module.exports.find = (callback) => {
fs.readFile('./db.json', (error, data) => {
if (error) {
callback(error);
}
let students = JSON.parse(data.toString()).students;
callback(null, students);
});
};
//添加学生
module.exports.addStu = (student, callback) => {
fs.readFile('./db.json', (error, data) => {
if (error) {
return callback(error);
}
let students = JSON.parse(data.toString()).students;
//不做的太细节,id只做简单处理
student.id = students.length + 1;
students.push(student);
//保存到json文件
fs.writeFile('./db.json', JSON.stringify({
students: students
}), (err) => {
callback(err);
});
});
};
//修改学生
module.exports.editStu = (student, callback) => {
fs.readFile('./db.json', (error, data) => {
if (error) {
return callback(error);
}
let students = JSON.parse(data.toString()).students;
let stu;
students.map((data, index) => {
if (parseInt(student.id) === data.id) {
stu = data;
}
});
for (let key in student) {
stu[key] = student[key];
}
//转化成整型变量
stu.id = parseInt(stu.id);
//保存到json文件
fs.writeFile('./db.json', JSON.stringify({
students: students
}), (err) => {
callback(err);
});
});
};
//根据ID查找学生
module.exports.findStuById = (id, callback) => {
fs.readFile('./db.json', (error, data) => {
if (error) {
return callback(error);
}
let students = JSON.parse(data.toString()).students;
students.map((data, index) => {
if (parseInt(id) === data.id) {
callback(null, data);
}
});
});
};
//删除学生
module.exports.delStu = (id, callback) => {
fs.readFile('./db.json', (error, data) => {
if (error) {
return callback(error);
}
let students = JSON.parse(data.toString()).students;
students.map((data, index) => {
if (parseInt(id) === data.id) {
students.splice(index, 1);
}
});
//保存到json文件
fs.writeFile('./db.json', JSON.stringify({
students: students
}), (err) => {
callback(err);
});
});
};
index.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">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/favicon.ico">
<link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/dashboard/">
<title>Dashboard Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/dist/css/bootstrap.min.css"
rel="stylesheet">
<!-- Custom styles for this template -->
<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/examples/dashboard/dashboard.css"
rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Dashboard</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Help</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">student <span class="sr-only">(current)</span></a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<button type="button" onclick="location.href='/students/option'" class="btn btn-success">添加</button>
<h2 class="sub-header">Section title</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>性别</th>
<th>学号</th>
</tr>
</thead>
<tbody>
{{each students}}
<tr>
<td>{{$value.id}}</td>
<td>{{$value.name}}</td>
<td>{{$value.gender}}</td>
<td>{{$value.number}}</td>
<td><button type="button"
onclick="location.href='/students/option?id='+{{$value.id}}"
class="btn btn-primary">修改</button>
<button type="button"
onclick="location.href='/students/delStu?id='+{{$value.id}}"
class="btn btn-danger">删除</button>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
option.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">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/favicon.ico">
<link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/dashboard/">
<title>Dashboard Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/dist/css/bootstrap.min.css"
rel="stylesheet">
<!-- Custom styles for this template -->
<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/examples/dashboard/dashboard.css"
rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="{{returnUrl}}" method="post">
<div class="form-group" style="display: none;">
<label for="exampleInputEmail1">id</label>
<input type="text" name="id" value="{{students.id}}" class="form-control" placeholder="Email">
</div>
<div class="form-group">
<label for="name">name</label>
<input type="text" class="form-control" name="name" value="{{students.name}}" id="name" placeholder="name">
</div>
<div class="form-group">
<label for="number">number</label>
<input type="text" value="{{students.number}}" name="number" class="form-control" id="number" placeholder="number">
</div>
<div class="form-group">
<label class="radio-inline">
<input type="radio" name="gender" id="inlineRadio1" value="1"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="inlineRadio2" value="2"> 女
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
</body>
</html>