Ver Fonte

增加了导出单篇文档为 PDF 的功能。

Dandy Cheung há 7 anos atrás
pai
commit
789d46c340
4 ficheiros alterados com 114 adições e 41 exclusões
  1. 11 0
      TODO
  2. 86 39
      controllers/document.go
  3. 2 1
      routers/router.go
  4. 15 1
      views/document/default_read.tpl

+ 11 - 0
TODO

@@ -0,0 +1,11 @@
+1、把 log 提取出 dbgout 之类的方法;
+2、把源代码里的 TODO 完成;
+3、Export 的两个 URL 应该可以合并,用是否有 :id 来区分;这样 0 号文档输出整个 book 更顺;
+4、统一代码风格,空格、命名之类的;
+5、美化 PDF 的输出格式;
+6、自动登录新开标签页而且并不能跳转至起始请求页的问题;
+7、用户分组管理;
+8、[自动]展示历史版本;增强历史版本对比显示的能力;
+9、[自动]展示作者信息;也许可以和上一需求合并考虑;
+10、查看了解评论功能;
+

+ 86 - 39
controllers/document.go

@@ -16,6 +16,8 @@ import (
 
 	"bytes"
 
+	"log"
+
 	"github.com/PuerkitoBio/goquery"
 	"github.com/astaxie/beego"
 	"github.com/astaxie/beego/orm"
@@ -125,6 +127,9 @@ func (c *DocumentController) Index() {
 	c.Data["Result"] = template.HTML(tree)
 	c.Data["Title"] = "概要"
 	c.Data["Content"] = template.HTML( blackfriday.MarkdownBasic([]byte(bookResult.Description)))
+
+	c.Data["DocumentId"] = "0"	// added by dandycheung, 2017-12-08, for exporting
+	log.Println("DocumentController.Index(): c.Data[\"DocumentId\"] = ", 0)
 }
 
 //阅读文档.
@@ -134,6 +139,9 @@ func (c *DocumentController) Read() {
 	token := c.GetString("token")
 	id := c.GetString(":id")
 
+	c.Data["DocumentId"] = id       // added by dandycheung, 2017-12-08, for exporting
+	log.Println("DocumentController.Read(): c.Data[\"DocumentId\"] = ", id, ", IsAjax = ", c.IsAjax())
+
 	if identify == "" || id == "" {
 		c.Abort("404")
 	}
@@ -735,8 +743,32 @@ func (c *DocumentController) Content() {
 	c.JsonResult(0, "ok", doc)
 }
 
-//导出文件
-func (c *DocumentController) Export() {
+func (c *DocumentController) ExportDoc() {
+	c.Export(true)
+}
+
+func (c *DocumentController) ExportBook() {
+	c.Export(false)
+}
+
+func (c *DocumentController) GetDocumentById(id string) (doc *models.Document, err error) {
+	doc = models.NewDocument()
+        if doc_id, err := strconv.Atoi(id); err == nil {
+                doc, err = doc.Find(doc_id)
+                if err != nil {
+                        return nil, err
+                }
+        } else {
+                doc, err = doc.FindByFieldFirst("identify", id)
+                if err != nil {
+			return nil, err
+                }
+        }
+	return doc, nil
+}
+
+// 导出
+func (c *DocumentController) Export(single_doc bool) {
 	c.Prepare()
 	c.TplName = "document/export.tpl"
 
@@ -791,10 +823,20 @@ func (c *DocumentController) Export() {
 
 		pathList := list.New()
 
-		RecursiveFun(0, "", dpath, c, bookResult, docs, pathList)
+		// 增加对单页文档的导出,dandycheung, 2017-12-07
+		if single_doc {
+			id := c.Ctx.Input.Param(":id")
+			if doc, err := c.GetDocumentById(id); err == nil {
+				EachFun("", dpath, c, bookResult, doc, pathList)
+			}
+		} else {
+			RecursiveFun(0, "", dpath, c, bookResult, docs, pathList)
+		}
 
 		defer os.RemoveAll(dpath)
 
+		// TODO: check if the pathList is empty
+
 		os.MkdirAll("./cache", 0766)
 		pdfpath := filepath.Join("cache", identify+"_"+c.CruSession.SessionID()+".pdf")
 
@@ -1142,49 +1184,54 @@ func (c *DocumentController) Compare()  {
 func RecursiveFun(parent_id int, prefix, dpath string, c *DocumentController, book *models.BookResult, docs []*models.Document, paths *list.List) {
 	for _, item := range docs {
 		if item.ParentId == parent_id {
-			name := prefix + strconv.Itoa(item.ParentId) + strconv.Itoa(item.OrderSort) + strconv.Itoa(item.DocumentId)
-			fpath := dpath + "/" + name + ".html"
-			paths.PushBack(fpath)
-
-			f, err := os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0777)
+			EachFun(prefix, dpath, c, book, item, paths)
 
-			if err != nil {
-				beego.Error(err)
-				c.Abort("500")
+			for _, sub := range docs {
+				if sub.ParentId == item.DocumentId {
+					prefix += strconv.Itoa(item.ParentId) + strconv.Itoa(item.OrderSort) + strconv.Itoa(item.DocumentId);
+					RecursiveFun(item.DocumentId, prefix, dpath, c, book, docs, paths)
+					break
+				}
 			}
+		}
+	}
+}
 
-			html, err := c.ExecuteViewPathTemplate("document/export.tpl", map[string]interface{}{"Model": book, "Lists": item, "BaseUrl": c.BaseUrl()})
-			if err != nil {
-				f.Close()
-				beego.Error(err)
-				c.Abort("500")
-			}
+func EachFun(prefix, dpath string, c *DocumentController, book *models.BookResult, item *models.Document, paths *list.List) {
+	name := prefix + strconv.Itoa(item.ParentId) + strconv.Itoa(item.OrderSort) + strconv.Itoa(item.DocumentId)
+	fpath := dpath + "/" + name + ".html"
+	paths.PushBack(fpath)
 
-			buf := bytes.NewReader([]byte(html))
-			doc, err := goquery.NewDocumentFromReader(buf)
-			doc.Find("img").Each(func(i int, contentSelection *goquery.Selection) {
-				if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(src, "/uploads/") {
-					contentSelection.SetAttr("src", c.BaseUrl()+src)
-				}
-			})
-			html, err = doc.Html()
+	f, err := os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0777)
 
-			if err != nil {
-				f.Close()
-				beego.Error(err)
-				c.Abort("500")
-			}
-			//html = strings.Replace(html,"<img src=\"/uploads","<img src=\""+ c.BaseUrl() +"/uploads",-1)
+	if err != nil {
+		beego.Error(err)
+		c.Abort("500")
+	}
 
-			f.WriteString(html)
-			f.Close()
+	html, err := c.ExecuteViewPathTemplate("document/export.tpl", map[string]interface{}{"Model": book, "Lists": item, "BaseUrl": c.BaseUrl()})
+	if err != nil {
+		f.Close()
+		beego.Error(err)
+		c.Abort("500")
+	}
 
-			for _, sub := range docs {
-				if sub.ParentId == item.DocumentId {
-					RecursiveFun(item.DocumentId, name, dpath, c, book, docs, paths)
-					break
-				}
-			}
+	buf := bytes.NewReader([]byte(html))
+	doc, err := goquery.NewDocumentFromReader(buf)
+	doc.Find("img").Each(func(i int, contentSelection *goquery.Selection) {
+		if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(src, "/uploads/") {
+			contentSelection.SetAttr("src", c.BaseUrl()+src)
 		}
+	})
+	html, err = doc.Html()
+
+	if err != nil {
+		f.Close()
+		beego.Error(err)
+		c.Abort("500")
 	}
+	//html = strings.Replace(html,"<img src=\"/uploads","<img src=\""+ c.BaseUrl() +"/uploads",-1)
+
+	f.WriteString(html)
+	f.Close()
 }

+ 2 - 1
routers/router.go

@@ -73,7 +73,8 @@ func init()  {
 	beego.Router("/docs/:key", &controllers.DocumentController{},"*:Index")
 	beego.Router("/docs/:key/:id", &controllers.DocumentController{},"*:Read")
 	beego.Router("/docs/:key/search", &controllers.DocumentController{},"post:Search")
-	beego.Router("/export/:key", &controllers.DocumentController{},"*:Export")
+        beego.Router("/export/:key", &controllers.DocumentController{},"*:ExportBook")
+	beego.Router("/export/:key/:id", &controllers.DocumentController{},"*:ExportDoc")
 	beego.Router("/qrcode/:key.png",&controllers.DocumentController{},"get:QrCode")
 
 	beego.Router("/attach_files/:key/:attach_id",&controllers.DocumentController{},"get:DownloadAttachment")

+ 15 - 1
views/document/default_read.tpl

@@ -58,7 +58,8 @@
                         {{if eq .Model.PrivatelyOwned 0}}
                         <li><a href="javascript:" data-toggle="modal" data-target="#shareProject">项目分享</a> </li>
                         <li role="presentation" class="divider"></li>
-                        <li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "pdf"}}" target="_blank">项目导出PDF</a> </li>
+                        <li><a href="javascript:void(0);" onclick="ExportPdfDoc()">文档导出为 PDF</a> </li>
+                        <li><a href="{{urlfor "DocumentController.ExportBook" ":key" .Model.Identify "output" "pdf"}}" target="_blank">项目导出为 PDF</a> </li>
                         {{end}}
 
                         <li><a href="{{urlfor "HomeController.Index"}}" title="返回首页">返回首页</a> </li>
@@ -234,6 +235,13 @@
 <script type="text/javascript" src="/static/js/jquery.highlight.js"></script>
 <script type="text/javascript" src="/static/js/kancloud.js"></script>
 <script type="text/javascript">
+active_book_id = {{.Model.Identify}};
+active_doc_id = {{.DocumentId}};
+$(function () {
+    $("body").on('article.open', function (event, $param) {
+        active_doc_id = $param.$id;
+    });
+});
 $(function () {
     $("#searchList").on("click","a",function () {
         var id = $(this).attr("data-id");
@@ -245,6 +253,12 @@ $(function () {
         });
     });
 });
+function ExportPdfDoc() {
+    var id = active_book_id;
+    if(active_doc_id != "0")
+        id += "/" + active_doc_id;
+    window.location.href = "/export/" + id + "?output=pdf";
+}
 </script>
 </body>
 </html>