2017年12月25日 20:15
原创作品,转载时请务必以超链接形式标明文章原始出处,否则将追究法律责任。

最近美国又他妈的皮痒了,在南海找事,还说什么中国必须接受南海仲裁结果,我去你大爷的,你以为你是谁啊。说实话只要我们要决一死战的勇气,还管什么华盛顿航母,佛吉尼亚潜艇,大不了大家一起死,不,全世界一起死。怎么个死法,中国惹急了先给俄罗斯来几颗核弹,然后俄罗斯反击中国的同时,也会给欧洲扔几颗核弹,给美国扔很多核弹,然后欧洲英法会给其他国家扔核弹,美国给世界扔核弹,俄罗斯只给北冰洋扔就行了,中国给美国和太平洋扔就行了,这样世界就不复存在了。


今天我们来看一下文件权限管理,这个其实是对共享出去的文件的一个简单的权限管理demo。在上节我写过的界面中,可以查询自己共享出去的文件。

wKiom1d_uvjwLs_IAABtoZkX9S0247.png

勾选Shared,我们查出自己共享出去的文件。或者我们可以通过点击ToolBar上面的SHARE按钮,实现共享文件。

$(".k-grid-share", "#file_list").bind("click", function (ev) {
    var selIds = [];
    $("#file_list table:eq(1)").find("tr").each(function () {
        var chkElement = $(this).children("td:first").find("input[type='checkbox']").first();
        if (chkElement.prop('checked')) {
            selIds.push(chkElement.val());
        }
    });
     
    if (selIds.length == 0) {
        showMsg('info', 'Please select at least one file to share!');
        return;
    }
     
    sharedUpdate(selIds, true);
});

首先是找到选中的文件的_id,然后调用shareUpdate方法去共享。

function sharedUpdate(selIds, shared) {
    msg = Messenger().post({
        message: "Do you want to " + (shared? 'share':'unshare') + " these file?",
        actions: {
            delete: {
                label: 'Yes',
                delay: 10,
                action: function () {
                    var postData = {
                        ids: selIds,
                        isShared: shared
                    };
                     
                    $.ajax({
                        url: '/file/share', 
                        type: 'PUT', 
                        dataType: 'json',
                        data: { postData: JSON.stringify(postData) },
                        success: function (res) {
                            if (!res.isSuc) {
                                showMsg('error', res.msg);
                                return;
                            }
                             
                            getFilelist(selGroupId);
                        }
                    });
                    msg.hide();
                }
            },
            cancel: {
                label: "No",
                action: function () {
                    msg.hide();
                }
            }
        }
    });
}

发送一个ajax请求,去修改传入文件的共享属性,看一下效果

wKiom1d_vNvTamX7AAASDfy2Q4A040.png

先会弹出确认,点击Yes,调用api file/share去修改共享属性,看一下后台。

router.put('/file/share', fileRoutes.fileShare);
exports.fileShare = function (req, res) {
    var data = JSON.parse(req.body.postData);
    var idArray = data.ids;
     
    if (!idArray || idArray == 0) {
        res.status(403).json(commonMsgRes.buildJsonErrorRes('NoRecord'));
        return;
    }
     
    fileModel.update({ _id: { $in: idArray } }, { $set: { isshared: data.isShared } }, { multi: true }
, function (error, result) {
        if (error) {
            res.json({ isSuc: false, msg: error.message });
        }
        else {
            res.json({ isSuc: true });
        }
    });
}

在后台,先把json字符串转化成js对象,然后用mongoose提供的update方法去批量更新数据。注意这里的$in,其实是和sqlServer中的in一个意思,$set意思是需要修改的属性,你可以在这里写多个属性进行修改,并不一定只是一个isshared属性,然后最后的multi:true,意思是更新多个doc。所以整个修改的意思就是找到_id在idArray中的file docs,然后将其isshared属性全部修改为传入的值。当然在这里你也可以使用mongoose中的findAndUpdate方法去做批量更新。


文件share好之后,我们看一下共享文件权限设置界面。

wKioL1d_wjHQRRJAAACeCc0GwYw849.png

查询出数据后,每个文件都可以设置权限,这里很简单的三个,要真做权限,还是买吉日嘎啦的走火入魔权限管理系统好了,自己不要瞎折腾。OK,那么这三个权限使我们mongodb数据库中配置的。

wKiom1d_wtPiluekAABhd0NeFyQ395.png

我们在界面可以选择一个或者多个。wKioL1d_wwayubJzAABALF21hNg124.png

选择完成后,点击Save,如果不想修改了,点击cancel,可以回到初始状态,我们来看一下js代码。

$("#file_list").kendoGrid({
    scrollable: true,
    allowCopy: true,
    resizable: false,
    sortable: true,
    height: 800,
    pageable: {
        refresh: true,
        pageSizes: [10, 20, 50, 100],
        buttonCount: 5,
    }, 
    toolbar: [{ name: 'authSet', text: "Batch Setup" , imageClass: 'k-icon k-i-lock' }],
    columns: [{
            template: "<div class='center-align-text'>" +
                "<input id='chkId_#=_id#' type='checkbox' class='k-checkbox' value='#=_id#' onclick='chkHeader_cl
                + "<label class='k-checkbox-label' for='chkId_#=_id#'></label></div>",
            field: "",
            title: "<div class='center-align-text'>" +
                "<input type='checkbox' class='k-checkbox' id='chk_all'/>" 
                + "<label class='k-checkbox-label' for='chk_all'></label></div>",
            width: 45,
            sortable: false
        },
        {
            field: "fullname", 
            title: "File Name"
        },
        {
            field: "isshared", 
            title: "Shared" ,
            template: '<select id="ddl_auth#=_id#" name="auth" multiple="multiple"></select>',
            sortable: false
        }, {
            command: [
                {
                    name: "authUpdate",
                    text: "Save",
                    imageClass: "k-icon k-i-tick",
                    click: updateFileAuth
                }, {
                    name: "authCancel",
                    text: "Cancel",
                    imageClass: "k-icon k-i-undo",
                    click: cancelUpdateFileAuth
                }
            ], 
            width: 230,
            title: "Operation"
        }], dataBound: function (rowBoundEvent) {
        $("#file_list select[name='auth']").each(function (index, element) {
            $(element).kendoMultiSelect({
                valuePrimitive: true,
                placeholder: "---Please Select---",
                ignoreCase: true,
                dataSource: authArray.length > 0? authArray:dataSource,
                dataTextField: "name",
                dataValueField: "_id",
                headerTemplate: '<div class="multi-select-header">' 
                            + 'Choose File Auth Below:</div>',
                dataBound: function (e) {
                    var dataItem = $("#file_list").data('kendoGrid').dataItem($(element).closest("tr"));
                    if (dataItem.auth && dataItem.auth.length > 0) {
                        var authArray = [];
                        dataItem.auth.forEach(function (v) {
                            authArray.push(v._id);
                        });
                         
                        this.value(authArray);
                    }
                     
                }
            });
        });
    }
});

大家注意isShared这一列,是个下拉列表,支持多选,然后在数据绑定完成以后,循环里面的下拉列表,将其渲染成kendoMultiSelect,注意这里的dataSource参数,如果authArray已经取到了,则使用,否则调用后台api获取。

var dataSource = new kendo.data.DataSource({
    transport: {
        read: {
            url: "/file/auth",
            dataType: "json"
        }
    }
});

如果在这里直接使用每次请求的话,会存在很多问题,性能问题,界面渲染也会出现一些重复渲染的问题。因为大家的auth都是一样的,所以我们先取到再说。

var authArray = [];
$.get('/file/auth', function (result) {
    authArray = result;
});

OK,接下来我们看一下Save功能,在grid的定义中,我们可以看到save调用的是updateFileAuth方法。

function updateFileAuth(e) {
    var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
    var fileId = dataItem._id;
    var authArray = $("#ddl_auth" + dataItem._id).data("kendoMultiSelect").value()
     
    if (!authArray || authArray.length == 0) {
        showMsg('info', 'Please select at least one auth!');
        return;
    }
     
    var postData = {
        fileId: dataItem._id,
        fileAuth: authArray
    };
     
    $.post('/file/auth', postData, function (res) {
        if (!res.isSuc) {
            showMsg('error', res.msg);
            return;
        }
         
        showMsg('success', 'Saved successfully!');
        $("#btn_searchShared").click();
    });
}

根据当前行拿到id,再根据id拿到下拉选中的值,kendoMultiSelect的value方法返回的就是一个数组。

最后我们将得到的数组传递到api去修改权限,看一下后台。

router.post('/file/auth', fileAuthRoutes.updateFileAuth);
exports.updateFileAuth = function (req, res) {
    var fileId = req.body.fileId;
    var fileAuth = req.body.fileAuth;
    var fileAuths = [];
     
    fileAuth.forEach(function (v) {
        fileAuths.push(mongoose.Types.ObjectId(v));
    });
     
    fileModel.findByIdAndUpdate(fileId, { '$set': { auth: fileAuths } }
        , function (error, doc) {
        console.log(error);
        if (error) {
            res.json({ isSuc: false, msg: error.message });
        }
        else {
            res.json({ isSuc: true });
        }
    });
}

在这里我们先将权限的id转化成ObjectId,再根据传入的文件id进行修改,ok,save就说完了。

再看一下cancel,其实就是将该行的权限id再赋给下拉列表。

function cancelUpdateFileAuth(e) {
    var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
    var fileId = dataItem._id;
    var authArray = [];
    if (dataItem != null && dataItem.auth.length > 0) {
        dataItem.auth.forEach(function (v) {
            authArray.push(v._id);
        });
    }
    $("#ddl_auth" + dataItem._id).data("kendoMultiSelect").value(authArray);
}

ok,最后就是batch批量设置,勾选数据,点击ToolBar上的BATCH SETUP,我们先看页面的代码。

wKiom1d_yLTx06NTAACSmsMSEe0041.png

这里的fileAuth_Window就是批量设置界面,在这里大家发现了一个循环的写法,不错,这就是jade模板中的语法,类似于razor视图引擎一样。看到这样的循环,我们在后台必须有代码要给页面这些值,类似于asp.net mvc中页面绑定的Model。

fileAuthSchemas.authModel.find({}, function (error, doc) {
    res.render('authorization/docauth', { authArray: doc });
});

看到了吧,在向客户端输出页面时,同时传了一个对象,对象中的authArray的值为doc。这样的话,我们就可以在页面直接使用这个变量authArray。

wKioL1d_yk7SDrZWAAAZgiCtUAQ554.png

我们选择三个,点击SETUP,AJAX调用后台api批量设置。

$("#btn_setup").click(function () {
    var selAuthIdArray = getSelAuthId();
    if (selAuthIdArray.length == 0) {
        showMsg('info', 'Please select at least one auth!');
        return;
    }
     
    var selIds = getSelFileId();
    if (selIds.length == 0) {
        showMsg('info', 'Please select at least one file to setup!');
        return;
    }
     
    showConfirm(updateFileAuthBatch);
});
 
function updateFileAuthBatch() {
    var selIds = getSelFileId();
    if (selIds.length == 0) {
        showMsg('info', 'Please select at least one file to setup!');
        return;
    }
     
    var postBody = {
        fileIdArray: selIds,
        fileAuth: getSelAuthId()
    };
     
    $.post('/file/auth/batch', postBody, function (result) {
        if (!result.isSuc) {
            showMsg('error', result.msg);
            return;
        }
 
        fileAuthWindow.data("kendoWindow").close();
        $("#btn_searchShared").click();
    });
}
 
function showConfirm(action) {
    msg = Messenger().post({
        message: "Do you want to setup?",
        actions: {
            save: {
                label: 'Yes',
                delay: 10,
                action: function () {
                    action();
                    msg.hide();
                }
            },
            cancel: {
                label: "No",
                action: function () {
                    msg.hide();
                }
            }
        }
    });
}

上面这段代码有没有很像C#中的委托呢?有点。最后我们看一下后台的批量设置api代码。

exports.batchUpdateFileAuth = function (req, res) {
    var fileIdArray = req.body.fileIdArray;
    var fileAuth = req.body.fileAuth;
    var fileAuths = [];
     
    if (!fileIdArray || fileIdArray.length == 0) {
        res.json(commonMsgRes.buildJsonErrorRes('NoRecord'));
        return;
    }
     
    fileAuth.forEach(function (v) {
        fileAuths.push(mongoose.Types.ObjectId(v));
    });
     
    fileModel.update({ _id: { $in: fileIdArray } }, { $set: { auth: fileAuths } }, { multi: true }
        , function (error, doc) {
        if (error) {
            res.json({ isSuc: false, msg: error.message });
        }
        else {
            res.json({ isSuc: true });
        }
    });
}

这样就设置成功了,我们来看一下效果。wKioL1d_y36AsYJMAACdV_6SYNc024.png

好了,下节进入我们的关键点,Excel在线保存,编辑。

学习Telerik Kendo UI:http://demos.telerik.com/kendo-ui/grid/index

发表评论
匿名  
用户评论
暂无评论