关于sumorio与nodeclub的评论功能设计
发布于 3年前 作者 sumory 1857 次浏览

sumorio的评论功能正在开发中,先看代码然后再看设计,目前查看一篇文章的代码是这样的:

exports.view_archive = function(req, res, next) {
    var archive_id = req.params.archive_id;
    var author_id;
    async.auto({
        archive : function(cb) {
            mysql.queryOne("select id,title,content,visit_count,reply_count,author_id,DATE_FORMAT(update_at,'%Y-%m-%d %H:%i:%s') as update_at,DATE_FORMAT(create_at,'%Y-%m-%d %H:%i:%s') as create_at from archive where id = ?", [ archive_id ],
                    function(err, archive) {
                        if (err) {
                            log.error('查找文章时发生异常');
                            cb(null, {});
                        }
                        if (!archive) {
                            cb(null, {});
                        }
                        author_id = archive.author_id;
                        cb(null, archive);
                    });
        },
        sidebar_data : [ 'archive', function(cb) {
            common.initSidebar(author_id, function(err, result) {
                if (err) {
                    log.error('查看文章,通过文章id查找用户信息错误');
                    cb(null, {});
                }
                if (!result) {
                    log.error('查看文章,通过文章id查找不到用户');
                    cb(null, {});
                }
                cb(null, result);
            });
        } ],
        updateArchive : [ 'archive', function(cb) {
            mysql.update("update archive set visit_count = visit_count + 1 where id = ?", [ archive_id ], function(err, info) {
                if (err) {
                    log.error('更新文章统计信息时发生异常');
                }
                cb(null, null);
            });
        } ],
        archive_categories : function(cb) {
            mysql.query("select * from category where id in (select category_id from archive_category where archive_id=?)", [ archive_id ], function(err, categories) {
                if (err) {
                    cb(null, []);
                }
                if (!categories) {
                    cb(null, []);
                }
                cb(null, categories);
            });
        },
        archive_replies : function(cb) {// 该篇文章的回复
            mysql.query("select * from reply where archive_id = ?", [ archive_id ], function(err, archive_replies) {
                if (err) {
                    cb(null, []);
                }
                if (!archive_replies) {
                    cb(null, []);
                }
                
                //为一级回复查找其author信息及其子回复的相应信息
                async.map(archive_replies, 
                    function(reply_item, callback) {    
                        mysql.queryOne('select * from user where id = ?', [ reply_item.author_id ], function(err, user) {
                            if (err) {
                                log.error('查询文章回复的作者信息出错:' + reply_item.author_id);
                            }
                            
                            reply_item.author = user || {}; 
                            
                            mysql.query('select * from reply where reply_id = ?', [ reply_item.id ], function(err, sub_replies) {//查询一个reply的子reply    
                                async.map(sub_replies, function(sub_reply_item, callback2) {
                                    mysql.queryOne('select * from user where id = ?', [ sub_reply_item.author_id ], function(err, sub_reply_user) {
                                        sub_reply_item.friendly_create_at = Util.format_date(sub_reply_item.create_at, true);
                                        sub_reply_item.author = sub_reply_user || {};
                                        callback2(null,sub_reply_item);//这个callback2为提交处理后的sub_reply_item
                                    });
                                }, function (err,sub_replies){
                                    reply_item.friendly_create_at = Util.format_date(reply_item.create_at, true);
                                    reply_item.replies = sub_replies;
                                    callback(null,reply_item);//这个callback为提交处理后的reply_item
                                });
                                  
                            });
                            
                        });    
                    }, 
                    function(err,archive_replies) {
                        cb(null, archive_replies);
                 });
            });
        }
    }, function(err, results) {
        if (err) {
            res.render('notify/notify', {
                error : '您查找的文章信息存在错误'
            });
            return;
        }
        // console.log(results.archive_replies);
        results.archive.replies = results.archive_replies;
        res.render('archive/archive', {
            result : results.sidebar_data,
            archive : results.archive,
            archive_categories : results.archive_categories
        });
        return;
    });

};
  1. 仔细看获得二级回复部分,好吧,如果你还没有晕的话,我都要吐了,不断地异步嵌套,当然乱的原因之一是我没有把方法拆出去。另一个原因是我本想模仿nodeclub的评论设计做二级(多级)回复。

  2. 目前nodeclub的评论是这样的,只能到二级回复,二级上的所有评论都是扁平化的,用@来弥补不能后续分级,个人感觉这样的设计有三点不足:

  • 不能实现无限制分级(多层分级即使有层级限制,但真的有意义吗?)
  • 给消息系统设计带来不一致性,其实一级回复也可以看成是@,类似于微博的评论设计
  • 目前,nodeclub通过消息提醒是不能直接跳到相应评论位置的。
  1. 计划的sumorio的评论设计,优点是样式和后台逻辑较为简单
  • 评论全部扁平化,不分级
  • 依靠@和消息提醒来做评论反馈
  • 通过消息提示要能直接回到相应评论位置

####小结 关于评论是否分级的问题网上已经有很多讨论,其实分不分级各有优缺点,找到适合业务的就ok了,我个人观点是既然有@了,就让’层级’歇歇吧。

2 回复

用了async 还这么多嵌套啊。。

已经是async里套async了,我看了下nodeclub的,也是eventproxy里有eventproxy,只不过独立出函数了。主要是中间变量不好接,很多情况下需要同步处理,前面的结果须在后面几步中修改。

回到顶部