从零开始,搭建博客系统MVC5+EF6搭建框架(5),博客详情页、留言、轮播图管理、右侧统计博文

来源:互联网 发布:rimworld for mac 编辑:程序博客网 时间:2024/06/16 18:43

一、博客系统进度回顾

   上一遍博客介绍到,系统已经实现到了发布以及前台布局展示,接下来就是实现一些,详情页,留言、轮播图管理、右侧博文统计信息实现。

二、博客系统详情页实现

2.1先来看看详情页展示的效果

image

image

2.2实现控制器在前台控制器中创建一个Blog的控制器,主要是展示博客分类以及详情页

Action详情页实现:

  1 /// <summary>  2         /// 详情页  3         /// </summary>  4         /// <param name="id"></param>  5         /// <returns></returns>  6         public ActionResult Detail(int id)  7         {  8             //获取控制器名称  9             ViewBag.controllername = RouteData.Values["controller"].ToString().ToLower(); 10             var model = BlogArticleServive.getBlogDetails(id); 11             ViewBag.gblist = GuestbookServices.QueryOrderBy(c => c.blogId == id, c => c.createdate, false).ToPagedList(1, 5); 12  13             //发布时间排序 14             ViewBag.blogtimelist = BlogArticleServive.QueryOrderBy(c => true, c => c.bCreateTime, false); 15             //评论排序 16             ViewBag.blogtrafficlist = BlogArticleServive.QueryOrderBy(c => true, c => c.btraffic, false); 17             //留言排序 18             string sql = @"select a.*,b.btitle from (select blogId,count(1) as counts  from Guestbook group by blogId) as a 19 inner join BlogArticle as b 20 on 21 b.bID=a.blogId order by counts desc"; 22  23             ViewBag.blogguestbooklist = GuestbookServices.RunProc<TopgbViewModels>(sql); 24  25             return View(model); 26         }
View Code

   由于展示的内容比实际存储在数据库中的信息多,所以把所有能展示的信息都放在BlogViewModels中,在blog业务逻辑层单独实现了一个包含上一页 下一页,以及摘要赋值的方法。

image

image

    由于这一部分需要从详情内容中只保留部分文字,所以这里需要对索取的详情信息做处理,由于详情信息是通过富文本编辑来添加的里面包含了很多html代码信息,所以在common程序集中,创建一个工具类,Tools类来存放,辅助的相关方法。

ReplaceHtmlTag方法:

  1   #region 去除富文本中的HTML标签  2         /// <summary>  3         /// 去除富文本中的HTML标签  4         /// </summary>  5         /// <param name="html"></param>  6         /// <param name="length"></param>  7         /// <returns></returns>  8         public static string ReplaceHtmlTag(string html, int length = 0)  9         { 10             string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", ""); 11             strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", ""); 12  13             if (length > 0 && strText.Length > length) 14                 return strText.Substring(0, length); 15  16             return strText; 17         } 18         #endregion
View Code

然后在获取到多有信息,要处理的地方就是用三元运算符来判断,截取前面的文字部分

image

2.3详情页视图代码

  1 @model Wchl.WMBlog.Model.VeiwModels.BlogViewModels  2   3 @{  4     ViewBag.Title = "博客详情页";  5 }  6 <link href="~/Content/lib/zui/doc.css" rel="stylesheet" />  7 <section>  8     <article>  9         <div spellcheck="false" class="example"> 10             <br> 11             <ul class="breadcrumb"> 12                 <li><i class="icon-location-arrow icon-muted"></i></li> 13                 <li><a href="/home/index">首页</a></li> 14                 <li><a href="/blog/index">博客</a></li> 15                 <li class="active">Data</li> 16             </ul> 17             <hr> 18             <article class="article"> 19                 <header> 20                     <h1 class="text-center">@Model.btitle</h1> 21                     <dl class="dl-inline"> 22                         <dt>发布时间:</dt> 23                         <dd>@Model.bCreateTime</dd> 24                         <dt>作者:</dt> 25                         <dd>@Model.bsubmitter</dd> 26                         <dt></dt> 27                         <dd class="pull-right"><span class="label label-success">新</span> <span class="label label-warning">火爆</span> <span class="label label-info">原创</span> <span class="label label-danger"><i class="icon-eye-open"></i> @Model.btraffic</span></dd> 28                     </dl> 29                     <section class="abstract"> 30                         <p><strong>摘要:</strong>@Model.digest</p> 31                     </section> 32                 </header> 33                 <section class="article-content"> 34                     @Html.Raw(Model.bcontent) 35                 </section> 36                 <footer> 37                     <p class="pull-right text-muted"> 38                         发布时间:@Model.bCreateTime.ToString("yyyy年MM月dd日 HH:mm:ss") &nbsp;点击数:@Model.btraffic 39                     </p> 40                     <p class="text-important">本文版权所有归<a href="###">@Model.bsubmitter</a></p> 41                     <ul class="pager pager-justify"> 42                         @if (Model.previous == null) 43                         { 44                           <li class="previous disabled"><a href="#" title=""><i class="icon-arrow-left"></i> 上一篇: </a></li> 45                         } 46                         else 47                         { 48                             <li class="previous"><a href="/blog/Detail/@Model.previousID " title="@Model.previous"><i class="icon-arrow-left"></i> 上一篇: @Model.previous.Substring(0, 5)  </a></li> 49                         } 50                         @if (Model.next == null) 51                         { 52                             <li class="next disabled"><a href="#">下一篇: <i class="icon-arrow-right"></i></a></li> 53                         } 54                         else 55                         { 56                             <li class="next"><a href="/blog/Detail/@Model.nextID " title="=@Model.next">下一篇:@Model.next.Substring(0, 5) <i class="icon-arrow-right"></i></a></li> 57                         } 58  59  60                     </ul> 61                 </footer> 62             </article> 63         </div> 64     </article> 65     <div id="comment"> 66         @Html.Partial("_GuestbookPage") 67     </div> 68  69 </section> 70 @section scripts 71 { 72     <script src="~/Content/lib/laypage/laypage.js"></script> 73     <script type="text/javascript"> 74         var blogid; 75         var curr; 76         $(function () { 77             $("#blogId").val(@Model.bID); 78             //运行分页 79             blogid = $("#blogId").val(); 80             guestbookpage(curr,blogid); 81         }) 82  83     function su(data) { 84         $("#comment").html(data); 85         $("#blogId").val(@Model.bID); 86         //setTimeout(function () { 87         //    if (document.getElementById('textcenter') != null) { 88         //            //运行分页 89         //            guestbookpage(1, blogid); 90         //    } 91         //}, 3000); 92         if (document.getElementById('textcenter') != null) { 93             //运行分页 94             guestbookpage(1, blogid); 95         } 96  97  98  99     }100 101     //以下将以jquery.ajax为例,演示一个异步分页102     function guestbookpage(curr,blogid) {103         $.getJSON('/blog/getGuestbook', {104             page: curr || 1,105             blogId: blogid//向服务端传的参数,此处只是演示106         }, function (res) {107             //此处仅仅是为了演示变化的内容108             $("#comments-list").html(res.content);109             //显示分页110             laypage({111                 cont: document.getElementById('textcenter'), //容器。值支持id名、原生dom对象,jquery对象。【如该容器为】:<div id="page1"></div>112                 pages: res.pages, //通过后台拿到的总页数113                 curr: curr || 1, //当前页114                 jump: function (obj, first) { //触发分页后的回调115                     if (!first) { //点击跳页触发函数自身,并传递当前页:obj.curr116                         curr = obj.curr;117                         guestbookpage(curr, blogid);118                     } else {119                         curr = first;120                         guestbookpage(curr, blogid);121                     }122 123                 }124             });125         });126     };127     </script>128     }129 
View Code

这里博客的详情页也是通过布局页来实现的。

三、博客系统详情页留言实现

3.1留言展示页面效果

image

先要创建一个类在数据库中创建一个表:

Guestbook类

  1 namespace Wchl.WMBlog.Model.Models  2 {  3     public class Guestbook  4     {  5   6         /// <summary>留言表  7         ///   8         /// </summary>  9         public int id { get; set; } 10  11         /// <summary>博客ID 12         ///  13         /// </summary> 14         public int? blogId { get; set; } 15         /// <summary>创建时间 16         ///  17         /// </summary> 18         public DateTime createdate { get; set; } 19         public string username { get; set; } 20  21         /// <summary>手机 22         ///  23         /// </summary> 24         public string phone { get; set; } 25         /// <summary>qq 26         ///  27         /// </summary> 28         public string QQ { get; set; } 29  30         /// <summary>留言内容 31         ///  32         /// </summary> 33         public string body { get; set; } 34         /// <summary>ip地址 35         ///  36         /// </summary> 37         public string ip { get; set; } 38  39         /// <summary>是否显示在前台,0否1是 40         ///  41         /// </summary> 42         public bool isshow { get; set; } 43  44         public BlogArticle blogarticle { get; set; } 45     } 46 }
View Code

GuestbookViewModels展示类:

  1 namespace Wchl.WMBlog.Model.VeiwModels  2 {  3     /// <summary>  4     /// 留言信息展示类  5     /// </summary>  6     public class GuestbookViewModels  7     {  8         /// <summary>留言表  9         ///  10         /// </summary> 11         public int id { get; set; } 12  13         /// <summary>博客ID 14         ///  15         /// </summary> 16         public int? blogId { get; set; } 17         /// <summary>创建时间 18         ///  19         /// </summary> 20         public DateTime createdate { get; set; } 21         public string username { get; set; } 22  23         /// <summary>手机 24         ///  25         /// </summary> 26         public string phone { get; set; } 27         /// <summary>qq 28         ///  29         /// </summary> 30         public string QQ { get; set; } 31  32         /// <summary>留言内容 33         ///  34         /// </summary> 35         public string body { get; set; } 36         /// <summary>ip地址 37         ///  38         /// </summary> 39         public string ip { get; set; } 40  41         /// <summary>是否显示在前台,0否1是 42         ///  43         /// </summary> 44         public bool isshow { get; set; } 45  46         public BlogArticle blogarticle { get; set; } 47     } 48 }
View Code

GuestbookMap字段约束:

  1   2 namespace Wchl.WMBlog.Model.Maps  3 {  4     public class GuestbookMap: EntityTypeConfiguration<Guestbook>  5     {  6         public GuestbookMap() {  7             this.HasKey(p => p.id);  8             //设置外键  9             this.HasRequired(p => p.blogarticle).WithMany().HasForeignKey(p => p.blogId); 10         } 11     } 12 }
View Code

接下来就是创建相应的仓储接口、实现,服务接口、实现,这里就不一一介绍了,跟上一篇实现博客类的是一样的。

我在实现这个功能的时候,想使用ajax来提交:

image

这里我把所有留言的内容放在一个部分视图页

_GuestbookPage代码:

  1 <article>  2     <div spellcheck="false" class="example">  3         <div class="comments">  4             <header>  5                 <div class="pull-right"><a href="#commentReplyForm2" class="btn btn-primary"><i class="icon-comment-alt"></i> 发表评论</a></div>  6                 <h3>所有评论</h3>  7             </header>  8             <section class="comments-list" id="comments-list">  9               @{ if (ViewBag.gblist != null) 10                   { 11                       foreach (var list in ViewBag.gblist) 12                       { 13                         <div class="comment"> 14                             <a href="###" class="avatar"> 15                                 <i class="icon-user icon-2x"></i> 16                             </a> 17                             <div class="content"> 18                                 <div class="pull-right text-muted">@list.createdate</div> 19                                 <div><a href="###"><strong>@list.username</strong></a></div> 20                                 <div class="text">@list.body</div> 21                                 <div class="actions"> 22                                     <a href="##">回复</a> 23                                 </div> 24                             </div> 25                         </div> 26                       } 27                   } 28  29             } 30             </section> 31             <br /> 32             <div class="text-center" id="textcenter"> 33  34             </div> 35             <footer> 36                 <div class="reply-form" id="commentReplyForm2"> 37                     <a href="###" class="avatar"><i class="icon-user icon-2x"></i></a> 38                     @using (Ajax.BeginForm("addGuestbook", "Blog", new AjaxOptions() 39                     { 40                         HttpMethod = "post", 41                         OnSuccess="su" 42  43                     }, new { @class = "form-horizontal" })) 44                     { 45                         <input type="hidden" id="blogId" name="blogId" value=""/> 46                         <div class="form-group col-md-4 form-inline"> 47                             <label for="username" class="col-xs-3">昵称</label> 48                             <div> 49                                 <input type="text" class="form-control" name="username" id="username" placeholder="昵称"> 50                             </div> 51                         </div> 52                         <div class="form-group col-md-4 form-inline"> 53                             <label for="phone" class="col-xs-3">手机</label> 54                             <div> 55                                 <input type="text" class="form-control" name="phone" id="phone" placeholder="手机"> 56                             </div> 57                         </div> 58                         <div class="form-group col-md-4 form-inline"> 59                             <label for="QQ" class="col-xs-3">Q Q</label> 60                             <div> 61                                 <input type="text" class="form-control" name="QQ" id="QQ" placeholder="Q Q"> 62                             </div> 63                         </div> 64                         <div class="form-group"></div> 65                         <div class="form-group"> 66                             <textarea class="form-control new-comment-text" id="body" name="body" rows="4" placeholder="撰写留言..."></textarea> 67                         </div> 68                         <div class="form-group comment-user"> 69                             <div class="row"> 70                                 <div class="col-md-2 col-md-offset-10"><button type="submit" class="btn btn-block btn-primary " value="提交">提交</button></div> 71                             </div> 72                         </div> 73                     } 74                 </div> 75             </footer> 76         </div> 77     </div> 78 </article> 79 
View Code

其中分为两部分,一部分是输入留言,一部分是展示信息。

留言提交的表单如下:

image

在blog控制器中实现添加数据方法:

  1         /// <summary>  2         ///提交评论  3         /// </summary>  4         /// <param name="model"></param>  5         /// <returns></returns>  6         [HttpPost]  7         public ActionResult addGuestbook(GuestbookViewModels model)  8         {  9             model.createdate = DateTime.Now; 10             model.ip = Request.UserHostAddress; 11             //AutoMapper自动映射 12             Mapper.Initialize(cfg => cfg.CreateMap<GuestbookViewModels, Guestbook > ()); 13             Guestbook models = Mapper.Map< GuestbookViewModels, Guestbook> (model); 14             BlogArticle blogArticle = BlogArticleServive.QueryWhere(a => a.bID == model.blogId).FirstOrDefault(); 15             blogArticle.bcommentNum += 1; 16             BlogArticleServive.SaverChanges(); 17             GuestbookServices.Add(models); 18             GuestbookServices.SaverChanges(); 19             ViewBag.gblist = GuestbookServices.QueryOrderBy(c => c.blogId == model.blogId, c => c.createdate, false).ToPagedList(1, 5); 20             return PartialView("_GuestbookPage"); 21         }
View Code

执行成功之后就把信息加载到分页信息的位置。

image

3.2添加实现之后就是展示数据,展示数据使用的是一个js分页插件laypage.js

在mvc的视图中只能在页面有一个model类,所以就只能使用ViewBag.gblist来传值了,本来这个打算用mvcpager插件,结果发现不行,就只能使用js来分页,实现如下:

image

后台blog控制器下,实现分页,然后拼接数据:

  1 /// <summary>  2         /// js分页实现  3         /// </summary>  4         /// <param name="page"></param>  5         /// <param name="blogId"></param>  6         /// <returns></returns>  7         public ActionResult getGuestbook(int page,int blogId)  8         {  9             StringBuilder sb = new StringBuilder(); 10             int pages = 0; 11             var modelsLists = GuestbookServices.QueryByPage(page, 5,out pages, c => c.blogId == blogId, c => c.createdate, false); 12             foreach (var item in modelsLists) 13             { 14                 sb.AppendFormat(@"<div class='comment'> 15 <a href = '###' class='avatar'> 16 <i class='icon-user icon-2x'></i> 17 </a> 18 <div class='content'> 19 <div class='pull-right text-muted'>{0}</div> 20 <div><a href = '###' ><strong > {1}</strong ></a ></div> 21 <div class='text'>{2}</div> 22 <div class='actions'> 23 <a href = '##' > 回复 </a> 24 </div > 25 </div > 26 </div >",item.createdate,item.username,item.body); 27             } 28             if (pages % 5 == 0) 29             { 30                 pages = pages / 5; 31             } 32             else 33             { 34                 pages = (pages / 5)+1; 35             } 36  37  38             return Json(new { 39                 content = sb.ToString(), 40                 pages= pages 41             }); 42         }
View Code

在详情页中直接调用就可以了实现分页了

image

四、博客系统广告轮播图管理实现

4.1实现效果这里的轮播图使用的是zui中组件来实现的,image

4.2主页轮播图视图中的代码实现

image

4.3轮播图管理后台页面实现展示

image

image

这里上传图片使用的是百度的上传控件

视图页代码实现:

  1   2 @{  3     ViewBag.Title = "广告管理";  4 }  5 @section stylesheet{  6     <link href="~/Content/CSS/blogArticleStyle.css" rel="stylesheet" />  7     <link href="~/Content/lib/DataTables/css/jquery.dataTables.css" rel="stylesheet" />  8     <link href="~/Content/lib/DataTables/css/dataTables.bootstrap.css" rel="stylesheet" />  9     <link href="~/Content/lib/webuploader/dist/webuploader.css" rel="stylesheet" /> 10     <style type="text/css"> 11         .uploader-list { 12             width: 100%; 13             overflow: hidden; 14         } 15  16         .file-item { 17             float: left; 18             position: relative; 19             margin: 0 20px 20px 0; 20             padding: 4px; 21         } 22  23             .file-item .info { 24                 position: absolute; 25                 left: 4px; 26                 bottom: 4px; 27                 right: 4px; 28                 height: 20px; 29                 line-height: 20px; 30                 text-indent: 5px; 31                 background: rgba(0, 0, 0, 0.6); 32                 color: white; 33                 overflow: hidden; 34                 white-space: nowrap; 35                 text-overflow: ellipsis; 36                 font-size: 12px; 37                 z-index: 10; 38             } 39  40             .file-item .error { 41                 position: absolute; 42                 top: 4px; 43                 left: 4px; 44                 right: 4px; 45                 background: red; 46                 color: white; 47                 text-align: center; 48                 height: 20px; 49                 font-size: 14px; 50                 line-height: 23px; 51             } 52  53         .upload-state-done:after { 54             content: "\f00c"; 55             font-family: FontAwesome; 56             font-style: normal; 57             font-weight: normal; 58             line-height: 1; 59             -webkit-font-smoothing: antialiased; 60             -moz-osx-font-smoothing: grayscale; 61             font-size: 32px; 62             position: absolute; 63             bottom: 0; 64             right: 4px; 65             color: #4cae4c; 66             z-index: 99; 67         } 68  69         .thumbnail { 70         } 71         /*表格信息对齐重写*/ 72         .dataTables_wrapper .dataTables_length { 73             float: left; 74             margin-left: 15px; 75             margin-top: 5px; 76         } 77     </style> 78 } 79  80 @*<link href="~/Content/CSS/userStyle.css" rel="stylesheet" />*@ 81 <script src="~/Content/lib/DataTables/js/jquery.dataTables.js"></script> 82 <script src="~/Content/lib/DataTables/js/dataTables.bootstrap.js"></script> 83 <script src="~/Content/lib/webuploader/dist/webuploader.js"></script> 84 <script type="text/javascript"> 85     var table; 86     // 图片上传demo 87     $(function () { 88         //百度上传方法 89         baiduuploader(); 90         //创建表格 91         creatabel(); 92     }); 93     //初始化表格 94     function creatabel() { 95         table = $('#adtabel').DataTable({ 96             "processing": true, 97             "serverSide": true, 98             //"paging": true, 99             "scrollY": 366,100             "ajax": {101                 url: '@Url.Action("getData", "Advertisement")'102                 //"dataType": "json"103             },104            // "pagingType": "full_numbers",105            // "sLoadingRecords": "正在加载数据...",106            // "sZeroRecords": "暂无数据",107             //"stateSave": true,108             "searching": false,109             "aaSorting": [[1, "desc"]],//默认第几个排序110             "dom": 'rt<"bottom"iflp><"clear">',111             "columns": [112                {113                    "data": "count",114                     "width": "28px",115                },116                {117                    "data": "imgUrl",118                    "width": "60px",119                    render: function (data, type, row, meta) {120                        //这里是主题  把url变成超链接、把图片路径显示为图片121                        //return "<a href='" + data + "'>" + data + "</a>";122                        return "<img src='" + data + "' style='width:50px;height:50px'  />";123                    }124                },125                { "data": "title" },126                { "data": "url" },127                { "data": "createdate" },128                { "data": "remark" },129                {130                    data: null131                }132             ],133             "columnDefs": [134                 {135                     //   指定第一列,从0开始,0表示第一列,1表示第二列……136                     targets: -1,137                     "width": "100px",138                     render: function (data, type, row, meta) {139                         return '<a type="button" class="btn btn-danger"  href="#" onclick="del(\'' + row.id + '\')" ><i class="icon icon-trash"></i>删除</a>'140                     }141                 }142             ],143             "language": {144                 "processing": "玩命加载中...",145                 "lengthMenu": "显示 _MENU_ 项结果",146                 "zeroRecords": "没有匹配结果",147                 "info": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",148                 "infoEmpty": "显示第 0 至 0 项结果,共 0 项",149                 "infoFiltered": "(由 _MAX_ 项结果过滤)",150                 "infoPostFix": "",151                 "url": "",152                 "paginate": {153                     "first": "首页",154                     "previous": "上一页",155                     "next": "下一页",156                     "last": "末页"157                 }158             }159         });160     };161 162     //删除轮播数据163     function del(adid) {164         if (confirm("是否确认删除?"))165         {166             $.post('@Url.Action("del", "Advertisement")', { id: adid },function(ajaxobj){167                 if(ajaxobj.status=="0")168                 {169                     //如果后台删除成功,则刷新表格,并提示用户删除成功170                     //保留分页信息171                     table.ajax.reload(null,false);172                     alert("删除成功");173                 }174             })175         }176     }177 178     //百度上传179     function baiduuploader() {180         var $ = jQuery,181            $list = $('#fileList'),182            // 优化retina, 在retina下这个值是2183            ratio = window.devicePixelRatio || 1,184 185            // 缩略图大小186            thumbnailWidth = 80 * ratio,187            thumbnailHeight = 80 * ratio,188 189            // Web Uploader实例190            uploader;191 192         // 初始化Web Uploader193         uploader = WebUploader.create({194 195             // 自动上传。196             auto: true,197 198             // swf文件路径199             swf: '/Content/lib/webuploader/dist/Uploader.swf',200 201             // 文件接收服务端。202             server: '@Url.Action("UpLoadProcess", "Advertisement")',203 204             // 选择文件的按钮。可选。205             // 内部根据当前运行是创建,可能是input元素,也可能是flash.206             pick: '#filePicker',207 208             // 只允许选择文件,可选。209             accept: {210                 title: 'Images',211                 extensions: 'gif,jpg,jpeg,bmp,png',212                 mimeTypes: 'image/*'213             }214         });215 216         // 当有文件添加进来的时候217         uploader.on('fileQueued', function (file) {218             var $li = $(219                     '<div id="' + file.id + '" class="file-item thumbnail">' +220                         '<img>' +221                         '<div class="info">' + file.name + '</div>' +222                     '</div>'223                     ),224                 $img = $li.find('img');225 226             $list.append($li);227 228             // 创建缩略图229             uploader.makeThumb(file, function (error, src) {230                 if (error) {231                     $img.replaceWith('<span>不能预览</span>');232                     return;233                 }234 235                 $img.attr('src', src);236             }, thumbnailWidth, thumbnailHeight);237         });238 239         // 文件上传过程中创建进度条实时显示。240         uploader.on('uploadProgress', function (file, percentage) {241             var $li = $('#' + file.id),242                 $percent = $li.find('.progress span');243 244             // 避免重复创建245             if (!$percent.length) {246                 $percent = $('<p class="progress"><span></span></p>')247                         .appendTo($li)248                         .find('span');249             }250 251             $percent.css('width', percentage * 100 + '%');252         });253 254         // 文件上传成功,给item添加成功class, 用样式标记上传成功。255         uploader.on('uploadSuccess', function (file, response) {256             $('#' + file.id).addClass('upload-state-done');257             //alert(response.filePath);258             $('#ImgUrl').val(response.filePath);259         });260 261         // 文件上传失败,现实上传出错。262         uploader.on('uploadError', function (file) {263             var $li = $('#' + file.id),264                 $error = $li.find('div.error');265 266             // 避免重复创建267             if (!$error.length) {268                 $error = $('<div class="error"></div>').appendTo($li);269             }270 271             $error.text('上传失败');272         });273 274         // 完成上传完了,成功或者失败,先删除进度条。275         uploader.on('uploadComplete', function (file) {276             $('#' + file.id).find('.progress').remove();277         });278     };279     //上传轮播信息成功之后调用280     function afterSu(ajaxobj) {281         if (ajaxobj.status == "0") {282             alert("上传成功!");283             window.location.reload();284         } else if (ajaxobj.status == "1") {285             alert("上传失败!");286             window.location.reload();287         }288     }289 </script>290 291 <!-- head star -->292 <div class="tnav row border-bottom white-bg page-heading">293     <div class="col-sm-4">294         <h2 class="fl">博客后台</h2>295         <ol class="breadcrumb fl">296             <li><a href="/admin/Home">广告管理</a></li>297             <li><strong>轮播图管理</strong></li>298         </ol>299     </div>300 </div>301 <!-- head end -->302 303 <div class="example scrollbar-hover" style="max-height: 600px; overflow: scroll;">304     <!--table star-->305     <table id="adtabel" class="table table-striped table-bordered table-hover dataTables-example dataTable" cellspacing="0">306         <thead>307             <tr>308                 <th>编号</th>309                 <th>图片</th>310                 <th>标题</th>311                 <th>链接</th>312                 <th>创建时间</th>313                 <th>备注</th>314                 <th>操作</th>315             </tr>316         </thead>317         <!-- tbody是必须的 -->318 319     </table>320     <!--table end-->321     <hr />322     <!--form star-->323     @using (Ajax.BeginForm("add", "Advertisement", new AjaxOptions()324     {325         HttpMethod = "post",326         OnSuccess = "afterSu"327     }, new { @class = "form-horizontal" }))328     {329         <input type="hidden" id="ImgUrl" name="ImgUrl" value="" />330             <div class="form-group">331                 <div class="form-group">332                     <label for="Title" class="col-sm-2">标题:</label>333                     <div class="col-md-4 col-sm-10">334                         <input type="text" class="form-control" id="Title" name="Title" placeholder="标题">335                     </div>336                 </div>337                 <div class="form-group">338                     <label for="Url" class="col-sm-2">链接:</label>339                     <div class="col-md-4 col-sm-10">340                         <input type="text" class="form-control" name="Url" id="Url" placeholder="http://">341                     </div>342                 </div>343                 <div class="form-group">344                     <label for="Remark" class="col-sm-2">备注:</label>345                     <div class="col-md-4 col-sm-10">346                         <textarea rows="2" type="text" class="form-control" name="Remark" id="Remark" placeholder="说明"></textarea>347                     </div>348                 </div>349             </div>350             <div class="form-group">351                 <label for="exampleInputPassword4" class="col-sm-2">上传图片:</label>352                 <div class="col-md-10 col-sm-10">353                     <!--dom结构部分-->354                     <div id="uploader-demo">355                         <!--用来存放item-->356                         <div id="fileList" class="uploader-list"></div>357                         <div id="filePicker">选择图片</div>358                     </div>359                 </div>360             </div>361             <div class="form-group">362                 <div class="col-sm-offset-2 col-sm-10">363                     <button type="submit" class="btn btn-info">提交</button>364                 </div>365             </div>366     }367     <!--form end-->368 </div>369 370 371 
View Code

控制器实现后台代码

  1 namespace Wchl.WMBlog.WebUI.Areas.admin.Controllers  2 {  3     public class AdvertisementController : BaseController  4     {  5         IAdvertisementServices AdvertisementServices;  6         public AdvertisementController(IAdvertisementServices AdvertisementServices)  7         {  8             this.AdvertisementServices = AdvertisementServices;  9         } 10  11         // GET: admin/Advertisement 12         public ActionResult Index() 13         { 14             return View(); 15         } 16  17         /// <summary> 18         /// 获取广告信息 19         /// </summary> 20         /// <returns></returns> 21         public ActionResult getData() 22         { 23             int pageIndex = Request["start"] != null ? int.Parse(Request["start"]) : 1; 24             int pageSize = Request["length"] != null ? int.Parse(Request["length"]) : 5; 25             int draw = Request["draw"] != null ? int.Parse(Request["draw"]) : 1; 26             int totalCount; 27             int count = 0; 28             var adInfoList = AdvertisementServices.QueryByBeginPage(pageIndex, pageSize, out totalCount, r =>true , r => r.Createdate, false); 29             var temp = from u in adInfoList 30                        select new { count= count+=1, ID = u.Id, Title = u.Title, ImgUrl = u.ImgUrl, Createdate = u.Createdate,url=u.Url, Remark = u.Remark }; 31             return Json(new { 32                 data = temp.ToList(), 33                 draw = draw, 34                 recordsTotal = totalCount, 35                 recordsFiltered = totalCount 36             },JsonRequestBehavior.AllowGet); 37         } 38  39         /// <summary> 40         /// 删除广告 41         /// </summary> 42         /// <param name="id"></param> 43         /// <returns></returns> 44         [HttpPost] 45         public ActionResult del(int id) 46         { 47             Advertisement model = new Advertisement() {Id=id }; 48             AdvertisementServices.Delete(model, false); 49             AdvertisementServices.SaverChanges(); 50             return Json(new { status = "0" },JsonRequestBehavior.AllowGet); 51         } 52  53         /// <summary> 54         /// 添加广告信息 55         /// </summary> 56         /// <returns></returns> 57         [HttpPost] 58         public ActionResult Add(AdvertisementViewModels model) 59         { 60             model.Createdate = DateTime.Now; 61             //AutoMapper自动映射 62             Mapper.Initialize(cfg => cfg.CreateMap<AdvertisementViewModels, Advertisement>()); 63             Advertisement models = Mapper.Map<AdvertisementViewModels, Advertisement>(model); 64             AdvertisementServices.Add(models); 65             AdvertisementServices.SaverChanges(); 66             return Json(new { status="0" },JsonRequestBehavior.AllowGet); 67         } 68  69         /// <summary> 70         /// 百度上传图片 71         /// </summary> 72         /// <param name="id">百度插件自定义对图片的命名id</param> 73         /// <param name="name">图片名称</param> 74         /// <param name="type">图片类型</param> 75         /// <param name="lastModifiedDate">图片本身的修改时间</param> 76         /// <param name="size">图片大小</param> 77         /// <param name="file">文件流</param> 78         /// <returns></returns> 79         public ActionResult UpLoadProcess(string id, string name, string type, string lastModifiedDate, int size, HttpPostedFileBase file) 80         { 81             string filePathName = string.Empty; 82  83             string localPath = Server.MapPath("/upload/"); 84             if (Request.Files.Count == 0) 85             { 86                 return Json(new { jsonrpc = 2.0, error = new { code = 102, message = "保存失败" }, id = "id" }); 87             } 88  89             string ex = Path.GetExtension(file.FileName); 90             filePathName = Guid.NewGuid().ToString("N") + ex; 91  92             string datedir = DateTime.Now.ToString("yyyyMMdd"); 93             if (!Directory.Exists(localPath + datedir)) 94             { 95                 Directory.CreateDirectory(localPath + datedir); 96             } 97             string path = localPath + datedir; 98             try 99             {100                 file.SaveAs(Path.Combine(path, filePathName));101             }102             catch (Exception)103             {104                 return Json(new { jsonrpc = 2.0, error = new { code = 103, message = "保存失败" }, id = "id" });105             }106             return Json(new107             {108                 jsonrpc = "2.0",109                 id = id,110                 filePath =  "/Upload/"+datedir + "/" + filePathName111             });112 113         }114     }115 }
View Code

广告对应的表的类Advertisement:

  1 namespace Wchl.WMBlog.Model.Models  2 {  3     public class Advertisement  4     {  5         /// <summary>  6         /// 分类ID  7         /// </summary>  8         public int Id { get; set; }  9         /// <summary> 10         /// 创建时间 11         /// </summary> 12         public DateTime Createdate { get; set; } 13  14         /// <summary> 15         /// 广告图片 16         /// </summary> 17         public string ImgUrl { get; set; } 18  19         /// <summary> 20         /// 广告标题 21         /// </summary> 22         public string Title { get; set; } 23  24         /// <summary> 25         /// 广告链接 26         /// </summary> 27         public string Url { get; set; } 28  29         /// <summary> 30         /// 备注 31         /// </summary> 32         public string Remark { get; set; } 33     } 34 }
View Code

展示类AdvertisementViewModels:

  1 namespace Wchl.WMBlog.Model.VeiwModels  2 {  3     /// <summary>  4     /// 广告类  5     /// </summary>  6     public class AdvertisementViewModels  7     {  8         /// <summary>  9         /// 分类ID 10         /// </summary> 11         public int Id { get; set; } 12         /// <summary> 13         /// 创建时间 14         /// </summary> 15         public DateTime Createdate { get; set; } 16  17         /// <summary> 18         /// 广告图片 19         /// </summary> 20         public string ImgUrl { get; set; } 21  22         /// <summary> 23         /// 广告标题 24         /// </summary> 25         public string Title { get; set; } 26  27         /// <summary> 28         /// 广告链接 29         /// </summary> 30         public string Url { get; set; } 31  32         /// <summary> 33         /// 备注 34         /// </summary> 35         public string Remark { get; set; } 36     } 37 }
View Code

表约束AdvertisementMap:

  1 namespace Wchl.WMBlog.Model.Maps  2 {  3     public class AdvertisementMap: EntityTypeConfiguration<Advertisement>  4     {  5         public AdvertisementMap()  6         {  7             this.HasKey(p => p.Id);  8             this.Property(p => p.ImgUrl).HasMaxLength(512);  9             this.Property(p => p.Title).HasMaxLength(64); 10             this.Property(p => p.Url).HasMaxLength(256); 11         } 12     } 13 }
View Code

这里实现的是添加图片自动上传:

image

image

image

五、博客系统右侧统计

5.1效果显示,这里的统计主要是对发布时间、阅读排行、评论排行做了统计。

image

后台实现代码:

image

部分布局视图代码:

  1 <!--右边栏部分-->  2 <aside>  3     <div class="col-md-4">  4         <section class="youbianlan">  5             <div class="panel-group">  6                 <div class="panel">  7                     <div class="panel-heading">  8                         <div class="panel-title panel-info">  9                             <h4>最新发布</h4> 10                         </div> 11                     </div> 12                     <div class="panel-body"> 13                         <ul> 14                             @{ 15                                 if (ViewBag.blogtimelist != null) 16                                 { 17                                     for (int i = 0; i < 10; i++) 18                                     { 19                                         <li><a href="/blog/Detail/@ViewBag.blogtimelist[i].bID">@ViewBag.blogtimelist[i].btitle</a></li> 20                                     } 21                                 } 22  23                             } 24                         </ul> 25                     </div> 26                 </div> 27             </div> 28         </section> 29         <section class="youbianlan"> 30             <div class="panel-group"> 31                 <div class="panel"> 32                     <div class="panel-heading"> 33                         <div class="panel-title panel-info"> 34                             <h4>阅读排行榜</h4> 35                         </div> 36                     </div> 37                     <div class="panel-body"> 38                         <ul> 39                             @{ 40                                 if (ViewBag.blogtrafficlist != null) 41                                 { 42                                     for (int i = 0; i < 10; i++) 43                                     { 44                                         <li><a href="/blog/Detail/@ViewBag.blogtrafficlist[i].bID">@ViewBag.blogtrafficlist[i].btitle</a></li> 45                                     } 46                                 } 47  48                             } 49                         </ul> 50                     </div> 51                 </div> 52             </div> 53         </section> 54         <section class="youbianlan"> 55             <div class="panel-group"> 56                 <div class="panel"> 57                     <div class="panel-heading"> 58                         <div class="panel-title panel-info"> 59                             <h4>评论排行榜</h4> 60                         </div> 61                     </div> 62                     <div class="panel-body"> 63                         <ul> 64                             @{ 65                                 List<TopgbViewModels> list = ViewBag.blogguestbooklist as List<TopgbViewModels>; 66                                 if (list != null && list.Any()) 67                                 { 68                                     if (list.Count < 10) 69                                     { 70                                         for (int i = 0; i < list.Count; i++) 71                                         { 72                                             <li><a href="/blog/Detail/@list[i].blogId">@list[i].btitle</a></li> 73                                         } 74                                     } 75                                     else 76                                     { 77                                         for (int i = 0; i < 10; i++) 78                                         { 79                                             <li><a href="/blog/Detail/@list[i].blogId">@list[i].btitle</a></li> 80                                         } 81                                     } 82  83                                 } 84  85                             } 86                         </ul> 87                     </div> 88                 </div> 89             </div> 90         </section> 91     </div> 92 </aside> 93 <!--右边栏部分结束--> 94  95 
View Code

 

这里重点讲讲怎么在EF中执行SQL语句:

在仓储父类的实现中这里传入的实体就是需要展示表内容的类:

image

六、博客系统小结

    现阶段博客系统已经完成了前台展示,后台发布基本功能,接下来打算在后台添加一个权限模块,个人能力有限,代码水平不够好,也许我这样的代码还入不了大神的法眼,等我把权限做完之后,我会一点一点的来修改代码。

   其实我写代码的时间不长,主要是每次想功能怎么实现的时候,要把每一步都想到,感觉编程,真正实现功能的开发编码的时间只有40%左右。

   如果大家对这个有什么意见和想法,可以提出来,我会尽量,去修改的,谢谢了。

 

补充内容:

根据园友提出的补漏部分说明:

这个QueryByBeginPage是在仓储层写的一个查询分页的功能,是为了配合DataTables使用的。

  1        /// <summary>  2         /// 从第几条开始用于DataTables  3         /// </summary>  4         /// <typeparam name="TKey"></typeparam>  5         /// <param name="pageIndex">第几页开始</param>  6         /// <param name="pagesize">一页几条</param>  7         /// <param name="rowcount">一共多少条</param>  8         /// <param name="predicate">条件</param>  9         /// <param name="keySelector">排序关键字</param> 10         /// <param name="IsQueryOrderBy">升序还是降序</param> 11         /// <returns></returns> 12         public List<TEntity> QueryByBeginPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) 13         { 14             rowcount = _dbSet.Count(predicate); 15             if (IsQueryOrderBy) 16             { 17                 return _dbSet.Where(predicate).OrderBy(keySelector).Skip(pageIndex).Take(pagesize).ToList(); 18             } 19             else 20             { 21                 return _dbSet.Where(predicate).OrderByDescending(keySelector).Skip(pageIndex).Take(pagesize).ToList(); 22             } 23         }
View Code

这个TopgbViewModels是查询统计留言排行用的一个类,是根据你数据库查询出来表建的相应的类

  1 /// <summary>  2     /// 留言排名展示类  3     /// </summary>  4     public class TopgbViewModels  5     {  6         /// <summary>博客ID  7         ///   8         /// </summary>  9         public int? blogId { get; set; } 10  11         /// <summary> 12         /// 评论数量 13         /// </summary> 14         public int counts { get; set; } 15  16         /// <summary>博客标题 17         ///  18         /// </summary> 19         public string btitle { get; set; } 20     }
View Code

有什么不明白的地方都可以跟我留言,我会尽量写清楚点,让大家看的明白点。

0 0
原创粉丝点击