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

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

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

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=\"#\" οnclick=\"show_add('{id}','保存','{name}','{logo_name}')\">修改</a>\n\
                    <a href=\"#\" οnclick=\"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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值