您的位置:首页 > Web前端 > Node.js

从零开始node.js入门项目(五)后台管理

2014-01-11 10:22 771 查看
因为代码越来越多,从这一节开始只贴出关键代码,所有文档和代码会打包到附件。

另外基本构架已经搭建好了,基本上下面工作就是完善构架赋予其血肉,所以章节也按业务逻辑和碰到的问题来组织。

express的session处理

session插件很多, 没有去一一比较,我们只选了其中session-mongoose,利用mongodb来存储session

1、安装

 npm install session-mongoose

2 、使用

在/index.js增加配置

var mongodb_con='mongodb://localhost:27017/bossDB';
app.use('/public', express.static(path.join(__dirname, 'public')));
//session配置
var sessionMongoose = require("session-mongoose")(express);
var sessionStore = new sessionMongoose({
url: mongodb_con,
interval: 120000
});
app.use(express.cookieParser());
app.use(express.session({ cookie: { maxAge:2*60*100000}, store: sessionStore, secret: 'boss_sys_v08@session' }));


session 赋值与调用

//赋值
req.session.admin_user_name = '12345';
//调用
var u=req.session.admin_user_name;


简单的权限过滤

我们要实现的目标是,除了指定的路径如登录、退出,后台所有的请求都要验证是否登录(session是否存在)

修改/core/routes.js 增加如下代码

//允许访问列表
var allow_allways=['/admin/login','/admin/logout'];
//简单session权限校验
app.all('/admin/*',function(req,res,next){
var pathname = url.parse(req.url).pathname;
if (req.session.admin_user_name==undefined && !allow_allways.in_array(pathname)){
res.redirect('/admin/login');
}else{
return next();
}
});


注意app.all中next的处理

通用增、删、改、查方法

仔细观察,不难发现后台大部分操作都是对某个集合的增、删、改、查,没什么好说的,封装成公共方法统一处理,而不是为

每个集合都去写一个增、删、改、查方法。

最好的做法是每个controller都继承这些公共方法,继承稍后实现,我们先看公共方法

公共方法

修改/controllers/admin_controller.js

//通用新增操作
controller.prototype.action_common_add=function(){
var parameters=this.req.body.form;
var collection=this.req.body.collection;
var res=this.res;
if (parameters){
var model = require('../models/'+collection);
//console.log(Admin_User.schema.attributeLabels);
var m = new model(parameters);
m.save(function (err,parameters) {
if(!err) {
res.send('1');
}else{
res.send(set_errors(err.errors,model.schema.attributeLabels));
}
});
return false;
}
};
//通用删除操作
controller.prototype.action_common_delete=function(){
var id=this.req.body.id;
var collection=this.req.body.collection;
var res=this.res;
var model = require('../models/'+collection);
model.remove({
'_id':id
},function(err){
if(!err){
res.send("1");
}else{
res.send("0");
}
});
};


前端调用

 以删除为例,/views/admin/admin_user_list.ejs

function user_delete(id){
if(!confirm('确实要删除吗?')){
return false;
}
$.post("/admin/common_delete",{id:id,collection:"admin_user"},function(ret) {
if (ret==1){
$("#tr"+id).remove();
}
});
}


mongodb分页

关于分页,主要用skip实现,据说数据多大话性能问题,没有实际证实,先分出页再说。

核心代码

var pagination={limit:page_size,skip:(page-1)*page_size};
model.find(find,null,pagination,function(err,docs){

});


实例

修改/controllers/admin_controller.js

//通用查询查询(带分页)
controller.prototype.action_common_find=function(){
var find=this.req.body.find;
var collection=this.req.body.collection;
var page=this.req.body.page;
var page_size=this.req.body.page_size;
var model = require('../models/'+collection);
var all_num=0;
var res=this.res;
var pagination=null;
//如果分页
if (page!=undefined && page_size!=undefined){
pagination={limit:page_size,skip:(page-1)*page_size};
model.count(find, function (err, count) {
all_num=count;
});
}
model.find(find,null,pagination,function(err,docs){
if(err){
docs={};
}
res.send({
all_num:all_num,
docs:docs
});
});
}


调用

 修改/views/admin/department_list.ejs

<table width="90%" id="data_table" class="table table-striped table-bordered">
<tr><th>部门名称</th><th>图标</th><th>操作</th></tr>
</table>
<div id="pagination"></div>
<script>
var page_condition={collection:'department',find:{},page:1,page_size:2};
$(document).ready(function(){
getcontent(page_condition);
});
function getcontent(condition){
var tmpl="<tr class=\"new_add\"><td>{name}</td><td>{logo_name}</td><td>\n\
<a href=\"#\" onclick=\"show_add('{id}','保存','{name}','{logo_name}')\">修改</a>\n\
  <a href=\"#\" onclick=\"user_delete({id})\">删除</a></td></tr>";
$.post("/admin/common_find",condition,function(ret) {
render_table("data_table",tmpl,ret,condition);
});
}
Array.union = function(a, b){
return a.concat(b).uniquelize();
};
function render_table(dom,tmpl,data,condition){
var html="";
var i=0;
for (var key in data.docs) {
var txt=tmpl.replace(/\{(\w+)\}/g,function(w,t){return data.docs[i][t];});
i++;
html+=txt;
}
$(".new_add").remove();
$("#"+dom).append(html);
var page_txt="";
if (data.all_num>0){
page_txt+='<ul class="pagination">';
if (condition.page>1){
page_txt+='<li><a href="javascript:go_page('+(condition.page-1)+')">«</a></li>';
}else{
page_txt+='<li class="disabled"><a >«</a></li>';
}
var max_page=Math.ceil(data.all_num/condition.page_size);
var arr=[];
var arr2=[1,2,4,5,6,7,8,max_page-1,max_page];
var x2=0;
for (var x1=(condition.page-3);x1<=(condition.page+3);x1++){
if (x1>0 && x1<max_page){
arr[x2]=x1;
x2++;
}
}
//合并后排序
arr=$.merge(arr,arr2);
arr.sort(function(a,b){return a>b?1:-1});
//消除重复
$.each(arr, function(key, val) {
if (arr[key]==arr[key-1]){
arr.splice(key,1);
}
});
//添加省略号
if (arr[2]!=3){
arr.splice(2,0,'...');
}
if (arr[8]!=9){
arr.splice(8,0,'...');
}
for (var x=0;x<arr.length;x++){
var a_class="";
if (arr[x]==condition.page){
a_class='active';
}
//如果有太多页则显示第一页、当前页前后3页、最后一页
if (!isNaN(arr[x])){
page_txt+='<li class='+a_class+'><a href="javascript:go_page('+arr[x]+')" >'+arr[x]+'</a></li>';
}else{
page_txt+='<li class="disabled"><a  >'+arr[x]+'</a></li>';
}

}
if (condition.page<max_page){
page_txt+='<li><a href="javascript:go_page('+(condition.page+1)+')">»</a></li>';
}else{
page_txt+='<li class="disabled"><a >»</a></li>';
}
page_txt+='</ul>';
if (max_page>1){
$("#pagination").html(page_txt);
}

}
}
function go_page(page){
page_condition.page=page;
getcontent(page_condition);
}
</script>


总结

用很少量代码(约300行)完成了整个BOSS系统后台业务逻辑,可见node.js用上各种插件后的强悍,下节将进入boss系统的前端,让我们先

享受下目前的战斗成果(华丽丽的bootstrap css 啊..)







内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐