diff --git a/controllers/DocumentController.go b/controllers/DocumentController.go
index cef65fb9..338d3b11 100644
--- a/controllers/DocumentController.go
+++ b/controllers/DocumentController.go
@@ -54,7 +54,7 @@ func (c *DocumentController) Index() {
bookResult := isReadable(identify, token, c)
- c.TplName = "document/" + bookResult.Theme + "_read.tpl"
+ c.TplName = fmt.Sprintf("document/%s_read.tpl",bookResult.Theme)
selected := 0
@@ -243,7 +243,7 @@ func (c *DocumentController) Edit() {
} else if bookResult.Editor == "html" {
c.TplName = "document/new_html_edit_template.tpl"
} else {
- c.TplName = "document/" + bookResult.Editor + "_edit_template.tpl"
+ c.TplName = fmt.Sprintf("document/%s_edit_template.tpl", bookResult.Editor)
}
c.Data["Model"] = bookResult
@@ -260,6 +260,11 @@ func (c *DocumentController) Edit() {
beego.Error("FindDocumentTree => ", err)
} else {
if len(trees) > 0 {
+ for _,tree := range trees {
+ if tree.Type == "lock" {
+ tree.DocumentName = tree.DocumentName + " [锁定]"
+ }
+ }
if jtree, err := json.Marshal(trees); err == nil {
c.Data["Result"] = template.JS(string(jtree))
}
@@ -297,6 +302,9 @@ func (c *DocumentController) Create() {
beego.Error(err)
c.JsonResult(6002, "项目不存在或权限不足")
}
+ if book.IsLock == 1 {
+ c.JsonResult(6004,"已锁定的项目不能创建文档")
+ }
bookId = book.BookId
} else {
@@ -306,7 +314,9 @@ func (c *DocumentController) Create() {
beego.Error("FindByIdentify => ", err)
c.JsonResult(6002, "项目不存在或权限不足")
}
-
+ if bookResult.IsLock {
+ c.JsonResult(6004,"已锁定的项目不能创建文档")
+ }
bookId = bookResult.BookId
}
@@ -349,7 +359,7 @@ func (c *DocumentController) Create() {
// 上传附件或图片
func (c *DocumentController) Upload() {
identify := c.GetString("identify")
- doc_id, _ := c.GetInt("doc_id")
+ docId, _ := c.GetInt("doc_id")
is_attach := true
if identify == "" {
@@ -402,6 +412,9 @@ func (c *DocumentController) Upload() {
if err != nil {
c.JsonResult(6006, "文档不存在或权限不足")
}
+ if book.IsLock == 1 {
+ c.JsonResult(6004,"已锁定的项目不能上传文件")
+ }
bookId = book.BookId
} else {
@@ -421,11 +434,14 @@ func (c *DocumentController) Upload() {
c.JsonResult(6006, "权限不足")
}
+ if book.IsLock {
+ c.JsonResult(6004,"已锁定的项目不能上传文件")
+ }
bookId = book.BookId
}
- if doc_id > 0 {
- doc, err := models.NewDocument().Find(doc_id)
+ if docId > 0 {
+ doc, err := models.NewDocument().Find(docId)
if err != nil {
c.JsonResult(6007, "文档不存在")
}
@@ -433,6 +449,9 @@ func (c *DocumentController) Upload() {
if doc.BookId != bookId {
c.JsonResult(6008, "文档不属于指定的项目")
}
+ if doc.IsLock == 1 {
+ c.JsonResult(6004,"已锁定的文档不能上传文件")
+ }
}
fileName := "attach_" + strconv.FormatInt(time.Now().UnixNano(), 16)
@@ -456,14 +475,14 @@ func (c *DocumentController) Upload() {
attachment.CreateAt = c.Member.MemberId
attachment.FileExt = ext
attachment.FilePath = strings.TrimPrefix(filePath, conf.WorkingDirectory)
- attachment.DocumentId = doc_id
+ attachment.DocumentId = docId
if fileInfo, err := os.Stat(filePath); err == nil {
attachment.FileSize = float64(fileInfo.Size())
}
- if doc_id > 0 {
- attachment.DocumentId = doc_id
+ if docId > 0 {
+ attachment.DocumentId = docId
}
if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") || strings.EqualFold(ext, ".png") || strings.EqualFold(ext, ".gif") {
@@ -568,13 +587,13 @@ func (c *DocumentController) DownloadAttachment() {
// 删除附件
func (c *DocumentController) RemoveAttachment() {
c.Prepare()
- attach_id, _ := c.GetInt("attach_id")
+ attachId, _ := c.GetInt("attach_id")
- if attach_id <= 0 {
+ if attachId <= 0 {
c.JsonResult(6001, "参数错误")
}
- attach, err := models.NewAttachment().Find(attach_id)
+ attach, err := models.NewAttachment().Find(attachId)
if err != nil {
beego.Error(err)
@@ -587,8 +606,11 @@ func (c *DocumentController) RemoveAttachment() {
beego.Error(err)
c.JsonResult(6003, "文档不存在")
}
+ if document.IsLockBook(document.DocumentId) {
+ c.JsonResult(6004,"已锁定的项目不能删除附件")
+ }
if document.IsLock == 1 {
- c.JsonResult(6004,"不能编辑已锁定的文档")
+ c.JsonResult(6004,"已锁定的文档不能删除附件")
}
if c.Member.Role != conf.MemberSuperRole {
rel, err := models.NewRelationship().FindByBookIdAndMemberId(document.BookId, c.Member.MemberId)
@@ -737,6 +759,9 @@ func (c *DocumentController) Content() {
beego.Info("%d|", version, doc.Version)
c.JsonResult(6005, "文档已被修改确定要覆盖吗?")
}
+ if doc.IsLock == 1 {
+ c.JsonResult(6003,"锁定的项目不能编辑")
+ }
history := models.NewDocumentHistory()
history.DocumentId = docId
@@ -798,23 +823,6 @@ func (c *DocumentController) Content() {
c.JsonResult(0, "ok", doc)
}
-//
-//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() {
@@ -1043,6 +1051,7 @@ func (c *DocumentController) History() {
}
}
+//删除文档历史
func (c *DocumentController) DeleteHistory() {
c.Prepare()
@@ -1101,6 +1110,7 @@ func (c *DocumentController) DeleteHistory() {
c.JsonResult(0, "ok")
}
+//重置文档历史
func (c *DocumentController) RestoreHistory() {
c.Prepare()
@@ -1158,6 +1168,7 @@ func (c *DocumentController) RestoreHistory() {
c.JsonResult(0, "ok", doc)
}
+//比较文档
func (c *DocumentController) Compare() {
c.Prepare()
@@ -1221,6 +1232,92 @@ func (c *DocumentController) Compare() {
}
}
+//锁定文档
+func (c *DocumentController) Lock() {
+ docId, _ := c.GetInt("doc_id", 0)
+ identify := c.GetString("identify")
+ // 如果是超级管理员则不判断权限
+ if c.Member.IsAdministrator() {
+ book, err := models.NewBook().FindByFieldFirst("identify", identify)
+ if err != nil {
+ beego.Error(err)
+ c.JsonResult(6002, "项目不存在或权限不足")
+ }
+
+ if book.IsLock == 1 {
+ c.JsonResult(6001,"项目已锁定")
+ }
+ } else {
+ bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
+
+ if err != nil || bookResult.RoleId == conf.BookObserver {
+ beego.Error("FindByIdentify => ", err)
+ c.JsonResult(6002, "项目不存在或权限不足")
+ }
+ if bookResult.IsLock {
+ c.JsonResult(6001,"项目已锁定")
+ }
+ }
+ document, err := models.NewDocument().Find(docId)
+
+ if err != nil {
+ beego.Error("获取文档失败 =>",err)
+ c.JsonResult(6004,"文档不存在")
+ }
+ if document.IsLock == 1 {
+ c.JsonResult(6005,"文档已锁定")
+ }
+ document.IsLock = 1
+ if err := document.InsertOrUpdate();err != nil {
+ beego.Error("锁定文档失败 =>",err)
+ c.JsonResult(6006,"锁定文档失败")
+ }
+ c.JsonResult(0, "文档已锁定", document)
+}
+
+// 解锁文档
+func (c *DocumentController) UnLock() {
+ docId, _ := c.GetInt("doc_id", 0)
+ identify := c.GetString("identify")
+ // 如果是超级管理员则不判断权限
+ if c.Member.IsAdministrator() {
+ book, err := models.NewBook().FindByFieldFirst("identify", identify)
+ if err != nil {
+ beego.Error(err)
+ c.JsonResult(6002, "项目不存在或权限不足")
+ }
+
+ if book.IsLock == 1 {
+ c.JsonResult(6001,"项目已锁定")
+ }
+ } else {
+ bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
+
+ if err != nil || bookResult.RoleId == conf.BookObserver {
+ beego.Error("FindByIdentify => ", err)
+ c.JsonResult(6002, "项目不存在或权限不足")
+ }
+ if bookResult.IsLock {
+ c.JsonResult(6001,"项目已锁定")
+ }
+ }
+ document, err := models.NewDocument().Find(docId)
+
+ if err != nil {
+ beego.Error("获取文档失败 =>",err)
+ c.JsonResult(6004,"文档不存在")
+ }
+ if document.IsLock == 1 {
+ document.IsLock = 0
+ if err := document.InsertOrUpdate();err != nil {
+ beego.Error("文档解锁失败 =>",err)
+ c.JsonResult(6006,"文档解锁失败")
+ }
+ }
+
+ c.JsonResult(0, "文档已解锁", document)
+}
+
// 递归生成文档序列数组
func RecursiveFun(parentId int, prefix, dpath string, c *DocumentController, book *models.BookResult, docs []*models.Document, paths *list.List) {
for _, item := range docs {
diff --git a/models/document.go b/models/document.go
index 3a261898..0174ab9d 100644
--- a/models/document.go
+++ b/models/document.go
@@ -216,3 +216,25 @@ func (m *Document) FindListByBookId(bookId int) (docs []*Document, err error) {
return
}
+
+//判断项目是否锁定
+func (m *Document) IsLockBook(docId int) bool {
+ document := NewDocument()
+ book := NewBook()
+
+ o := orm.NewOrm()
+
+ err := o.QueryTable(m.TableNameWithPrefix()).Filter("document_id",docId).One(document,"book_id")
+ if err != nil {
+ beego.Error("查询文档失败 =>",err)
+ return false
+ }
+ err = o.QueryTable(book.TableNameWithPrefix()).Filter("book_id",document.BookId).One(book,"is_lock")
+
+ if err != nil {
+ beego.Error("查询项目失败 =>",err)
+ return false
+ }
+
+ return book.IsLock == 1
+}
\ No newline at end of file
diff --git a/models/document_tree.go b/models/document_tree.go
index 39e8d7cd..ddc198a2 100644
--- a/models/document_tree.go
+++ b/models/document_tree.go
@@ -18,6 +18,7 @@ type DocumentTree struct {
BookIdentify string `json:"-"`
Version int64 `json:"version"`
State *DocumentSelected `json:"state,omitempty"`
+ Type string `json:"type"`
}
type DocumentSelected struct {
Selected bool `json:"selected"`
@@ -32,7 +33,7 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree, error) {
var docs []*Document
- count, err := o.QueryTable(m).Filter("book_id", book_id).OrderBy("order_sort", "document_id").Limit(math.MaxInt32).All(&docs, "document_id", "version", "document_name", "parent_id", "identify")
+ count, err := o.QueryTable(m).Filter("book_id", book_id).OrderBy("order_sort", "document_id").Limit(math.MaxInt32).All(&docs, "document_id", "version", "document_name", "parent_id", "identify","is_lock")
if err != nil {
return trees, err
@@ -50,6 +51,11 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree, error) {
tree.Identify = item.Identify
tree.Version = item.Version
tree.BookIdentify = book.Identify
+ if item.IsLock == 1 {
+ tree.Type = "lock"
+ }else{
+ tree.Type = "unlock"
+ }
if item.ParentId > 0 {
tree.ParentId = item.ParentId
} else {
diff --git a/routers/router.go b/routers/router.go
index 3f2368e5..b31ec54e 100644
--- a/routers/router.go
+++ b/routers/router.go
@@ -68,6 +68,8 @@ func init() {
beego.Router("/api/:key/content/?:id", &controllers.DocumentController{}, "*:Content")
beego.Router("/api/:key/compare/:id", &controllers.DocumentController{}, "*:Compare")
beego.Router("/api/search/user/:key", &controllers.SearchController{}, "*:User")
+ beego.Router("/api/:key/lock", &controllers.DocumentController{}, "*:Lock")
+ beego.Router("/api/:key/unlock", &controllers.DocumentController{}, "*:UnLock")
beego.Router("/history/get", &controllers.DocumentController{}, "get:History")
beego.Router("/history/delete", &controllers.DocumentController{}, "*:DeleteHistory")
diff --git a/static/css/jstree.css b/static/css/jstree.css
index 6a02dc76..3387f19f 100644
--- a/static/css/jstree.css
+++ b/static/css/jstree.css
@@ -198,3 +198,8 @@
line-height: 30px;
height: 30px;
}
+
+.jstree .lock-text{
+ color: #c00;
+ font-size: 12px;
+}
\ No newline at end of file
diff --git a/static/js/editor.js b/static/js/editor.js
index 070763c7..1b084dd8 100644
--- a/static/js/editor.js
+++ b/static/js/editor.js
@@ -106,7 +106,7 @@ function openDeleteDocumentDialog($node) {
function openEditCatalogDialog($node) {
var $then = $("#addDocumentModal");
var doc_id = parseInt($node ? $node.id : 0);
- var text = $node ? $node.text : '';
+ var text = $node ? $node.text.split(' [锁定]";
+ window.treeCatalog.rename_node(node, name);
+ window.treeCatalog.set_type(node,"lock");
+ }else{
+ layer.msg(res.message,{icon : 2})
+ }
+ }).fail(function () {
+ layer.close(index);
+ layer.msg("锁定失败",{icon : 2})
+ });
+}
+/**
+ * 解锁文档
+ * @param $node
+ */
+function unLockDocumentAction($node) {
+ var index = layer.load(1, {
+ shade: [0.1, '#fff'] // 0.1 透明度的白色背景
+ });
+
+ $.post(window.unLockURL,{"identify" : window.book.identify,"doc_id" : $node.id}).done(function (res) {
+ layer.close(index);
+ if(res.errcode === 0){
+ var node = {"id":$node.id};
+ var name = res.data.doc_name;
+ window.treeCatalog.rename_node(node,name);
+ window.treeCatalog.set_type(node,"unlock");
+ }else{
+ layer.msg("解锁失败",{icon : 2})
+ }
+ }).fail(function () {
+ layer.close(index);
+ layer.msg("解锁失败",{icon : 2})
+ });
+}
+
/**
* 发布项目
*/
diff --git a/static/js/markdown.js b/static/js/markdown.js
index b2c9db51..3eab5150 100644
--- a/static/js/markdown.js
+++ b/static/js/markdown.js
@@ -75,6 +75,9 @@ $(function () {
* 实现标题栏操作
*/
$("#editormd-tools").on("click", "a[class!='disabled']", function () {
+ if($(this).hasClass('disabled')){
+ return false;
+ }
var name = $(this).find("i").attr("name");
if (name === "attachment") {
$("#uploadAttachModal").modal("show");
@@ -148,6 +151,15 @@ $(function () {
layer.close(index);
if (res.errcode === 0) {
+ var node = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id, "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version };
+ if(res.data.is_lock){
+ node.type = "lock";
+ node.text = node.text + " [锁定]";
+ // window.editor.config('readOnly',true);
+ }else{
+ node.type = "unlock";
+ window.editor.config('readOnly',false);
+ }
window.isLoad = true;
try {
window.editor.clear();
@@ -156,10 +168,11 @@ $(function () {
}catch(e){
console.log(e);
}
- var node = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id, "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version };
+
pushDocumentCategory(node);
window.selectNode = node;
pushVueLists(res.data.attach);
+
} else {
layer.msg("文档加载失败");
}
@@ -244,6 +257,10 @@ $(function () {
*/
function resetEditorChanged($is_change) {
if ($is_change && !window.isLoad) {
+ var type = window.treeCatalog.get_type(window.selectNode);
+ if(type === "lock"){
+ return;
+ }
$("#markdown-save").removeClass('disabled').addClass('change');
} else {
$("#markdown-save").removeClass('change').addClass('disabled');
@@ -265,8 +282,11 @@ $(function () {
},
success: function (res) {
if (res.errcode === 0) {
- var data = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id , "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version };
+ var data = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id , "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version ,"type": res.data.is_lock ? "lock" : "unlock"};
+ if(res.data.is_lock){
+ data.text = data.text + " [锁定]";
+ }
var node = window.treeCatalog.get_node(data.id);
if (node) {
window.treeCatalog.rename_node({ "id": data.id }, data.text);
@@ -293,6 +313,12 @@ $(function () {
"types": {
"default": {
"icon": false // 删除默认图标
+ },
+ "lock" : {
+ "icon" : false
+ },
+ "unlock" : {
+ "icon" : false
}
},
'core': {
@@ -304,45 +330,78 @@ $(function () {
"contextmenu": {
show_at_node: false,
select_node: false,
- "items": {
- "添加文档": {
- "separator_before": false,
- "separator_after": true,
- "_disabled": false,
- "label": "添加文档",
- "icon": "fa fa-plus",
- "action": function (data) {
- var inst = $.jstree.reference(data.reference),
- node = inst.get_node(data.reference);
+ 'items' : function(node) {
+ var items = {
+ "添加文档": {
+ "separator_before": false,
+ "separator_after": true,
+ "_disabled": false,
+ "label": "添加文档",
+ "icon": "fa fa-plus",
+ "action": function (data) {
+ var inst = $.jstree.reference(data.reference),
+ node = inst.get_node(data.reference);
- openCreateCatalogDialog(node);
- }
- },
- "编辑": {
- "separator_before": false,
- "separator_after": true,
- "_disabled": false,
- "label": "编辑",
- "icon": "fa fa-edit",
- "action": function (data) {
- var inst = $.jstree.reference(data.reference);
- var node = inst.get_node(data.reference);
- openEditCatalogDialog(node);
- }
- },
- "删除": {
- "separator_before": false,
- "separator_after": true,
- "_disabled": false,
- "label": "删除",
- "icon": "fa fa-trash-o",
- "action": function (data) {
- var inst = $.jstree.reference(data.reference);
- var node = inst.get_node(data.reference);
- openDeleteDocumentDialog(node);
+ openCreateCatalogDialog(node);
+ }
+ },
+ "编辑": {
+ "separator_before": false,
+ "separator_after": true,
+ "_disabled": false,
+ "label": "编辑",
+ "icon": "fa fa-edit",
+ "action": function (data) {
+ var inst = $.jstree.reference(data.reference);
+ var node = inst.get_node(data.reference);
+ openEditCatalogDialog(node);
+ }
+ },
+ "删除": {
+ "separator_before": false,
+ "separator_after": true,
+ "_disabled": false,
+ "label": "删除",
+ "icon": "fa fa-trash-o",
+ "action": function (data) {
+ var inst = $.jstree.reference(data.reference);
+ var node = inst.get_node(data.reference);
+ openDeleteDocumentDialog(node);
+ }
+ },
+ "unlock" : {
+ "separator_before": false,
+ "separator_after": true,
+ "_disabled": false,
+ "label": "解锁",
+ "icon": "fa fa-unlock",
+ "action": function (data) {
+ var inst = $.jstree.reference(data.reference);
+ var node = inst.get_node(data.reference);
+ unLockDocumentAction(node);
+ }
+ },
+ "lock" : {
+ "separator_before": false,
+ "separator_after": true,
+ "_disabled": false,
+ "label": "锁定",
+ "icon": "fa fa-lock",
+ "action": function (data) {
+ var inst = $.jstree.reference(data.reference);
+ var node = inst.get_node(data.reference);
+ lockDocumentAction(node);
+ }
}
+ };
+ console.log(this.get_type(node));
+ if(this.get_type(node) === "lock") {
+ delete items.lock;
+ }else{
+ delete items.unlock;
}
- }
+ return items;
+ },
}
}).on('loaded.jstree', function () {
window.treeCatalog = $(this).jstree();
diff --git a/views/document/markdown_edit_template.tpl b/views/document/markdown_edit_template.tpl
index 5d8d7e80..7d2a99b0 100644
--- a/views/document/markdown_edit_template.tpl
+++ b/views/document/markdown_edit_template.tpl
@@ -20,6 +20,8 @@
window.sortURL = "{{urlfor "BookController.SaveSort" ":key" .Model.Identify}}";
window.historyURL = "{{urlfor "DocumentController.History"}}";
window.removeAttachURL = "{{urlfor "DocumentController.RemoveAttachment"}}";
+ window.lockURL = "{{urlfor "DocumentController.Lock" ":key" .Model.Identify}}";
+ window.unLockURL = "{{urlfor "DocumentController.UnLock" ":key" .Model.Identify}}";