利用nodejs实现商品管理系统(二)
下面实现商品管理系统
第一步:对应的ejs与数据交换的编写格式。
商品列表界面product.ejs
<% for(var i=0;i<list.length;i++){%> <tr> <td><%=i+1%></td> <td><img width="100" src="<%=list[i].pic%>" alt=""/></td> <td><%=list[i].title%></td> <td><%=list[i].price%></td> <td><%=list[i].fee%></td> <td class="text-center"> <a href="/productedit?id=<%=list[i]._id%>" class="btn btn-success">修改</a> <a href="/productdelete?id=<%=list[i]._id%>" class="btn btn-danger">删除</a> </td> </tr> <%}%>
商品编辑页面
<form action="/doProductEdit" method="post" enctype="multipart/form-data"> <ul> <input type="hidden" name="_id" value="<%=list._id%>"/> <input type="hidden" name="pic" value="<%=list.pic%>"/> <li> 商品名称: <input type="text" name="title" value="<%=list.title%>"/></li> <li> 商品图片: <input type="file" name="pic"/> <br/> <br/> <img src="<%=list.pic%>" width="100"/> <br/> <br/> </li> <li> 商品价格: <input type="text" name="price" value="<%=list.price%>"/></li> <li> 商品邮费: <input type="text" name="fee" value="<%=list.fee%>"/></li> <li> 商品描述: <textarea name="description" id="" cols="60" rows="8"><%=list.description%></textarea> </li> <li> <br/> <button type="submit" class="btn btn-default">提交</button> </li> </ul> </form>
商品增加页面productadd.ejs
<form action="/doProductAdd" method="post" enctype="multipart/form-data"> <ul> <li> 商品名称: <input type="text" name="title"/></li> <li> 商品图片: <input type="file" name="pic"/></li> <li> 商品价格: <input type="text" name="price"/></li> <li> 商品邮费: <input type="text" name="fee"/></li> <li> 商品描述: <textarea name="description" id="" cols="60" rows="8"></textarea> </li> <li> <br/> <button type="submit" class="btn btn-default">提交</button> </li> </ul> </form>
第二步:由于商品的增删改查都要用到数据库,所以第二步应该讲数据库封装起来,接着在app.js中引用相应的模块。
新建db.js,开始判断是否连接数据库成功。
var MongoClient=require('mongodb').MongoClient; var DbUrl='mongodb://localhost:27017/productmanage'; var ObjectID = require('mongodb').ObjectID; function __connectDb(callback){ MongoClient.connect(DbUrl,function(err,db){ if(err){ console.log('数据库连接失败'); return; } //增加 修改 删除 callback(db); }) }
exports.ObjectID=ObjectID; //查找数据 exports.find=function(collectionname,json,callback){ __connectDb(function(db){ var result=db.collection(collectionname).find(json); result.toArray(function(error,data){ db.close();/* 关闭数据库*/ callback(error,data);/*拿到数据执行回调函数*/ }) }) } //插入数据 exports.insert=function(collectionname,json,callback){ __connectDb(function(db){ db.collection(collectionname).insertOne(json,function(error,data){ callback(error,data); }) }) } //更新数据 exports.update=function(collectionname,json1,json2,callback){ __connectDb(function(db){ db.collection(collectionname).updateOne(json1,{$set:json2},function(error,data){ callback(error,data); }) }) } //删除数据 exports.deleteOne=function(collectionname,json,callback){ __connectDb(function(db){ db.collection(collectionname).deleteOne(json,function(error,data){ callback(error,data); }) }) }
第三步:编辑相应的路由
3.1商品增加路由
//商品列表 app.get('/product',function(req,res){ DB.find('product',{},function(err,data){ res.render('product',{ list:data }); }) }) //显示增加商品的页面 app.get('/productadd',function(req,res){ res.render('productadd'); })
当点击增加商品时,跳转到doProductAdd路由上
<form action="/doProductAdd" method="post" enctype="multipart/form-data">
在第一篇的时候使用body-parser来接收用户密码和用户名,但是在商品增加编辑中存在图片上传问题,body-parser无法实现,所以改用multiparty模块。
先安装multiparty
npm install multiparty --save
在引入:
var multiparty = require('multiparty');
使用post获取商品增加提交的数据
app.post('/doProductAdd',function(req,res){ //获取表单的数据 以及post过来的图片 var form = new multiparty.Form(); form.uploadDir='upload' //上传图片保存的地址 upload目录必须存在 form.parse(req, function(err, fields, files) { //获取提交的数据以及图片上传成功返回的图片信息
//fields获取表单的数据 files得到图片上传成功返回的信息 var title=fields.title[0]; var price=fields.price[0]; var fee=fields.fee[0]; var description=fields.description[0]; var pic=files.pic[0].path;
//在数据库中插入数据 DB.insert('product',{ title:title, price:price, fee,//效果与上面一致 description, pic },function(err,data){ if(!err){ res.redirect('/product'); /*上传成功跳转到首页*/ } }) }); })
此时添加/upload路由获取图片信息,因为此时图片的地址是/upload/xxxxxxx.jpg,否则默认从public从查找资源。
app.use('/upload',express.static('upload'));
拓展:如果此时图片的地址是 /xxxxxxx.jpg,可以直接配置,注意路由!
app.use(express.static('upload'));
3.2商品编辑路由
注意:无论是商品编辑还是删除都是通过get传值来获取商品的数据库id号
<a href="/productedit?id=<%=list[i]._id%>" class="btn btn-success">修改</a> <a href="/productdelete?id=<%=list[i]._id%>" class="btn btn-danger">删除</a>
app.js中
app.get('/productedit',function(req,res){ //获取get传值 id var id=req.query.id; console.log(id); //去数据库查询这个id对应的数据 自增长的id 要用{"_id":new DB.ObjectID(id) DB.find('product',{"_id":new DB.ObjectID(id)},function(err,data){ //console.log(data); res.render('productedit',{ list:data[0] }); }); })
在修改商品form表格上依然使用post来提交数据
<form action="/doProductEdit" method="post" enctype="multipart/form-data">
在编辑/doProductEdit路由的时候,如果并没有修改图片信息,此时我们需要作出判断,否则会在upload文件上存在一串非图片信息的字符串,最终返回/product界面时,没有出现并没有修改的商品图片。
最终在修改的商品信息返回到product页面
app.post('/doProductEdit',function(req,res) { var form = new multiparty.Form(); form.uploadDir = 'upload' // 上传图片保存的地址 form.parse(req, function (err, fields, files) { //获取提交的数据以及图片上传成功返回的图片信息 //console.log(fields); console.log(files); var _id = fields._id[0]; /*修改的条件*/ var title = fields.title[0]; var price = fields.price[0]; var fee = fields.fee[0]; var description = fields.description[0]; var originalFilename = files.pic[0].originalFilename; var pic = files.pic[0].path; if (originalFilename) { /*修改了图片*/ var setData = { title, price, fee, description, pic }; } else { /*没有修改图片*/ var setData = { title, price, fee, description }; //删除生成的临时文件 fs.unlink(pic); } DB.update('product', {"_id": new DB.ObjectID(_id)}, setData, function (err, data) { if (!err) { res.redirect('/product'); } }) }); })
3.3商品删除
app.get('/productdelete',function(req,res){ //获取id var id=req.query.id; DB.deleteOne('product',{"_id":new DB.ObjectID(id)},function(err){ if(!err){ res.redirect('/product'); } }) })
最后的最后,奉上项目的源码地址:https://github.com/xinhua6/productManage.git