Ver código fonte

增加评论功能

wangbin05 4 anos atrás
pai
commit
7fb0e66ddc

+ 1 - 0
commands/command.go

@@ -109,6 +109,7 @@ func RegisterModel() {
 		new(models.TeamMember),
 		new(models.TeamRelationship),
 		new(models.Itemsets),
+		new(models.Comment),
 	)
 	gob.Register(models.Blog{})
 	gob.Register(models.Document{})

+ 0 - 2
controllers/BookController.go

@@ -516,7 +516,6 @@ func (c *BookController) Create() {
 		book.Identify = identify
 		book.DocCount = 0
 		book.MemberId = c.Member.MemberId
-		book.CommentCount = 0
 		book.Version = time.Now().Unix()
 		book.IsEnableShare = 0
 		book.IsUseFirstDocument = 1
@@ -634,7 +633,6 @@ func (c *BookController) Import() {
 	book.Identify = identify
 	book.DocCount = 0
 	book.MemberId = c.Member.MemberId
-	book.CommentCount = 0
 	book.Version = time.Now().Unix()
 	book.ItemId = itemId
 

+ 67 - 0
controllers/CommentController.go

@@ -0,0 +1,67 @@
+package controllers
+
+import (
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+
+	"github.com/mindoc-org/mindoc/conf"
+	"github.com/mindoc-org/mindoc/models"
+	"github.com/mindoc-org/mindoc/utils/pagination"
+)
+
+type CommentController struct {
+	BaseController
+}
+
+func (c *CommentController) Lists() {
+
+	docid, _ := c.GetInt("docid", 0)
+	pageIndex, _ := c.GetInt("page", 1)
+
+	beego.Info("CommentController.Lists", docid, pageIndex)
+
+	// 获取评论、分页
+	comments, count := models.NewComment().QueryCommentByDocumentId(docid, pageIndex, conf.PageSize)
+	page := pagination.PageUtil(int(count), pageIndex, conf.PageSize, comments)
+	beego.Info("docid=", docid, "Page", page)
+
+	var data struct {
+		DocId     int               `json:"doc_id"`
+		Page      pagination.Page   `json:"page"`
+	}
+	data.DocId = docid
+	data.Page = page
+
+	c.JsonResult(0, "ok", data)
+	return
+}
+
+func (c *CommentController) Create() {
+	content := c.GetString("content")
+	id, _ := c.GetInt("doc_id")
+
+	m := models.NewComment()
+	m.DocumentId = id
+	if len(c.Member.RealName) != 0 {
+		m.Author = c.Member.RealName
+	} else {
+		m.Author = c.Member.Account
+	}
+	m.MemberId = c.Member.MemberId
+	m.IPAddress = c.Ctx.Request.RemoteAddr
+	m.IPAddress = strings.Split(m.IPAddress, ":")[0]
+	m.CommentDate = time.Now()
+	m.Content = content
+	beego.Info(m)
+	m.Insert()
+
+	c.JsonResult(0, "ok")
+}
+
+func (c *CommentController) Index() {
+
+	c.Prepare()
+	c.TplName = "comment/index.tpl"
+}

+ 25 - 6
controllers/DocumentController.go

@@ -65,6 +65,15 @@ func (c *DocumentController) Index() {
 			c.Data["Content"] = template.HTML(doc.Release)
 
 			c.Data["Description"] = utils.AutoSummary(doc.Release, 120)
+			doc.IncrViewCount(doc.DocumentId)
+			c.Data["ViewCount"] = doc.ViewCount + 1
+			c.Data["DocumentId"] = doc.DocumentId
+
+			// 获取评论、分页
+			comments, count := models.NewComment().QueryCommentByDocumentId(doc.DocumentId, 1, conf.PageSize)
+			page := pagination.PageUtil(int(count), 1, conf.PageSize, comments)
+			c.Data["Page"] = page
+			beego.Info("docid=", doc.DocumentId, "Page", page)
 		}
 	} else {
 		c.Data["Title"] = "概要"
@@ -83,7 +92,6 @@ func (c *DocumentController) Index() {
 	}
 	c.Data["Model"] = bookResult
 	c.Data["Result"] = template.HTML(tree)
-
 }
 
 // 阅读文档
@@ -138,6 +146,7 @@ func (c *DocumentController) Read() {
 
 	doc.Processor()
 
+	c.Data["DocumentId"] = doc.DocumentId
 	attach, err := models.NewAttachment().FindListByDocumentId(doc.DocumentId)
 	if err == nil {
 		doc.AttachList = attach
@@ -146,19 +155,29 @@ func (c *DocumentController) Read() {
 	doc.IncrViewCount(doc.DocumentId)
 	c.Data["ViewCount"] = doc.ViewCount + 1
 
+	// 获取评论、分页
+	comments, count := models.NewComment().QueryCommentByDocumentId(doc.DocumentId, 1, conf.PageSize)
+	page := pagination.PageUtil(int(count), 1, conf.PageSize, comments)
+	c.Data["Page"] = page
+	beego.Info("docid=", doc.DocumentId, "Page", page)
+
 	if c.IsAjax() {
 		var data struct {
-			DocTitle string `json:"doc_title"`
-			Body     string `json:"body"`
-			Title    string `json:"title"`
-			Version  int64  `json:"version"`
-			ViewCount int   `json:"view_count"`
+			DocTitle  string            `json:"doc_title"`
+			Body      string            `json:"body"`
+			Title     string            `json:"title"`
+			Version   int64             `json:"version"`
+			ViewCount int               `json:"view_count"`
+			DocId     int               `json:"doc_id"`
+			Page      pagination.Page   `json:"page"`
 		}
 		data.DocTitle = doc.DocumentName
 		data.Body = doc.Release
 		data.Title = doc.DocumentName + " - Powered by MinDoc"
 		data.Version = doc.Version
 		data.ViewCount = doc.ViewCount + 1
+		data.DocId = doc.DocumentId
+		data.Page = page
 
 		c.JsonResult(0, "ok", data)
 	}

+ 0 - 19
controllers/comment.go

@@ -1,19 +0,0 @@
-package controllers
-
-type CommentController struct {
-	BaseController
-}
-
-func (c *CommentController) Lists() {
-
-}
-
-func (c *CommentController) Create() {
-
-	c.JsonResult(0, "ok")
-}
-
-func (c *CommentController) Index() {
-	c.Prepare()
-	c.TplName = "comment/index.tpl"
-}

+ 11 - 0
models/BookResult.go

@@ -233,6 +233,17 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
 			m.ItemName = item.ItemName
 		}
 	}
+	if m.CommentStatus == "closed" {
+		m.IsDisplayComment = false
+	} else if m.CommentStatus == "open" {
+		m.IsDisplayComment = true
+	} else if m.CommentStatus == "registered_only" {
+		// todo
+	} else if m.CommentStatus == "group_only" {
+		// todo
+	} else {
+		m.IsDisplayComment = false;
+	}
 	return m
 }
 

+ 10 - 0
models/comment.go → models/CommentModel.go

@@ -52,6 +52,7 @@ func (m *Comment) TableNameWithPrefix() string {
 func NewComment() *Comment {
 	return &Comment{}
 }
+
 func (m *Comment) Find(id int) (*Comment, error) {
 	if id <= 0 {
 		return m, ErrInvalidParameter
@@ -62,6 +63,15 @@ func (m *Comment) Find(id int) (*Comment, error) {
 	return m, err
 }
 
+// 根据文档id查询文档评论
+func (m *Comment) QueryCommentByDocumentId(doc_id, page, pagesize int) (comments []Comment, count int64) {
+	o := orm.NewOrm()
+	offset := (page - 1) * pagesize
+	o.QueryTable(m.TableNameWithPrefix()).Filter("document_id", doc_id).OrderBy("comment_date").Offset(offset).Limit(pagesize).All(&comments)
+	count, _ = o.QueryTable(m.TableNameWithPrefix()).Filter("document_id", doc_id).Count()
+	return
+}
+
 func (m *Comment) Update(cols ...string) error {
 	o := orm.NewOrm()
 

+ 83 - 21
static/js/kancloud.js

@@ -4,7 +4,6 @@ var events = function () {
         window.sessionStorage && window.sessionStorage.setItem("MinDoc::LastLoadDocument:" + window.book.identify, $param.$id);
         var prevState = window.history.state || {};
         if ('pushState' in history) {
-
             if ($param.$id) {
                 prevState.$id === $param.$id || window.history.pushState($param, $param.$id, $param.$url);
             } else {
@@ -43,6 +42,86 @@ var events = function () {
 
 }();
 
+function format(d) {
+    return d < 10 ? "0" + d : "" + d;
+}
+
+function timeFormat(time) {
+    var span = Date.parse(time)
+    var date = new Date(span)
+    var year = date.getFullYear();
+    var month = format(date.getMonth() + 1);
+    var day = format(date.getDate());
+    var hour = format(date.getHours());
+    var min = format(date.getMinutes());
+    var sec = format(date.getSeconds());
+    return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
+}
+
+function onPageClicked(page, docid) {
+    $.ajax({
+        url : "/comment/lists?page=" + page + "&docid=" + docid,
+        type : "GET",
+        beforeSend : function (xhr) {
+            NProgress.start();
+        },
+        success : function (res) {
+            console.log(res.data);
+            loadComment(res.data.page, res.data.doc_id);
+        },
+        complete : function () {
+            NProgress.done();
+        },
+        error : function () {
+            layer.msg("加载失败");
+        }
+    });
+}
+
+// 加载评论
+function loadComment(page, docid) {
+    $("#commentList").empty();
+    var html = ""
+    var c = page.List;
+    for (var i = 0; c && i < c.length; i++) {
+        html += "<div class=\"comment-item\" data-id=\"" + c[i].comment_id + "\">";
+            html += "<p class=\"info\"><a class=\"name\">" + c[i].author + "</a><span class=\"date\">" + timeFormat(c[i].comment_date) + "</span></p>";
+            html += "<div class=\"content\">" + c[i].content + "</div>";
+            html += "<p class=\"util\">";
+                html += "<span class=\"operate\">";
+                    html += "<span class=\"number\">" + i + "#</span>";
+                html += "</span>";
+            html += "</p>";
+        html += "</div>";
+    }
+    $("#commentList").append(html);
+
+    if (page.TotalPage > 1) {
+        $("#page").bootstrapPaginator({
+            currentPage: page.PageNo,
+            totalPages: page.TotalPage,
+            bootstrapMajorVersion: 3,
+            size: "middle",
+            onPageClicked: function(e,originalEvent,type,page){
+                onPageClicked(page, docid);
+            }
+        });
+    } else {
+        $("#page").find("li").remove();
+    }
+}
+
+// 重新渲染页面
+function renderPage(data) {
+    $("#page-content").html(data.body);
+    $("title").text(data.title);
+    $("#article-title").text(data.doc_title);
+    $("#article-info").text(data.doc_info);
+    $("#view_count").text("阅读次数:" + data.view_count);
+    $("#doc_id").val(data.doc_id);
+    loadComment(data.page, data.doc_id);
+}
+
 /***
  * 加载文档到阅读区
  * @param $url
@@ -61,11 +140,7 @@ function loadDocument($url, $id, $callback) {
                 }else if(data.version && data.version != $callback){
                     return true;
                 }
-                $("#page-content").html(data.body);
-                $("title").text(data.title);
-                $("#article-title").text(data.doc_title);
-                $("#article-info").text(data.doc_info);
-                $("#view_count").text("阅读次数:" + data.view_count);
+                renderPage(data);
 
                 events.trigger('article.open', {$url: $url, $id: $id});
 
@@ -77,23 +152,13 @@ function loadDocument($url, $id, $callback) {
         },
         success : function (res) {
             if (res.errcode === 0) {
-                var body = res.data.body;
-                var doc_title = res.data.doc_title;
-                var title = res.data.title;
-                var doc_info = res.data.doc_info;
-                var view_count = res.data.view_count;
+                renderPage(res.data);
 
-                $body = body;
+                $body = res.data.body;
                 if (typeof $callback === "function" ) {
                     $body = $callback(body);
                 }
 
-                $("#page-content").html($body);
-                $("title").text(title);
-                $("#article-title").text(doc_title);
-                $("#article-info").text(doc_info);
-                $("#view_count").text("阅读次数:" + view_count);
-
                 events.data($id, res.data);
 
                 events.trigger('article.open', { $url : $url, $id : $id });
@@ -129,9 +194,6 @@ function initHighlighting() {
     }
 }
 
-
-
-
 $(function () {
     $(".view-backtop").on("click", function () {
         $('.manual-right').animate({ scrollTop: '0px' }, 200);

+ 25 - 0
utils/pagination/pagination.go

@@ -112,3 +112,28 @@ func (p *Pagination) pageURL(page string) string {
 	return u.String()
 }
 
+type Page struct {
+	PageNo		int         `json:"PageNo"`
+	PageSize	int         `json:"PageSize"`
+	TotalPage	int         `json:"TotalPage"`
+	TotalCount	int         `json:"TotalCount"`
+	FirstPage	bool        `json:"FirstPage"`
+	LastPage	bool        `json:"LastPage"`
+	List		interface{} `json:"List"`
+}
+
+func PageUtil(count int, pageNo int, pageSize int, list interface{}) Page {
+	tp := count / pageSize
+	if count%pageSize > 0 {
+		tp = count/pageSize + 1
+	}
+	return Page {
+		PageNo: pageNo,
+		PageSize: pageSize,
+		TotalPage: tp,
+		TotalCount: count,
+		FirstPage: pageNo == 1,
+		LastPage: pageNo == tp,
+		List: list,
+	}
+}

+ 17 - 0
views/book/setting.tpl

@@ -93,6 +93,23 @@
                                     </label>
                                 </div>
                             </div>
+                            <div class="form-group">
+                                <label>评论</label>
+                                <div class="radio">
+                                    <label class="radio-inline">
+                                        <input type="radio"{{if eq .Model.CommentStatus "closed"}} checked{{end}} name="comment_status" value="closed"> 关闭评论
+                                    </label>
+                                    <label class="radio-inline">
+                                        <input type="radio"{{if eq .Model.CommentStatus "open"}} checked{{end}} name="comment_status" value="open"> 所有人可见
+                                    </label>
+                                    <label class="radio-inline">
+                                        <input type="radio"{{if eq .Model.CommentStatus "registered_only"}} checked{{end}} name="comment_status" value="registered_only"> 注册用户可见
+                                    </label>
+                                    <label class="radio-inline">
+                                        <input type="radio"{{if eq .Model.CommentStatus "group_only"}} checked{{end}} name="comment_status" value="group_only"> 成员可见
+                                    </label>
+                                </div>
+                            </div>
                 {{if eq .Model.PrivatelyOwned 1}}
                 <div class="form-group">
                     <label>访问密码</label>

+ 62 - 43
views/document/default_read.tpl

@@ -168,61 +168,51 @@
                     </div>
                 </div>
                 <div class="article-content">
+                    <!-- 文章内容 -->
                     <div class="article-body  {{if eq .Model.Editor "markdown"}}markdown-body editormd-preview-container{{else}}editor-content{{end}}"  id="page-content">
                         {{.Content}}
                     </div>
-                    <!--
-                    {{/*
+
                     {{if .Model.IsDisplayComment}}
                     <div id="articleComment" class="m-comment">
-                        <div class="comment-result">
-                            <strong class="title">相关评论(<b class="comment-total">{{.Model.CommentCount}}</b>)</strong>
-                            <div class="comment-post">
-                                <form class="form" action="/comment/create" method="post">
-                                    <label class="enter w-textarea textarea-full">
-                                        <textarea class="textarea-input form-control" name="content" placeholder="文明上网,理性发言" style="height: 72px;"></textarea>
-                                        <input type="hidden" name="doc_id" value="118003">
-                                    </label>
-                                    <div class="util cf">
-                                        <div class="pull-left"><span style="font-size: 12px;color: #999"> 支持Markdown语法 </span></div>
-                                        <div class="pull-right">
-                                            <span class="form-tip w-fragment fragment-tip">Ctrl + Enter快速发布</span>
-                                            <label class="form-submit w-btn btn-success btn-m">
-                                                <button class="btn btn-success btn-sm" type="submit">发布</button>
-                                            </label>
-                                        </div>
-                                    </div>
-                                </form>
+                        <!-- 评论列表 -->
+                        <div class="comment-list" id="commentList">
+                            {{range $i, $c := .Page.List}}
+                            <div class="comment-item" data-id="{{$c.CommentId}}">
+                                <p class="info"><a class="name">{{$c.Author}}</a><span class="date">{{date $c.CommentDate "Y-m-d H:i:s"}}</span></p>
+                                <div class="content">{{$c.Content}}</div>
+                                <p class="util">
+                                    <span class="operate">
+                                        <span class="number">{{$i}}#</span>
+                                    </span>
+                                </p>
                             </div>
-                            <div class="clearfix"></div>
-                            <div class="comment-list">
-                                <div class="comment-empty"><b class="text">暂无相关评论</b></div>
-                                <div class="comment-item" data-id="5841">
-                                    <p class="info"><a href="/@phptest" class="name">静夜思</a><span class="date">9月1日评论</span></p>
-                                    <div class="content">一直不明白,控制器分层和模型分层调用起来到底有什么区别</div>
-                                    <p class="util">
-                                        <span class="vote">
-                                            <a class="agree e-agree" href="javascript:;" data-id="5841" title="赞成">
-                                                <i class="fa fa-thumbs-o-up"></i></a><b class="count">4</b>
-                                            <a class="oppose e-oppose" href="javascript:;" data-id="5841" title="反对"><i class="fa fa-thumbs-o-down"></i></a>
-                                        </span>
-                                        <a class="reply e-reply" data-account="phptest">回复</a>
-                                        <span class="operate toggle">
-                                            <a class="delete e-delete" data-id="5841" data-href="/comment/delete"><i class="icon icon-cross"></i></a>
-                                            <span class="number">23#</span>
-                                        </span>
-                                    </p>
+                            {{end}}
+                        </div>
+
+                        <!-- 翻页 -->
+                        <ul id="page"></ul>
+
+                        <!-- 发表评论 -->
+                        <div class="comment-post">
+                            <form class="form" id="commentForm" action="{{urlfor "CommentController.Create"}}" method="post">
+                                <label class="enter w-textarea textarea-full">
+                                    <textarea class="textarea-input form-control" name="content" placeholder="文明上网,理性发言" style="height: 72px;"></textarea>
+                                    <input type="hidden" name="doc_id" id="doc_id" value="{{.DocumentId}}">
+                                </label>
+                                <div class="pull-right">
+                                        <button class="btn btn-success btn-sm" type="submit">发布</button>
                                 </div>
-                            </div>
+                            </form>
                         </div>
                     </div>
                     {{end}}
-*/}}-->
+
+                    <!-- 返回顶部 -->
                     <div class="jump-top">
                         <a href="javascript:;" class="view-backtop"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
                     </div>
                 </div>
-
             </div>
         </div>
         <div class="manual-progress"><b class="progress-bar"></b></div>
@@ -247,7 +237,7 @@
                 <div class="form-group">
                     <label for="password" class="col-sm-2 control-label">项目地址</label>
                     <div class="col-sm-10">
-                        <input type="text" value="{{urlfor "DocumentController.Index" ":key" .Model.Identify}}" class="form-control" onmouseover="this.select()" id="projectUrl" title="项目地址">
+                        <input type="text" value="{{urlfor "DocumentController.Index" ":key" .Model.Identify}}" class="form-control" onmouseover="this.select()" title="项目地址">
                     </div>
                     <div class="clearfix"></div>
                 </div>
@@ -276,7 +266,7 @@
                 <div class="form-group">
                     <label for="password" class="col-sm-2 control-label">项目地址</label>
                     <div class="col-sm-10">
-                        <input type="text" value="{{urlfor "DocumentController.Index" ":key" .Model.Identify}}" class="form-control" onmouseover="this.select()" id="projectUrl" title="项目地址">
+                        <input type="text" value="{{urlfor "DocumentController.Index" ":key" .Model.Identify}}" class="form-control" onmouseover="this.select()" title="项目地址">
                     </div>
                     <div class="clearfix"></div>
                 </div>
@@ -290,6 +280,7 @@
 
 <script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}"></script>
 <script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}"></script>
+<script src="{{cdnjs "/static/js/bootstrap-paginator.min.js"}}"></script>
 <script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
 <script src="{{cdnjs "/static/layer/layer.js"}}" type="text/javascript"></script>
 <script src="{{cdnjs "/static/jstree/3.3.4/jstree.min.js"}}" type="text/javascript"></script>
@@ -299,6 +290,18 @@
 <script src="{{cdnjs "/static/js/kancloud.js" "version"}}" type="text/javascript"></script>
 <script src="{{cdnjs "/static/js/splitbar.js" "version"}}" type="text/javascript"></script>
 <script type="text/javascript">
+if ({{.Page.TotalPage}} > 1) {
+    $("#page").bootstrapPaginator({
+        currentPage: '{{.Page.PageNo}}',
+        totalPages: '{{.Page.TotalPage}}',
+        bootstrapMajorVersion: 3,
+        size: "middle",
+        onPageClicked: function(e, originalEvent, type, page){
+            onPageClicked(page, {{.DocumentId}});
+        }
+    });
+}
+
 $(function () {
     $("#searchList").on("click","a",function () {
         var id = $(this).attr("data-id");
@@ -346,6 +349,22 @@ $(function () {
             window.jsTree.jstree().open_all()
         }
     })
+
+    // 提交评论
+    $("#commentForm").ajaxForm({
+        beforeSubmit : function () {
+        },
+        success : function (res) {
+            if(res.errcode === 0){
+                console.log("success")
+            }else{
+                console.log("error")
+            }
+        },
+        error : function () {
+            console.log("server error")
+        }
+    });
 });
 </script>
 {{.Scripts}}