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

本篇文章我就不罗嗦了,主要讲的是共享文件列表,主要功能就是查看别人共享的文件。

wKioL1eB-6SzQRnoAACfJTq-o-c136.png

打开该界面,用户可以在左侧看到共享文件的人员的信息,点击该人可以查看该人共享了哪些文件。在Grid里面有查看文件修改记录,编辑,标记为星标文件等功能。OK,我们先看一下UI代码。

div(style='padding:5px;')
 include ../common/search.jade
.row-margin 
hr.panel-line  
#splitter(style='height:750px;')
 div
    ul#div_pane.state-selected
     li.k-state-active
       span.k-link.k-state-selected All Users
       div(style='padding:5px')
        a(href='javascript:void(0)' onclick='showFileList("",null,null,null)')
         table.link-pane-list
          tr
           td(rowspan='2' style='width:55px')
            img.round-img(src='/images/userlogin.png')
           td(style='padding-left:20px;')
            h5 All Users
            div Newegg
      - for(var i=0;i<docs.length;i++){ 
      li
       span.k-link #{docs[i]._id}
        span(style='color:red;margin-left:5px') (#{docs[i].total})
       - var users = docs[i].users;
       - for(var j=0;j<users.length;j++){
       div(style='padding:5px')
        a#link_user(href='javascript:void(0)' onclick='showFileList("#{users[j].userId}",null,null,null)')
         table.link-pane-list
          tr
           td(rowspan='2' style='width:55px')
            img.round-img(src='data:image/png; base64,#{users[j].photo}')
           td(style='padding-left:20px;')
            h5 #{users[j].userName}
            span #{users[j].jobtitle}
       - }
     -}
 #file_sharedlist
 
#wd_details
 
script#popup_detail(type="text/x-kendo-template")
 dl
  dt
   label File Name:
  dd #=fullname#
  dt
   label CreateDate:
  dd #=kendo.toString(createdate,'MM/dd/yyyy HH:mm tt')#
  dt
   label LastEditUser:
  dd #=lastedituser#
  dt
   label LastEditDate:
  dd #=kendo.toString(lasteditdate,'MM/dd/yyyy HH:mm tt')#
 
block scripts
 script(type='text/javascript' src='/javascripts/local/doc/docshared.js')

看到吧,UI其实很简单,最上面引用了一个公共search页面,然后下面又看到了for循环,不错,又使用了jade的视图特性。在这里其实是循环构造我们的kendoPanelBar中的内容,注意这里的onclick,调用showFileList拿到该用户所共享的文件。接下来注意这里的img用户图像,在MongoDB中我们存储的是一个Base64位的字符串,所以我们展示图片的时候要写成下面这样。

img.round-img(src='data:image/png; base64,#{users[j].photo}')

我们看一下这个photo字段到底存储的是什么。

wKiom1eB-DPCCLDuAABt-UAzicM801.png

真的是Base64的字符串。在C#中,我们很容易将一张图片转化成base64,但是在node.js中我们办呢。

var request = require('request');
request({ url: session.user.Avatar, encoding: null }, function (err, res, body){
    var image = body.toString('base64');
});

这段代码的意思是我们实用request模块,下载图片,然后将图片转化成base64,注意这里的toString是node.js平台提供的,我们不需要引用任何外部模块,在该系列博客中,我们引用了好多模块

wKioL1eB-Tbjy6e_AAA-gDMqVR8135.png

就连cassandra这么高大上的东西都有,简直了,不说了。这一系列的其实都是些皮毛,等这一系列讲完,我们还有更高层次的实战,这些篇其实都是给初学者看的,是鸡肋。OK,我们看一下后台代码。

router.get('/docshare', function (req, res) {
    userSchemas.userModel.aggregate([{
            $match: { userid: { $ne: session.user.UserID } }
        }, {
            $sort : { _id: 1, userid: 1 }
        }, {
            $group : {
                _id : '$department', total : { $sum : 1 }, 
                users: {
                    $push: {
                        userId: '$userid', 
                        userName: '$username',
                        avatar: '$avatar',
                        jobtitle: '$jobtitle',
                        department: '$department'
                        photo: '$photo'
                    }
                }
            }
        }]).exec(function (error, doc) {
        res.render('document/docshare', { docs: doc });
    });
});

这个语句初学者看起来感觉灰常郁闷,不要紧,这段其实就是使用了聚合函数而已。首先$match是匹配条件,$sort是排序,根据userid和主键排序。$group其实就是分组了,分组的条件就是用户所在的部门,总数累加1。最后将分组的对象放到users中,并指定每个对象所包含的属性。最后将页面输出到客户端,客户端页面直接循环docs进行左边panelBar的渲染。

OK,左边就说完了,右边的话其实就是个kendoGrid,之前也说了好多次,在这里就不再赘述。点击Grid中的星标按钮的代码如下。

function markFile(e) {
    var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
    $.post('/file/mark', { fileId: dataItem._id }, function (res) {
        if (res.isSuc) {
            debugger
            showMsg('info','The file marked successfully!');
        }
    });
}

后台代码如下

exports.fileMark = function (req, res) {
    var fileMarkEntity = new fileMarkModel({
        userid: session.user.UserID,
        file: req.body.fileId
    });
     
    fileMarkModel.findOne({ userid: session.user.UserID, file: req.body.fileId }, function (error, doc) {
        if (!doc) {
            fileMarkEntity.save(function (error, doc) {
                if (error) {
                    res.json({ isSuc: false, msg: error.message });
                }
                else {
                    res.json({ isSuc: true });
                }
            });
        }
        else {
            res.json({ isSuc: true });
        }
    });
}

星标邮件,我们可以在专门的页面查看。

wKioL1eCABaSqVroAABZLyWYkAI134.png

在该页面可以查看标记的星标文件,并且可以取消标记,看一下这个页面的代码

.row-margin
hr.panel-line
div#div_file(style='min-height:350px;max-height:350px')
 - for(var i=0;i<docsMark.length;i++){
    -if(i%10==0){
       .clear-float
    -}
    div.row-margin(style='width:10%;float:left')
     -if(docsMark[i].file){
       div.center-align-text
        input.k-checkbox(id='chk_marked#{docsMark[i].file._id}' type='checkbox' value='#{docsMark[i].file._id}')
        label.k-checkbox-label(for='chk_marked#{docsMark[i].file._id}')
         span.glyphicon.glyphicon-star-empty
       a(href='javascript:void(0)' style='text-decoration: none;color:#666666')
        img.excel-img(id='#{docsMark[i].file._id}' src='/images/excel_share.png')  
        div(style='word-break: break-word;width:90px;') #{docsMark[i].file.fullname}
     -}
     -else{
       div.center-align-text
        input.k-checkbox(id='chk_marked#{docsMark[i]._id}' type='checkbox')
        label.k-checkbox-label(for='chk_marked#{docsMark[i]._id}')
         span.glyphicon.glyphicon-star-empty
       a(href='javascript:void(0)' style='text-decoration: none;color:#666666')
        img.excel-img(id='#{docsMark[i]._id}' src='/images/excel_share.png')  
        div(style='word-break: break-word;width:90px;') #{docsMark[i].fullname}
     -}
 -}
.clear-float
router.get('/page', function (req, res) {
    if (req.query.q == 'm') {
        res.render('document/docself');
    }
    else if (req.query.q == 's') {
        res.redirect('/docshare');
    }
    else if (req.query.q == 'c') {
        res.render('other/chatroom');
    }
    else if (req.query.q == 'r') {
        fileAuthSchemas.authModel.find({}, function (error, doc) {
            res.render('authorization/docauth', { authArray: doc });
        });
    }
    else if (req.query.q == 'u') {
        fileMarkSchemas.filemarkModel.find({ userid: session.user.UserID })
        .populate('file')
        .exec(function (error, docMark) {
            var markFileIdArray = [];
            docMark.forEach(function (v) {
                markFileIdArray.push(v.file._id);
            });
            var query = fileSchemas.fileModel.find({ lastedituserid: session.user.UserID, _id: { $nin: markFileIdArray } });
            query.sort('-lasteditdate').limit(20).exec('find', function (error, docRecent) {
                res.render('document/docrecent', 
                {
                    totalMarkCount: docMark.length || 0, 
                    docsMark: docMark || [],
                    totalRecentCount: docRecent.length || 0, 
                    docsRecent: docRecent || []
                });
            });
        });
    }
});

注意最后的一个页面就是我们的最近使用页面,我们不仅返回星标文件,而且返回最近使用文件。在获取最近使用文件的时候,排除星标文件。

var query = fileSchemas.fileModel.find({ lastedituserid: session.user.UserID, _id: { $nin: markFileIdArray } });

注意这里的$nin,就是not in的意思。其实fileMark collection中存储了文件和用户的关系。

wKioL1eCCb_h11x5AABBEPzdMZo935.png

在这里我把nosql用的像sql一样。

OK,这篇文章就讲到这里,进来看了希望你能够评论一下,也许我会送源码给你。学习请加群:548635112(Node.js实战)

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