Kaynağa Gözat

实现Markdown编辑器编辑合并功能

Minho 8 yıl önce
ebeveyn
işleme
d8dd092f3e
29 değiştirilmiş dosya ile 268 ekleme ve 50 silme
  1. 8 0
      controllers/base.go
  2. 54 0
      controllers/document.go
  3. 4 1
      models/document_history.go
  4. 128 0
      static/fonts/notosans.css
  5. BIN
      static/fonts/notosans/v6/5pCv5Yz4eMu9gmvX8nNhfRJtnKITppOI_IvcXXDNrsc.woff2
  6. BIN
      static/fonts/notosans/v6/C7bP6N8yXZ-PGLzbFLtQKRJtnKITppOI_IvcXXDNrsc.woff2
  7. BIN
      static/fonts/notosans/v6/LeFlHvsZjXu2c3ZRgBq9nFtXRa8TVwTICgirnJhmVJw.woff2
  8. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1-gdm0LZdjqr5-oayXSOefg.woff2
  9. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ10Tj6bCwSDA5u__Fbjwz3f0.woff2
  10. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ15X5f-9o1vgP2EXwfjgl7AY.woff2
  11. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ16-j2U0lmluP9RWlSytm3ho.woff2
  12. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ16aRobkAwv3vxw3jMhVENGA.woff2
  13. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1_8zf_FOSsgRmwsS7Aa9k2w.woff2
  14. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1xWV49_lSm1NYrwo-zkhivY.woff2
  15. BIN
      static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1z0LW-43aMEzIO6XUTLjad8.woff2
  16. BIN
      static/fonts/notosans/v6/erE3KsIWUumgD1j_Ca-V-xJtnKITppOI_IvcXXDNrsc.woff2
  17. BIN
      static/fonts/notosans/v6/gEkd0pn-sMtQ_P4HUpi6WBJtnKITppOI_IvcXXDNrsc.woff2
  18. BIN
      static/fonts/notosans/v6/iLJc6PpCnnbQjYc1Jq4v0xJtnKITppOI_IvcXXDNrsc.woff2
  19. BIN
      static/fonts/notosans/v6/iPF-u8L1qkTPHaKjvXERnxJtnKITppOI_IvcXXDNrsc.woff2
  20. BIN
      static/fonts/notosans/v6/mTzVK0-EJOCaJiOPeaz-hxJtnKITppOI_IvcXXDNrsc.woff2
  21. 4 1
      static/js/editor.js
  22. 28 32
      static/mergely/editor/editor.js
  23. 0 5
      static/mergely/editor/editor.min.js
  24. BIN
      static/uploads/201704/avatar_1a17b5dc.jpeg
  25. BIN
      static/uploads/201704/avatar_20b6b820.jpg
  26. BIN
      static/uploads/201704/avatar_29b82bd4.jpeg
  27. BIN
      static/uploads/201704/avatar_37594ca0.jpg
  28. 25 11
      views/document/compare.tpl
  29. 17 0
      views/document/history.tpl

+ 8 - 0
controllers/base.go

@@ -110,3 +110,11 @@ func (c *BaseController) ExecuteViewPathTemplate(tplName string,data interface{}
 func (c *BaseController) BaseUrl() string {
 	return c.Ctx.Input.Scheme() + "://" + c.Ctx.Request.Host
 }
+
+//显示错误信息页面.
+func (c *BaseController) ShowErrorPage(errCode int,errMsg string)  {
+	c.TplName = "errors/error.tpl"
+	c.Data["ErrorMessage"] = errMsg
+	c.Data["ErrorCode"] = errCode
+	c.StopRun()
+}

+ 54 - 0
controllers/document.go

@@ -1081,6 +1081,60 @@ func (c *DocumentController) RestoreHistory() {
 func (c *DocumentController) Compare()  {
 	c.Prepare()
 	c.TplName = "document/compare.tpl"
+	history_id ,_ := strconv.Atoi(c.Ctx.Input.Param(":id"))
+	identify := c.Ctx.Input.Param(":key")
+
+	book_id := 0
+	editor := "markdown"
+
+	//如果是超级管理员则忽略权限判断
+	if c.Member.IsAdministrator() {
+		book, err := models.NewBook().FindByFieldFirst("identify", identify)
+		if err != nil {
+			beego.Error("DocumentController.Compare => ", err)
+			c.Abort("403")
+			return
+		}
+		book_id = book.BookId
+		c.Data["Model"] = book
+		editor = book.Editor
+	} else {
+		bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
+
+		if err != nil || bookResult.RoleId == conf.BookObserver {
+			beego.Error("FindByIdentify => ", err)
+			c.Abort("403")
+			return
+		}
+		book_id = bookResult.BookId
+		c.Data["Model"] = bookResult
+		editor = bookResult.Editor
+	}
+
+	if history_id <= 0 {
+		c.ShowErrorPage(60002,"参数错误")
+	}
+
+	history,err := models.NewDocumentHistory().Find(history_id)
+	if err != nil {
+		beego.Error("DocumentController.Compare => ",err)
+		c.ShowErrorPage(60003,err.Error())
+	}
+	doc,err := models.NewDocument().Find(history.DocumentId)
+
+	if doc.BookId != book_id {
+		c.ShowErrorPage(60002,"参数错误")
+	}
+	c.Data["HistoryId"] = history_id
+	c.Data["DocumentId"] = doc.DocumentId
+
+	if editor == "markdown" {
+		c.Data["HistoryContent"] = history.Markdown
+		c.Data["Content"] = doc.Markdown
+	}else{
+		c.Data["HistoryContent"] = template.HTML(history.Content)
+		c.Data["Content"] = template.HTML(doc.Content)
+	}
 }
 
 //递归生成文档序列数组.

+ 4 - 1
models/document_history.go

@@ -50,8 +50,11 @@ func (m *DocumentHistory) TableNameWithPrefix() string {
 func NewDocumentHistory() *DocumentHistory {
 	return &DocumentHistory{}
 }
-func (m *DocumentHistory) Find()  {
+func (m *DocumentHistory) Find(id int) (*DocumentHistory,error) {
+	o := orm.NewOrm()
+	err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id",id).One(m)
 
+	return m,err
 }
 //清空指定文档的历史.
 func (m *DocumentHistory) Clear(doc_id int) error {

+ 128 - 0
static/fonts/notosans.css

@@ -0,0 +1,128 @@
+/* cyrillic-ext */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/C7bP6N8yXZ-PGLzbFLtQKRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
+    unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
+}
+/* cyrillic */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/iLJc6PpCnnbQjYc1Jq4v0xJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
+    unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* devanagari */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/5pCv5Yz4eMu9gmvX8nNhfRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
+    unicode-range: U+02BC, U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200B-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
+}
+/* greek-ext */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/gEkd0pn-sMtQ_P4HUpi6WBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
+    unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/iPF-u8L1qkTPHaKjvXERnxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
+    unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/mTzVK0-EJOCaJiOPeaz-hxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
+    unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/erE3KsIWUumgD1j_Ca-V-xJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
+    unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans'), local('NotoSans'), url(notosans/v6/LeFlHvsZjXu2c3ZRgBq9nFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
+    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
+}
+/* cyrillic-ext */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ16-j2U0lmluP9RWlSytm3ho.woff2) format('woff2');
+    unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
+}
+/* cyrillic */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ15X5f-9o1vgP2EXwfjgl7AY.woff2) format('woff2');
+    unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* devanagari */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ10Tj6bCwSDA5u__Fbjwz3f0.woff2) format('woff2');
+    unicode-range: U+02BC, U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200B-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
+}
+/* greek-ext */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ1xWV49_lSm1NYrwo-zkhivY.woff2) format('woff2');
+    unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ16aRobkAwv3vxw3jMhVENGA.woff2) format('woff2');
+    unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ1_8zf_FOSsgRmwsS7Aa9k2w.woff2) format('woff2');
+    unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ1z0LW-43aMEzIO6XUTLjad8.woff2) format('woff2');
+    unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+    font-family: 'Noto Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(notosans/v6/PIbvSEyHEdL91QLOQRnZ1-gdm0LZdjqr5-oayXSOefg.woff2) format('woff2');
+    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
+}

BIN
static/fonts/notosans/v6/5pCv5Yz4eMu9gmvX8nNhfRJtnKITppOI_IvcXXDNrsc.woff2


BIN
static/fonts/notosans/v6/C7bP6N8yXZ-PGLzbFLtQKRJtnKITppOI_IvcXXDNrsc.woff2


BIN
static/fonts/notosans/v6/LeFlHvsZjXu2c3ZRgBq9nFtXRa8TVwTICgirnJhmVJw.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1-gdm0LZdjqr5-oayXSOefg.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ10Tj6bCwSDA5u__Fbjwz3f0.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ15X5f-9o1vgP2EXwfjgl7AY.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ16-j2U0lmluP9RWlSytm3ho.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ16aRobkAwv3vxw3jMhVENGA.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1_8zf_FOSsgRmwsS7Aa9k2w.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1xWV49_lSm1NYrwo-zkhivY.woff2


BIN
static/fonts/notosans/v6/PIbvSEyHEdL91QLOQRnZ1z0LW-43aMEzIO6XUTLjad8.woff2


BIN
static/fonts/notosans/v6/erE3KsIWUumgD1j_Ca-V-xJtnKITppOI_IvcXXDNrsc.woff2


BIN
static/fonts/notosans/v6/gEkd0pn-sMtQ_P4HUpi6WBJtnKITppOI_IvcXXDNrsc.woff2


BIN
static/fonts/notosans/v6/iLJc6PpCnnbQjYc1Jq4v0xJtnKITppOI_IvcXXDNrsc.woff2


BIN
static/fonts/notosans/v6/iPF-u8L1qkTPHaKjvXERnxJtnKITppOI_IvcXXDNrsc.woff2


BIN
static/fonts/notosans/v6/mTzVK0-EJOCaJiOPeaz-hxJtnKITppOI_IvcXXDNrsc.woff2


+ 4 - 1
static/js/editor.js

@@ -232,12 +232,14 @@ function formatBytes($size) {
 function uploadImage($id,$callback) {
     /** 粘贴上传图片 **/
     document.getElementById($id).addEventListener('paste', function(e) {
-        e.preventDefault();
+
         var clipboard = e.clipboardData;
         for (var i = 0, len = clipboard.items.length; i < len; i++) {
             if (clipboard.items[i].kind === 'file' || clipboard.items[i].type.indexOf('image') > -1) {
+
                 var imageFile = clipboard.items[i].getAsFile();
 
+                console.log(imageFile)
                 var fileName = Date.parse(new Date());
 
                 switch (imageFile.type){
@@ -277,6 +279,7 @@ function uploadImage($id,$callback) {
 
                     }
                 });
+                e.preventDefault();
             }
         }
     });

+ 28 - 32
static/mergely/editor/editor.js

@@ -97,17 +97,20 @@ $(document).ready(function() {
 		height: 'auto',
 		cmsettings: {
 			lineNumbers: true,
-			readOnly: isSample
+			readOnly: false
 		}
 	});
-	if (parameters.get('lhs', null)) {
-		var url = parameters.get('lhs');
-		crossdomainGET(ed, 'lhs', url);
-	}
-	if (parameters.get('rhs', null)) {
-		var url = parameters.get('rhs');
-		crossdomainGET(ed, 'rhs', url);
-	}
+
+    ed.mergely("lhs", $("#historyContent").html());
+    ed.mergely("rhs", $("#documentContent").html());
+	// if (parameters.get('lhs', null)) {
+	// 	var url = parameters.get('lhs');
+	// 	crossdomainGET(ed, 'lhs', url);
+	// }
+	// if (parameters.get('rhs', null)) {
+	// 	var url = parameters.get('rhs');
+	// 	crossdomainGET(ed, 'rhs', url);
+	// }
 
 	// set query string options
 	var urloptions = {};
@@ -161,7 +164,7 @@ $(document).ready(function() {
 	});
 	
 	// Load
-	if (key.length == 8) {
+	if (key.length === 8) {
 		$.when(
 			$.ajax({
 				type: 'GET', async: true, dataType: 'text',
@@ -301,29 +304,22 @@ $(document).ready(function() {
 		if (id == 'file-new') {
 			window.location = '/editor';
 		}
-		else if (id == 'file-save') {
-			// download directly from browser
-			var text = ed.mergely('diff');
-			if (navigator.userAgent.toLowerCase().indexOf('msie') === -1) {
-				if (key == '') key = ''.random(8);
-				var link = jQuery('<a />', {
-					href: 'data:application/stream;base64,' + window.btoa(unescape(encodeURIComponent(text))),
-					target: '_blank',
-					text: 'clickme',
-					id: key
-				});
-				link.attr('download', key + '.diff');
-				jQuery('body').append(link);
-				var a = $('a#' + key);
-				a[0].click();
-				a.remove();
-			}
-			else {
-				var blob = new Blob([text]);
-				window.navigator.msSaveOrOpenBlob(blob, key + '.diff');
+		else if (id === 'file-save') {
+			var rhs = ed.mergely('get', 'rhs');
+
+			if(window.top.hasOwnProperty("editor")){
+                if(window.top.editor.hasOwnProperty("$txt")){
+                    window.top.editor.$txt.html(rhs);
+				}else{
+
+                    window.top.editor.clear();
+                    window.top.editor.insertValue(rhs);
+				}
+
+                window.top.layer.closeAll();
 			}
-		}
-		else if (id == 'file-share') {
+
+		}else if (id == 'file-share') {
 			handleShare(ed);
 		}
 		else if (id == 'file-import') {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 5
static/mergely/editor/editor.min.js


BIN
static/uploads/201704/avatar_1a17b5dc.jpeg


BIN
static/uploads/201704/avatar_20b6b820.jpg


BIN
static/uploads/201704/avatar_29b82bd4.jpeg


BIN
static/uploads/201704/avatar_37594ca0.jpg


+ 25 - 11
views/document/compare.tpl

@@ -4,12 +4,8 @@
 <head>
     <meta charset="utf-8" />
     <title>文档比较 - Powered by MinDoc</title>
-    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
-    <meta name="description" content="Merge and Diff your documents with diff online and share" />
-    <meta name="keywords" content="diff,merge,compare,jsdiff,comparison,difference,file,text,unix,patch,algorithm,saas,longest common subsequence,diff online" />
-    <meta name="author" content="Jamie Peabody" />
     <link rel="shortcut icon" href="/favicon.ico" />
-    <link href='http://fonts.googleapis.com/css?family=Noto+Sans:400,700' rel='stylesheet' type='text/css' />
+    <link href="/static/fonts/notosans.css" rel='stylesheet' type='text/css' />
     <script type="text/javascript" src="/static/jquery/1.12.4/jquery.min.js"></script>
     <link type='text/css' rel='stylesheet' href='/static/mergely/editor/lib/wicked-ui.css' />
     <script type="text/javascript" src="/static/mergely/editor/lib/wicked-ui.js"></script>
@@ -20,25 +16,43 @@
     <link type="text/css" rel="stylesheet" href="/static/mergely/editor/lib/farbtastic/farbtastic.css" />
     <script type="text/javascript" src="/static/mergely/lib/codemirror.min.js"></script>
     <script type="text/javascript" src="/static/mergely/lib/mergely.min.js"></script>
-    <script type="text/javascript" src="/static/mergely/editor/editor.min.js"></script>
+    <script type="text/javascript" src="/static/mergely/editor/editor.js"></script>
     <link type="text/css" rel="stylesheet" href="/static/mergely/lib/codemirror.css" />
     <link type="text/css" rel="stylesheet" href="/static/mergely/lib/mergely.css" />
     <link type='text/css' rel='stylesheet' href='/static/mergely/editor/editor.css' />
     <script type="text/javascript" src="/static/mergely/lib/searchcursor.js"></script>
-
     <script type="text/javascript">
         var key = '';
-        var isSample = key == 'usaindep';
+       // var isSample = key === 'usaindep';
     </script>
-
-
 </head>
 <body style="visibility:hidden">
+<!-- toolbar -->
+<ul id="toolbar">
+    <li id="tb-file-save" data-icon="icon-save" title="保存">保存合并</li>
+    <li class="separator"></li>
+    <li id="tb-view-change-prev" data-icon="icon-arrow-up" title="上一处差异">上一处差异</li>
+    <li id="tb-view-change-next" data-icon="icon-arrow-down" title="下一处差异">下一处差异</li>
+    <li class="separator"></li>
+    <li id="tb-edit-right-merge-left" data-icon="icon-arrow-left-v" title="合并到左侧">合并到左侧</li>
+    <li id="tb-edit-left-merge-right" data-icon="icon-arrow-right-v" title="合并到右侧">合并到右侧</li>
+    <li id="tb-view-swap" data-icon="icon-swap" title="左右切换">左右切换</li>
+</ul>
 
+<!-- find -->
+<div class="find">
+    <input type="text" placeholder="请输入关键字"/>
+    <button class="find-prev"><span class="icon icon-arrow-up"></span></button>
+    <button class="find-next"><span class="icon icon-arrow-down"></span></button>
+    <button class="find-close"><span class="icon icon-x-mark"></span></button>
+</div>
 <!-- editor -->
-<div style="position: absolute;top: 0px;bottom: 10px;left: 5px;right: 5px;overflow-y: hidden;padding-bottom: 2px;">
+<div style="position: absolute;top: 33px;bottom: 10px;left: 5px;right: 5px;overflow-y: hidden;padding-bottom: 2px;">
     <div id="mergely"></div>
 </div>
+<template id="historyContent">{{.HistoryContent}}</template>
+<template id="documentContent">{{.Content}}</template>
+<script type="text/javascript" src="/static/layer/layer.js"></script>
 
 </body>
 </html>

+ 17 - 0
views/document/history.tpl

@@ -52,6 +52,11 @@
                     <button class="btn btn-success btn-sm restore-btn" data-id="{{$item.HistoryId}}" data-loading-text="恢复中...">
                         恢复
                     </button>
+                    {{if eq $.Model.Editor "markdown"}}
+                    <button class="btn btn-success btn-sm compare-btn" data-id="{{$item.HistoryId}}">
+                        合并
+                    </button>
+                    {{end}}
                 </td>
             </tr>
             {{else}}
@@ -128,6 +133,18 @@
                 })
             }
         });
+        $(".compare-btn").on("click",function () {
+            var historyId = $(this).attr("data-id");
+
+            window.compareIndex = window.top.layer.open({
+                type: 2,
+                title: '文档比较【左侧为历史文档,右侧为当前文档,请将文档合并到右侧】',
+                shade: 0.8,
+                area: ['380px', '90%'],
+                content: "{{urlfor "DocumentController.Compare" ":key" .Model.Identify ":id" ""}}" + historyId
+            });
+            window.top.layer.full(window.compareIndex);
+        });
     });
 </script>
 </body>

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor