Merge branch 'master' into hjy-dev
2
.gitignore
vendored
@ -32,3 +32,5 @@ database/mindoc.db
|
||||
/conf/app.conf
|
||||
/vendor
|
||||
/runtime
|
||||
/uploads/*.*
|
||||
!/uploads/.gitkeep
|
||||
|
@ -143,6 +143,11 @@ func RegisterModel() {
|
||||
gob.Register(models.Document{})
|
||||
gob.Register(models.Template{})
|
||||
//migrate.RegisterMigration()
|
||||
err := orm.RunSyncdb("default", false, true)
|
||||
if err != nil {
|
||||
logs.Error("注册Model失败 ->", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterLogger 注册日志
|
||||
|
@ -79,7 +79,7 @@ avatar=/static/images/headimgurl.jpg
|
||||
token_size=12
|
||||
|
||||
#上传文件的后缀,如果不限制后缀可以设置为 *
|
||||
upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif
|
||||
upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif|mp4|webm|avi
|
||||
|
||||
#上传的文件大小限制
|
||||
# - 如果不填写, 则默认1GB,如果希望超过1GB,必须带单位
|
||||
|
@ -106,9 +106,9 @@ func GetDefaultCover() string {
|
||||
return URLForWithCdnImage(web.AppConfig.DefaultString("cover", "/static/images/book.jpg"))
|
||||
}
|
||||
|
||||
// 获取允许的商城文件的类型.
|
||||
// 获取允许的上传文件的类型.
|
||||
func GetUploadFileExt() []string {
|
||||
ext := web.AppConfig.DefaultString("upload_file_ext", "png|jpg|jpeg|gif|txt|doc|docx|pdf")
|
||||
ext := web.AppConfig.DefaultString("upload_file_ext", "png|jpg|jpeg|gif|txt|doc|docx|pdf|mp4")
|
||||
|
||||
temp := strings.Split(ext, "|")
|
||||
|
||||
@ -201,7 +201,7 @@ func GetExportOutputPath() string {
|
||||
return exportOutputPath
|
||||
}
|
||||
|
||||
// 判断是否是允许商城的文件类型.
|
||||
// 判断是否是允许上传的文件类型.
|
||||
func IsAllowUploadFileExt(ext string) bool {
|
||||
|
||||
if strings.HasPrefix(ext, ".") {
|
||||
|
@ -318,6 +318,7 @@ next = next
|
||||
no = no
|
||||
edit_title = Edit Blog
|
||||
private_blog_tips = Private blog, please enter password to access
|
||||
print_text = Enable Printing
|
||||
|
||||
[doc]
|
||||
modify_doc = Modify Document
|
||||
@ -439,6 +440,7 @@ ft_last_editor = Last editor:
|
||||
ft_create_time = Create time:
|
||||
ft_update_time = Update time:
|
||||
view_count = Number of views
|
||||
changetheme = Switch themes
|
||||
|
||||
[project]
|
||||
prj_space_list = Project Space List
|
||||
|
@ -318,6 +318,7 @@ next = 下一篇
|
||||
no = 无
|
||||
edit_title = 编辑文章
|
||||
private_blog_tips = 加密文章,请输入密码访问
|
||||
print_text = 开启打印
|
||||
|
||||
[doc]
|
||||
modify_doc = 修改文档
|
||||
@ -439,6 +440,7 @@ ft_last_editor = 最后编辑:
|
||||
ft_create_time = 创建时间:
|
||||
ft_update_time = 更新时间:
|
||||
view_count = 阅读次数
|
||||
changetheme = 切换主题
|
||||
|
||||
[project]
|
||||
prj_space_list = 项目空间列表
|
||||
|
@ -122,6 +122,7 @@ func (c *BookController) Setting() {
|
||||
if book.PrivateToken != "" {
|
||||
book.PrivateToken = conf.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken)
|
||||
}
|
||||
|
||||
c.Data["Model"] = book
|
||||
|
||||
}
|
||||
@ -153,6 +154,7 @@ func (c *BookController) SaveBook() {
|
||||
isUseFirstDocument := strings.TrimSpace(c.GetString("is_use_first_document")) == "on"
|
||||
autoSave := strings.TrimSpace(c.GetString("auto_save")) == "on"
|
||||
itemId, _ := c.GetInt("itemId")
|
||||
pringState := strings.TrimSpace(c.GetString("print_state")) == "on"
|
||||
|
||||
if strings.Count(description, "") > 500 {
|
||||
c.JsonResult(6004, i18n.Tr(c.Lang, "message.project_desc_tips"))
|
||||
@ -164,7 +166,8 @@ func (c *BookController) SaveBook() {
|
||||
if !models.NewItemsets().Exist(itemId) {
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.project_space_not_exist"))
|
||||
}
|
||||
if editor != EditorMarkdown && editor != EditorCherryMarkdown && editor != EditorHtml && editor != EditorNewHtml {
|
||||
// if editor != EditorMarkdown && editor != EditorCherryMarkdown && editor != EditorHtml && editor != EditorNewHtml {
|
||||
if editor != EditorMarkdown && editor != EditorCherryMarkdown && editor != EditorHtml && editor != EditorNewHtml && editor != EditorFroala {
|
||||
editor = EditorMarkdown
|
||||
}
|
||||
|
||||
@ -210,6 +213,11 @@ func (c *BookController) SaveBook() {
|
||||
} else {
|
||||
book.AutoSave = 0
|
||||
}
|
||||
if pringState {
|
||||
book.PrintSate = 1
|
||||
} else {
|
||||
book.PrintSate = 0
|
||||
}
|
||||
if err := book.Update(); err != nil {
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed"))
|
||||
}
|
||||
@ -455,6 +463,7 @@ func (c *BookController) Create() {
|
||||
description := strings.TrimSpace(c.GetString("description", ""))
|
||||
privatelyOwned, _ := strconv.Atoi(c.GetString("privately_owned"))
|
||||
commentStatus := c.GetString("comment_status")
|
||||
editor := c.GetString("editor")
|
||||
itemId, _ := c.GetInt("itemId")
|
||||
|
||||
if bookName == "" {
|
||||
@ -521,6 +530,7 @@ func (c *BookController) Create() {
|
||||
book.CommentCount = 0
|
||||
book.PrivatelyOwned = privatelyOwned
|
||||
book.CommentStatus = commentStatus
|
||||
|
||||
book.Identify = identify
|
||||
book.DocCount = 0
|
||||
book.MemberId = c.Member.MemberId
|
||||
@ -530,8 +540,7 @@ func (c *BookController) Create() {
|
||||
book.IsDownload = 1
|
||||
book.AutoRelease = 0
|
||||
book.ItemId = itemId
|
||||
|
||||
book.Editor = "markdown"
|
||||
book.Editor = editor
|
||||
book.Theme = "default"
|
||||
|
||||
if err := book.Insert(c.Lang); err != nil {
|
||||
@ -772,6 +781,39 @@ func (c *BookController) Release() {
|
||||
c.JsonResult(0, i18n.Tr(c.Lang, "message.publish_to_queue"))
|
||||
}
|
||||
|
||||
// 更新项目排序
|
||||
func (c *BookController) UpdateBookOrder() {
|
||||
if !c.Member.IsAdministrator() {
|
||||
c.JsonResult(403, "权限不足")
|
||||
return
|
||||
}
|
||||
type Params struct {
|
||||
Ids string `form:"ids"`
|
||||
}
|
||||
var params Params
|
||||
if err := c.ParseForm(¶ms); err != nil {
|
||||
c.JsonResult(6003, "参数错误")
|
||||
return
|
||||
}
|
||||
idArray := strings.Split(params.Ids, ",")
|
||||
orderCount := len(idArray)
|
||||
for _, id := range idArray {
|
||||
bookId, _ := strconv.Atoi(id)
|
||||
orderCount--
|
||||
book, err := models.NewBook().Find(bookId)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
book.BookId = bookId
|
||||
book.OrderIndex = orderCount
|
||||
err = book.Update()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
c.JsonResult(0, "ok")
|
||||
}
|
||||
|
||||
// 文档排序.
|
||||
func (c *BookController) SaveSort() {
|
||||
c.Prepare()
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"image/png"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -36,6 +38,16 @@ type DocumentController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
// Document prev&next
|
||||
type DocumentTreeFlatten struct {
|
||||
DocumentId int `json:"id"`
|
||||
DocumentName string `json:"text"`
|
||||
// ParentId interface{} `json:"parent"`
|
||||
Identify string `json:"identify"`
|
||||
// BookIdentify string `json:"-"`
|
||||
// Version int64 `json:"version"`
|
||||
}
|
||||
|
||||
// 文档首页
|
||||
func (c *DocumentController) Index() {
|
||||
c.Prepare()
|
||||
@ -98,7 +110,6 @@ func (c *DocumentController) Index() {
|
||||
c.Data["IS_DOCUMENT_INDEX"] = true
|
||||
c.Data["Model"] = bookResult
|
||||
c.Data["Result"] = template.HTML(tree)
|
||||
|
||||
}
|
||||
|
||||
// CheckPassword : Handles password verification for private documents,
|
||||
@ -186,6 +197,41 @@ func (c *DocumentController) Read() {
|
||||
doc.AttachList = attach
|
||||
}
|
||||
|
||||
// prev,next
|
||||
treeJson, err := models.NewDocument().FindDocumentTree2(bookResult.BookId)
|
||||
if err != nil {
|
||||
logs.Error("生成项目文档树时出错 ->", err)
|
||||
}
|
||||
|
||||
res := getTreeRecursive(treeJson, 0)
|
||||
flat := make([]DocumentTreeFlatten, 0)
|
||||
Flatten(res, &flat)
|
||||
var index int
|
||||
for i, v := range flat {
|
||||
if v.Identify == id {
|
||||
index = i
|
||||
}
|
||||
}
|
||||
var PrevName, PrevPath, NextName, NextPath string
|
||||
if index == 0 {
|
||||
c.Data["PrevName"] = "没有了"
|
||||
PrevName = "没有了"
|
||||
} else {
|
||||
c.Data["PrevPath"] = identify + "/" + flat[index-1].Identify
|
||||
c.Data["PrevName"] = flat[index-1].DocumentName
|
||||
PrevPath = identify + "/" + flat[index-1].Identify
|
||||
PrevName = flat[index-1].DocumentName
|
||||
}
|
||||
if index == len(flat)-1 {
|
||||
c.Data["NextName"] = "没有了"
|
||||
NextName = "没有了"
|
||||
} else {
|
||||
c.Data["NextPath"] = identify + "/" + flat[index+1].Identify
|
||||
c.Data["NextName"] = flat[index+1].DocumentName
|
||||
NextPath = identify + "/" + flat[index+1].Identify
|
||||
NextName = flat[index+1].DocumentName
|
||||
}
|
||||
|
||||
doc.IncrViewCount(doc.DocumentId)
|
||||
doc.ViewCount = doc.ViewCount + 1
|
||||
doc.PutToCache()
|
||||
@ -205,7 +251,7 @@ func (c *DocumentController) Read() {
|
||||
data.DocId = doc.DocumentId
|
||||
data.DocIdentify = doc.Identify
|
||||
data.DocTitle = doc.DocumentName
|
||||
data.Body = doc.Release
|
||||
data.Body = doc.Release + "<div class='wiki-bottom-left'>上一篇: <a href='/docs/" + PrevPath + "' rel='prev'>" + PrevName + "</a><br />下一篇: <a href='/docs/" + NextPath + "' rel='next'>" + NextName + "</a><br /></div>"
|
||||
data.Title = doc.DocumentName + " - Powered by SSHotRiver"
|
||||
data.Version = doc.Version
|
||||
data.ViewCount = doc.ViewCount
|
||||
@ -229,7 +275,6 @@ func (c *DocumentController) Read() {
|
||||
|
||||
if err != nil && err != orm.ErrNoRows {
|
||||
logs.Error("生成项目文档树时出错 ->", err)
|
||||
|
||||
c.ShowErrorPage(500, i18n.Tr(c.Lang, "message.build_doc_tree_error"))
|
||||
}
|
||||
|
||||
@ -238,7 +283,7 @@ func (c *DocumentController) Read() {
|
||||
c.Data["Model"] = bookResult
|
||||
c.Data["Result"] = template.HTML(tree)
|
||||
c.Data["Title"] = doc.DocumentName
|
||||
c.Data["Content"] = template.HTML(doc.Release)
|
||||
c.Data["Content"] = template.HTML(doc.Release + "<div class='wiki-bottom-left'>上一篇: <a href='/docs/" + PrevPath + "' rel='prev'>" + PrevName + "</a><br />下一篇: <a href='/docs/" + NextPath + "' rel='next'>" + NextName + "</a><br /></div>")
|
||||
c.Data["ViewCount"] = doc.ViewCount
|
||||
c.Data["FoldSetting"] = "closed"
|
||||
if bookResult.Editor == EditorCherryMarkdown {
|
||||
@ -251,6 +296,34 @@ func (c *DocumentController) Read() {
|
||||
}
|
||||
}
|
||||
|
||||
// 递归得到树状结构体
|
||||
func getTreeRecursive(list []*models.DocumentTree, parentId int) (res []*models.DocumentTree) {
|
||||
for _, v := range list {
|
||||
if v.ParentId == parentId {
|
||||
v.Children = getTreeRecursive(list, v.DocumentId)
|
||||
res = append(res, v)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// 递归将树状结构体转换为扁平结构体数组
|
||||
// func Flatten(list []*models.DocumentTree, flattened *[]DocumentTreeFlatten) (flatten *[]DocumentTreeFlatten) {
|
||||
func Flatten(list []*models.DocumentTree, flattened *[]DocumentTreeFlatten) {
|
||||
// Treeslice := make([]*DocumentTreeFlatten, 0)
|
||||
for _, v := range list {
|
||||
tree := make([]DocumentTreeFlatten, 1)
|
||||
tree[0].DocumentId = v.DocumentId
|
||||
tree[0].DocumentName = v.DocumentName
|
||||
tree[0].Identify = v.Identify
|
||||
*flattened = append(*flattened, tree...)
|
||||
if len(v.Children) > 0 {
|
||||
Flatten(v.Children, flattened)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 编辑文档
|
||||
func (c *DocumentController) Edit() {
|
||||
c.Prepare()
|
||||
@ -414,158 +487,190 @@ func (c *DocumentController) Upload() {
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.param_error"))
|
||||
}
|
||||
|
||||
name := "editormd-file-file"
|
||||
|
||||
file, moreFile, err := c.GetFile(name)
|
||||
if err == http.ErrMissingFile || moreFile == nil {
|
||||
name = "editormd-image-file"
|
||||
file, moreFile, err = c.GetFile(name)
|
||||
if err == http.ErrMissingFile || moreFile == nil {
|
||||
c.JsonResult(6003, i18n.Tr(c.Lang, "message.upload_file_empty"))
|
||||
return
|
||||
names := []string{"editormd-file-file", "editormd-image-file", "file", "editormd-resource-file"}
|
||||
var files []*multipart.FileHeader
|
||||
for _, name := range names {
|
||||
file, err := c.GetFiles(name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if len(file) > 0 && err == nil {
|
||||
files = append(files, file...)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(6002, err.Error())
|
||||
if len(files) == 0 {
|
||||
c.JsonResult(6003, i18n.Tr(c.Lang, "message.upload_file_empty"))
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
result2 := []map[string]interface{}{}
|
||||
var result map[string]interface{}
|
||||
for i, _ := range files {
|
||||
//for each fileheader, get a handle to the actual file
|
||||
file, err := files[i].Open()
|
||||
|
||||
type Size interface {
|
||||
Size() int64
|
||||
}
|
||||
|
||||
if conf.GetUploadFileSize() > 0 && moreFile.Size > conf.GetUploadFileSize() {
|
||||
c.JsonResult(6009, i18n.Tr(c.Lang, "message.upload_file_size_limit"))
|
||||
}
|
||||
|
||||
ext := filepath.Ext(moreFile.Filename)
|
||||
//文件必须带有后缀名
|
||||
if ext == "" {
|
||||
c.JsonResult(6003, i18n.Tr(c.Lang, "message.upload_file_type_error"))
|
||||
}
|
||||
//如果文件类型设置为 * 标识不限制文件类型
|
||||
if conf.IsAllowUploadFileExt(ext) == false {
|
||||
c.JsonResult(6004, i18n.Tr(c.Lang, "message.upload_file_type_error"))
|
||||
}
|
||||
|
||||
bookId := 0
|
||||
|
||||
// 如果是超级管理员,则不判断权限
|
||||
if c.Member.IsAdministrator() {
|
||||
book, err := models.NewBook().FindByFieldFirst("identify", identify)
|
||||
defer file.Close()
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.doc_not_exist_or_no_permit"))
|
||||
c.JsonResult(6002, err.Error())
|
||||
}
|
||||
|
||||
bookId = book.BookId
|
||||
} else {
|
||||
book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
|
||||
// defer file.Close()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("DocumentController.Edit => ", err)
|
||||
if err == orm.ErrNoRows {
|
||||
type Size interface {
|
||||
Size() int64
|
||||
}
|
||||
|
||||
// if conf.GetUploadFileSize() > 0 && moreFile.Size > conf.GetUploadFileSize() {
|
||||
if conf.GetUploadFileSize() > 0 && files[i].Size > conf.GetUploadFileSize() {
|
||||
c.JsonResult(6009, i18n.Tr(c.Lang, "message.upload_file_size_limit"))
|
||||
}
|
||||
|
||||
// ext := filepath.Ext(moreFile.Filename)
|
||||
ext := filepath.Ext(files[i].Filename)
|
||||
//文件必须带有后缀名
|
||||
if ext == "" {
|
||||
c.JsonResult(6003, i18n.Tr(c.Lang, "message.upload_file_type_error"))
|
||||
}
|
||||
//如果文件类型设置为 * 标识不限制文件类型
|
||||
if conf.IsAllowUploadFileExt(ext) == false {
|
||||
c.JsonResult(6004, i18n.Tr(c.Lang, "message.upload_file_type_error"))
|
||||
}
|
||||
|
||||
bookId := 0
|
||||
|
||||
// 如果是超级管理员,则不判断权限
|
||||
if c.Member.IsAdministrator() {
|
||||
book, err := models.NewBook().FindByFieldFirst("identify", identify)
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.doc_not_exist_or_no_permit"))
|
||||
}
|
||||
|
||||
bookId = book.BookId
|
||||
} else {
|
||||
book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("DocumentController.Edit => ", err)
|
||||
if err == orm.ErrNoRows {
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.no_permission"))
|
||||
}
|
||||
|
||||
c.JsonResult(6001, err.Error())
|
||||
}
|
||||
|
||||
// 如果没有编辑权限
|
||||
if book.RoleId != conf.BookEditor && book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder {
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.no_permission"))
|
||||
}
|
||||
|
||||
c.JsonResult(6001, err.Error())
|
||||
bookId = book.BookId
|
||||
}
|
||||
|
||||
// 如果没有编辑权限
|
||||
if book.RoleId != conf.BookEditor && book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder {
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.no_permission"))
|
||||
if docId > 0 {
|
||||
doc, err := models.NewDocument().Find(docId)
|
||||
if err != nil {
|
||||
c.JsonResult(6007, i18n.Tr(c.Lang, "message.doc_not_exist"))
|
||||
}
|
||||
|
||||
if doc.BookId != bookId {
|
||||
c.JsonResult(6008, i18n.Tr(c.Lang, "message.doc_not_belong_project"))
|
||||
}
|
||||
}
|
||||
|
||||
bookId = book.BookId
|
||||
}
|
||||
fileName := "m_" + cryptil.UniqueId() + "_r"
|
||||
filePath := filepath.Join(conf.WorkingDirectory, "uploads", identify)
|
||||
|
||||
if docId > 0 {
|
||||
doc, err := models.NewDocument().Find(docId)
|
||||
if err != nil {
|
||||
c.JsonResult(6007, i18n.Tr(c.Lang, "message.doc_not_exist"))
|
||||
//将图片和文件分开存放
|
||||
attachment := models.NewAttachment()
|
||||
var strategy filetil.FileTypeStrategy
|
||||
if filetil.IsImageExt(files[i].Filename) {
|
||||
strategy = filetil.ImageStrategy{}
|
||||
attachment.ResourceType = "image"
|
||||
} else if filetil.IsVideoExt(files[i].Filename) {
|
||||
strategy = filetil.VideoStrategy{}
|
||||
attachment.ResourceType = "video"
|
||||
} else {
|
||||
strategy = filetil.DefaultStrategy{}
|
||||
attachment.ResourceType = "file"
|
||||
}
|
||||
|
||||
if doc.BookId != bookId {
|
||||
c.JsonResult(6008, i18n.Tr(c.Lang, "message.doc_not_belong_project"))
|
||||
}
|
||||
}
|
||||
filePath = strategy.GetFilePath(filePath, fileName, ext)
|
||||
|
||||
fileName := "m_" + cryptil.UniqueId() + "_r"
|
||||
filePath := filepath.Join(conf.WorkingDirectory, "uploads", identify)
|
||||
path := filepath.Dir(filePath)
|
||||
|
||||
//将图片和文件分开存放
|
||||
if filetil.IsImageExt(moreFile.Filename) {
|
||||
filePath = filepath.Join(filePath, "images", fileName+ext)
|
||||
} else {
|
||||
filePath = filepath.Join(filePath, "files", fileName+ext)
|
||||
}
|
||||
_ = os.MkdirAll(path, os.ModePerm)
|
||||
|
||||
path := filepath.Dir(filePath)
|
||||
|
||||
_ = os.MkdirAll(path, os.ModePerm)
|
||||
|
||||
err = c.SaveToFile(name, filePath)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("保存文件失败 -> ", err)
|
||||
c.JsonResult(6005, i18n.Tr(c.Lang, "message.failed"))
|
||||
}
|
||||
|
||||
attachment := models.NewAttachment()
|
||||
attachment.BookId = bookId
|
||||
attachment.FileName = moreFile.Filename
|
||||
attachment.CreateAt = c.Member.MemberId
|
||||
attachment.FileExt = ext
|
||||
attachment.FilePath = strings.TrimPrefix(filePath, conf.WorkingDirectory)
|
||||
attachment.DocumentId = docId
|
||||
|
||||
if fileInfo, err := os.Stat(filePath); err == nil {
|
||||
attachment.FileSize = float64(fileInfo.Size())
|
||||
}
|
||||
|
||||
if docId > 0 {
|
||||
attachment.DocumentId = docId
|
||||
}
|
||||
|
||||
if filetil.IsImageExt(moreFile.Filename) {
|
||||
attachment.HttpPath = "/" + strings.Replace(strings.TrimPrefix(filePath, conf.WorkingDirectory), "\\", "/", -1)
|
||||
if strings.HasPrefix(attachment.HttpPath, "//") {
|
||||
attachment.HttpPath = conf.URLForWithCdnImage(string(attachment.HttpPath[1:]))
|
||||
}
|
||||
|
||||
isAttach = false
|
||||
}
|
||||
|
||||
err = attachment.Insert()
|
||||
|
||||
if err != nil {
|
||||
os.Remove(filePath)
|
||||
logs.Error("文件保存失败 ->", err)
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed"))
|
||||
}
|
||||
|
||||
if attachment.HttpPath == "" {
|
||||
attachment.HttpPath = conf.URLForNotHost("DocumentController.DownloadAttachment", ":key", identify, ":attach_id", attachment.AttachmentId)
|
||||
|
||||
if err := attachment.Update(); err != nil {
|
||||
logs.Error("保存文件失败 ->", err)
|
||||
//copy the uploaded file to the destination file
|
||||
dst, err := os.Create(filePath)
|
||||
defer dst.Close()
|
||||
if _, err := io.Copy(dst, file); err != nil {
|
||||
logs.Error("保存文件失败 -> ", err)
|
||||
c.JsonResult(6005, i18n.Tr(c.Lang, "message.failed"))
|
||||
}
|
||||
}
|
||||
|
||||
result := map[string]interface{}{
|
||||
"errcode": 0,
|
||||
"success": 1,
|
||||
"message": "ok",
|
||||
"url": attachment.HttpPath,
|
||||
"alt": attachment.FileName,
|
||||
"is_attach": isAttach,
|
||||
"attach": attachment,
|
||||
}
|
||||
attachment.BookId = bookId
|
||||
// attachment.FileName = moreFile.Filename
|
||||
attachment.FileName = files[i].Filename
|
||||
attachment.CreateAt = c.Member.MemberId
|
||||
attachment.FileExt = ext
|
||||
attachment.FilePath = strings.TrimPrefix(filePath, conf.WorkingDirectory)
|
||||
attachment.DocumentId = docId
|
||||
|
||||
c.Ctx.Output.JSON(result, true, false)
|
||||
if fileInfo, err := os.Stat(filePath); err == nil {
|
||||
attachment.FileSize = float64(fileInfo.Size())
|
||||
}
|
||||
|
||||
if docId > 0 {
|
||||
attachment.DocumentId = docId
|
||||
}
|
||||
|
||||
if filetil.IsImageExt(files[i].Filename) || filetil.IsVideoExt(files[i].Filename) {
|
||||
attachment.HttpPath = "/" + strings.Replace(strings.TrimPrefix(filePath, conf.WorkingDirectory), "\\", "/", -1)
|
||||
if strings.HasPrefix(attachment.HttpPath, "//") {
|
||||
attachment.HttpPath = conf.URLForWithCdnImage(string(attachment.HttpPath[1:]))
|
||||
}
|
||||
|
||||
isAttach = false
|
||||
}
|
||||
|
||||
err = attachment.Insert()
|
||||
|
||||
if err != nil {
|
||||
os.Remove(filePath)
|
||||
logs.Error("文件保存失败 ->", err)
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed"))
|
||||
}
|
||||
|
||||
if attachment.HttpPath == "" {
|
||||
attachment.HttpPath = conf.URLForNotHost("DocumentController.DownloadAttachment", ":key", identify, ":attach_id", attachment.AttachmentId)
|
||||
|
||||
if err := attachment.Update(); err != nil {
|
||||
logs.Error("保存文件失败 ->", err)
|
||||
c.JsonResult(6005, i18n.Tr(c.Lang, "message.failed"))
|
||||
}
|
||||
}
|
||||
result = map[string]interface{}{
|
||||
"errcode": 0,
|
||||
"success": 1,
|
||||
"message": "ok",
|
||||
"url": attachment.HttpPath,
|
||||
"link": attachment.HttpPath,
|
||||
"alt": attachment.FileName,
|
||||
"is_attach": isAttach,
|
||||
"attach": attachment,
|
||||
"resource_type": attachment.ResourceType,
|
||||
}
|
||||
result2 = append(result2, result)
|
||||
}
|
||||
if len(files) == 1 {
|
||||
// froala单文件上传
|
||||
c.Ctx.Output.JSON(result, true, false)
|
||||
} else {
|
||||
c.Ctx.Output.JSON(result2, true, false)
|
||||
}
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
@ -868,6 +973,7 @@ func (c *DocumentController) Export() {
|
||||
c.Prepare()
|
||||
|
||||
identify := c.Ctx.Input.Param(":key")
|
||||
|
||||
if identify == "" {
|
||||
c.ShowErrorPage(500, i18n.Tr(c.Lang, "message.param_error"))
|
||||
}
|
||||
@ -906,7 +1012,6 @@ func (c *DocumentController) Export() {
|
||||
if !strings.HasPrefix(bookResult.Cover, "http:://") && !strings.HasPrefix(bookResult.Cover, "https:://") {
|
||||
bookResult.Cover = conf.URLForWithCdnImage(bookResult.Cover)
|
||||
}
|
||||
|
||||
if output == Markdown {
|
||||
if bookResult.Editor != EditorMarkdown && bookResult.Editor != EditorCherryMarkdown {
|
||||
c.ShowErrorPage(500, i18n.Tr(c.Lang, "message.cur_project_not_support_md"))
|
||||
|
@ -6,4 +6,5 @@ const (
|
||||
EditorCherryMarkdown = "cherry_markdown"
|
||||
EditorHtml = "html"
|
||||
EditorNewHtml = "new_html"
|
||||
EditorFroala = "froala"
|
||||
)
|
||||
|
28
go.mod
@ -13,7 +13,7 @@ require (
|
||||
github.com/lib/pq v1.10.5
|
||||
github.com/lifei6671/gocaptcha v0.2.0
|
||||
github.com/mattn/go-runewidth v0.0.13
|
||||
github.com/mattn/go-sqlite3 v1.14.15
|
||||
github.com/mattn/go-sqlite3 v1.14.17
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/russross/blackfriday/v2 v2.1.0
|
||||
)
|
||||
@ -22,18 +22,33 @@ require (
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
|
||||
github.com/Unknwon/goconfig v1.0.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/astaxie/beego v1.12.1 // indirect
|
||||
github.com/beego/bee v1.12.3 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cosiner/argv v0.1.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/gadelkareem/delve v1.4.2-0.20200619175259-dcd01330766f // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-redis/redis/v7 v7.4.1 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
|
||||
github.com/magiconair/properties v1.8.1 // indirect
|
||||
github.com/mattn/go-colorable v0.0.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.3 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.2 // indirect
|
||||
github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.13.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
@ -41,13 +56,24 @@ require (
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/rivo/uniseg v0.3.4 // indirect
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
|
||||
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||
github.com/smartwalle/pongo2render v1.0.1 // indirect
|
||||
github.com/smartystreets/goconvey v1.7.2 // indirect
|
||||
github.com/spf13/afero v1.1.2 // indirect
|
||||
github.com/spf13/cast v1.3.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.0.0 // indirect
|
||||
github.com/spf13/pflag v1.0.3 // indirect
|
||||
github.com/spf13/viper v1.7.0 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
go.starlark.net v0.0.0-20190702223751-32f345186213 // indirect
|
||||
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect
|
||||
golang.org/x/image v0.5.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.51.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
182
go.sum
@ -21,6 +21,7 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
@ -35,6 +36,9 @@ github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e h1:NeAW1fUYUEWhft
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OwnLocal/goes v1.0.0/go.mod h1:8rIFjBGTue3lCU0wplczcUgt9Gxgrkkrw7etMIcn8TM=
|
||||
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||
github.com/Unknwon/goconfig v1.0.0 h1:9IAu/BYbSLQi8puFjUQApZTxIHqSwrj5d8vpP8vTq4A=
|
||||
@ -46,19 +50,33 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/astaxie/beego v1.12.1 h1:dfpuoxpzLVgclveAXe4PyNKqkzgm5zF4tgF2B3kkM2I=
|
||||
github.com/astaxie/beego v1.12.1/go.mod h1:kPBWpSANNbSdIqOc8SUL9h+1oyBMZhROeYsXQDbidWQ=
|
||||
github.com/beego/bee v1.12.3 h1:9gCJRAhSWtUasJsX4p3BXH9QQf7MS09PdYP3xE6iD5Q=
|
||||
github.com/beego/bee v1.12.3/go.mod h1:WNn8+mpl0sbRgP3JKh6wJG3pSCpEQ8hoDMZFBb0n/Ps=
|
||||
github.com/beego/beego/v2 v2.0.5 h1:fa2TBWfKGDs35Ck9an9SVnpS0zM8sRTXlW8rFjpeYlE=
|
||||
github.com/beego/beego/v2 v2.0.5/go.mod h1:CH2/JIaB4ceGYVQlYqTAFft4pVk/ol1ZkakUrUvAyns=
|
||||
github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
|
||||
github.com/beego/i18n v0.0.0-20161101132742-e9308947f407 h1:WtJfx5HqASTQp7HfiZldnin8KQV2futplF3duGp5PGc=
|
||||
github.com/beego/i18n v0.0.0-20161101132742-e9308947f407/go.mod h1:KLeFCpAMq2+50NkXC8iiJxLLiiTfTqrGtKEVm+2fk7s=
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@ -66,18 +84,46 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cosiner/argv v0.1.0 h1:BVDiEL32lwHukgJKP87btEPenzrrHUjajs/8yzaqcXg=
|
||||
github.com/cosiner/argv v0.1.0/go.mod h1:EusR6TucWKX+zFgtdUsKT2Cvg45K5rtpCcWz4hK06d8=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
|
||||
github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
|
||||
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
||||
github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915 h1:rNVrewdFbSujcoKZifC6cHJfqCTbCIR7XTLHW5TqUWU=
|
||||
github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915/go.mod h1:fB4mx6dzqFinCxIf3a7Mf5yLk+18Bia9mPAnuejcvDA=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gadelkareem/delve v1.4.2-0.20200619175259-dcd01330766f h1:SXR+MNQLeyoKOHwKziU6RU8wKEaGTNhL9rkHRuKND3A=
|
||||
github.com/gadelkareem/delve v1.4.2-0.20200619175259-dcd01330766f/go.mod h1:yRnaIw9CedrRtnrIhNVh1JLOz0cjEUWOEM5FaWEMOV0=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@ -91,15 +137,20 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI=
|
||||
github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -127,6 +178,7 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@ -141,6 +193,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-dap v0.2.0/go.mod h1:5q8aYQFnHOAZEMP+6vmq25HKYAEwE+LF5yh7JKrrhSQ=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@ -156,15 +209,41 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/howeyc/fsnotify v0.9.0 h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY=
|
||||
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
@ -174,12 +253,18 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
||||
github.com/juju/errors v0.0.0-20190930114154-d42613fe1ab9/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
||||
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kardianos/service v1.2.1 h1:AYndMsehS+ywIS6RB9KOlcXzteWUzxgMgBymJD7+BYk=
|
||||
github.com/kardianos/service v1.2.1/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
@ -187,16 +272,35 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=
|
||||
github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lifei6671/gocaptcha v0.2.0 h1:CwMjGitq5MsYtWODQhlphdl7WhDdD243y1O2d3l8yFU=
|
||||
github.com/lifei6671/gocaptcha v0.2.0/go.mod h1:mcUWn1eB+kHOBHLQdmWAQ83bhEGrFTnGMqRCY7sFgUc=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.0.0-20170327083344-ded68f7a9561/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
||||
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -208,18 +312,27 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.9.2 h1:7NiByeVF4jKSG1lDF3X8LTIkq2/bu+1uYbIm1eS5tzk=
|
||||
github.com/pelletier/go-toml v1.9.2/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b h1:8uaXtUkxiy+T/zdLWuxa/PG4so0TPZDZfafFNNSaptE=
|
||||
github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
@ -231,6 +344,8 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
@ -238,27 +353,56 @@ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+
|
||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
|
||||
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartwalle/pongo2render v1.0.1 h1:rsPnDTu/+zIT5HEB5RbMjxKY5hisov26j0isZL/7YS0=
|
||||
github.com/smartwalle/pongo2render v1.0.1/go.mod h1:MGnTzND7nEMz7g194kjlnw8lx/V5JJlb1hr5kDXEO0I=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
||||
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
|
||||
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.0-20170417170307-b6cb39589372/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v0.0.0-20170417173400-9e4c21054fa1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@ -266,16 +410,31 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.starlark.net v0.0.0-20190702223751-32f345186213 h1:lkYv5AKwvvduv5XWP6szk/bvvgO6aDeUujhZQXIFTes=
|
||||
go.starlark.net v0.0.0-20190702223751-32f345186213/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 h1:QlVATYS7JBoZMVaf+cNjb90WD/beKVHnIxFKT4QaHVI=
|
||||
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -321,7 +480,10 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@ -374,9 +536,12 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -386,8 +551,10 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -433,7 +600,9 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
@ -449,13 +618,16 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191127201027-ecd32218bd7f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
@ -564,8 +736,13 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@ -583,5 +760,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
@ -1,4 +1,4 @@
|
||||
//数据库模型.
|
||||
// 数据库模型.
|
||||
package models
|
||||
|
||||
import (
|
||||
@ -12,8 +12,15 @@ import (
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/mindoc-org/mindoc/conf"
|
||||
"github.com/mindoc-org/mindoc/utils/filetil"
|
||||
// "gorm.io/driver/sqlite"
|
||||
// "gorm.io/gorm"
|
||||
// "gorm.io/gorm/logger"
|
||||
// "gorm.io/gorm/schema"
|
||||
)
|
||||
|
||||
// 定义全局的db对象,我们执行数据库操作主要通过他实现。
|
||||
// var _db *gorm.DB
|
||||
|
||||
// Attachment struct .
|
||||
type Attachment struct {
|
||||
AttachmentId int `orm:"column(attachment_id);pk;auto;unique" json:"attachment_id"`
|
||||
@ -26,6 +33,7 @@ type Attachment struct {
|
||||
FileExt string `orm:"column(file_ext);size(50);description(文件后缀)" json:"file_ext"`
|
||||
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add;description(创建时间)" json:"create_time"`
|
||||
CreateAt int `orm:"column(create_at);type(int);description(创建人id)" json:"create_at"`
|
||||
ResourceType string `orm:"-" json:"resource_type"`
|
||||
}
|
||||
|
||||
// TableName 获取对应上传附件数据库表名.
|
||||
@ -83,7 +91,7 @@ func (m *Attachment) Find(id int) (*Attachment, error) {
|
||||
return m, err
|
||||
}
|
||||
|
||||
//查询指定文档的附件列表
|
||||
// 查询指定文档的附件列表
|
||||
func (m *Attachment) FindListByDocumentId(docId int) (attaches []*Attachment, err error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
@ -91,7 +99,7 @@ func (m *Attachment) FindListByDocumentId(docId int) (attaches []*Attachment, er
|
||||
return
|
||||
}
|
||||
|
||||
//分页查询附件
|
||||
// 分页查询附件
|
||||
func (m *Attachment) FindToPager(pageIndex, pageSize int) (attachList []*AttachmentResult, totalCount int, err error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
|
@ -82,7 +82,8 @@ type Book struct {
|
||||
//是否使用第一篇文章项目为默认首页,0 否/1 是
|
||||
IsUseFirstDocument int `orm:"column(is_use_first_document);type(int);default(0);description(是否使用第一篇文章项目为默认首页,0 否/1 是)" json:"is_use_first_document"`
|
||||
//是否开启自动保存:0 否/1 是
|
||||
AutoSave int `orm:"column(auto_save);type(tinyint);default(0);description(是否开启自动保存:0 否/1 是)" json:"auto_save"`
|
||||
AutoSave int `orm:"column(auto_save);type(tinyint);default(0);description(是否开启自动保存:0 否/1 是)" json:"auto_save"`
|
||||
PrintSate int `orm:"column(print_state);type(tinyint);default(1);description(启用打印:0 否/1 是)" json:"print_state"`
|
||||
}
|
||||
|
||||
func (book *Book) String() string {
|
||||
|
@ -71,6 +71,7 @@ type BookResult struct {
|
||||
IsDisplayComment bool `json:"is_display_comment"`
|
||||
IsDownload bool `json:"is_download"`
|
||||
AutoSave bool `json:"auto_save"`
|
||||
PrintState bool `json:"print_state"`
|
||||
Lang string
|
||||
}
|
||||
|
||||
@ -213,6 +214,7 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
|
||||
m.HistoryCount = book.HistoryCount
|
||||
m.IsDownload = book.IsDownload == 0
|
||||
m.AutoSave = book.AutoSave == 1
|
||||
m.PrintState = book.PrintSate == 1
|
||||
m.ItemId = book.ItemId
|
||||
m.RoleId = conf.BookRoleNoSpecific
|
||||
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/mindoc-org/mindoc/conf"
|
||||
// "gorm.io/driver/sqlite"
|
||||
// "gorm.io/gorm"
|
||||
)
|
||||
|
||||
type DocumentTree struct {
|
||||
@ -19,14 +21,24 @@ type DocumentTree struct {
|
||||
Version int64 `json:"version"`
|
||||
State *DocumentSelected `json:"-"`
|
||||
AAttrs map[string]interface{} `json:"a_attr"`
|
||||
Children []*DocumentTree `json:"children"`
|
||||
}
|
||||
|
||||
// type DocumentTreeJson struct {
|
||||
// gorm.Model
|
||||
// DocumentId int `json:"id"`
|
||||
// DocumentName string `json:"text"`
|
||||
// ParentId interface{} `json:"parent"`
|
||||
// Children []*DocumentTreeJson `json:"children" gorm:"-"`
|
||||
// }
|
||||
|
||||
type DocumentSelected struct {
|
||||
Selected bool `json:"selected"`
|
||||
Opened bool `json:"opened"`
|
||||
Disabled bool `json:"disabled"`
|
||||
}
|
||||
|
||||
//获取项目的文档树状结构
|
||||
// 获取项目的文档树状结构
|
||||
func (item *Document) FindDocumentTree(bookId int) ([]*DocumentTree, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
@ -79,6 +91,59 @@ func (item *Document) FindDocumentTree(bookId int) ([]*DocumentTree, error) {
|
||||
return trees, nil
|
||||
}
|
||||
|
||||
// 获取项目的文档树状结构2
|
||||
func (item *Document) FindDocumentTree2(bookId int) ([]*DocumentTree, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
trees := make([]*DocumentTree, 0)
|
||||
|
||||
var docs []*Document
|
||||
|
||||
count, err := o.QueryTable(item).Filter("book_id", bookId).
|
||||
OrderBy("order_sort", "document_id").
|
||||
Limit(math.MaxInt32).
|
||||
All(&docs, "document_id", "version", "document_name", "parent_id", "identify", "is_open")
|
||||
|
||||
if err != nil {
|
||||
return trees, err
|
||||
}
|
||||
book, _ := NewBook().Find(bookId)
|
||||
|
||||
trees = make([]*DocumentTree, count)
|
||||
|
||||
for index, item := range docs {
|
||||
tree := &DocumentTree{
|
||||
AAttrs: map[string]interface{}{"is_open": false, "opened": 0},
|
||||
}
|
||||
if index == 0 {
|
||||
tree.State = &DocumentSelected{Selected: true, Opened: true}
|
||||
tree.AAttrs = map[string]interface{}{"is_open": true, "opened": 1}
|
||||
} else if item.IsOpen == 1 {
|
||||
tree.State = &DocumentSelected{Selected: false, Opened: true}
|
||||
tree.AAttrs = map[string]interface{}{"is_open": true, "opened": 1}
|
||||
}
|
||||
if item.IsOpen == 2 {
|
||||
tree.State = &DocumentSelected{Selected: false, Opened: false, Disabled: true}
|
||||
tree.AAttrs = map[string]interface{}{"disabled": true, "opened": 2}
|
||||
}
|
||||
tree.DocumentId = item.DocumentId
|
||||
tree.Identify = item.Identify
|
||||
tree.Version = item.Version
|
||||
tree.BookIdentify = book.Identify
|
||||
// if item.ParentId > 0 {
|
||||
tree.ParentId = item.ParentId
|
||||
// } else {
|
||||
// tree.ParentId = "#"
|
||||
// }
|
||||
|
||||
tree.DocumentName = item.DocumentName
|
||||
|
||||
trees[index] = tree
|
||||
}
|
||||
|
||||
return trees, nil
|
||||
}
|
||||
|
||||
func (item *Document) CreateDocumentTreeForHtml(bookId, selectedId int) (string, error) {
|
||||
trees, err := item.FindDocumentTree(bookId)
|
||||
if err != nil {
|
||||
@ -94,7 +159,7 @@ func (item *Document) CreateDocumentTreeForHtml(bookId, selectedId int) (string,
|
||||
|
||||
}
|
||||
|
||||
//使用递归的方式获取指定ID的顶级ID
|
||||
// 使用递归的方式获取指定ID的顶级ID
|
||||
func getSelectedNode(array []*DocumentTree, parent_id int) int {
|
||||
|
||||
for _, item := range array {
|
||||
@ -108,7 +173,7 @@ func getSelectedNode(array []*DocumentTree, parent_id int) int {
|
||||
}
|
||||
|
||||
func getDocumentTree(array []*DocumentTree, parentId int, selectedId int, selectedParentId int, buf *bytes.Buffer) {
|
||||
buf.WriteString("<ul>")
|
||||
buf.WriteString("<ul style='display:none;'>")
|
||||
|
||||
for _, item := range array {
|
||||
pid := 0
|
||||
|
@ -193,6 +193,7 @@ func init() {
|
||||
web.Router("/book/:key/release", &controllers.BookController{}, "post:Release")
|
||||
web.Router("/book/:key/sort", &controllers.BookController{}, "post:SaveSort")
|
||||
web.Router("/book/:key/teams", &controllers.BookController{}, "*:Team")
|
||||
web.Router("/book/updatebookorder", &controllers.BookController{}, "post:UpdateBookOrder")
|
||||
|
||||
web.Router("/book/create", &controllers.BookController{}, "*:Create")
|
||||
web.Router("/book/itemsets/search", &controllers.BookController{}, "*:ItemsetsSearch")
|
||||
|
@ -2656,7 +2656,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
.cherry[data-toolbar-theme=dark] .cherry-insert-table-menu-item.active {
|
||||
background-color: #d7e6fe;
|
||||
background-color: #4b4b4b;
|
||||
}
|
||||
|
||||
.cherry-dropdown {
|
||||
@ -2692,17 +2692,18 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-dropdown {
|
||||
background: #20304b;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item {
|
||||
background: transparent;
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #fff;
|
||||
background: #e4e4e4;
|
||||
color: #0a001f;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
.cherry-toolbar {
|
||||
@ -2710,7 +2711,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
height: 48px;
|
||||
height: 34px;
|
||||
font-size: 16px;
|
||||
line-height: 2.3;
|
||||
flex-basis: 100%;
|
||||
@ -2720,6 +2721,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
box-shadow: 0 0 10px rgba(128, 145, 165, 0.2);
|
||||
background: white;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cherry-toolbar .icon-loading.loading {
|
||||
@ -2742,25 +2744,25 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-toolbar {
|
||||
background: #20304b;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 0 10px rgba(128, 145, 165, 0.2);
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button:hover {
|
||||
color: #fff;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #0a001f;
|
||||
transition: all .3s;
|
||||
background: #e4e4e4;
|
||||
}
|
||||
|
||||
.cherry-toolbar .toolbar-left,
|
||||
.cherry-toolbar .toolbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@ -2935,12 +2937,12 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-bubble {
|
||||
border-color: #20304b;
|
||||
background: #20304b;
|
||||
border-color: #ffffff;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
@ -2950,15 +2952,15 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-bubble .cherry-bubble-top {
|
||||
border-bottom-color: #20304b;
|
||||
border-bottom-color: #ffffff;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-bubble .cherry-bubble-bottom {
|
||||
border-top-color: #20304b;
|
||||
border-top-color: #ffffff;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button:hover {
|
||||
border-color: #20304b;
|
||||
border-color: #ffffff;
|
||||
}
|
||||
|
||||
.cherry-switch-paste .switch-btn--bg {
|
||||
@ -3012,7 +3014,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-switch-paste[data-type=text] .cherry-text-btn {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-switch-paste[data-type=text] .cherry-md-btn {
|
||||
@ -3020,7 +3022,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-switch-paste[data-type=md] .cherry-md-btn {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-switch-paste[data-type=md] .cherry-text-btn {
|
||||
@ -3192,7 +3194,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
.cherry-editor .cm-s-default .cm-url {
|
||||
background: #d7e6fe;
|
||||
background: #4b4b4b;
|
||||
font-family: "Menlo", "Liberation Mono", "Consolas", "DejaVu Sans Mono", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
@ -3347,7 +3349,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
[data-toolbar-theme=dark] .cherry-color-wrap h3 {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
.cherry-color-wrap .cherry-color-text {
|
||||
@ -3522,7 +3524,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
.cherry.theme__dark .cherry-floatmenu .cherry-toolbar-button,
|
||||
.cherry.theme__dark .cherry-bubble .cherry-toolbar-button,
|
||||
.cherry.theme__dark .cherry-sidebar .cherry-toolbar-button {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button:hover,
|
||||
@ -3547,7 +3549,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
.cherry.theme__dark .cherry-dropdown .cherry-dropdown-item {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
.cherry.theme__dark .cherry-dropdown .cherry-dropdown-item:hover {
|
||||
@ -3561,7 +3563,7 @@ div[data-type=codeBlock] .token.inserted {
|
||||
}
|
||||
|
||||
.cherry.theme__dark .cherry-dropdown.cherry-color-wrap h3 {
|
||||
color: #d7e6fe;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
.cherry.theme__dark .cherry-dropdown.cherry-color-wrap .cherry-color-item {
|
||||
|
@ -21811,7 +21811,7 @@
|
||||
function handleUpload(editor) {
|
||||
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'image';
|
||||
var accept = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '*';
|
||||
var callback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
||||
// var callback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
||||
// type为上传文件类型 image|video|audio|pdf|word
|
||||
var input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
@ -21819,14 +21819,18 @@
|
||||
input.value = '';
|
||||
input.style.display = 'none';
|
||||
input.accept = accept; // document.body.appendChild(input);
|
||||
input.multiple = 'multiple';
|
||||
|
||||
input.addEventListener('change', function (event) {
|
||||
// @ts-ignore
|
||||
var _event$target$files = _slicedToArray(event.target.files, 1),
|
||||
file = _event$target$files[0]; // 文件上传后的回调函数可以由调用方自己实现
|
||||
|
||||
|
||||
// var _event$target$files = _slicedToArray(event.target.files, 1),
|
||||
// file = _event$target$files[0]; // 文件上传后的回调函数可以由调用方自己实现
|
||||
// 3xxx 20240607
|
||||
let files = event.target.files;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
var file = files[i]
|
||||
editor.options.fileUpload(file, function (url) {
|
||||
var callback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
||||
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
// 文件上传的默认回调行数,调用方可以完全不使用该函数
|
||||
@ -21866,6 +21870,7 @@
|
||||
|
||||
editor.editor.doc.replaceSelection(code);
|
||||
});
|
||||
}
|
||||
});
|
||||
input.click();
|
||||
}
|
||||
@ -22787,7 +22792,7 @@
|
||||
|
||||
var $lineNum = Math.max(0, lineNum);
|
||||
this.jumpToLine($lineNum, endLine, percent);
|
||||
Logger.log('滚动预览区域,左侧应scroll to ', $lineNum);
|
||||
// Logger.log('滚动预览区域,左侧应scroll to ', $lineNum);
|
||||
}
|
||||
/**
|
||||
*
|
||||
@ -42214,7 +42219,7 @@
|
||||
|
||||
{
|
||||
// 生产环境屏蔽
|
||||
Logger.log('markdown引擎渲染了:', str);
|
||||
// Logger.log('markdown引擎渲染了:', str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56919,7 +56924,7 @@
|
||||
|
||||
onScroll = function onScroll() {
|
||||
if (_this2.applyingDomChanges) {
|
||||
Logger.log(new Date(), 'sync scroll locked');
|
||||
// Logger.log(new Date(), 'sync scroll locked');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -57248,13 +57253,13 @@
|
||||
return obj[index].sign;
|
||||
});
|
||||
var res = myersDiff.doDiff();
|
||||
Logger.log(res);
|
||||
// Logger.log(res);
|
||||
this.$dealWithMyersDiffResult(res, oldHtmlList.list, newHtmlList.list, domContainer);
|
||||
} else if (newHtmlList.list.length && !oldHtmlList.list.length) {
|
||||
var _context8;
|
||||
|
||||
// 全新增
|
||||
Logger.log('add all');
|
||||
// Logger.log('add all');
|
||||
|
||||
forEach$3(_context8 = newHtmlList.list).call(_context8, function (piece) {
|
||||
domContainer.appendChild(piece.dom);
|
||||
@ -57263,7 +57268,7 @@
|
||||
var _context9;
|
||||
|
||||
// 全删除
|
||||
Logger.log('delete all');
|
||||
// Logger.log('delete all');
|
||||
|
||||
forEach$3(_context9 = oldHtmlList.list).call(_context9, function (piece) {
|
||||
domContainer.removeChild(piece.dom);
|
||||
|
@ -576,6 +576,17 @@ table>tbody>tr:hover {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.manual-article .wiki-bottom-left {
|
||||
border-top: 1px solid #E5E5E5;
|
||||
line-height: 25px;
|
||||
color: #333;
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 30px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.manual-article .jump-top .view-backtop {
|
||||
position: fixed;
|
||||
bottom: -30px;
|
||||
|
@ -288,7 +288,8 @@ body .scrollbar-track-color {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
margin: 18px 0;
|
||||
height: 280px
|
||||
height: 280px;
|
||||
border: 1px solid #ffffff;
|
||||
}
|
||||
|
||||
.manual-list .list-item .manual-item-standard {
|
||||
|
@ -454,6 +454,10 @@ body .scrollbar-track-color {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.markdown-category .editor-status.markdown-tree {
|
||||
bottom: 30px !important;
|
||||
}
|
||||
|
||||
.markdown-category .markdown-nav .nav-item {
|
||||
font-size: 14px;
|
||||
padding: 0 9px;
|
||||
@ -566,7 +570,7 @@ iframe.cherry-dialog-iframe {
|
||||
}
|
||||
|
||||
@media screen and (max-width: 839px) {
|
||||
.toc {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
.toc {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
@ -20,7 +20,8 @@
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
border-bottom: none;
|
||||
line-height: 1.5
|
||||
line-height: 1.5;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.editormd-preview-container table td,.editormd-preview-container table th {
|
||||
@ -50,30 +51,43 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.whole-article-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.article-body .markdown-toc{
|
||||
position: fixed;
|
||||
right: 0;
|
||||
right: 50px;
|
||||
width: 260px;
|
||||
font-size: 12px;
|
||||
margin-top: -70px;
|
||||
overflow: auto;
|
||||
margin-right: 50px;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.markdown-toc ul{
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
.markdown-toc-list {
|
||||
padding:20px 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-toc .markdown-toc-list>li{
|
||||
padding: 3px 10px 3px 16px;
|
||||
line-height: 18px;
|
||||
border-left: 2px solid #e8e8e8;
|
||||
/*border-left: 2px solid #e8e8e8;*/
|
||||
color: #595959;
|
||||
margin-left: -2px;
|
||||
}
|
||||
.markdown-toc .markdown-toc-list>li.active{
|
||||
border-right: 2px solid #25b864;
|
||||
}
|
||||
|
||||
.article-body .markdown-article{
|
||||
margin-right: 250px;
|
||||
width: calc(100% - 260px);
|
||||
/*margin-right: 250px;*/
|
||||
}
|
||||
.article-body.content .markdown-toc{
|
||||
position: relative;
|
||||
@ -86,7 +100,7 @@
|
||||
.markdown-toc-list .directory-item {
|
||||
padding: 3px 10px 3px 16px;
|
||||
line-height: 18px;
|
||||
border-left: 2px solid #e8e8e8;
|
||||
/*border-left: 2px solid #e8e8e8;*/
|
||||
color: #595959;
|
||||
}
|
||||
.markdown-toc-list .directory-item-link {
|
||||
|
@ -3594,7 +3594,7 @@
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
.markdown-body img, .markdown-body video {
|
||||
max-width: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
@ -2878,7 +2878,8 @@
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
|
||||
.markdown-body img, .markdown-body video {
|
||||
max-width: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
@ -46,149 +46,149 @@
|
||||
action += "&callback=" + settings.uploadCallbackURL + "&dialog_id=editormd-image-dialog-" + guid;
|
||||
}
|
||||
|
||||
var dialogContent = ( (settings.imageUpload) ? "<form action=\"" + action +"\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
|
||||
( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
|
||||
"<label>" + imageLang.url + "</label>" +
|
||||
"<input type=\"text\" data-url />" + (function(){
|
||||
return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
|
||||
"<input type=\"file\" name=\"" + classPrefix + "image-file\" accept=\"image/jpeg,image/png,image/gif,image/jpg\" />" +
|
||||
"<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
|
||||
"</div>" : "";
|
||||
})() +
|
||||
"<br/>" +
|
||||
"<label>" + imageLang.alt + "</label>" +
|
||||
"<input type=\"text\" value=\"" + selection + "\" data-alt />" +
|
||||
"<br/>" +
|
||||
"<label>" + imageLang.link + "</label>" +
|
||||
"<input type=\"text\" value=\"http://\" data-link />" +
|
||||
"<br/>" +
|
||||
( (settings.imageUpload) ? "</form>" : "</div>");
|
||||
|
||||
//var imageFooterHTML = "<button class=\"" + classPrefix + "btn " + classPrefix + "image-manager-btn\" style=\"float:left;\">" + imageLang.managerButton + "</button>";
|
||||
|
||||
dialog = this.createDialog({
|
||||
title : imageLang.title,
|
||||
width : (settings.imageUpload) ? 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 link = this.find("[data-link]").val();
|
||||
|
||||
if (url === "")
|
||||
{
|
||||
alert(imageLang.imageURLEmpty);
|
||||
return false;
|
||||
}
|
||||
|
||||
var altAttr = (alt !== "") ? " \"" + alt + "\"" : "";
|
||||
|
||||
if (link === "" || link === "http://")
|
||||
{
|
||||
cm.replaceSelection("");
|
||||
}
|
||||
else
|
||||
{
|
||||
cm.replaceSelection("[](" + link + 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 + "image-dialog-" + guid);
|
||||
|
||||
if (!settings.imageUpload) {
|
||||
return ;
|
||||
var dialogContent = ((settings.imageUpload) ? "<form action=\"" + action + "\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">") +
|
||||
((settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "") +
|
||||
"<label>" + imageLang.url + "</label>" +
|
||||
"<input type=\"text\" data-url />" + (function() {
|
||||
return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
|
||||
// 3xxx 下行添加multiple=\"multiple\"
|
||||
"<input type=\"file\" name=\"" + classPrefix + "image-file\" accept=\"image/jpeg,image/png,image/gif,image/jpg\" multiple=\"multiple\" />" +
|
||||
"<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
|
||||
"</div>" : "";
|
||||
})() +
|
||||
"<br/>" +
|
||||
"<label>" + imageLang.alt + "</label>" +
|
||||
"<input type=\"text\" value=\"" + selection + "\" data-alt />" +
|
||||
"<br/>" +
|
||||
"<label>" + imageLang.link + "</label>" +
|
||||
"<input type=\"text\" value=\"http://\" data-link />" +
|
||||
"<br/>" +
|
||||
((settings.imageUpload) ? "</form>" : "</div>");
|
||||
//var imageFooterHTML = "<button class=\"" + classPrefix + "btn " + classPrefix + "image-manager-btn\" style=\"float:left;\">" + imageLang.managerButton + "</button>";
|
||||
dialog = this.createDialog({
|
||||
title: imageLang.title,
|
||||
width: (settings.imageUpload) ? 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 link = this.find("[data-link]").val();
|
||||
if (url === "") {
|
||||
alert(imageLang.imageURLEmpty);
|
||||
return false;
|
||||
}
|
||||
// 这里增加循环
|
||||
let arr = url.split(";");
|
||||
var altAttr = (alt !== "") ? " \"" + alt + "\"" : "";
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (link === "" || link === "http://") {
|
||||
// cm.replaceSelection("");
|
||||
cm.replaceSelection("");
|
||||
} else {
|
||||
// cm.replaceSelection("[](" + link + altAttr + ")");
|
||||
cm.replaceSelection("[](" + link + altAttr + ")");
|
||||
}
|
||||
}
|
||||
if (alt === "") {
|
||||
cm.setCursor(cursor.line, cursor.ch + 2);
|
||||
}
|
||||
this.hide().lockScreen(false).hideMask();
|
||||
return false;
|
||||
}],
|
||||
|
||||
var fileInput = dialog.find("[name=\"" + classPrefix + "image-file\"]");
|
||||
|
||||
fileInput.bind("change", function() {
|
||||
var fileName = fileInput.val();
|
||||
var isImage = new RegExp("(\\.(" + settings.imageFormats.join("|") + "))$"); // /(\.(webp|jpg|jpeg|gif|bmp|png))$/
|
||||
|
||||
if (fileName === "")
|
||||
{
|
||||
alert(imageLang.uploadFileEmpty);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isImage.test(fileName))
|
||||
{
|
||||
alert(imageLang.formatNotAllowed + settings.imageFormats.join(", "));
|
||||
|
||||
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 (json.success === 1)
|
||||
{
|
||||
dialog.find("[data-url]").val(json.url);
|
||||
}
|
||||
else
|
||||
{
|
||||
alert(json.message);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
dialog.find("[type=\"submit\"]").bind("click", submitHandler).trigger("click");
|
||||
});
|
||||
cancel: [lang.buttons.cancel, function() {
|
||||
this.hide().lockScreen(false).hideMask();
|
||||
return false;
|
||||
}]
|
||||
}
|
||||
});
|
||||
dialog.attr("id", classPrefix + "image-dialog-" + guid);
|
||||
if (!settings.imageUpload) {
|
||||
return;
|
||||
}
|
||||
var fileInput = dialog.find("[name=\"" + classPrefix + "image-file\"]");
|
||||
fileInput.bind("change", function() {
|
||||
// 3xxx 20240602
|
||||
// let formData = new FormData();
|
||||
// 获取文本框dom
|
||||
// var doc = document.getElementById('doc');
|
||||
// 获取上传控件dom
|
||||
// var upload = document.getElementById('upload');
|
||||
// let files = upload.files;
|
||||
//遍历文件信息append到formData存储
|
||||
// for (let i = 0; i < files.length; i++) {
|
||||
// let file = files[i]
|
||||
// formData.append('files', file)
|
||||
// }
|
||||
// 获取文件名
|
||||
// var fileName = upload.files[0].name;
|
||||
// 获取文件路径
|
||||
// var filePath = upload.value;
|
||||
// doc.value = fileName;
|
||||
// 3xxx
|
||||
console.log(fileInput);
|
||||
console.log(fileInput[0].files);
|
||||
let files = fileInput[0].files;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
var fileName = files[i].name;
|
||||
// var fileName = fileInput.val();
|
||||
var isImage = new RegExp("(\\.(" + settings.imageFormats.join("|") + "))$"); // /(\.(webp|jpg|jpeg|gif|bmp|png))$/
|
||||
if (fileName === "") {
|
||||
alert(imageLang.uploadFileEmpty);
|
||||
return false;
|
||||
}
|
||||
|
||||
dialog = editor.find("." + dialogName);
|
||||
dialog.find("[type=\"text\"]").val("");
|
||||
dialog.find("[type=\"file\"]").val("");
|
||||
dialog.find("[data-link]").val("http://");
|
||||
|
||||
this.dialogShowMask(dialog);
|
||||
this.dialogLockScreen();
|
||||
dialog.show();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
if (!isImage.test(fileName)) {
|
||||
alert(imageLang.formatNotAllowed + settings.imageFormats.join(", "));
|
||||
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 + ")");
|
||||
var url="";
|
||||
for (let i = 0; i < json.length; i++) {
|
||||
if (json[i].success === 1) {
|
||||
if (i==0){
|
||||
url=json[i].url;
|
||||
}else{
|
||||
url=url+";"+json[i].url;
|
||||
}
|
||||
} else {
|
||||
alert(json[i].message);
|
||||
}
|
||||
}
|
||||
dialog.find("[data-url]").val(url)
|
||||
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("");
|
||||
dialog.find("[data-link]").val("http://");
|
||||
this.dialogShowMask(dialog);
|
||||
this.dialogLockScreen();
|
||||
dialog.show();
|
||||
};
|
||||
};
|
||||
|
||||
// CommonJS/Node.js
|
||||
if (typeof require === "function" && typeof exports === "object" && typeof module === "object")
|
||||
|
@ -53,8 +53,10 @@ $(function () {
|
||||
shade: [0.1, '#fff'] // 0.1 透明度的白色背景
|
||||
});
|
||||
} else if ($state === "success") {
|
||||
if ($res.errcode === 0) {
|
||||
var value = '';
|
||||
// if ($res.errcode === 0) {
|
||||
// var value = '';
|
||||
if ($res[0].errcode === 0) {
|
||||
var value = '';
|
||||
window.editor.insertValue(value);
|
||||
}
|
||||
}
|
||||
|
@ -140,6 +140,7 @@ $(function () {
|
||||
MathJax: window.MathJax,
|
||||
},
|
||||
isPreviewOnly: false,
|
||||
fileUpload: myFileUpload,
|
||||
engine: {
|
||||
global: {
|
||||
urlProcessor(url, srcType) {
|
||||
@ -261,19 +262,6 @@ $(function () {
|
||||
resetEditorChanged(true);
|
||||
});
|
||||
openLastSelectedNode();
|
||||
uploadImage("manualEditorContainer", function ($state, $res) {
|
||||
console.log("注册上传图片")
|
||||
if ($state === "before") {
|
||||
return layer.load(1, {
|
||||
shade: [0.1, '#fff'] // 0.1 透明度的白色背景
|
||||
});
|
||||
} else if ($state === "success") {
|
||||
if ($res.errcode === 0) {
|
||||
var value = '';
|
||||
window.editor.insertValue(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/***
|
||||
@ -519,6 +507,7 @@ $(function () {
|
||||
}
|
||||
},
|
||||
'core': {
|
||||
'worker':true,
|
||||
'check_callback': true,
|
||||
"multiple": false,
|
||||
'animation': 0,
|
||||
@ -614,77 +603,37 @@ $(function () {
|
||||
});
|
||||
});
|
||||
|
||||
function uploadImage($id, $callback) {
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
unsupportType: '不支持的图片格式',
|
||||
uploadFailed: '图片上传失败'
|
||||
function myFileUpload(file, callback) {
|
||||
// 创建 FormData 对象以便包含要上传的文件
|
||||
var formData = new FormData();
|
||||
formData.append("editormd-file-file", file); // "file" 是与你的服务端接口相对应的字段名
|
||||
var layerIndex = 0;
|
||||
// AJAX 请求
|
||||
$.ajax({
|
||||
url: window.fileUploadURL, // 确保此 URL 是文件上传 API 的正确 URL
|
||||
type: "POST",
|
||||
async: false, // 3xxx 20240609这里修改为同步,保证cherry批量上传图片时,插入的图片名称是正确的,否则,插入的图片名称都是最后一个名称
|
||||
dataType: "json",
|
||||
data: formData,
|
||||
processData: false, // 必须设置为 false,因为数据是 FormData 对象,不需要对数据进行序列化处理
|
||||
contentType: false, // 必须设置为 false,因为是 FormData 对象,jQuery 将不会设置内容类型头
|
||||
|
||||
beforeSend: function () {
|
||||
layerIndex = layer.load(1, {
|
||||
shade: [0.1, '#fff'] // 0.1 透明度的白色背景
|
||||
});
|
||||
},
|
||||
'en': {
|
||||
unsupportType: 'Unsupport image type',
|
||||
uploadFailed: 'Upload image failed'
|
||||
}
|
||||
}
|
||||
/** 粘贴上传图片 **/
|
||||
document.getElementById($id).addEventListener('paste', function (e) {
|
||||
if (e.clipboardData && e.clipboardData.items) {
|
||||
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();
|
||||
|
||||
var fileName = String((new Date()).valueOf());
|
||||
|
||||
switch (imageFile.type) {
|
||||
case "image/png" :
|
||||
fileName += ".png";
|
||||
break;
|
||||
case "image/jpg" :
|
||||
fileName += ".jpg";
|
||||
break;
|
||||
case "image/jpeg" :
|
||||
fileName += ".jpeg";
|
||||
break;
|
||||
case "image/gif" :
|
||||
fileName += ".gif";
|
||||
break;
|
||||
default :
|
||||
layer.msg(locales[lang].unsupportType);
|
||||
return;
|
||||
}
|
||||
var form = new FormData();
|
||||
|
||||
form.append('editormd-image-file', imageFile, fileName);
|
||||
|
||||
var layerIndex = 0;
|
||||
|
||||
$.ajax({
|
||||
url: window.imageUploadURL,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: form,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
beforeSend: function () {
|
||||
layerIndex = $callback('before');
|
||||
},
|
||||
error: function () {
|
||||
layer.close(layerIndex);
|
||||
$callback('error');
|
||||
layer.msg(locales[lang].uploadFailed);
|
||||
},
|
||||
success: function (data) {
|
||||
layer.close(layerIndex);
|
||||
$callback('success', data);
|
||||
if (data.errcode !== 0) {
|
||||
layer.msg(data.message);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
error: function () {
|
||||
layer.close(layerIndex);
|
||||
layer.msg(locales[lang].uploadFailed);
|
||||
},
|
||||
success: function (data) {
|
||||
layer.close(layerIndex);
|
||||
if (data[0].errcode !== 0) {
|
||||
layer.msg(data[0].message);
|
||||
} else {
|
||||
callback(data[0].url); // 假设返回的 JSON 中包含上传文件的 URL,调用回调函数并传入 URL
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -437,6 +437,85 @@ function uploadImage($id, $callback) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function uploadResource($id, $callback) {
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
unsupportType: '不支持的图片/视频格式',
|
||||
uploadFailed: '图片/视频上传失败'
|
||||
},
|
||||
'en': {
|
||||
unsupportType: 'Unsupport image/video type',
|
||||
uploadFailed: 'Upload image/video failed'
|
||||
}
|
||||
}
|
||||
/** 粘贴上传的资源 **/
|
||||
document.getElementById($id).addEventListener('paste', function (e) {
|
||||
if (e.clipboardData && e.clipboardData.items) {
|
||||
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 resource = clipboard.items[i].getAsFile();
|
||||
|
||||
var fileName = String((new Date()).valueOf());
|
||||
console.log(resource.type)
|
||||
switch (resource.type) {
|
||||
case "image/png" :
|
||||
fileName += ".png";
|
||||
break;
|
||||
case "image/jpg" :
|
||||
fileName += ".jpg";
|
||||
break;
|
||||
case "image/jpeg" :
|
||||
fileName += ".jpeg";
|
||||
break;
|
||||
case "image/gif" :
|
||||
fileName += ".gif";
|
||||
break;
|
||||
case "video/mp4":
|
||||
fileName += ".mp4";
|
||||
break;
|
||||
case "video/webm":
|
||||
fileName += ".webm";
|
||||
break;
|
||||
default :
|
||||
layer.msg(locales[lang].unsupportType);
|
||||
return;
|
||||
}
|
||||
var form = new FormData();
|
||||
|
||||
form.append('editormd-resource-file', resource, fileName);
|
||||
|
||||
var layerIndex = 0;
|
||||
|
||||
$.ajax({
|
||||
url: window.imageUploadURL,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: form,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
beforeSend: function () {
|
||||
layerIndex = $callback('before');
|
||||
},
|
||||
error: function () {
|
||||
layer.close(layerIndex);
|
||||
$callback('error');
|
||||
layer.msg(locales[lang].uploadFailed);
|
||||
},
|
||||
success: function (data) {
|
||||
layer.close(layerIndex);
|
||||
$callback('success', data);
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化代码高亮
|
||||
*/
|
||||
|
496
static/js/froala-editor.js
Normal file
@ -0,0 +1,496 @@
|
||||
$(function () {
|
||||
//超大屏幕
|
||||
var toolbarButtons = ['fullscreen', 'bold', 'italic', 'underline', 'strikeThrough', 'subscript', 'superscript', 'fontFamily', 'fontSize', '|', 'color', 'emoticons', 'inlineStyle', 'paragraphStyle', '|', 'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 'insertHR', '-', 'insertLink', 'insertImage', 'insertVideo', 'insertFile', 'insertTable', 'undo', 'redo', 'clearFormatting', 'selectAll', 'html'];
|
||||
//大屏幕
|
||||
var toolbarButtonsMD = ['fullscreen', 'bold', 'italic', 'underline', 'fontFamily', 'fontSize', 'color', 'paragraphStyle', 'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 'insertHR', 'insertLink', 'insertImage', 'insertVideo', 'insertFile', 'insertTable', 'undo', 'redo', 'clearFormatting'];
|
||||
//小屏幕
|
||||
var toolbarButtonsSM = ['fullscreen', 'bold', 'italic', 'underline', 'fontFamily', 'fontSize', 'insertLink', 'insertImage', 'insertTable', 'undo', 'redo'];
|
||||
//手机
|
||||
var toolbarButtonsXS = ['bold', 'italic', 'fontFamily', 'fontSize', 'undo', 'redo'];
|
||||
|
||||
window.addDocumentModalFormHtml = $(this).find("form").html();
|
||||
window.editor = new FroalaEditor("#froalaEditor", {
|
||||
// enter: $.FroalaEditor.ENTER_P,
|
||||
placeholderText: '请输入内容',
|
||||
charCounterCount: true, //默认
|
||||
// charCounterMax : -1,//默认
|
||||
saveInterval: 0, //不自动保存,默认10000
|
||||
// theme : "red",
|
||||
height: "100%",
|
||||
toolbarBottom: false, //默认
|
||||
toolbarButtonsMD: toolbarButtonsMD,
|
||||
toolbarButtonsSM: toolbarButtonsSM,
|
||||
toolbarButtonsXS: toolbarButtonsXS,
|
||||
toolbarInline: false, //true选中设置样式,默认false
|
||||
imageUploadMethod: 'POST',
|
||||
// heightMin: 450,
|
||||
charCounterMax: 3000,
|
||||
// imageUploadURL: "uploadImgEditor",
|
||||
// imageParams: { postId: "123" },
|
||||
params: {
|
||||
// acl: '01',
|
||||
// AWSAccessKeyId: '02',
|
||||
// policy: '03',
|
||||
// signature: '04',
|
||||
editor : "froalaEditor",
|
||||
},
|
||||
autosave: true,
|
||||
autosaveInterval: 2500,
|
||||
// saveURL: 'hander/FroalaHandler.ashx',
|
||||
saveParams: { postId: '1' },
|
||||
spellcheck: false,
|
||||
imageUploadURL: window.imageUploadURL, //'/uploadimg', //上传到本地服务器
|
||||
// imageUploadParams: { pid: '{{.product.ProjectId}}' },
|
||||
// imageDeleteURL: 'lib/delete_image.php', //删除图片
|
||||
// imagesLoadURL: 'lib/load_images.php', //管理图片
|
||||
videoUploadURL: window.imageUploadURL,
|
||||
// videoUploadParams: { pid: '{{.product.ProjectId}}' },
|
||||
fileUploadURL: window.imageUploadURL,
|
||||
// fileUploadParams: { pid: '{{.product.ProjectId}}' },
|
||||
// enter: $.FroalaEditor.ENTER_BR,
|
||||
language: 'zh_cn',
|
||||
// Add the custom buttons in the toolbarButtons list, after the separator.
|
||||
toolbarButtons: [toolbarButtons, ['saveIcon', 'insert','alert']]
|
||||
// toolbarButtons: ['bold', 'italic', 'underline', 'paragraphFormat', 'align','color','fontSize','insertImage','insertTable','undo', 'redo']
|
||||
});
|
||||
|
||||
FroalaEditor.DefineIcon('alert', {NAME: 'info', SVG_KEY: 'user'});
|
||||
FroalaEditor.RegisterCommand('alert', {
|
||||
title: 'Hello',
|
||||
focus: false,
|
||||
undo: false,
|
||||
refreshAfterCallback: false,
|
||||
callback: function () {
|
||||
alert('Hello!');
|
||||
}
|
||||
});
|
||||
|
||||
// FroalaEditor.DefineIcon('magicIcon', {NAME: 'magic'});
|
||||
FroalaEditor.DefineIcon('saveIcon', {NAME: 'plus', SVG_KEY: 'cogs'});
|
||||
FroalaEditor.RegisterCommand('saveIcon', {
|
||||
title: '保存',
|
||||
focus: false,
|
||||
undo: true,
|
||||
refreshAfterCallback: true,
|
||||
callback: function () {
|
||||
saveDocument();
|
||||
}
|
||||
});
|
||||
|
||||
FroalaEditor.DefineIcon('insert', {NAME: 'plus', SVG_KEY: 'add'});
|
||||
FroalaEditor.RegisterCommand('insert', {
|
||||
title: '发布',
|
||||
focus: true,
|
||||
undo: true,
|
||||
refreshAfterCallback: true,
|
||||
callback: function () {
|
||||
// this.html.insert('My New HTML');
|
||||
// saveDocument(true,callback);
|
||||
releaseBook();
|
||||
}
|
||||
});
|
||||
|
||||
// new FroalaEditor('div#froala-editor', {
|
||||
// // Add the custom buttons in the toolbarButtons list, after the separator.
|
||||
// toolbarButtons: [['undo', 'redo' , 'bold'], ['alert', 'clear', 'insert']]
|
||||
// })
|
||||
|
||||
// editor.config.mapAk = window.baiduMapKey;
|
||||
// editor.config.printLog = false;
|
||||
// editor.config.showMenuTooltips = true
|
||||
// editor.config.menuTooltipPosition = 'down'
|
||||
// editor.config.uploadImgUrl = window.imageUploadURL;
|
||||
// editor.config.uploadImgFileName = "editormd-image-file";
|
||||
// editor.config.uploadParams = {
|
||||
// "editor" : "froalaEditor"
|
||||
// };
|
||||
// editor.config.uploadImgServer = window.imageUploadURL;
|
||||
// editor.config.customUploadImg = function (resultFiles, insertImgFn) {
|
||||
// // resultFiles 是 input 中选中的文件列表
|
||||
// // insertImgFn 是获取图片 url 后,插入到编辑器的方法
|
||||
// var file = resultFiles[0];
|
||||
// // file type is only image.
|
||||
// if (/^image\//.test(file.type)) {
|
||||
// var form = new FormData();
|
||||
// form.append('editormd-image-file', file, file.name);
|
||||
|
||||
// var layerIndex = 0;
|
||||
|
||||
// $.ajax({
|
||||
// url: window.imageUploadURL,
|
||||
// type: "POST",
|
||||
// dataType: "json",
|
||||
// data: form,
|
||||
// processData: false,
|
||||
// contentType: false,
|
||||
// error: function() {
|
||||
// layer.close(layerIndex);
|
||||
// layer.msg("图片上传失败");
|
||||
// },
|
||||
// success: function(data) {
|
||||
// layer.close(layerIndex);
|
||||
// if(data.errcode !== 0){
|
||||
// layer.msg(data.message);
|
||||
// }else{
|
||||
// insertImgFn(data.url);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// } else {
|
||||
// console.warn('You could only upload images.');
|
||||
// }
|
||||
// };
|
||||
// editor.config.lang = window.lang;
|
||||
// editor.i18next = window.i18next;
|
||||
// editor.config.languages['en']['froalaEditor']['menus']['title']['保存'] = 'save';
|
||||
// editor.config.languages['en']['froalaEditor']['menus']['title']['发布'] = 'publish';
|
||||
// editor.config.languages['en']['froalaEditor']['menus']['title']['附件'] = 'attachment';
|
||||
// editor.config.languages['en']['froalaEditor']['menus']['title']['history'] = 'history';
|
||||
|
||||
window.editormdLocales = {
|
||||
'zh-CN': {
|
||||
placeholder: '本编辑器支持 Markdown 编辑,左边编写,右边预览。',
|
||||
contentUnsaved: '编辑内容未保存,需要保存吗?',
|
||||
noDocNeedPublish: '没有需要发布的文档',
|
||||
loadDocFailed: '文档加载失败',
|
||||
fetchDocFailed: '获取当前文档信息失败',
|
||||
cannotAddToEmptyNode: '空节点不能添加内容',
|
||||
overrideModified: '文档已被其他人修改确定覆盖已存在的文档吗?',
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
contentsNameEmpty: '目录名称不能为空',
|
||||
addDoc: '添加文档',
|
||||
edit: '编辑',
|
||||
delete: '删除',
|
||||
loadFailed: '加载失败请重试',
|
||||
tplNameEmpty: '模板名称不能为空',
|
||||
tplContentEmpty: '模板内容不能为空',
|
||||
saveSucc: '保存成功',
|
||||
serverExcept: '服务器异常',
|
||||
paramName: '参数名称',
|
||||
paramType: '参数类型',
|
||||
example: '示例值',
|
||||
remark: '备注',
|
||||
},
|
||||
'en': {
|
||||
placeholder: 'This editor supports Markdown editing, writing on the left and previewing on the right.',
|
||||
contentUnsaved: 'The edited content is not saved, need to save it?',
|
||||
noDocNeedPublish: 'No Document need to be publish',
|
||||
loadDocFailed: 'Load Document failed',
|
||||
fetchDocFailed: 'Fetch Document info failed',
|
||||
cannotAddToEmptyNode: 'Cannot add content to empty node',
|
||||
overrideModified: 'The document has been modified by someone else, are you sure to overwrite the document?',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
contentsNameEmpty: 'Document Name cannot be empty',
|
||||
addDoc: 'Add Document',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
loadFailed: 'Failed to load, please try again',
|
||||
tplNameEmpty: 'Template name cannot be empty',
|
||||
tplContentEmpty: 'Template content cannot be empty',
|
||||
saveSucc: 'Save success',
|
||||
serverExcept: 'Server Exception',
|
||||
paramName: 'Parameter',
|
||||
paramType: 'Type',
|
||||
example: 'Example',
|
||||
remark: 'Remark',
|
||||
}
|
||||
};
|
||||
|
||||
// window.editor.config.onchange = function (newHtml) {
|
||||
// var saveMenu = window.editor.menus.menuList.find((item) => item.key == 'save');
|
||||
// // 判断内容是否改变
|
||||
// if (window.source !== window.editor.txt.html()) {
|
||||
// saveMenu.$elem.addClass('selected');
|
||||
// } else {
|
||||
// saveMenu.$elem.removeClass('selected');
|
||||
// }
|
||||
// };
|
||||
|
||||
// window.editor.create();
|
||||
|
||||
// $("#froalaEditor").css("height","100%");
|
||||
|
||||
if(window.documentCategory.length > 0){
|
||||
var item = window.documentCategory[0];
|
||||
var $select_node = { node : {id : item.id}};
|
||||
loadDocument($select_node);
|
||||
}
|
||||
|
||||
/***
|
||||
* 加载指定的文档到编辑器中
|
||||
* @param $node
|
||||
*/
|
||||
function loadDocument($node) {
|
||||
var index = layer.load(1, {
|
||||
shade: [0.1,'#fff'] //0.1透明度的白色背景
|
||||
});
|
||||
|
||||
$.get(window.editURL + $node.node.id ).done(function (res) {
|
||||
layer.close(index);
|
||||
|
||||
if(res.errcode === 0){
|
||||
window.isLoad = true;
|
||||
|
||||
// window.editor.txt.clear();
|
||||
// window.editor.txt.html(res.data.content);
|
||||
window.editor.html.set('');
|
||||
window.editor.events.focus();
|
||||
window.editor.html.set(res.data.content);
|
||||
// 将原始内容备份
|
||||
window.source = res.data.content;
|
||||
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("文档加载失败");
|
||||
}
|
||||
}).fail(function () {
|
||||
layer.close(index);
|
||||
layer.msg("文档加载失败");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存文档到服务器
|
||||
* @param $is_cover 是否强制覆盖
|
||||
*/
|
||||
function saveDocument($is_cover,callback) {
|
||||
var index = null;
|
||||
var node = window.selectNode;
|
||||
|
||||
// var html = window.editor.txt.html() ;
|
||||
var html = window.editor.html.get();
|
||||
|
||||
var content = "";
|
||||
if($.trim(html) !== ""){
|
||||
content = toMarkdown(html, { gfm: true });
|
||||
}
|
||||
var version = "";
|
||||
|
||||
if (!node) {
|
||||
layer.msg(editormdLocales[lang].fetchDocFailed);
|
||||
return;
|
||||
}
|
||||
var doc_id = parseInt(node.id);
|
||||
|
||||
for(var i in window.documentCategory){
|
||||
var item = window.documentCategory[i];
|
||||
|
||||
if(item.id === doc_id){
|
||||
version = item.version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$.ajax({
|
||||
beforeSend : function () {
|
||||
index = layer.load(1, {shade: [0.1,'#fff'] });
|
||||
},
|
||||
url : window.editURL,
|
||||
data : {"identify" : window.book.identify,"doc_id" : doc_id,"markdown" : content,"html" : html,"cover" : $is_cover ? "yes":"no","version": version},
|
||||
type :"post",
|
||||
dataType :"json",
|
||||
success : function (res) {
|
||||
layer.close(index);
|
||||
if(res.errcode === 0){
|
||||
for(var i in window.documentCategory){
|
||||
var item = window.documentCategory[i];
|
||||
|
||||
if(item.id === doc_id){
|
||||
window.documentCategory[i].version = res.data.version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 更新内容备份
|
||||
window.source = res.data.content;
|
||||
// 触发编辑器 onchange 回调函数
|
||||
// window.editor.config.onchange();
|
||||
// window.editor.onchange();
|
||||
// window.editor.events: {
|
||||
// 'contentChanged': function () {
|
||||
// // Do something here.
|
||||
// // this is the editor instance.
|
||||
// console.log(this);
|
||||
// }
|
||||
// }
|
||||
if(typeof callback === "function"){
|
||||
callback();
|
||||
}
|
||||
}else if(res.errcode === 6005){
|
||||
var confirmIndex = layer.confirm(editormdLocales[lang].overrideModified, {
|
||||
btn: [editormdLocales[lang].confirm, editormdLocales[lang].cancel] // 按钮
|
||||
}, function () {
|
||||
layer.close(confirmIndex);
|
||||
saveDocument(true,callback);
|
||||
});
|
||||
}else{
|
||||
layer.msg(res.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 添加顶级文档
|
||||
*/
|
||||
$("#addDocumentForm").ajaxForm({
|
||||
beforeSubmit : function () {
|
||||
var doc_name = $.trim($("#documentName").val());
|
||||
if (doc_name === ""){
|
||||
return showError("目录名称不能为空","#add-error-message")
|
||||
}
|
||||
window.addDocumentFormIndex = layer.load(1, { shade: [0.1,'#fff'] });
|
||||
return true;
|
||||
},
|
||||
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 node = window.treeCatalog.get_node(data.id);
|
||||
if(node){
|
||||
window.treeCatalog.rename_node({"id":data.id},data.text);
|
||||
|
||||
}else {
|
||||
window.treeCatalog.create_node(data.parent, data);
|
||||
window.treeCatalog.deselect_all();
|
||||
window.treeCatalog.select_node(data);
|
||||
}
|
||||
pushDocumentCategory(data);
|
||||
$("#markdown-save").removeClass('change').addClass('disabled');
|
||||
$("#addDocumentModal").modal('hide');
|
||||
}else{
|
||||
showError(res.message,"#add-error-message")
|
||||
}
|
||||
layer.close(window.addDocumentFormIndex);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 文档目录树
|
||||
*/
|
||||
$("#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": window.editormdLocales[window.lang].addDoc,//"添加文档",
|
||||
"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": window.editormdLocales[window.lang].edit,
|
||||
"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": window.editormdLocales[window.lang].delete,
|
||||
"icon": "fa fa-trash-o",
|
||||
"action": function (data) {
|
||||
var inst = $.jstree.reference(data.reference);
|
||||
var node = inst.get_node(data.reference);
|
||||
openDeleteDocumentDialog(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).on('loaded.jstree', function () {
|
||||
window.treeCatalog = $(this).jstree();
|
||||
}).on('select_node.jstree', function (node, selected, event) {
|
||||
// if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) {
|
||||
// if (confirm(window.editormdLocales[window.lang].contentUnsaved)) {
|
||||
// saveDocument(false,function () {
|
||||
// loadDocument(selected);
|
||||
// });
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
loadDocument(selected);
|
||||
|
||||
}).on("move_node.jstree", jstree_save);
|
||||
|
||||
window.saveDocument = saveDocument;
|
||||
|
||||
window.releaseBook = function () {
|
||||
// if(Object.prototype.toString.call(window.documentCategory) === '[object Array]' && window.documentCategory.length > 0){
|
||||
// if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) {
|
||||
// if(confirm(editormdLocales[lang].contentUnsaved)) {
|
||||
// saveDocument();
|
||||
// }
|
||||
// }
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
publishToQueue: '发布任务已推送到任务队列,稍后将在后台执行。',
|
||||
},
|
||||
'en': {
|
||||
publishToQueue: 'The publish task has been pushed to the queue</br> and will be executed soon.',
|
||||
}
|
||||
}
|
||||
$.ajax({
|
||||
url: window.releaseURL,
|
||||
data: {"identify": window.book.identify},
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
success: function (res) {
|
||||
if (res.errcode === 0) {
|
||||
layer.msg(locales[lang].publishToQueue);
|
||||
} else {
|
||||
layer.msg(res.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
// }else{
|
||||
// layer.msg(editormdLocales[lang].noDocNeedPublish)
|
||||
// }
|
||||
};
|
||||
|
||||
// $(window).resize(function(e) {
|
||||
// var $container = $(editor.$textContainerElem.elems[0]);
|
||||
// var $manual = $container.closest('.manual-froalaEditor');
|
||||
// var maxHeight = $manual.closest('.manual-editor-container').innerHeight();
|
||||
// var statusHeight = $manual.siblings('.manual-editor-status').outerHeight(true);
|
||||
// var manualHeihgt = maxHeight - statusHeight;
|
||||
// $manual.height(manualHeihgt);
|
||||
// var toolbarHeight = $container.siblings('.w-e-toolbar').outerHeight(true);
|
||||
// $container.height($container.parent().innerHeight() - toolbarHeight);
|
||||
// });
|
||||
// $(window).trigger('resize');
|
||||
});
|
@ -143,9 +143,7 @@ function renderPage($data) {
|
||||
$("#doc_id").val($data.doc_id);
|
||||
if ($data.page) {
|
||||
loadComment($data.page, $data.doc_id);
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pageClicked(-1, $data.doc_id);
|
||||
}
|
||||
|
||||
@ -156,6 +154,7 @@ function renderPage($data) {
|
||||
$("#view_container").removeClass("theme__dark theme__green theme__light theme__red theme__default")
|
||||
$("#view_container").addClass($data.markdown_theme)
|
||||
}
|
||||
checkMarkdownTocElement();
|
||||
}
|
||||
|
||||
/***
|
||||
@ -229,7 +228,24 @@ function initHighlighting() {
|
||||
}
|
||||
}
|
||||
|
||||
function handleEvent(event) {
|
||||
switch (event.keyCode) {
|
||||
case 70: // ctrl + f 打开搜索面板 并获取焦点
|
||||
$(".navg-item[data-mode='search']").click();
|
||||
document.getElementById('searchForm').querySelector('input').focus();
|
||||
event.preventDefault();
|
||||
break;
|
||||
case 27: // esc 关闭搜索面板
|
||||
$(".navg-item[data-mode='view']").click();
|
||||
event.preventDefault();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
window.addEventListener('keydown', handleEvent)
|
||||
|
||||
checkMarkdownTocElement();
|
||||
$(".view-backtop").on("click", function () {
|
||||
$('.manual-right').animate({ scrollTop: '0px' }, 200);
|
||||
});
|
||||
@ -280,7 +296,7 @@ $(function () {
|
||||
|
||||
|
||||
$(window).resize(function (e) {
|
||||
var h = $(".manual-catalog").innerHeight() - 20;
|
||||
var h = $(".manual-catalog").innerHeight() - 50;
|
||||
$(".markdown-toc").height(h);
|
||||
}).resize();
|
||||
|
||||
@ -334,6 +350,11 @@ $(function () {
|
||||
$(".m-manual").removeClass("manual-mode-view manual-mode-collect manual-mode-search").addClass("manual-mode-" + mode);
|
||||
});
|
||||
|
||||
const input = document.getElementById('searchForm').querySelector('input');
|
||||
input.addEventListener('input', function() {
|
||||
$("#btnSearch").click();
|
||||
});
|
||||
|
||||
/**
|
||||
* 项目内搜索
|
||||
*/
|
||||
@ -417,4 +438,18 @@ function loadCopySnippets() {
|
||||
[].forEach.call(snippets, function (snippet) {
|
||||
Prism.highlightElement(snippet);
|
||||
});
|
||||
}
|
||||
|
||||
function checkMarkdownTocElement() {
|
||||
let toc = $(".markdown-toc-list");
|
||||
let articleComment = $("#articleComment");
|
||||
if (toc.length) {
|
||||
$(".wiki-bottom-left").css("width", "calc(100% - 260px)");
|
||||
articleComment.css("width", "calc(100% - 260px)");
|
||||
articleComment.css("margin", "30px 0 70px 0");
|
||||
} else {
|
||||
$(".wiki-bottom-left").css("width", "100%");
|
||||
articleComment.css("width", "100%");
|
||||
articleComment.css("margin", "30px auto 70px auto;");
|
||||
}
|
||||
}
|
@ -245,15 +245,22 @@ $(function () {
|
||||
|
||||
//如果没有选中节点则选中默认节点
|
||||
openLastSelectedNode();
|
||||
uploadImage("docEditor", function ($state, $res) {
|
||||
uploadResource("docEditor", function ($state, $res) {
|
||||
if ($state === "before") {
|
||||
return layer.load(1, {
|
||||
shade: [0.1, '#fff'] // 0.1 透明度的白色背景
|
||||
});
|
||||
} else if ($state === "success") {
|
||||
if ($res.errcode === 0) {
|
||||
var value = '';
|
||||
window.editor.insertValue(value);
|
||||
if ($res.resource_type === 'video') {
|
||||
let value = `<video controls><source src="${$res.url}" type="video/mp4"></video>`;
|
||||
window.editor.insertValue(value);
|
||||
} else {
|
||||
let value = '';
|
||||
window.editor.insertValue(value);
|
||||
}
|
||||
} else {
|
||||
layer.msg("上传失败:" + $res.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -77,10 +77,11 @@ $(function () {
|
||||
shade: [0.1, '#fff'] // 0.1 透明度的白色背景
|
||||
});
|
||||
} else if ($state === "success") {
|
||||
if ($res.errcode === 0) {
|
||||
|
||||
// if ($res.errcode === 0) {
|
||||
if ($res[0].errcode === 0) {
|
||||
var range = window.editor.getSelection();
|
||||
window.editor.insertEmbed(range.index, 'image', $res.url);
|
||||
// window.editor.insertEmbed(range.index, 'image', $res.url);
|
||||
window.editor.insertEmbed(range.index, 'image', $res[0].url);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
73
static/js/sort.js
Normal file
@ -0,0 +1,73 @@
|
||||
let draggedItem = null;
|
||||
let draggedItemIndex = null;
|
||||
|
||||
document.querySelectorAll('.list-item').forEach(item => {
|
||||
item.addEventListener('mousedown', function() {
|
||||
draggedItem = item;
|
||||
// 获取当前item在list-item中的索引
|
||||
const parentNode = item.parentNode;
|
||||
draggedItemIndex = Array.from(parentNode.children).indexOf(draggedItem);
|
||||
item.setAttribute('draggable', true);
|
||||
});
|
||||
|
||||
item.addEventListener('dragstart', function() {
|
||||
});
|
||||
|
||||
item.addEventListener('dragover', function(e) {
|
||||
e.preventDefault();
|
||||
if (draggedItem !== item) {
|
||||
item.style.border = '1px dashed #d4d4d5';
|
||||
}
|
||||
});
|
||||
|
||||
item.addEventListener('dragleave', function() {
|
||||
item.style.border = '';
|
||||
});
|
||||
|
||||
item.addEventListener('drop', function() {
|
||||
item.style.border = '';
|
||||
if (draggedItem !== null) {
|
||||
const parentNode = item.parentNode;
|
||||
const draggedIndex = Array.from(parentNode.children).indexOf(draggedItem);
|
||||
const targetIndex = Array.from(parentNode.children).indexOf(item);
|
||||
|
||||
if (draggedIndex < targetIndex) {
|
||||
parentNode.insertBefore(draggedItem, item.nextSibling);
|
||||
} else {
|
||||
parentNode.insertBefore(draggedItem, item);
|
||||
}
|
||||
// 获取当前最新的data-id属性列表 去除null
|
||||
const newSortList = Array.from(parentNode.children).map(item => item.getAttribute('data-id')).filter(item => item !== null);
|
||||
const newSortListStr = newSortList.join(',');
|
||||
// 更新排序
|
||||
$.ajax({
|
||||
url: window.updateBookOrder,
|
||||
type: 'POST',
|
||||
data: {
|
||||
ids: newSortListStr,
|
||||
},
|
||||
success: function (res) {
|
||||
if (res.errcode === 0) {
|
||||
layer.msg("排序成功", {icon: 1});
|
||||
draggedItem = null;
|
||||
} else {
|
||||
layer.msg(res.message, {icon: 2});
|
||||
const parentNode = item.parentNode;
|
||||
// 在parentNode中找到当前拖拽的item
|
||||
const draggedIndex = Array.from(parentNode.children).indexOf(draggedItem);
|
||||
console.log('draggedIndex:', draggedIndex);
|
||||
// 移除当前拖拽的item
|
||||
parentNode.removeChild(draggedItem);
|
||||
// 将draggedItem放到原来的位置
|
||||
parentNode.insertBefore(draggedItem, parentNode.children[draggedItemIndex]);
|
||||
draggedItem = null;
|
||||
}
|
||||
},
|
||||
error: function (err) {
|
||||
console.log('error:', err)
|
||||
draggedItem = null;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
@ -86,7 +86,7 @@
|
||||
.jstree-wholerow-ul {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.jstree-wholerow-ul .jstree-leaf > .jstree-ocl {
|
||||
cursor: pointer;
|
||||
|
1
uploads/.gitignore
vendored
@ -1 +0,0 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
0
uploads/.gitkeep
Normal file
Before Width: | Height: | Size: 372 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 367 KiB |
Before Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 282 KiB |
Before Width: | Height: | Size: 230 KiB |
Before Width: | Height: | Size: 558 KiB |
Before Width: | Height: | Size: 25 KiB |
@ -1,21 +1,43 @@
|
||||
package filetil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"io"
|
||||
"fmt"
|
||||
"math"
|
||||
"io/ioutil"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
//==================================
|
||||
//更多文件和目录的操作,使用filepath包和os包
|
||||
//==================================
|
||||
|
||||
//返回的目录扫描结果
|
||||
type FileTypeStrategy interface {
|
||||
GetFilePath(filePath, fileName, ext string) string
|
||||
}
|
||||
|
||||
type ImageStrategy struct{}
|
||||
|
||||
func (i ImageStrategy) GetFilePath(filePath, fileName, ext string) string {
|
||||
return filepath.Join(filePath, "images", fileName+ext)
|
||||
}
|
||||
|
||||
type VideoStrategy struct{}
|
||||
|
||||
func (v VideoStrategy) GetFilePath(filePath, fileName, ext string) string {
|
||||
return filepath.Join(filePath, "videos", fileName+ext)
|
||||
}
|
||||
|
||||
type DefaultStrategy struct{}
|
||||
|
||||
func (d DefaultStrategy) GetFilePath(filePath, fileName, ext string) string {
|
||||
return filepath.Join(filePath, "files", fileName+ext)
|
||||
}
|
||||
|
||||
// 返回的目录扫描结果
|
||||
type FileList struct {
|
||||
IsDir bool //是否是目录
|
||||
Path string //文件路径
|
||||
@ -25,10 +47,10 @@ type FileList struct {
|
||||
ModTime int64 //文件修改时间戳
|
||||
}
|
||||
|
||||
//目录扫描
|
||||
//@param dir 需要扫描的目录
|
||||
//@return fl 文件列表
|
||||
//@return err 错误
|
||||
// 目录扫描
|
||||
// @param dir 需要扫描的目录
|
||||
// @return fl 文件列表
|
||||
// @return err 错误
|
||||
func ScanFiles(dir string) (fl []FileList, err error) {
|
||||
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err == nil {
|
||||
@ -47,7 +69,7 @@ func ScanFiles(dir string) (fl []FileList, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
//拷贝文件
|
||||
// 拷贝文件
|
||||
func CopyFile(source string, dst string) (err error) {
|
||||
sourceFile, err := os.Open(source)
|
||||
if err != nil {
|
||||
@ -56,17 +78,16 @@ func CopyFile(source string, dst string) (err error) {
|
||||
|
||||
defer sourceFile.Close()
|
||||
|
||||
_,err = os.Stat(filepath.Dir(dst))
|
||||
_, err = os.Stat(filepath.Dir(dst))
|
||||
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
os.MkdirAll(filepath.Dir(dst),0766)
|
||||
}else{
|
||||
os.MkdirAll(filepath.Dir(dst), 0766)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
destFile, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -86,7 +107,7 @@ func CopyFile(source string, dst string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
//拷贝目录
|
||||
// 拷贝目录
|
||||
func CopyDir(source string, dest string) (err error) {
|
||||
|
||||
// get properties of source dir
|
||||
@ -107,7 +128,7 @@ func CopyDir(source string, dest string) (err error) {
|
||||
|
||||
for _, obj := range objects {
|
||||
|
||||
sourceFilePointer := filepath.Join(source , obj.Name())
|
||||
sourceFilePointer := filepath.Join(source, obj.Name())
|
||||
|
||||
destinationFilePointer := filepath.Join(dest, obj.Name())
|
||||
|
||||
@ -205,15 +226,15 @@ func Round(val float64, places int) float64 {
|
||||
return t
|
||||
}
|
||||
|
||||
//判断指定目录下是否存在指定后缀的文件
|
||||
func HasFileOfExt(path string,exts []string) bool {
|
||||
// 判断指定目录下是否存在指定后缀的文件
|
||||
func HasFileOfExt(path string, exts []string) bool {
|
||||
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
|
||||
ext := filepath.Ext(info.Name())
|
||||
|
||||
for _,item := range exts {
|
||||
if strings.EqualFold(ext,item) {
|
||||
for _, item := range exts {
|
||||
if strings.EqualFold(ext, item) {
|
||||
return os.ErrExist
|
||||
}
|
||||
}
|
||||
@ -224,6 +245,7 @@ func HasFileOfExt(path string,exts []string) bool {
|
||||
|
||||
return err == os.ErrExist
|
||||
}
|
||||
|
||||
// IsImageExt 判断是否是图片后缀
|
||||
func IsImageExt(filename string) bool {
|
||||
ext := filepath.Ext(filename)
|
||||
@ -232,25 +254,37 @@ func IsImageExt(filename string) bool {
|
||||
strings.EqualFold(ext, ".jpeg") ||
|
||||
strings.EqualFold(ext, ".png") ||
|
||||
strings.EqualFold(ext, ".gif") ||
|
||||
strings.EqualFold(ext,".svg") ||
|
||||
strings.EqualFold(ext,".bmp") ||
|
||||
strings.EqualFold(ext,".webp")
|
||||
strings.EqualFold(ext, ".svg") ||
|
||||
strings.EqualFold(ext, ".bmp") ||
|
||||
strings.EqualFold(ext, ".webp")
|
||||
}
|
||||
//忽略字符串中的BOM头
|
||||
func ReadFileAndIgnoreUTF8BOM(filename string) ([]byte,error) {
|
||||
|
||||
data,err := ioutil.ReadFile(filename)
|
||||
// IsImageExt 判断是否是视频后缀
|
||||
func IsVideoExt(filename string) bool {
|
||||
ext := filepath.Ext(filename)
|
||||
|
||||
return strings.EqualFold(ext, ".mp4") ||
|
||||
strings.EqualFold(ext, ".webm") ||
|
||||
strings.EqualFold(ext, ".ogg") ||
|
||||
strings.EqualFold(ext, ".avi") ||
|
||||
strings.EqualFold(ext, ".flv") ||
|
||||
strings.EqualFold(ext, ".mov")
|
||||
}
|
||||
|
||||
// 忽略字符串中的BOM头
|
||||
func ReadFileAndIgnoreUTF8BOM(filename string) ([]byte, error) {
|
||||
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
if data == nil {
|
||||
return nil,nil
|
||||
return nil, nil
|
||||
}
|
||||
data = bytes.Replace(data,[]byte("\r"),[]byte(""),-1)
|
||||
data = bytes.Replace(data, []byte("\r"), []byte(""), -1)
|
||||
if len(data) >= 3 && data[0] == 0xef && data[1] == 0xbb && data[2] == 0xbf {
|
||||
return data[3:],err
|
||||
return data[3:], err
|
||||
}
|
||||
|
||||
|
||||
return data,nil
|
||||
return data, nil
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="manual-reader">
|
||||
{{template "widgets/header.tpl" .}}
|
||||
{{template "widgets/header.tpl" .}}
|
||||
<div class="container manual-body">
|
||||
<div class="row">
|
||||
<div class="page-left">
|
||||
@ -104,7 +104,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "widgets/footer.tpl" .}}
|
||||
{{template "widgets/footer.tpl" .}}
|
||||
</div>
|
||||
|
||||
|
||||
@ -114,6 +114,7 @@
|
||||
<script src="{{cdnjs "/static/js/main.js"}}" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
const blogId = Number($("#blogId").val());
|
||||
$("#gloablEditForm").ajaxForm({
|
||||
beforeSubmit : function () {
|
||||
var title = $.trim($("#title").val());
|
||||
@ -126,6 +127,10 @@
|
||||
if($res.errcode === 0) {
|
||||
showSuccess("{{i18n .Lang "message.success"}}");
|
||||
$("#blogId").val($res.data.blog_id);
|
||||
if (blogId === 0) {
|
||||
// 优化新增文章后直接跳转到编辑页面
|
||||
window.location.href = {{urlfor "BlogController.ManageEdit" ":id" "xxx"}}.replace("xxx", $res.data.blog_id)
|
||||
}
|
||||
}else{
|
||||
showError($res.message);
|
||||
}
|
||||
@ -135,12 +140,12 @@
|
||||
$("#btnSaveBlogInfo").button("reset");
|
||||
}
|
||||
}).find("input[name='status']").change(function () {
|
||||
var $status = $(this).val();
|
||||
if($status === "password"){
|
||||
$("#blogPassword").show();
|
||||
}else{
|
||||
$("#blogPassword").hide();
|
||||
}
|
||||
var $status = $(this).val();
|
||||
if($status === "password"){
|
||||
$("#blogPassword").show();
|
||||
}else{
|
||||
$("#blogPassword").hide();
|
||||
}
|
||||
});
|
||||
$("#gloablEditForm").find("input[name='blog_type']").change(function () {
|
||||
var $link = $(this).val();
|
||||
|
@ -180,6 +180,25 @@
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<!--选择编辑器模式-->
|
||||
<div class="form-group">
|
||||
<label>{{i18n $.Lang "blog.text_editor"}}</label>
|
||||
<div class="col-lg-20">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="editor" value="markdown"> Markdown
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="editor" checked value="cherry_markdown"> Markdown (cherry)
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="editor" value="new_html"> Html (Quill)
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="editor" value="html"> Html (wangEditor)
|
||||
</label>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-right text-center" style="width: 235px;">
|
||||
<canvas id="bookCover" height="230px" width="170px"><img src="{{cdnimg "/static/images/book.jpg"}}"> </canvas>
|
||||
|
@ -97,6 +97,10 @@
|
||||
<label class="radio-inline">
|
||||
<input type="radio"{{if eq .Model.Editor "html"}} checked{{end}} name="editor" value="html"> Html {{i18n $.Lang "blog.text_editor"}}(wangEditor)
|
||||
</label>
|
||||
<!-- 3xxx 20240603 -->
|
||||
<label class="radio-inline">
|
||||
<input type="radio" {{if eq .Model.Editor "froala"}} checked{{end}} name="editor" value="froala"> Froala {{i18n $.Lang "blog.text_editor"}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -124,6 +128,15 @@
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="form-group">
|
||||
<label for="autoRelease">{{i18n $.Lang "blog.print_text"}}</label>
|
||||
<div class="controls">
|
||||
<div class="switch switch-small" data-on="primary" data-off="info">
|
||||
<input type="checkbox" id="autoSave" name="print_state"{{if .Model.PrintState }} checked{{end}} data-size="small" placeholder="{{i18n $.Lang "blog.print_text"}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="autoRelease">{{i18n $.Lang "blog.auto_publish"}}</label>
|
||||
<div class="controls">
|
||||
|
@ -64,16 +64,13 @@
|
||||
<div class="nav-plus pull-right" id="btnAddDocument" data-toggle="tooltip" data-title="{{i18n .Lang "doc.create_doc"}}" data-direction="right"><i class="fa fa-plus" aria-hidden="true"></i></div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="markdown-tree" id="sidebar"> </div>
|
||||
</div>
|
||||
<div class="markdown-editor-container" id="manualEditorContainer" style="min-width: 920px;">
|
||||
<div class="markdown-editormd">
|
||||
<div id="docEditor" class="markdown-editormd-active"></div>
|
||||
</div>
|
||||
<div class="markdown-tree editor-status" id="sidebar"> </div>
|
||||
<div class="markdown-editor-status">
|
||||
<div id="attachInfo" class="item">0 {{i18n .Lang "doc.attachments"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="markdown-editor-container" id="manualEditorContainer" style="min-width: 920px;">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -88,7 +88,9 @@
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if .Model.PrintState}}
|
||||
<a href="javascript:window.print();" id="printSinglePage" class="btn btn-default" style="margin-right: 10px;"><i class="fa fa-print"></i> {{i18n .Lang "doc.print"}}</a>
|
||||
{{end}}
|
||||
<div class="dropdown pull-right" style="margin-right: 10px;">
|
||||
{{if eq .Model.PrivatelyOwned 0}}
|
||||
{{if .Model.IsEnableShare}}
|
||||
|
316
views/document/froala_edit_template.tpl
Normal file
@ -0,0 +1,316 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{i18n .Lang "doc.edit_doc"}} - Powered by MinDoc</title>
|
||||
<style type="text/css">
|
||||
.w-e-menu.selected>i {
|
||||
color: #44B036 !important;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
window.IS_ENABLE_IFRAME = '{{conf "enable_iframe" }}' === 'true';
|
||||
window.BASE_URL = '{{urlfor "HomeController.Index" }}';
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
window.editor = null;
|
||||
window.imageUploadURL = "{{urlfor "DocumentController.Upload" "identify" .Model.Identify}}";
|
||||
window.fileUploadURL = "{{urlfor "DocumentController.Upload" "identify" .Model.Identify}}";
|
||||
window.documentCategory = {{.Result}};
|
||||
window.book = {{.ModelResult}};
|
||||
window.selectNode = null;
|
||||
window.deleteURL = "{{urlfor "DocumentController.Delete" ":key" .Model.Identify}}";
|
||||
window.editURL = "{{urlfor "DocumentController.Content" ":key" .Model.Identify ":id" ""}}";
|
||||
window.releaseURL = "{{urlfor "BookController.Release" ":key" .Model.Identify}}";
|
||||
window.sortURL = "{{urlfor "BookController.SaveSort" ":key" .Model.Identify}}";
|
||||
window.baiduMapKey = "{{.BaiDuMapKey}}";
|
||||
window.historyURL = "{{urlfor "DocumentController.History"}}";
|
||||
window.removeAttachURL = "{{urlfor "DocumentController.RemoveAttachment"}}";
|
||||
window.vueApp = null;
|
||||
window.lang = {{i18n $.Lang "common.js_lang"}};
|
||||
</script>
|
||||
<!-- Bootstrap -->
|
||||
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/jstree/3.3.4/themes/default/style.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss (print "/static/editor.md/lib/highlight/styles/" .HighlightStyle ".css") "version"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/webuploader/webuploader.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/css/jstree.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/css/markdown.css"}}" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="/static/froala/css/codemirror.min.css">
|
||||
|
||||
<link rel="stylesheet" href="/static/froala/css/froala_editor.min.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/froala_style.min.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/code_view.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/draggable.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/colors.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/emoticons.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/image_manager.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/image.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/line_breaker.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/table.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/char_counter.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/video.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/fullscreen.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/file.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/quick_insert.css">
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/help.css">
|
||||
<!-- <link rel="stylesheet" href="/static/froala/css/third_party/spell_checker.css"> -->
|
||||
<link rel="stylesheet" href="/static/froala/css/plugins/special_characters.css">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="m-manual manual-editor">
|
||||
|
||||
<div class="manual-body">
|
||||
<div class="manual-category" id="manualCategory" style="top: 0;">
|
||||
<div class="manual-nav">
|
||||
<div class="nav-item active"><i class="fa fa-bars" aria-hidden="true"></i> {{i18n .Lang "doc.document"}}</div>
|
||||
<div class="nav-plus pull-right" data-toggle="tooltip" data-title="{{i18n .Lang "doc.backward"}}" data-direction="right">
|
||||
<a style="color: #999999;" href="{{urlfor "BookController.Dashboard" ":key" .Model.Identify}}" target="_blank"><i class="fa fa-chevron-left" aria-hidden="true"></i></a>
|
||||
</div>
|
||||
<div class="nav-plus pull-right" id="btnAddDocument" data-toggle="tooltip" data-title="{{i18n .Lang "doc.create_doc"}}" data-direction="right"><i class="fa fa-plus" aria-hidden="true"></i></div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="manual-tree" id="sidebar">
|
||||
</div>
|
||||
</div>
|
||||
<div class="manual-editor-container" id="manualEditorContainer" style="top: 0;">
|
||||
<div class="manual-wangEditor">
|
||||
<div id="froalaEditor" class="manual-editormd-active" style="height: 100%"></div>
|
||||
</div>
|
||||
<div class="manual-editor-status">
|
||||
<div id="attachInfo" class="item" style="display: inline-block; padding: 0 3em;">0 {{i18n .Lang "doc.attachments"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="addDocumentModal" tabindex="-1" style="z-index: 10001 !important;" role="dialog" aria-labelledby="addDocumentModalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form method="post" action="{{urlfor "DocumentController.Create" ":key" .Model.Identify}}" id="addDocumentForm" class="form-horizontal">
|
||||
<input type="hidden" name="identify" value="{{.Model.Identify}}">
|
||||
<input type="hidden" name="doc_id" value="0">
|
||||
<input type="hidden" name="parent_id" value="0">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">{{i18n .Lang "doc.create_doc"}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">{{i18n .Lang "doc.doc_name"}} <span class="error-message">*</span></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" name="doc_name" id="documentName" placeholder="{{i18n .Lang "doc.doc_name"}}" class="form-control" maxlength="50">
|
||||
<p style="color: #999;font-size: 12px;">{{i18n .Lang "doc.doc_name_tips"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">{{i18n .Lang "doc.doc_id"}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" name="doc_identify" id="documentIdentify" placeholder="{{i18n .Lang "doc.doc_id"}}" class="form-control" maxlength="50">
|
||||
<p style="color: #999;font-size: 12px;">{{i18n .Lang "doc.doc_id_tips"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<span id="add-error-message" class="error-message"></span>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{i18n .Lang "common.cancel"}}</button>
|
||||
<button type="submit" class="btn btn-primary" id="btnSaveDocument" data-loading-text="{{i18n .Lang "message.processing"}}">{{i18n .Lang "doc.save"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="uploadAttachModal" tabindex="-1" style="z-index: 10001 !important;" role="dialog" aria-labelledby="uploadAttachModalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form method="post" action="{{urlfor "DocumentController.Create" ":key" .Model.Identify}}" id="addDocumentForm" class="form-horizontal">
|
||||
<input type="hidden" name="identify" value="{{.Model.Identify}}">
|
||||
<input type="hidden" name="doc_id" value="0">
|
||||
<input type="hidden" name="parent_id" value="0">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">{{i18n .Lang "doc.upload_attachment"}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="attach-drop-panel">
|
||||
<div class="upload-container" id="filePicker"><i class="fa fa-upload" aria-hidden="true"></i></div>
|
||||
</div>
|
||||
<div class="attach-list" id="attachList">
|
||||
<template v-for="item in lists">
|
||||
<div class="attach-item" :id="item.attachment_id">
|
||||
<template v-if="item.state == 'wait'">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100">
|
||||
<span class="sr-only">0% Complete (success)</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="item.state == 'error'">
|
||||
<span class="error-message">${item.message}</span>
|
||||
<button type="button" class="btn btn-sm close" @click="removeAttach(item.attachment_id)">
|
||||
<i class="fa fa-remove" aria-hidden="true"></i>
|
||||
</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a :href="item.http_path" target="_blank" :title="item.file_name">${item.file_name}</a>
|
||||
<span class="text">(${(item.file_size/1024/1024).toFixed(4)}MB)</span>
|
||||
<span class="error-message">${item.message}</span>
|
||||
<button type="button" class="btn btn-sm close" @click="removeAttach(item.attachment_id)">
|
||||
<i class="fa fa-remove" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div class="clearfix"></div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<span id="add-error-message" class="error-message"></span>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{i18n .Lang "common.cancel"}}</button>
|
||||
<button type="button" class="btn btn-primary" id="btnUploadAttachFile" data-dismiss="modal">{{i18n .Lang "common.confirm"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <script src="https://cdn.jsdelivr.net/npm/i18next/i18next.min.js"></script> -->
|
||||
<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/vuejs/vue.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/jstree/3.3.4/jstree.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/webuploader/webuploader.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/class2browser.js"}}" type="text/javascript"></script>
|
||||
<!-- <script src="{{cdnjs "/static/wangEditor/wangEditor.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/wangEditor-plugins/save-menu.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/wangEditor-plugins/release-menu.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/wangEditor-plugins/attach-menu.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/wangEditor-plugins/history-menu.js"}}" type="text/javascript"></script> -->
|
||||
<script src="{{cdnjs "/static/layer/layer.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/to-markdown/dist/to-markdown.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/editor.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/froala-editor.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/custom-elements-builtin-0.6.5.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/js/x-frame-bypass-1.0.2.js"}}" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript" src="/static/froala/js/froala_editor.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/align.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/char_counter.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/code_beautifier.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/code_view.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/colors.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/draggable.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/emoticons.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/entities.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/file.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/font_size.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/font_family.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/fullscreen.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/image.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/image_manager.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/line_breaker.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/inline_style.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/link.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/lists.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/paragraph_format.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/paragraph_style.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/quick_insert.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/quote.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/table.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/save.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/url.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/video.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/help.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/print.min.js"></script>
|
||||
<!-- <script type="text/javascript" src="/static/froala/js/third_party/spell_checker.min.js"></script> -->
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/special_characters.min.js"></script>
|
||||
<script type="text/javascript" src="/static/froala/js/plugins/word_paste.min.js"></script>
|
||||
<script src="/static/froala/js/languages/zh_cn.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
lang = {{ i18n $.Lang "common.js_lang" }};
|
||||
$("#attachInfo").on("click", function() {
|
||||
$("#uploadAttachModal").modal("show");
|
||||
});
|
||||
|
||||
window.uploader = null;
|
||||
|
||||
$("#uploadAttachModal").on("shown.bs.modal", function() {
|
||||
if (window.uploader === null) {
|
||||
try {
|
||||
window.uploader = WebUploader.create({
|
||||
auto: true,
|
||||
dnd: true,
|
||||
swf: '{{.BaseUrl}}/static/webuploader/Uploader.swf',
|
||||
server: '{{urlfor "DocumentController.Upload"}}',
|
||||
formData: { "identify": {{.Model.Identify }}, "doc_id": window.selectNode.id },
|
||||
pick: "#filePicker",
|
||||
fileVal: "editormd-file-file",
|
||||
fileNumLimit: 1,
|
||||
compress: false
|
||||
}).on("beforeFileQueued", function(file) {
|
||||
uploader.reset();
|
||||
}).on('fileQueued', function(file) {
|
||||
var item = {
|
||||
state: "wait",
|
||||
attachment_id: file.id,
|
||||
file_size: file.size,
|
||||
file_name: file.name,
|
||||
message: "{{i18n .Lang " doc.uploading "}}"
|
||||
};
|
||||
window.vueApp.lists.splice(0, 0, item);
|
||||
|
||||
}).on("uploadError", function(file, reason) {
|
||||
for (var i in window.vueApp.lists) {
|
||||
var item = window.vueApp.lists[i];
|
||||
if (item.attachment_id == file.id) {
|
||||
item.state = "error";
|
||||
item.message = "{{i18n .Lang " message.upload_failed "}}:" + reason;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}).on("uploadSuccess", function(file, res) {
|
||||
|
||||
for (var index in window.vueApp.lists) {
|
||||
var item = window.vueApp.lists[index];
|
||||
if (item.attachment_id === file.id) {
|
||||
if (res.errcode === 0) {
|
||||
window.vueApp.lists.splice(index, 1, res.attach);
|
||||
} else {
|
||||
item.message = res.message;
|
||||
item.state = "error";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}).on("beforeFileQueued", function(file) {
|
||||
|
||||
}).on("uploadComplete", function() {
|
||||
|
||||
}).on("uploadProgress", function(file, percentage) {
|
||||
var $li = $('#' + file.id),
|
||||
$percent = $li.find('.progress .progress-bar');
|
||||
|
||||
$percent.css('width', percentage * 100 + '%');
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -508,7 +508,6 @@
|
||||
}
|
||||
|
||||
}).on("uploadSuccess",function (file, res) {
|
||||
|
||||
for(var index in window.vueApp.lists){
|
||||
var item = window.vueApp.lists[index];
|
||||
if(item.attachment_id === file.id){
|
||||
|
@ -14,7 +14,9 @@
|
||||
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/css/main.css" "version"}}" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
window.updateBookOrder = "{{urlfor "BookController.UpdateBookOrder"}}";
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="manual-reader manual-container">
|
||||
@ -23,7 +25,7 @@
|
||||
<div class="row">
|
||||
<div class="manual-list">
|
||||
{{range $index,$item := .Lists}}
|
||||
<div class="list-item">
|
||||
<div class="list-item" data-id="{{$item.BookId}}">
|
||||
<dl class="manual-item-standard">
|
||||
<dt>
|
||||
<a href="{{urlfor "DocumentController.Index" ":key" $item.Identify}}" title="{{$item.BookName}}-{{$item.CreateName}}">
|
||||
@ -59,6 +61,8 @@
|
||||
</div>
|
||||
<script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/layer/layer.js"}}"></script>
|
||||
<script src="{{cdnjs "/static/js/sort.js"}}" type="text/javascript"></script>
|
||||
{{.Scripts}}
|
||||
</body>
|
||||
</html>
|