1.创建顶级目录,初始化包
npm init -y
2.下载项目所需的依赖
npm install 包名 --save
3.创建入口文件index.js(图书管理系统)
// 引入所需的依赖包
const express = require('express');
const path = require('path');//路径模块
const router = require('./router.js');//路由模块
const template = require('art-template');
const bodyParser = require('body-parser');
const app = express();
// 启动静态资源服务
// /www虚拟路径
app.use('/www',express.static('public'));
// 设置模板引擎的步骤
// 1.设置模板的路径
app.set('views',path.join(__dirname,'views'));
// 2.设置模板引擎的后缀
// art 模板引擎的后缀
app.set('view engine','art');
// 3.使express兼容art-template模板引擎
app.engine('art', require('express-art-template'));
// 处理请求参数
// 挂载参数处理中间件(post)
app.use(bodyParser.urlencoded({ extended: false }));
// 处理json格式的参数
app.use(bodyParser.json());
//启动服务器功能
// 1.配置路由
app.use(router);
// 2.监听端口
app.listen(3000,()=>{
console.log('running...');
})
4.创建二级目录views(专门放置页面文件),并在目录中创建模板页面,主页面index.art,添加图书页面addBook.art及修改图书页面editBook.art(其实是html页面,只不过art-template这个模板引擎包需要设置以art为后缀名)
//index.art
图书管理系统
图书管理系统
添加图书
编号
名称
作者
分类
描述
操作
{{each list}}
{{$value.id}}
{{$value.name}}
{{$value.author}}
{{$value.category}}
{{$value.desc}}
修改|删除
{{/each}}
---------------------------------------------------------------------
//addBook.art
添加图书
-------------------------------------------------------------------------------
//editBook.art
修改图书
5.创建二级目录public,创建页面相关的样式
body,div,h1{
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
a{
text-decoration: none;
color:inherit;
}
input,textarea,button,select{
border:none;
}
input:focus,textarea:focus,button:focus,select:focus{
outline: none;
outline-offset: 0;
}
.header{
font-size: 24px;
display: flex;
justify-content: center;
line-height: 70px;
color:#fff;
background-color:rgba(10,10,10,.7);
letter-spacing: 4px;
}
.header .add{
display: block;
font-size: 18px;
height: 26px;
line-height: 26px;
padding: 0 6px;
margin-top: 40px;
margin-left: 20px;
background-color:lightblue;
border-radius: 4px;
letter-spacing: normal;
}
.info table{
width: 100%;
text-align: center;
border-bottom: 2px solid #ccc;
border-right: 2px solid #ccc;
}
th,td{
border-top: 2px solid #ccc;
border-left: 2px solid #ccc;
line-height: 40px;
}
th{
font-size: 20px;
background-color: #f5f5f5;
}
td{
font-size: 18px;
}
.del a{
background-color: #ccc;
color: #fff;
padding:0 4px;
border-radius: 4px;
margin: 0 5px;
box-sizing: border-box;
}
/* 添加图书样式 */
.addheader{
text-align: center;
font-size: 24px;
line-height: 60px;
background-color:lightblue;
letter-spacing: 4px;
}
.addbook{
display: flex;
flex-direction: column;
background-color:#f5f5f5;
font-size: 20px;
padding: 20px 60px;
box-sizing: border-box;
}
.addbook>div{
line-height: 30px;
display: flex;
margin-top: 30px;
}
.addbook>div>input{
border-radius: 4px;
flex: 1;
padding: 0 10px;
border: 1px solid #ccc;
}
.addbook>div>button{
font-size: 20px;
width: 50%;
line-height: 30px;
margin: 0 auto;
background-color:lightblue;
border-radius: 4px;
cursor: pointer;
}
6.创建虚拟的图书信息json文件
[{
"name": "天龙八部",
"author": "金庸",
"category": "小说",
"desc": "武侠小说"
},
{
"name": "浮生六记",
"author": "沈复",
"category": "文学",
"desc": "个人生平记述"
},
{
"name": "边城",
"author": "沈从文",
"category": "文学",
"desc": "优美散文作品"
}
]
7.创建路由模块及业务模块,完成页面图书信息的渲染,图书数据的增添、修改及删除操作
/* 路由模块 */
const express =require('express');
const router =express.Router();
const service =require('./service.js');
// 路由处理 将路由绑定到业务模块上
// 渲染主页
router.get('/',service.showIndex);
// 添加图书(跳转到添加图书的页面)
router.get('/toAddBook',service.toAddBook);
//添加图书(提交表单一般用post)
router.post('/addBook',service.addBook);
// 跳转到修改图书信息页面
router.get('/toEditBook',service.toEditBook);
// 修改图书后提交表单
router.post('/editBook',service.editBook);
// 删除图书信息
router.get('/deleteBook',service.deleteBook);
// 导出路由
module.exports=router;
/* 业务模块 */
const data = require('./data.json');
const path = require('path');
const fs = require('fs');
// 自动生成图书编号(自增)
let maxBookCode = ()=>{
let arr = [];
// 遍历循环数据的每一项,取出编号id
data.forEach((item)=>{
arr.push(item.id);
});
// 返回编号id的最大值
// Math.max.apply获取数组中的最大值
return Math.max.apply(null,arr);
}
// 把内存数据写入文件
let writeDataToFile = (res) => {
fs.writeFile(path.join(__dirname,'data.json'),JSON.stringify(data,null,4),(err)=>{
if(err){
res.send('server error');
}
// 文件写入成功之后重新跳转到主页面
res.redirect('/');
});
}
// 渲染主页面
exports.showIndex=(req,res)=>{
// express中将数据渲染到页面的语法
// 参数一:模板名称;参数二:渲染模板的数据
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);
// 把内存中的数据写入文件
writeDataToFile(res);
}
// 跳转到修改图书的页面
exports.toEditBook=(req,res)=>{
// 获取当前需要修改图书记录的编号
let id = req.query.id;
let book = {};
data.forEach((item)=>{
if(id == item.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(let key in info){
item[key] = info[key];
}
return;
}
});
// 把内存中的数据写入文件
writeDataToFile(res);
}
// 删除图书信息
exports.deleteBook = (req,res) =>{
let id = req.query.id;
data.forEach((item,index)=>{
if(id == item.id){
// 删除数组的一项数据
data.splice(index,1);
}
return;
});
// 把内存中的数据写入文件
writeDataToFile(res);
}
8.使用cmd,在顶级目录下输入命令 node .
,显示runing …,在浏览器输入localhost:3000就可以成功显示页面了
说明:使用WampServer服务器软件和Navicat数据库管理工具创建图书信息数据,不使用之前创建的虚拟的图书信息json文件
1.创建操作数据库的sql.js文件
/*
封装操作数据库的通用api
*/
// 加载数据库驱动
const mysql = require('mysql');
exports.base = (sql,data,callback)=>{
// 创建数据库连接
const connection = mysql.createConnection({
host : 'localhost',//数据库所在的服务器的域名或者ip地址
user: 'root', // 登录数据库的账号
password : '',//登录数据库的密码
database : 'books'
});
// 执行连接操作
connection.connect();
//操作数据库(数据库操作也是异步的,需要通过回调函数返回结果)
connection.query(sql,data, function (error, results, fields) {
if (error) throw error;
callback(results);
});
//关闭数据库
connection.end();
}
2.修改业务模块内容(与数据库绑定)
/* 绑定数据库的业务模块 */
const data = require('./data.json');
const path = require('path');
const fs = require('fs');
const db = require('./sql.js');
// 自动生成图书编号(自增)
let maxBookCode = ()=>{
let arr = [];
// 遍历循环数据的每一项,取出编号id
data.forEach((item)=>{
arr.push(item.id);
});
// 返回编号id的最大值
// Math.max.apply获取数组中的最大值
return Math.max.apply(null,arr);
}
// 把内存数据写入文件
let writeDataToFile = (res) => {
fs.writeFile(path.join(__dirname,'data.json'),JSON.stringify(data,null,4),(err)=>{
if(err){
res.send('server error');
}
// 文件写入成功之后重新跳转到主页面
res.redirect('/');
});
}
// 渲染主页面
exports.showIndex=(req,res)=>{
// 通过数据库引入数据
let sql = 'select * from book';
db.base(sql,null,(result)=>{
// express中将数据渲染到页面的语法
// 参数一:模板名称;参数二:渲染模板的数据
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];
}
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 sql ='select * from book where id =?';
let data = [id];
db.base(sql,data,(result)=>{
// 将获取到的图书信息渲染到页面
res.render('editBook',result[0]);
})
}
// 编辑图书更新数据
exports.editBook = (req,res) =>{
let info = req.body;
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)=>{
if(result.affectedRows == 1){
res.redirect('/');
}
});
}
// 删除图书信息
exports.deleteBook = (req,res) =>{
let id = req.query.id;
let sql = 'delete from book where id =?';
let data = [id];
db.base(sql,data,(result)=>{
if(result.affectedRows == 1){
res.redirect('/');
}
});
}
3.修改路由模块,将之前的业务模块替换成与数据库绑定的业务模块
const service =require('./service-sql.js');
注意:显示页面需要先把WampServer服务器软件成功启动,再使用cmd,在顶级目录下输入命令 node .
,显示runing …,在浏览器输入localhost:3000就可以成功显示页面了