From ca1b1a4b83560e32d1634953003a96a1e30a4be8 Mon Sep 17 00:00:00 2001 From: Minho Date: Thu, 27 Apr 2017 18:19:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=96=87=E6=A1=A3=E7=BC=96?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/app.conf | 5 +- conf/app.conf.example | 5 +- conf/enumerate.go | 37 ++- controllers/book.go | 2 +- controllers/document.go | 250 +++++++++++++++++- main.go | 1 + models/attachment.go | 11 +- models/comment.go | 2 +- models/document.go | 94 +++++-- routers/router.go | 8 +- static/css/jstree.css | 196 ++++++++++++++ static/css/markdown.css | 62 ++++- .../plugins/file-dialog/file-dialog.js | 214 +++++++++++++++ .../plugins/video-dialog/video-dialog.js | 97 ------- static/js/markdown.js | 198 +++++++++++++- uploads/.gitignore | 1 + .../b4c17ca29fe7b7f4dec402d7dd7543c6_100.png | Bin 55132 -> 0 bytes views/document/markdown_edit_template.tpl | 85 +++--- 18 files changed, 1095 insertions(+), 173 deletions(-) create mode 100644 static/css/jstree.css create mode 100644 static/editor.md/plugins/file-dialog/file-dialog.js delete mode 100644 static/editor.md/plugins/video-dialog/video-dialog.js create mode 100644 uploads/.gitignore delete mode 100644 uploads/201704/b4c17ca29fe7b7f4dec402d7dd7543c6_100.png diff --git a/conf/app.conf b/conf/app.conf index a654c10c..c31c45c5 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -22,4 +22,7 @@ db_password=123456 cover=/static/images/book.jpg #默认编辑器 -editor=markdown \ No newline at end of file +editor=markdown + +#上传文件的后缀 +upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif \ No newline at end of file diff --git a/conf/app.conf.example b/conf/app.conf.example index 9b371d9f..eda91138 100644 --- a/conf/app.conf.example +++ b/conf/app.conf.example @@ -27,4 +27,7 @@ cover=/static/images/book.jpg avatar=/static/images/headimgurl.jpg #默认阅读令牌长度 -token_size=12 \ No newline at end of file +token_size=12 + +#上传文件的后缀 +upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif \ No newline at end of file diff --git a/conf/enumerate.go b/conf/enumerate.go index a4c9b198..df0e7d8a 100644 --- a/conf/enumerate.go +++ b/conf/enumerate.go @@ -1,7 +1,10 @@ // package conf 为配置相关. package conf -import "github.com/astaxie/beego" +import ( + "github.com/astaxie/beego" + "strings" +) // 登录用户的Session名 const LoginSessionName = "LoginSessionName" @@ -53,4 +56,36 @@ func GetTokenSize() int { func GetDefaultCover() string { return beego.AppConfig.DefaultString("cover","/static/images/book.jpg") +} + +func GetUploadFileExt() []string { + ext := beego.AppConfig.DefaultString("upload_file_ext","png|jpg|jpeg|gif|txt|doc|docx|pdf") + + temp := strings.Split(ext,"|") + + exts := make([]string,len(temp)) + + i := 0 + for _,item := range temp { + if item != "" { + exts[i] = item + i++ + } + } + return exts +} + +func IsAllowUploadFileExt(ext string) bool { + + if strings.HasPrefix(ext,".") { + ext = string(ext[1:]) + } + exts := GetUploadFileExt() + + for _,item := range exts { + if strings.EqualFold(item,ext) { + return true + } + } + return false } \ No newline at end of file diff --git a/controllers/book.go b/controllers/book.go index 60178778..eec3d1cc 100644 --- a/controllers/book.go +++ b/controllers/book.go @@ -381,7 +381,7 @@ func (c *BookController) Create() { c.JsonResult(6002,"项目标识不能为空") } if ok,err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`,identify); !ok || err != nil { - c.JsonResult(6003,"文档标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头") + c.JsonResult(6003,"项目标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头") } if strings.Count(identify,"") > 50 { c.JsonResult(6004,"文档标识不能超过50字") diff --git a/controllers/document.go b/controllers/document.go index 75089dde..271f0fa5 100644 --- a/controllers/document.go +++ b/controllers/document.go @@ -1,8 +1,21 @@ package controllers import ( + "os" + "time" + "regexp" + "strconv" + "strings" + "net/http" + "path/filepath" + "encoding/json" + "html/template" + "github.com/lifei6671/godoc/models" "github.com/astaxie/beego/logs" + "github.com/lifei6671/godoc/conf" + "github.com/astaxie/beego" + "github.com/astaxie/beego/orm" ) type DocumentController struct { @@ -21,12 +34,16 @@ func (c *DocumentController) Edit() { c.Prepare() identify := c.Ctx.Input.Param(":key") + if identify == "" { + c.Abort("404") + } - book,err := models.NewBook().FindByFieldFirst("identify",identify) + book,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) if err != nil { logs.Error("DocumentController.Edit => ",err) - c.Abort("500") + + c.Abort("403") } if book.Editor == "markdown" { c.TplName = "document/markdown_edit_template.tpl" @@ -34,4 +51,231 @@ func (c *DocumentController) Edit() { c.TplName = "document/html_edit_template.tpl" } -} \ No newline at end of file + c.Data["Model"] = book + + r,_ := json.Marshal(book) + + c.Data["ModelResult"] = template.JS(string(r)) + + c.Data["Result"] = template.JS("[]") + + trees ,err := models.NewDocument().FindDocumentTree(book.BookId) + logs.Info("",trees) + if err != nil { + logs.Error("FindDocumentTree => ", err) + }else{ + if len(trees) > 0 { + if jtree, err := json.Marshal(trees); err == nil { + c.Data["Result"] = template.JS(string(jtree)) + } + }else{ + c.Data["Result"] = template.JS("[]") + } + } + +} + +//创建一个文档 +func (c *DocumentController) Create() { + identify := c.GetString("identify") + doc_identify := c.GetString("doc_identify") + doc_name := c.GetString("doc_name") + parent_id,_ := c.GetInt("parent_id",0) + + if identify == "" { + c.JsonResult(6001,"参数错误") + } + if doc_name == "" { + c.JsonResult(6004,"文档名称不能为空") + } + if doc_identify != "" { + if ok, err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`, doc_identify); !ok || err != nil { + + c.JsonResult(6003, "文档标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头") + } + d,_ := models.NewDocument().FindByFieldFirst("identify",doc_identify); + if d.DocumentId > 0{ + c.JsonResult(6006,"文档标识已被使用") + } + } + + bookResult,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) + + if err != nil || bookResult.RoleId == conf.BookObserver { + logs.Error("FindByIdentify => ",err) + c.JsonResult(6002,"项目不存在或权限不足") + } + if parent_id > 0 { + doc,err := models.NewDocument().Find(parent_id) + if err != nil || doc.BookId != bookResult.BookId{ + c.JsonResult(6003,"父分类不存在") + } + } + + document := models.NewDocument() + document.MemberId = c.Member.MemberId + document.BookId = bookResult.BookId + if doc_identify != ""{ + document.Identify = doc_identify + } + document.Version = time.Now().UnixNano() + document.DocumentName = doc_name + document.ParentId = parent_id + logs.Info("%+v",document) + if err := document.InsertOrUpdate();err != nil { + logs.Error("InsertOrUpdate => ",err) + c.JsonResult(6005,"保存失败") + }else{ + logs.Info("",document) + c.JsonResult(0,"ok",document) + } +} + +//上传附件或图片 +func (c *DocumentController) Upload() { + + identify := c.GetString("identify") + + if identify == "" { + c.JsonResult(6001,"参数错误") + } + + + name := "editormd-file-file" + + file,moreFile,err := c.GetFile(name) + if err == http.ErrMissingFile { + name = "editormd-image-file" + file,moreFile,err = c.GetFile(name); + if err == http.ErrMissingFile { + c.JsonResult(6003,"没有发现需要上传的文件") + } + } + if err != nil { + c.JsonResult(6002,err.Error()) + } + + defer file.Close() + + ext := filepath.Ext(moreFile.Filename) + + if ext == "" { + c.JsonResult(6003,"无法解析文件的格式") + } + + if !conf.IsAllowUploadFileExt(ext) { + c.JsonResult(6004,"不允许的文件类型") + } + + book,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) + + if err != nil { + logs.Error("DocumentController.Edit => ",err) + if err == orm.ErrNoRows { + c.JsonResult(6006,"权限不足") + } + c.JsonResult(6001,err.Error()) + } + //如果没有编辑权限 + if book.RoleId != conf.BookEditor && book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder { + c.JsonResult(6006,"权限不足") + } + + fileName := "attachment_" + strconv.FormatInt(time.Now().UnixNano(), 16) + + filePath := "uploads/" + time.Now().Format("200601") + "/" + fileName + ext + + err = c.SaveToFile(name,filePath) + + if err != nil { + logs.Error("SaveToFile => ",err) + c.JsonResult(6005,"保存文件失败") + } + attachment := models.NewAttachment() + attachment.BookId = book.BookId + attachment.FileName = moreFile.Filename + attachment.CreateAt = c.Member.MemberId + attachment.FileExt = ext + attachment.FilePath = filePath + + if strings.EqualFold(ext,".jpg") || strings.EqualFold(ext,".jpeg") || strings.EqualFold(ext,"png") || strings.EqualFold(ext,"gif") { + attachment.HttpPath = c.BaseUrl() + "/" + filePath + } + + err = attachment.Insert(); + + if err != nil { + os.Remove(filePath) + logs.Error("Attachment Insert => ",err) + c.JsonResult(6006,"文件保存失败") + } + if attachment.HttpPath == "" { + attachment.HttpPath = c.BaseUrl() + beego.URLFor("DocumentController.DownloadAttachment",":key", identify, ":attach_id", attachment.AttachmentId) + + if err := attachment.Update();err != nil { + logs.Error("SaveToFile => ",err) + c.JsonResult(6005,"保存文件失败") + } + } + result := map[string]interface{}{ + "success" : 1, + "message" :"ok", + "url" : attachment.HttpPath, + "alt" : attachment.FileName, + } + + c.Data["json"] = result + c.ServeJSON(true) + c.StopRun() +} + +//DownloadAttachment 下载附件. +func (c *DocumentController) DownloadAttachment() { + c.Prepare() + + identify := c.Ctx.Input.Param(":key") + attach_id,_ := strconv.Atoi(c.Ctx.Input.Param(":attach_id")) + token := c.GetString("token") + + member_id := 0 + + if c.Member != nil { + member_id = c.Member.MemberId + } + book_id := 0 + + //判断用户是否参与了项目 + bookResult,err := models.NewBookResult().FindByIdentify(identify,member_id) + + if err != nil { + //判断项目公开状态 + book,err := models.NewBook().FindByFieldFirst("identify",identify) + if err != nil { + c.Abort("404") + } + //如果项目是私有的,并且token不正确 + if (book.PrivatelyOwned == 1 && token == "" ) || ( book.PrivatelyOwned == 1 && book.PrivateToken != token ){ + c.Abort("403") + } + book_id = book.BookId + }else{ + book_id = bookResult.BookId + } + + attachment,err := models.NewAttachment().Find(attach_id) + + if err != nil { + logs.Error("DownloadAttachment => ", err) + if err == orm.ErrNoRows { + c.Abort("404") + } else { + c.Abort("500") + } + } + if attachment.BookId != book_id { + c.Abort("404") + } + c.Ctx.Output.Download(attachment.FilePath,attachment.FileName) + + c.StopRun() +} diff --git a/main.go b/main.go index 29b80b2f..c93c90b0 100644 --- a/main.go +++ b/main.go @@ -16,5 +16,6 @@ func main() { beego.SetStaticPath("uploads","uploads") + beego.Run() } diff --git a/models/attachment.go b/models/attachment.go index 559132e5..a5331b5c 100644 --- a/models/attachment.go +++ b/models/attachment.go @@ -9,9 +9,11 @@ import ( // Attachment struct . type Attachment struct { AttachmentId int `orm:"column(attachment_id);pk;auto;unique" json:"attachment_id"` - DocumentId int `orm:"column(document_id);type(int)" json:"document_id"` - FileName string `orm:"column(file_name);size(2000)" json:"file_name"` + BookId int `orm:"column(book_id);type(int)" json:"book_id"` + FileName string `orm:"column(file_name);size(255)" json:"file_name"` + FilePath string `orm:"column(file_path);size(2000)" json:"file_path"` FileSize float64 `orm:"column(file_size);type(float)" json:"file_size"` + HttpPath string `orm:"column(http_path);size(2000)" json:"http_path"` FileExt string `orm:"column(file_ext);size(50)" json:"file_ext"` CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add"` CreateAt int `orm:"column(create_at);type(int)" json:"create_at"` @@ -41,6 +43,11 @@ func (m *Attachment) Insert() error { return err } +func (m *Attachment) Update() error { + o := orm.NewOrm() + _,err := o.Update(m) + return err +} func (m *Attachment) Find(id int) (*Attachment,error) { if id <= 0 { diff --git a/models/comment.go b/models/comment.go index 5ab0b206..bb627ff1 100644 --- a/models/comment.go +++ b/models/comment.go @@ -84,7 +84,7 @@ func (m *Comment) Insert() error { document := NewDocument() //如果评论的文档不存在 - if err := document.Find(m.DocumentId); err != nil { + if _,err := document.Find(m.DocumentId); err != nil { return err } book ,err := NewBook().Find(document.BookId); diff --git a/models/document.go b/models/document.go index eeef450f..8f98f157 100644 --- a/models/document.go +++ b/models/document.go @@ -2,32 +2,43 @@ package models import ( "time" + "github.com/lifei6671/godoc/conf" "github.com/astaxie/beego/orm" ) // Document struct. type Document struct { - DocumentId int `orm:"pk;auto;unique;column(document_id)" json:"document_id"` - DocumentName string `orm:"column(document_name);size(500)" json:"document_name"` + DocumentId int `orm:"pk;auto;unique;column(document_id)" json:"doc_id"` + DocumentName string `orm:"column(document_name);size(500)" json:"doc_name"` // Identify 文档唯一标识 - Identify string `orm:"column(identify);size(100);unique" json:"identify"` + Identify string `orm:"column(identify);size(100);unique;null;default(null)" json:"identify"` BookId int `orm:"column(book_id);type(int);index" json:"book_id"` - OrderSort int `orm:"column(order_sort);default(0);type(int)" json:"order_sort"` + ParentId int `orm:"column(parent_id);type(int);index" json:"parent_id"` + OrderSort int `orm:"column(order_sort);default(0);type(int);index" json:"order_sort"` // Markdown markdown格式文档. Markdown string `orm:"column(markdown);type(longtext)" json:"markdown"` // Release 发布后的Html格式内容. Release string `orm:"column(release);type(longtext)" json:"release"` // Content 未发布的 Html 格式内容. Content string `orm:"column(content);type(longtext)" json:"content"` - CreateTime time.Time `orm:"column(create_time);type(datetime)" json:"create_time"` - CreateAt int `orm:"column(create_at);type(int)" json:"create_at"` + CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"` + MemberId int `orm:"column(member_id);type(int)" json:"member_id"` ModifyTime time.Time `orm:"column(modify_time);type(datetime);auto_now" json:"modify_time"` - ModifyAt int `orm:"column(modify_at);type(int)" json:"modify_at"` - Version int64 `orm:"type(bigint);column(version)" json:"version"` + ModifyAt int `orm:"column(modify_at);type(int)" json:"-"` + Version int64 `orm:"type(bigint);column(version)" json:"-"` } - +type DocumentTree struct { + DocumentId int `json:"id,string"` + DocumentName string `json:"text"` + ParentId int `json:"parent_id,string"` + State *DocumentSelected `json:"state,omitempty"` +} +type DocumentSelected struct { + Selected bool `json:"selected"` + Opened bool `json:"opened"` +} // TableName 获取对应数据库表名. func (m *Document) TableName() string { return "documents" @@ -45,9 +56,9 @@ func NewDocument() *Document { return &Document{} } -func (m *Document) Find(id int) error { +func (m *Document) Find(id int) (*Document,error) { if id <= 0 { - return ErrInvalidParameter + return m,ErrInvalidParameter } o := orm.NewOrm() @@ -55,9 +66,60 @@ func (m *Document) Find(id int) error { err := o.Read(m) if err == orm.ErrNoRows{ - return ErrDataNotExist + return m,ErrDataNotExist } - return nil + return m,nil +} + + +func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){ + o := orm.NewOrm() + + trees := make([]*DocumentTree,0) + + var docs []*Document + + count ,err := o.QueryTable(m).Filter("book_id",book_id).OrderBy("-order_sort","document_id").All(&docs,"document_id","document_name","parent_id") + + if err != nil { + return trees,err + } + + trees = make([]*DocumentTree,count) + + for index,item := range docs { + tree := &DocumentTree{} + if index == 0{ + tree.State = &DocumentSelected{ Selected: true, Opened: true } + } + tree.DocumentId = item.DocumentId + tree.ParentId = item.ParentId + tree.DocumentName = item.DocumentName + + trees[index] = tree + } + + return trees,nil +} + +func (m *Document) InsertOrUpdate(cols... string) error { + o := orm.NewOrm() + + if m.DocumentId > 0 { + _,err := o.Update(m) + return err + }else{ + _,err := o.Insert(m) + return err + } +} + +func (m *Document) FindByFieldFirst(field string,v interface{}) (*Document,error) { + o := orm.NewOrm() + + err := o.QueryTable(m.TableNameWithPrefix()).Filter(field,v).One(m) + + return m,err } @@ -70,9 +132,3 @@ func (m *Document) Find(id int) error { - - - - - - diff --git a/routers/router.go b/routers/router.go index e92add0a..1abbb8d7 100644 --- a/routers/router.go +++ b/routers/router.go @@ -14,7 +14,7 @@ func init() { beego.Router("/find_password", &controllers.AccountController{},"*:FindPassword") beego.Router("/manager", &controllers.ManagerController{},"*:Index") - beego.Router("/manager/users", &controllers.ManagerController{},"*:Users") + beego.Router("/manager/users", &controllers.ManagerController{}) beego.Router("/manager/member/create", &controllers.ManagerController{},"post:CreateMember") beego.Router("/manager/member/update-member-status",&controllers.ManagerController{},"post:UpdateMemberStatus") beego.Router("/manager/member/change-member-role", &controllers.ManagerController{},"post:ChangeMemberRole") @@ -45,9 +45,13 @@ func init() { beego.Router("/book/setting/token", &controllers.BookController{},"post:CreateToken") beego.Router("/book/setting/delete", &controllers.BookController{},"post:Delete") - beego.Router("/book/:key/edit/?:id", &controllers.DocumentController{},"*:Edit") + beego.Router("/docs/:key/edit/?:id", &controllers.DocumentController{},"*:Edit") + beego.Router("/docs/upload",&controllers.DocumentController{},"post:Upload") + beego.Router("/docs/:key/create",&controllers.DocumentController{},"post:Create") beego.Router("/docs/:key", &controllers.DocumentController{},"*:Index") beego.Router("/docs/:key/:id", &controllers.DocumentController{},"*:Read") + + beego.Router("/:key/attach_files/:attach_id",&controllers.DocumentController{},"get:DownloadAttachment") } diff --git a/static/css/jstree.css b/static/css/jstree.css new file mode 100644 index 00000000..39883626 --- /dev/null +++ b/static/css/jstree.css @@ -0,0 +1,196 @@ +.jstree-contextmenu{ + z-index: 999999; +} +.jstree-contextmenu { + z-index: 3000 +} + +.jstree-contextmenu.jstree-default-contextmenu { + border: 1px solid #d6d6d6; + box-shadow: 0 0 8px rgba(99,99,99,.3); + background-color: #f6f6f6; + padding: 0 +} + +.jstree-contextmenu.jstree-default-contextmenu li { + display: block +} + +.jstree-contextmenu.jstree-default-contextmenu .vakata-context-separator { + display: none +} + +.jstree-contextmenu.jstree-default-contextmenu .vakata-contextmenu-sep { + display: none +} + +.jstree-contextmenu.jstree-default-contextmenu li a { + border-bottom: 0; + height: 30px; + line-height: 24px; + padding-top: 3px; + padding-bottom: 3px +} + +.jstree-contextmenu.jstree-default-contextmenu li.vakata-context-hover a { + text-shadow: none; + background: #116cd6; + box-shadow: none; + color: #fff +} + +.jstree-contextmenu.jstree-default-contextmenu li>a>i:empty { + width: 24px; + height: 24px; + line-height: 24px; + vertical-align: middle +} + +.jstree .jstree-node .jstree-anchor { + padding-right: 36px; + color: #666 +} + +.jstree .jstree-node .m-tree-operate { + position: absolute; + right: 6px; + z-index: 100; + display: block +} + +.jstree .jstree-node .m-tree-operate .operate-show { + font-size: 20px; + color: #999; + display: none +} + +.jstree .jstree-node .m-tree-operate .operate-show i { + height: 24px; + line-height: 24px; + vertical-align: top; + margin-top: 1px; + display: inline-block; + font-size: 18px; + transition-property: transform; + transition-duration: .3s; + transition-timing-function: .3s; + transition-delay: 0s; + -moz-transition-property: transform; + -moz-transition-duration: .3s; + -moz-transition-timing-function: .3s; + -moz-transition-delay: 0s; + -webkit-transition-property: transform; + -webkit-transition-duration: .3s; + -webkit-transition-timing-function: .3s; + -webkit-transition-delay: 0s; + -o-transition-property: transform; + -o-transition-duration: .3s; + -o-transition-timing-function: .3s; + -o-transition-delay: 0s +} + +.jstree .jstree-node .m-tree-operate .operate-hide { + width: 0; + right: 100%; + top: 2px; + position: absolute; + overflow: hidden; + transition-property: width; + transition-duration: .3s; + transition-timing-function: linear; + transition-delay: 0s; + -moz-transition-property: width; + -moz-transition-duration: .3s; + -moz-transition-timing-function: linear; + -moz-transition-delay: 0s; + -webkit-transition-property: width; + -webkit-transition-duration: .3s; + -webkit-transition-timing-function: linear; + -webkit-transition-delay: 0s; + -o-transition-property: width; + -o-transition-duration: .3s; + -o-transition-timing-function: linear; + -o-transition-delay: 0s +} + +.jstree .jstree-node .m-tree-operate .operate-hide b { + font-size: 12px; + display: inline-block; + margin: 3px 2px 0; + vertical-align: top; + width: 18px; + height: 18px; + text-align: center; + line-height: 18px; + border-radius: 9px; + color: #fff; + cursor: pointer +} + +.jstree .jstree-node .m-tree-operate .operate-hide b.add { + background-color: #39f +} + +.jstree .jstree-node .m-tree-operate .operate-hide b.del { + background-color: #c00 +} + +.jstree .jstree-node .m-tree-operate .operate-hide b.edit { + background-color: #e5b120 +} + +.jstree .jstree-node .m-tree-operate .operate-hide b.up { + background-color: #3e8a2a; + font-size: 18px +} + +.jstree .jstree-node .m-tree-operate .operate-hide b.down { + background-color: #3e8a2a; + font-size: 18px +} + +.jstree .jstree-node .m-tree-operate:hover .operate-hide { + width: 108px +} + +.jstree .jstree-node .m-tree-operate:hover .operate-show i { + color: #333; + transform: rotate(360deg); + -ms-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -webkit-transform: rotate(360deg); + -o-transform: rotate(360deg) +} + +.jstree .jstree-node .jstree-anchor.jstree-clicked ,.jstree .jstree-hovered{ + color: #ffffff !important; +} + +.jstree .jstree-node .m-tree-operate.operate-hover .operate-hide { + width: 108px +} +.jstree-default .jstree-wholerow-clicked { + background: #10af88; + background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); + background: linear-gradient(to bottom, #10af88 0%, #10af88 100%); + color: #ffffff; +} +.jstree-default .jstree-wholerow { + height: 30px; +} +.jstree-default .jstree-node { + min-height: 30px; + line-height: 30px; + margin-left: 30px; + min-width: 30px; +} +.jstree-default .jstree-node { + min-height: 30px; + line-height: 30px; + margin-left: 30px; + min-width: 30px; +} +.jstree-default .jstree-anchor { + line-height: 30px; + height: 30px; +} \ No newline at end of file diff --git a/static/css/markdown.css b/static/css/markdown.css index 731a04f9..f8f9e237 100644 --- a/static/css/markdown.css +++ b/static/css/markdown.css @@ -4,9 +4,10 @@ body{ left: 0; right: 0; bottom: 0; - color: #FAFAFA; } - +.error-message{ + color: red; +} .manual-head{ padding: 5px 5px 5px 5px; position: fixed; @@ -18,6 +19,46 @@ body{ border-top: 1px solid #DDDDDD; bottom: 0; top: 40px; + background-color: #FAFAFA; +} +.manual-category .manual-nav { + font-size: 14px; + color: #333333; + font-weight: 200; + zoom:1; + border-bottom: 1px solid #ddd +} +.manual-category .manual-tree{ + margin-top: 10px; +} +.manual-category .manual-nav .nav-item{ + font-size: 14px; + padding: 0 9px; + cursor: pointer; + float: left; + height: 30px; + line-height: 30px; + color: #666; +} +.manual-category .manual-nav .nav-plus { + color: #999; + cursor: pointer; + height: 24px; + width: 24px; + line-height: 24px; + display: inline-block; + margin-top: 4px +} +.manual-category .manual-nav .nav-plus:hover{ + color: #333333; +} +.manual-category .manual-nav .nav-item.active{ + border-bottom: 1px solid #fafafa; + margin-bottom: -1px; + border-left: 1px solid #ddd; + border-right: 1px solid #ddd; + padding-left: 8px; + padding-right: 8px; } .manual-editor-container{ position: absolute; @@ -26,6 +67,11 @@ body{ right: 0; bottom: 0; overflow: hidden; + border-top: 1px solid #DDDDDD; +} +.manual-editor-container .manual-editormd{ + position: absolute; + bottom: 15px; } .editormd-group{ float: left; @@ -76,4 +122,16 @@ body{ text-align: center; font-family: icomoon,Helvetica,Arial,sans-serif; font-style: normal; +} + +.manual-editor-status{ + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 30px; + overflow: hidden; + border-left: 1px solid #DDDDDD; + color: #555; + background-color: #FAFAFA; } \ No newline at end of file diff --git a/static/editor.md/plugins/file-dialog/file-dialog.js b/static/editor.md/plugins/file-dialog/file-dialog.js new file mode 100644 index 00000000..5c241ab8 --- /dev/null +++ b/static/editor.md/plugins/file-dialog/file-dialog.js @@ -0,0 +1,214 @@ +/*! + * File (upload) dialog plugin for Editor.md + * + * @file file-dialog.js + * @author minho + * @version 0.1.0 + * @updateTime 2017-01-06 + * {@link https://github.com/lifei6671/SmartWiki} + * @license MIT + */ + +(function() { + + var factory = function (exports) { + + var pluginName = "file-dialog"; + + exports.fn.fileDialog = function() { + + var _this = this; + var cm = this.cm; + var lang = this.lang; + var editor = this.editor; + var settings = this.settings; + var cursor = cm.getCursor(); + var selection = cm.getSelection(); + var fileLang = lang.dialog.file; + var classPrefix = this.classPrefix; + var iframeName = classPrefix + "file-iframe"; + var dialogName = classPrefix + pluginName, dialog; + + cm.focus(); + + var loading = function(show) { + var _loading = dialog.find("." + classPrefix + "dialog-mask"); + _loading[(show) ? "show" : "hide"](); + }; + + if (editor.find("." + dialogName).length < 1) + { + var guid = (new Date).getTime(); + var action = settings.fileUploadURL + (settings.fileUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid; + + if (settings.crossDomainUpload) + { + action += "&callback=" + settings.uploadCallbackURL + "&dialog_id=editormd-file-dialog-" + guid; + } + + var dialogContent = ( (settings.fileUpload) ? "
" : "
" ) + + ( (settings.fileUpload) ? "" : "" ) + + "" + + "" + (function(){ + return (settings.fileUpload) ? "
" + + "" + + "" + + "
" : ""; + })() + + "
" + + "" + + "" + + "
" + + ""+ + ( (settings.fileUpload) ? "" : "
"); + + //var imageFooterHTML = ""; + + dialog = this.createDialog({ + title : "文件上传", + width : (settings.fileUpload) ? 465 : 380, + height : 254, + name : dialogName, + content : dialogContent, + mask : settings.dialogShowMask, + drag : settings.dialogDraggable, + lockScreen : settings.dialogLockScreen, + maskStyle : { + opacity : settings.dialogMaskOpacity, + backgroundColor : settings.dialogMaskBgColor + }, + buttons : { + enter : [lang.buttons.enter, function() { + var url = this.find("[data-url]").val(); + var alt = this.find("[data-alt]").val(); + var icon = this.find("[data-icon]").val(); + + if (url === "") + { + alert(fileLang.fileURLEmpty); + return false; + } + + var altAttr = (alt !== "") ? " \"" + alt + "\"" : ""; + + + if (icon === "" || !icon) + { + cm.replaceSelection("[" + alt + "](" + url + altAttr + ")"); + } + else + { + cm.replaceSelection("[![" + alt + "](" + icon + ")"+ alt +"](" + url + altAttr + ")"); + } + + + if (alt === "") { + cm.setCursor(cursor.line, cursor.ch + 2); + } + + this.hide().lockScreen(false).hideMask(); + + return false; + }], + + cancel : [lang.buttons.cancel, function() { + this.hide().lockScreen(false).hideMask(); + + return false; + }] + } + }); + + dialog.attr("id", classPrefix + "file-dialog-" + guid); + + if (!settings.fileUpload) { + return ; + } + + var fileInput = dialog.find("[name=\"" + classPrefix + "file-file\"]"); + + fileInput.bind("change", function() { + var fileName = fileInput.val(); + + if (fileName === "") + { + alert(fileLang.uploadFileEmpty); + + return false; + } + + loading(true); + + var submitHandler = function() { + + var uploadIframe = document.getElementById(iframeName); + + uploadIframe.onload = function() { + + loading(false); + + var body = (uploadIframe.contentWindow ? uploadIframe.contentWindow : uploadIframe.contentDocument).document.body; + var json = (body.innerText) ? body.innerText : ( (body.textContent) ? body.textContent : null); + + json = (typeof JSON.parse !== "undefined") ? JSON.parse(json) : eval("(" + json + ")"); + + if(!settings.crossDomainUpload) + { + if (json.success === 1) + { + dialog.find("[data-url]").val(json.url); + + json.alt && dialog.find("[data-alt]").val(json.alt); + } + else + { + alert(json.message); + } + } + + return false; + }; + }; + + dialog.find("[type=\"submit\"]").bind("click", submitHandler).trigger("click"); + }); + } + + dialog = editor.find("." + dialogName); + dialog.find("[type=\"text\"]").val(""); + dialog.find("[type=\"file\"]").val(""); + + this.dialogShowMask(dialog); + this.dialogLockScreen(); + dialog.show(); + + }; + + }; + + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + { + module.exports = factory; + } + else if (typeof define === "function") // AMD/CMD/Sea.js + { + if (define.amd) { // for Require.js + + define(["editormd"], function(editormd) { + factory(editormd); + }); + + } else { // for Sea.js + define(function(require) { + var editormd = require("./../../editormd"); + factory(editormd); + }); + } + } + else + { + factory(window.editormd); + } + +})(); diff --git a/static/editor.md/plugins/video-dialog/video-dialog.js b/static/editor.md/plugins/video-dialog/video-dialog.js deleted file mode 100644 index 712ea9f0..00000000 --- a/static/editor.md/plugins/video-dialog/video-dialog.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * 插入视频插件,编辑器必须开启html识别 - * - * @file video-dialog.js - * @author Minho - * @version 0.1 - * @licence MIT - */ -(function() { - var factory = function (exports) { - - var $ = jQuery; - var pluginName = "video-dialog"; - - exports.fn.videoDialog = function () { - var _this = this; - var lang = this.lang; - var editor = this.editor; - var settings = this.settings; - var path = settings.pluginPath + pluginName + "/"; - var classPrefix = this.classPrefix; - var dialogName = classPrefix + pluginName, dialog; - var dialogLang = lang.dialog.help; - - if (editor.find("." + dialogName).length < 1) { - - var dialogContent = ""; - - dialog = this.createDialog({ - name: dialogName, - title: dialogLang.title, - width: 840, - height: 540, - mask: settings.dialogShowMask, - drag: settings.dialogDraggable, - content: dialogContent, - lockScreen: settings.dialogLockScreen, - maskStyle: { - opacity: settings.dialogMaskOpacity, - backgroundColor: settings.dialogMaskBgColor - }, - buttons: { - close: [lang.buttons.close, function () { - this.hide().lockScreen(false).hideMask(); - - return false; - }] - } - }); - } - - dialog = editor.find("." + dialogName); - - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); - - var videoContent = dialog.find(".markdown-body"); - - if (videoContent.html() === "") { - $.get(path + "help.md", function (text) { - var md = exports.$marked(text); - videoContent.html(md); - - videoContent.find("a").attr("target", "_blank"); - }); - } - }; - - }; - - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") - { - module.exports = factory; - } - else if (typeof define === "function") // AMD/CMD/Sea.js - { - if (define.amd) { // for Require.js - - define(["editormd"], function(editormd) { - factory(editormd); - }); - - } else { // for Sea.js - define(function(require) { - var editormd = require("./../../editormd"); - factory(editormd); - }); - } - } - else - { - factory(window.editormd); - } -})(); - diff --git a/static/js/markdown.js b/static/js/markdown.js index dba3140d..42dcc846 100644 --- a/static/js/markdown.js +++ b/static/js/markdown.js @@ -1,3 +1,19 @@ +function showError($msg,$id) { + if(!$id){ + $id = "#form-error-message" + } + $($id).addClass("error-message").removeClass("success-message").text($msg); + return false; +} + +function showSuccess($msg,$id) { + if(!$id){ + $id = "#form-error-message" + } + $($id).addClass("success-message").removeClass("error-message").text($msg); + return true; +} + $(function () { window.editor = editormd("docEditor", { width : "100%", @@ -7,33 +23,31 @@ $(function () { placeholder: "本编辑器支持Markdown编辑,左边编写,右边预览", imageUpload: true, imageFormats: ["jpg", "jpeg", "gif", "png", "JPG", "JPEG", "GIF", "PNG"], - imageUploadURL: "/upload", + imageUploadURL: window.imageUploadURL , toolbarModes : "full", fileUpload: true, + fileUploadURL : window.fileUploadURL, taskList : true, flowChart : true, htmlDecode : "style,script,iframe,title,onmouseover,onmouseout,style", lineNumbers : false, - fileUploadURL : '/upload', + tocStartLevel : 1, tocm : true, saveHTMLToTextarea : true, onload : function() { this.hideToolbar(); - // this.videoDialog(); - //this.executePlugin("video-dialog","video-dialog/video-dialog"); } }); + editormd.loadPlugin("/static/editor.md/plugins/file-dialog/file-dialog"); - editormd.loadPlugin("/static/editor.md/plugins/video-dialog/video-dialog", function(){ - //editormd.videoDialog(); - }); - + /** + * 实现标题栏操作 + */ $("#editormd-tools").on("click","a[class!='disabled']",function () { var name = $(this).find("i").attr("name"); - if(name === "attachment"){ - + window.editor.fileDialog(); }else if(name === "history"){ }else if(name === "sidebar"){ @@ -67,9 +81,6 @@ $(function () { } cm.replaceSelection(selectionText.join("\n")); } - }else if(name === "video"){ - //插入视频 - window.editor.videoDialog(); }else { var action = window.editor.toolbarHandlers[name]; @@ -79,4 +90,165 @@ $(function () { } } }) ; + + //实现小提示 + $("[data-toggle='tooltip']").hover(function () { + var title = $(this).attr('data-title'); + var direction = $(this).attr("data-direction"); + var tips = 3; + if(direction === "top"){ + tips = 1; + }else if(direction === "right"){ + tips = 2; + }else if(direction === "bottom"){ + tips = 3; + }else if(direction === "left"){ + tips = 4; + } + index = layer.tips(title, this, { + tips: tips + }); + }, function () { + layer.close(index); + }); + + $("#btnAddDocument").on("click",function () { + $("#addDocumentModal").modal("show"); + }); + $("#addDocumentModal").on("show.bs.modal",function () { + window.addDocumentModalFormHtml = $(this).find("form").html(); + }).on("hidden.bs.modal",function () { + $(this).find("form").html(window.addDocumentModalFormHtml); + }); + + function loadDocument($node) { + var index = layer.load(1, { + shade: [0.1,'#fff'] //0.1透明度的白色背景 + }); + + $.get("/docs/"+ window.book.identify +"/" + $node.node.id ).done(function (data) { + win.isEditorChange = true; + layer.close(index); + $("#documentId").val(selected.node.id); + window.editor.clear(); + if(data.errcode === 0 && data.data.doc.content){ + window.editor.insertValue(data.data.doc.content); + window.editor.setCursor({line:0, ch:0}); + }else if(data.errcode !== 0){ + layer.msg("文档加载失败"); + } + }).fail(function () { + layer.close(index); + layer.msg("文档加载失败"); + }); + } + /** + * 添加文档 + */ + $("#addDocumentForm").ajaxForm({ + beforeSubmit : function () { + var doc_name = $.trim($("#documentName").val()); + if (doc_name === ""){ + return showError("目录名称不能为空","#add-error-message") + } + return true; + }, + success : function (res) { + if(res.errcode === 0){ + var data = { "id" : res.data.doc_id,'parent' : res.data.parent_id,"text" : res.data.doc_name}; + + var node = window.treeCatalog.get_node(data.id); + if(node){ + window.treeCatalog.rename_node({"id":data.id},data.text); + }else { + var result = window.treeCatalog.create_node(res.data.parent_id, data, 'last'); + window.treeCatalog.deselect_all(); + window.treeCatalog.select_node(data); + window.editor.clear(); + } + $("#markdown-save").removeClass('change').addClass('disabled'); + $("#addDocumentModal").modal('hide'); + }else{ + showError(res.message,"#add-error-message") + } + }, + error :function () { + + } + }); + + /** + * 文档目录树 + */ + $("#sidebar").jstree({ + 'plugins': ["wholerow", "types", 'dnd', 'contextmenu'], + "types": { + "default": { + "icon": false // 删除默认图标 + } + }, + 'core': { + 'check_callback': true, + "multiple": false, + 'animation': 0, + "data": window.documentCategory + }, + "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); + + 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); + editDocumentDialog(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); + deleteDocumentDialog(node); + } + } + } + } + }).on('loaded.jstree', function () { + window.treeCatalog = $(this).jstree(); + var $select_node_id = window.treeCatalog.get_selected(); + if($select_node_id) { + var $select_node = window.treeCatalog.get_node($select_node_id[0]) + if ($select_node) { + $select_node.node = { + id: $select_node.id + }; + + loadDocument($select_node); + } + } + }); }); \ No newline at end of file diff --git a/uploads/.gitignore b/uploads/.gitignore new file mode 100644 index 00000000..bfa6a22a --- /dev/null +++ b/uploads/.gitignore @@ -0,0 +1 @@ +# Created by .ignore support plugin (hsz.mobi) diff --git a/uploads/201704/b4c17ca29fe7b7f4dec402d7dd7543c6_100.png b/uploads/201704/b4c17ca29fe7b7f4dec402d7dd7543c6_100.png deleted file mode 100644 index 0ed7379eca16b1ef4402122fcdbf3a768b060396..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55132 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 diff --git a/views/document/markdown_edit_template.tpl b/views/document/markdown_edit_template.tpl index a2e9bb1f..6313a36b 100644 --- a/views/document/markdown_edit_template.tpl +++ b/views/document/markdown_edit_template.tpl @@ -6,12 +6,19 @@ 编辑文档 - Powered by MinDoc - + + @@ -61,7 +68,6 @@ - @@ -84,46 +90,65 @@

+
+ + +
+
+
-
+
+
+ +
+
+ + - + - \ No newline at end of file