- 新建一个目录作为工作区
- 进入工作区所在目录的终端进行npm的初始化
npm init
- 下载需要用到的包
npm install express art-template body-parser --save
- 下载兼容包
npm install express-art-template --save
- 下载mysql驱动
npm install mysql
- 项目目录结构如下
- 入口文件index.js
const express = require("express");
const router = require("./router.js");
const template = require("art-template");
const path = require("path");
const bodyParser = require("body-parser");
const app = express();
// 设置模板引擎
app.set("views",path.join(__dirname,"views"));
app.set("view engine","art");
// 使用express兼容art-template
app.engine("art",require("express-art-template"));
//处理请求参数
app.use(bodyParser.urlencoded({extended:false}));//处理post请求
app.use(bodyParser.json());
//处理静态资源(css等)
app.use("/www",express.static("public"));
//启动服务器
//1.配置路由
app.use(router);
//2.监听端口
app.listen(3000,()=>{
console.log("running...");
})
const express = require("express");
const router = express.Router();
const service = require("./service");
//路由处理
//渲染主页
router.get("/",service.showIndex);
//添加图书(跳转到添加图书的页面)
router.get("/toAddBook",service.toAddBook);
//添加图书(提交表单)
router.post("/addBook",service.addBook);
//修改图书(跳转到修改图书的页面)
router.get("/toEditBook",service.toEditBook);
//修改图书(提交表单)
router.post("/editBook",service.editBook);
//删除图书
router.get("/deleteBook",service.deleteBook);
//导出
module.exports = router;
- 处理业务操作的service.js(基于json文件)
const data = require("./data.json");
const path = require("path");
const fs = require("fs");
const { stringify } = require("querystring");
//自动生成图书编号(自增)
let maxBookCode = ()=>{
let arr = [];
data.forEach((item)=>{
arr.push(item.id);
});
return Math.max.apply(null,arr);
}
//渲染主页面
exports.showIndex = (req,res)=>{
res.render("index",{list:data});
}
//添加图书页面
exports.toAddBook = (req,res)=>{
res.render("addBook",{});
}
//添加图书保存数据
exports.addBook = (req,res)=>{
//获取表单数据
let info = req.body;
let book = {};
for(let key in info){
book[key]= info[key];
}
book.id=maxBookCode()+1;
data.push(book);
//写入文件
fs.writeFile(path.join(__dirname,"data.json"),JSON.stringify(data),(err)=>{
if(err){
res.send("server error");
}
//跳转到主页面
res.redirect("/")
})
}
//添加修改页面
exports.toEditBook = (req,res)=>{
let id = req.query.id;
let book = null;
data.forEach((item)=>{
if(item.id==id){
book = item;
return;
}
})
res.render("editBook",book);
}
exports.editBook = (req,res)=>{
let info = req.body;
data.forEach((item)=>{
if(info.id==item.id){
for(key in info){
item[key]=info[key];
}
return;
}
})
fs.writeFile(path.join(__dirname,"data.json"),JSON.stringify(data),(err)=>{
if(err){
res.send("server error");
}
//跳转到主页面
res.redirect("/")
})
}
exports.deleteBook = (req,res)=>{
let id = req.query.id;
let book = null;
data.forEach((item,index)=>{
if(item.id==id){
data.splice(index,1); //删除该图书
}
})
fs.writeFile(path.join(__dirname,"data.json"),JSON.stringify(data),(err)=>{
if(err){
res.send("server error");
}
//跳转到主页面
res.redirect("/")
})
}
- 保存数据的data.json文件(后期可以用数据库代替)
[{"id":"1","name":"三国演义","author":"罗贯中","category":"文学","desc":"一个杀伐战争的年代"},
{"id":"2","name":"水浒传","author":"施耐庵","category":"文学","desc":"108条好汉的故事"},
{"id":"3","name":"西游记","author":"吴承恩","category":"文学","desc":"师徒四人西游取经","_locals":{}},
{"id":"4","name":"红楼梦","author":"曹雪芹","category":"文学","desc":"贾宝玉和林黛玉的爱情故事"}]
/*
处理业务操作
*/
// const data = require("./data.json");
const db = require("./db");
const path = require("path");
const fs = require("fs");
const { stringify } = require("querystring");
// //自动生成图书编号(自增)
// let maxBookCode = ()=>{
// let arr = [];
// data.forEach((item)=>{
// arr.push(item.id);
// });
// return Math.max.apply(null,arr);
// }
//渲染主页面
exports.showIndex = (req,res)=>{
// res.render("index",{list:data});
let sql = "select * from book ";
db.base(sql,null,(result)=>{
res.render("index",{list:result});
})
}
//添加图书页面
exports.toAddBook = (req,res)=>{
res.render("addBook",{});
}
//添加图书保存数据
exports.addBook = (req,res)=>{
//获取表单数据
let info = req.body;
let book = {};
for(let key in info){
book[key]= info[key];
}
// book.id=maxBookCode()+1;
// data.push(book);
// //写入文件
// fs.writeFile(path.join(__dirname,"data.json"),JSON.stringify(data),(err)=>{
// if(err){
// res.send("server error");
// }
// //跳转到主页面
// res.redirect("/")
// })
let sql = "insert into book set ?";
db.base(sql,book,(result)=>{
if(result.affectedRows==1){
res.redirect("/");
}
})
}
//添加修改页面
exports.toEditBook = (req,res)=>{
let id = req.query.id;
// let book = null;
// data.forEach((item)=>{
// if(item.id==id){
// book = item;
// return;
// }
// })
let sql ="select * from book where id =?";
let data = [id];
db.base(sql,data,(result)=>{
console.log(result)
res.render("editBook",result[0]);
})
}
exports.editBook = (req,res)=>{
let info = req.body;
// data.forEach((item)=>{
// if(info.id==item.id){
// for(key in info){
// item[key]=info[key];
// }
// return;
// }
// })
let sql = "update book set name =?,author=?,category=?,description =? where id=?";
let data = [info.name,info.author,info.category,info.description,info.id];
db.base(sql,data,(result)=>{
res.redirect("/");
})
// fs.writeFile(path.join(__dirname,"data.json"),JSON.stringify(data),(err)=>{
// if(err){
// res.send("server error");
// }
// //跳转到主页面
// res.redirect("/")
// })
}
exports.deleteBook = (req,res)=>{
let id = req.query.id;
// let book = null;
// data.forEach((item,index)=>{
// if(item.id==id){
// data.splice(index,1); //删除该图书
// }
// })
// fs.writeFile(path.join(__dirname,"data.json"),JSON.stringify(data),(err)=>{
// if(err){
// res.send("server error");
// }
// //跳转到主页面
// res.redirect("/")
// })
let sql = "delete from book where id=?";
let data = [id];
db.base(sql,data,(result)=>{
if(result.affectedRows==1){
res.redirect("/");
}
})
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书管理系统</title>
<link rel="stylesheet" type="text/css" href="/www/style.css"
</head>
<body>
<div class="title"><span>图书管理系统</span><a href="/toAddBook">添加图书</a></div>
<div class="content">
<table>
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>作者</th>
<th>分类</th>
<th>描述</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{each list}}//这里将会被数据填充
<tr>
<td>
{{$value.id}}
</td>
<td>
{{$value.name}}
</td>
<td>
{{$value.author}}
</td>
<td>
{{$value.category}}
</td>
<td>
{{$value.description}}
</td>
<td>
<a href="/toEditBook?id={{$value.id}}">修改</a>|
<a href="/deleteBook?id={{$value.id}}">删除</a>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</body>
</html>
.title{
text-align: center;
height: 80px;
line-height: 80px;
}
.title span{
margin: 0 auto;
font-size: 30px;
font-weight: 800;
}
.content{
background-color: blanchedalmond;
}
.content table{
width: 100%;
text-align: center;
border-right: 1px solid orange;
border-bottom: 1px solid orange;
}
.content td,th{
border-left: 1px solid orange;
border-top: 1px solid orange;
height: 40px;
line-height: 40px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加图书</title>
</head>
<body>
<div>添加图书</div>
<form action="/addBook" method="post">
名称:<input type="text" name="name"><br>
作者:<input type="text" name="author"><br>
分类:<input type="text" name="category"><br>
描述:<input type="text" name="description"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改图书</title>
</head>
<body>
<div>修改图书</div>
<form action="/editBook" method="post">
<!-- 设置一个隐藏域保存id -->
<input type="hidden" name="id" value="{{id}}">
名称:<input type="text" name="name" value="{{name}}"><br>
作者:<input type="text" name="author" value="{{author}}"><br>
分类:<input type="text" name="category" value="{{category}}"><br>
描述:<input type="text" name="description" value="{{description}}"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
- 运行
node .
- 运行结果(添加、修改删除操作均可正常使用)