Perf: 项目优化 (#958)

* feat: 首页项目拖拽排序功能

* feat: 增加首页项目拖拽排序增加只能管理员进行, 排序失败元素回到原本位置

* perf: 新建文章以后直接进入到编辑文章页面

* perf: 优化文档打开时或刷新时样式闪动问题

* perf: 优化表格样式

* feat: 支持上传视频功能

* feat: 视频样式调整

* feat: 直接粘贴视频上传功能

* perf: 优化markdown目录显示

* feat: 项目配置新增是否开启打印功能

* perf: 优化模型自动更新表字段

* perf: 创建项目时增加选择编辑器功能

* perf: 优化cherry-markdown 菜单栏
pull/968/head
zhanzhenping 2024-07-08 15:41:56 +08:00 committed by GitHub
parent 1ea922106d
commit 532dccebff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 83 additions and 33 deletions

View File

@ -143,6 +143,11 @@ func RegisterModel() {
gob.Register(models.Document{}) gob.Register(models.Document{})
gob.Register(models.Template{}) gob.Register(models.Template{})
//migrate.RegisterMigration() //migrate.RegisterMigration()
err := orm.RunSyncdb("default", false, true)
if err != nil {
logs.Error("注册Model失败 ->", err)
os.Exit(1)
}
} }
// RegisterLogger 注册日志 // RegisterLogger 注册日志

View File

@ -318,6 +318,7 @@ next = next
no = no no = no
edit_title = Edit Blog edit_title = Edit Blog
private_blog_tips = Private blog, please enter password to access private_blog_tips = Private blog, please enter password to access
print_text = Enable Printing
[doc] [doc]
modify_doc = Modify Document modify_doc = Modify Document

View File

@ -318,6 +318,7 @@ next = 下一篇
no = no =
edit_title = 编辑文章 edit_title = 编辑文章
private_blog_tips = 加密文章,请输入密码访问 private_blog_tips = 加密文章,请输入密码访问
print_text = 开启打印
[doc] [doc]
modify_doc = 修改文档 modify_doc = 修改文档

View File

@ -122,6 +122,7 @@ func (c *BookController) Setting() {
if book.PrivateToken != "" { if book.PrivateToken != "" {
book.PrivateToken = conf.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken) book.PrivateToken = conf.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken)
} }
c.Data["Model"] = book c.Data["Model"] = book
} }
@ -153,6 +154,7 @@ func (c *BookController) SaveBook() {
isUseFirstDocument := strings.TrimSpace(c.GetString("is_use_first_document")) == "on" isUseFirstDocument := strings.TrimSpace(c.GetString("is_use_first_document")) == "on"
autoSave := strings.TrimSpace(c.GetString("auto_save")) == "on" autoSave := strings.TrimSpace(c.GetString("auto_save")) == "on"
itemId, _ := c.GetInt("itemId") itemId, _ := c.GetInt("itemId")
pringState := strings.TrimSpace(c.GetString("print_state")) == "on"
if strings.Count(description, "") > 500 { if strings.Count(description, "") > 500 {
c.JsonResult(6004, i18n.Tr(c.Lang, "message.project_desc_tips")) c.JsonResult(6004, i18n.Tr(c.Lang, "message.project_desc_tips"))
@ -211,6 +213,11 @@ func (c *BookController) SaveBook() {
} else { } else {
book.AutoSave = 0 book.AutoSave = 0
} }
if pringState {
book.PrintSate = 1
} else {
book.PrintSate = 0
}
if err := book.Update(); err != nil { if err := book.Update(); err != nil {
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed")) c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed"))
} }
@ -456,6 +463,7 @@ func (c *BookController) Create() {
description := strings.TrimSpace(c.GetString("description", "")) description := strings.TrimSpace(c.GetString("description", ""))
privatelyOwned, _ := strconv.Atoi(c.GetString("privately_owned")) privatelyOwned, _ := strconv.Atoi(c.GetString("privately_owned"))
commentStatus := c.GetString("comment_status") commentStatus := c.GetString("comment_status")
editor := c.GetString("editor")
itemId, _ := c.GetInt("itemId") itemId, _ := c.GetInt("itemId")
if bookName == "" { if bookName == "" {
@ -522,6 +530,7 @@ func (c *BookController) Create() {
book.CommentCount = 0 book.CommentCount = 0
book.PrivatelyOwned = privatelyOwned book.PrivatelyOwned = privatelyOwned
book.CommentStatus = commentStatus book.CommentStatus = commentStatus
book.Identify = identify book.Identify = identify
book.DocCount = 0 book.DocCount = 0
book.MemberId = c.Member.MemberId book.MemberId = c.Member.MemberId
@ -531,8 +540,7 @@ func (c *BookController) Create() {
book.IsDownload = 1 book.IsDownload = 1
book.AutoRelease = 0 book.AutoRelease = 0
book.ItemId = itemId book.ItemId = itemId
book.Editor = editor
book.Editor = "markdown"
book.Theme = "default" book.Theme = "default"
if err := book.Insert(c.Lang); err != nil { if err := book.Insert(c.Lang); err != nil {

View File

@ -83,6 +83,7 @@ type Book struct {
IsUseFirstDocument int `orm:"column(is_use_first_document);type(int);default(0);description(是否使用第一篇文章项目为默认首页,0 否/1 是)" json:"is_use_first_document"` IsUseFirstDocument int `orm:"column(is_use_first_document);type(int);default(0);description(是否使用第一篇文章项目为默认首页,0 否/1 是)" json:"is_use_first_document"`
//是否开启自动保存0 否/1 是 //是否开启自动保存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 { func (book *Book) String() string {

View File

@ -71,6 +71,7 @@ type BookResult struct {
IsDisplayComment bool `json:"is_display_comment"` IsDisplayComment bool `json:"is_display_comment"`
IsDownload bool `json:"is_download"` IsDownload bool `json:"is_download"`
AutoSave bool `json:"auto_save"` AutoSave bool `json:"auto_save"`
PrintState bool `json:"print_state"`
Lang string Lang string
} }
@ -213,6 +214,7 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
m.HistoryCount = book.HistoryCount m.HistoryCount = book.HistoryCount
m.IsDownload = book.IsDownload == 0 m.IsDownload = book.IsDownload == 0
m.AutoSave = book.AutoSave == 1 m.AutoSave = book.AutoSave == 1
m.PrintState = book.PrintSate == 1
m.ItemId = book.ItemId m.ItemId = book.ItemId
m.RoleId = conf.BookRoleNoSpecific m.RoleId = conf.BookRoleNoSpecific

View File

@ -2656,7 +2656,7 @@ div[data-type=codeBlock] .token.inserted {
} }
.cherry[data-toolbar-theme=dark] .cherry-insert-table-menu-item.active { .cherry[data-toolbar-theme=dark] .cherry-insert-table-menu-item.active {
background-color: #d7e6fe; background-color: #4b4b4b;
} }
.cherry-dropdown { .cherry-dropdown {
@ -2692,17 +2692,18 @@ div[data-type=codeBlock] .token.inserted {
} }
[data-toolbar-theme=dark] .cherry-dropdown { [data-toolbar-theme=dark] .cherry-dropdown {
background: #20304b; background: #ffffff;
} }
[data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item { [data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item {
background: transparent; background: transparent;
color: #d7e6fe; color: #4b4b4b;
} }
[data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item:hover { [data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item:hover {
background: rgba(255, 255, 255, 0.1); background: #e4e4e4;
color: #fff; color: #0a001f;
transition: all .3s;
} }
.cherry-toolbar { .cherry-toolbar {
@ -2710,7 +2711,7 @@ div[data-type=codeBlock] .token.inserted {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 0 20px; padding: 0 20px;
height: 48px; height: 34px;
font-size: 16px; font-size: 16px;
line-height: 2.3; line-height: 2.3;
flex-basis: 100%; flex-basis: 100%;
@ -2720,6 +2721,7 @@ div[data-type=codeBlock] .token.inserted {
box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); box-shadow: 0 0 10px rgba(128, 145, 165, 0.2);
background: white; background: white;
overflow: hidden; overflow: hidden;
align-items: center;
} }
.cherry-toolbar .icon-loading.loading { .cherry-toolbar .icon-loading.loading {
@ -2742,25 +2744,25 @@ div[data-type=codeBlock] .token.inserted {
} }
[data-toolbar-theme=dark] .cherry-toolbar { [data-toolbar-theme=dark] .cherry-toolbar {
background: #20304b; background: #ffffff;
box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); box-shadow: 0 0 10px rgba(128, 145, 165, 0.2);
} }
[data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button { [data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button {
color: #d7e6fe; color: #4b4b4b;
background: transparent; background: transparent;
} }
[data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button:hover { [data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button:hover {
color: #fff; color: #0a001f;
background: rgba(255, 255, 255, 0.1); transition: all .3s;
background: #e4e4e4;
} }
.cherry-toolbar .toolbar-left, .cherry-toolbar .toolbar-left,
.cherry-toolbar .toolbar-right { .cherry-toolbar .toolbar-right {
display: flex; display: flex;
align-items: center; align-items: center;
height: 48px;
overflow: hidden; overflow: hidden;
} }
@ -2935,12 +2937,12 @@ div[data-type=codeBlock] .token.inserted {
} }
[data-toolbar-theme=dark] .cherry-bubble { [data-toolbar-theme=dark] .cherry-bubble {
border-color: #20304b; border-color: #ffffff;
background: #20304b; background: #ffffff;
} }
[data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button { [data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button {
color: #d7e6fe; color: #4b4b4b;
background: transparent; background: transparent;
} }
@ -2950,15 +2952,15 @@ div[data-type=codeBlock] .token.inserted {
} }
[data-toolbar-theme=dark] .cherry-bubble .cherry-bubble-top { [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 { [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 { [data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button:hover {
border-color: #20304b; border-color: #ffffff;
} }
.cherry-switch-paste .switch-btn--bg { .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 { [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 { [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 { [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 { [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 { .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-family: "Menlo", "Liberation Mono", "Consolas", "DejaVu Sans Mono", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
font-size: 0.9em; font-size: 0.9em;
} }
@ -3347,7 +3349,7 @@ div[data-type=codeBlock] .token.inserted {
} }
[data-toolbar-theme=dark] .cherry-color-wrap h3 { [data-toolbar-theme=dark] .cherry-color-wrap h3 {
color: #d7e6fe; color: #4b4b4b;
} }
.cherry-color-wrap .cherry-color-text { .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-floatmenu .cherry-toolbar-button,
.cherry.theme__dark .cherry-bubble .cherry-toolbar-button, .cherry.theme__dark .cherry-bubble .cherry-toolbar-button,
.cherry.theme__dark .cherry-sidebar .cherry-toolbar-button { .cherry.theme__dark .cherry-sidebar .cherry-toolbar-button {
color: #d7e6fe; color: #4b4b4b;
} }
.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button:hover, .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 { .cherry.theme__dark .cherry-dropdown .cherry-dropdown-item {
color: #d7e6fe; color: #4b4b4b;
} }
.cherry.theme__dark .cherry-dropdown .cherry-dropdown-item:hover { .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 { .cherry.theme__dark .cherry-dropdown.cherry-color-wrap h3 {
color: #d7e6fe; color: #4b4b4b;
} }
.cherry.theme__dark .cherry-dropdown.cherry-color-wrap .cherry-color-item { .cherry.theme__dark .cherry-dropdown.cherry-color-wrap .cherry-color-item {

View File

@ -22792,7 +22792,7 @@
var $lineNum = Math.max(0, lineNum); var $lineNum = Math.max(0, lineNum);
this.jumpToLine($lineNum, endLine, percent); this.jumpToLine($lineNum, endLine, percent);
Logger.log('scroll to ', $lineNum); // Logger.log('滚动预览区域左侧应scroll to ', $lineNum);
} }
/** /**
* *
@ -42219,7 +42219,7 @@
{ {
// 生产环境屏蔽 // 生产环境屏蔽
Logger.log('markdown', str); // Logger.log('markdown引擎渲染了', str);
} }
} }
@ -56924,7 +56924,7 @@
onScroll = function onScroll() { onScroll = function onScroll() {
if (_this2.applyingDomChanges) { if (_this2.applyingDomChanges) {
Logger.log(new Date(), 'sync scroll locked'); // Logger.log(new Date(), 'sync scroll locked');
return; return;
} }
@ -57253,13 +57253,13 @@
return obj[index].sign; return obj[index].sign;
}); });
var res = myersDiff.doDiff(); var res = myersDiff.doDiff();
Logger.log(res); // Logger.log(res);
this.$dealWithMyersDiffResult(res, oldHtmlList.list, newHtmlList.list, domContainer); this.$dealWithMyersDiffResult(res, oldHtmlList.list, newHtmlList.list, domContainer);
} else if (newHtmlList.list.length && !oldHtmlList.list.length) { } else if (newHtmlList.list.length && !oldHtmlList.list.length) {
var _context8; var _context8;
// 全新增 // 全新增
Logger.log('add all'); // Logger.log('add all');
forEach$3(_context8 = newHtmlList.list).call(_context8, function (piece) { forEach$3(_context8 = newHtmlList.list).call(_context8, function (piece) {
domContainer.appendChild(piece.dom); domContainer.appendChild(piece.dom);
@ -57268,7 +57268,7 @@
var _context9; var _context9;
// 全删除 // 全删除
Logger.log('delete all'); // Logger.log('delete all');
forEach$3(_context9 = oldHtmlList.list).call(_context9, function (piece) { forEach$3(_context9 = oldHtmlList.list).call(_context9, function (piece) {
domContainer.removeChild(piece.dom); domContainer.removeChild(piece.dom);

View File

@ -180,6 +180,25 @@
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
</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>
<div class="pull-right text-center" style="width: 235px;"> <div class="pull-right text-center" style="width: 235px;">
<canvas id="bookCover" height="230px" width="170px"><img src="{{cdnimg "/static/images/book.jpg"}}"> </canvas> <canvas id="bookCover" height="230px" width="170px"><img src="{{cdnimg "/static/images/book.jpg"}}"> </canvas>

View File

@ -128,6 +128,15 @@
</div> </div>
{{end}} {{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"> <div class="form-group">
<label for="autoRelease">{{i18n $.Lang "blog.auto_publish"}}</label> <label for="autoRelease">{{i18n $.Lang "blog.auto_publish"}}</label>
<div class="controls"> <div class="controls">

View File

@ -88,7 +88,9 @@
</div> </div>
{{end}} {{end}}
{{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> <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;"> <div class="dropdown pull-right" style="margin-right: 10px;">
{{if eq .Model.PrivatelyOwned 0}} {{if eq .Model.PrivatelyOwned 0}}
{{if .Model.IsEnableShare}} {{if .Model.IsEnableShare}}