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

来源:互联网 发布:北京云计算公司排名 编辑:程序博客网 时间:2024/06/07 00:44

因为代码越来越多,从这一节开始只贴出关键代码,所有文档和代码会打包到附件。

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

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 啊..)






1 0