一步步搭建本身的博客 .NET版(二、评论功能)

前言 

    此次开发的博客主要功能或特色:
    第一:能够兼容各终端,特别是手机端。
    第二:到时会用到大量html5,炫啊。
    第三:导入博客园的精华文章,并作分类。(不要封我)
    第四:作个插件,任何网站上的技术文章均可以转发收藏 到本博客。html

因此打算写个系类:《一步步搭建本身的博客html5

 

    演示地址:http://blog.haojima.net/      群内共享源码:469075305 数据库

 

    上一篇《一步步开发本身的博客(一)》发表以后获得的效应还不错,获得了二十几个赞。而后建的QQ群 两天不到 就有了进三十来我的。你们在群里关于建站经验讨论也是十分热烈。因而可知,你们对拥有本身的独立空间 是多么的渴望。浏览器

    这篇主要是分析 评论功能。在这里,不得不吐槽下 博客园的评论功能。cookie

    第1、对于阅读者。你们有没有在看评论的时候,看着看着有往上翻?特别是有些对骂的评论,都不知道是谁在骂谁。不得不往上翻那个@的人发的是什么。不知道 这句话 是 对谁的哪句话作的回复。虽然有“引用”功能,但也有不少人没有使用。布局

    第2、对于博主。在回复各位园友时,点击回复 ,而后 跳到 最下方,而后评论框 自动出现@***  回复以后。想回复下一位,又要把滚动条拖上去。而后 又忘记 这我的是否是已经回复过了。又往下拖 看本身有没有回复过,或者有没有漏掉谁。若是评论够多的话 我相信 各位应该都这样的感受,个人那个头 个人那个晕。测试

    在这里 我就打算规避这类问题,像QQ空间的评论 就很爽,谁在和谁对话 一目了然。网站

表结构

      对于这样的一个需求,没有作过的也许一时没有了头绪。这里最主要的关系就是,“引用”- 谁对谁说。是对哪条评论 展开的讨论。spa

      其实我把表结构拿出来,相信你们就明白了。.net

      这里  我再详细分析下每一个字段。

      ID:表主键

      Content:评论的内容     

 

      CommentID:引用的评论内容的ID。

      BlogUsersId:用户ID

      BlogsId:博客ID

      ReplyUserID:引用的评论的用户ID。

      ReplyUserName:引用的评论的用户名。

 

      CommentSort:没用(原本觉得会用到)

      ContentLevy:没用(原本觉得会用到)

       这里要说明下    CommentID:引用的评论内容的ID。其实并不是真的是评论内容ID 而是"父评论ID"。咱们为了简单起见,把评论分红两种。

父评论,子评论。什么是父评论,子评论?父:初始评论,子:在父评论的基础上进行评论,或者子评论的基础上进行评论。(这里就不分 子子评论  子子子评论了。我想递归应该也能够作到,但不想那么复杂了)

      那么上面还有一个字段没有解释:

      IsInitial  是不是"父评论"

 

 

如图:      

实现

     经过对表结构的简单分析,我相信 你们应该已经很是明白 我会怎么去实现了。

   第1、评论提交

var BlogId = int.Parse(Request.Form["BlogId"]);
var UserId = MySession.UserInfoSessioin.Id; //int.Parse(Request.Form["UserId"]);
var CommentID = int.Parse(Request.Form["CommentID"]);
var Content = Request.Form["Content"];
var ReplyUserID = int.Parse(Request.Form["ReplyUser"]);
var ReplyUserName = string.Empty;
var User = BLL.Common.CacheData.GetUserInfo().Where(t => t.Id == ReplyUserID).FirstOrDefault();
if (null != User)
{
    ReplyUserName = string.IsNullOrEmpty(User.UserNickname) ? User.UserName : User.UserNickname;
}

BLL.BlogCommentBLL comment = new BLL.BlogCommentBLL();
comment.Add(new BlogComment()
{
    BlogUsersId = UserId,
    BlogsId = BlogId,
    Content = Content,
    CommentID = CommentID,
    ReplyUserID = ReplyUserID,
    ReplyUserName = ReplyUserName,
    IsInitial = CommentID == -1
});
comment.save();

 

       一目了然,其实就是一个对象存入数据库了。至于每一个字段的取值,你想怎么取看你本身的。

   第2、加载评论

      评论的加载 可能会比提交复杂那么一点。提交有先后 怎么去归类布局呢?

      首先要对 父评论 的筛选,而后加载父评论 和 父评论下的子评论。感受要进行屡次数据库的查询,那么咱们只能尝试尽量少的查询。

      下面来具体看实现代码。      

int blogId = int.Parse(Request.Form["blogID"]);
int pageIndex = int.Parse(Request.Form["pageIndex"]);
BLL.CommentHandle com = new BLL.CommentHandle();
Dictionary<string, object> dic = new Dictionary<string, object>();
var comObj = com.GetComment(blogId, pageIndex);
if (null == comObj)
    return PartialView("Null");
dic.Add("commentList", comObj);//对应的评论
dic.Add("SessionUser", BLL.Common.MySession.UserInfoSessioin);
return PartialView(dic);      
  com.GetComment(blogId, pageIndex) 方法 根据 博客ID  和  第几页评论 作为参数,取评论数据,下面给出方法的详细实现:
public List<List<BlogComment>> GetComment(int blogId, int pageIndex)
{
    int total;
    BLL.BlogCommentBLL com = new BlogCommentBLL();
    //IsInitial == true 父评论 (第一次数据库查询:查询30条父评论)
    List<int> disCom = com.GetList<int>(pageIndex, 30, out total, t => t.IsInitial == true && t.BlogsId == blogId,
                        false, t => t.Id).Select(t => t.Id).ToList();
    if (pageIndex > total)//已经没有评论信息了
    {
        return null;
    }
    //第二次数据库查询:查询30条父评论 和30条父评论下的子评论
    var listCom = com.GetList(t => disCom.Contains(t.CommentID) || disCom.Contains(t.Id)).ToList();
    List<List<BlogComment>> ComObj = new List<List<BlogComment>>();
    var ini = listCom.Where(t => t.IsInitial == true).ToList();//这里就不查数据库了直接进行集合筛选
    //对评论进行分组(以父评论 分组)
    foreach (BlogComment item in ini)
    {
        item.BlogUsers = CacheData.GetUserInfo().Where(t => t.Id == item.BlogUsersId).FirstOrDefault();              
        var userobj = CacheData.GetUserInfo().Where(t => t.Id == item.ReplyUserID).FirstOrDefault();
        if (null != userobj)
            item.ReplyUserName = userobj.UserNickname;
        //添加 以父评论 为一分组 的评论
        ComObj.Add(GetCom(item, listCom));
    }
    return ComObj;
}

    上面进行了二次数据库查询,其他的时候 都是进行 数据集合的筛选。在上面的代码中 咱们看到了 方法 GetCom(item, listCom)// 取 顶级评论 下的子评论

private List<BlogComment> GetCom(BlogComment com, List<BlogComment> list)
{
    var li = list.Where(t => t.CommentID == com.Id).ToList();
    li.Insert(0, com);
    return li;
}

效果图和演示地址

        在此实现的所有过程都已经分析完了。咱们来看看效果图和演示地址。

        效果图:

        演示地址:http://blog.haojima.net/admin/268.html (界面丑是丑了点,后期再美化。若是有美工愿意免费合做,很是欢迎~~)

        若是您对本篇文章感兴趣,那就麻烦您点个赞,您的鼓励将是个人动力。 固然您还能够加入QQ群:嗨 博客讨论。

        若是您有更好的处理方式,但愿不要吝啬赐教。

        一步步开发本身的博客 .NET版系列:http://www.cnblogs.com/zhaopei/tag/Hi-Blogs/

        本文连接:http://www.cnblogs.com/zhaopei/p/4744846.html 

 


 

疑问

     我在构思开发博客的时候,有个疑问。那就是怎样更好的统计文章阅读量。

     我知道的方式:

     第1、经过Cookie。(缺点:若是要进行访问量排行的话,能够人为清理cookie,恶意刷新访问量)

     第2、经过客户端取得IP(缺点:1.若是访问量大的话,每次插入数据库以前都要先查询是否存在。2.如今咱们大可能是公用外网IP,没法统计独立访客)

     疑问:1.cnzz的独立访客(UV)是怎么统计的。2.博客园的文章阅读量是怎么统计的。(进过测试,文章刷新第二遍的时候能够看到 阅读量 加一 ,而后清理cookie 后刷新 阅读量 加一,而后无论怎么刷 都没反应了)

     若是实在是找不到好的解决方案,我打算用 IP+系统版本+浏览器版本号 做为“联合主键”,若是“主键”24小时内重复两次以上,则不统计,若是cookie存在也不统计。

 

哪位大虾知道更好的解决方案能告诉我下,万分感谢。

相关文章
相关标签/搜索