Browse Source

markdown

master
mail_yanpeng@163.com 4 years ago
parent
commit
fc21a40401
  1. 2
      controllers/BlogController.go
  2. 16
      static/css/common.css
  3. 3
      static/css/common.min.css
  4. 70
      views/editblog.html
  5. 102
      views/iframe/blog.html
  6. 77
      views/iframe/note.html
  7. 298
      views/newblog.html

2
controllers/BlogController.go

@ -75,6 +75,7 @@ func (this *BlogController) Edit() {
id, _ := this.GetInt64("id")
title := this.GetString("title")
blogHtml := this.GetString("blogHtml")
blogValue := this.GetString("blogValue")
blogDesc := this.GetString("blogDesc")
catory := this.GetString("catory")
catoryId, _ := strconv.ParseInt(catory, 10, 64)
@ -89,6 +90,7 @@ func (this *BlogController) Edit() {
blog.BlogHtml = blogHtml
blog.BlogDesc = blogDesc
blog.CategoryId = catoryId
blog.BlogValue = blogValue
blog.Utime = time.Now()
err = blogService.EditBlog(blog, labels)
if err == nil {

16
static/css/common.css

@ -711,3 +711,19 @@ img {
.search-content{
font-size: 12px;
}
.v-note-wrapper {
height: 100%;
z-index: 99 !important;
}
.modal_form{
display: flex;
margin-bottom: 10px;
}
.modal_form .span-lable{
display: inline-block;
width: 100px;
height: 30px;
line-height: 30px;
}

3
static/css/common.min.css

File diff suppressed because one or more lines are too long

70
views/editblog.html

@ -5,27 +5,10 @@
<script src="/static/editor/mavon-editor.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
</head>
<style>
.modal_form{
display: flex;
margin-bottom: 10px;
}
.modal_form .span-lable{
display: inline-block;
width: 100px;
height: 30px;
line-height: 30px;
}
</style>
<body>
<div class="root-container" id="vue-app">
<div class="blog-title">
<i-input type="text" v-model="blog.Title" placeholder="请输入文章标题"/>
<input type="text" id="blog-title" placeholder="请输入文章标题" value="{{.Blog.Title}}">
<button type="button" id="newBtn" class="layui-btn layui-btn-radius layui-btn-danger layui-btn-sm "
style="border-radius: 12px">
发布文章
</button>
</div>
<mavon-editor :externalLink="externalLink" :toolbars="toolbars" v-model="blog.BlogValue" @imgAdd="$imgAdd"
@save="saveHandler" @change="changeHandler" ref=md></mavon-editor>
@ -35,7 +18,7 @@
title="发布文章"
:mask-closable="false">
<div class="modal_form">
<span class="span-lable">开发语言</span>
<span class="span-lable">文章分类</span>
<i-select v-model="blog.CategoryId" style="width:300px">
<i-option v-for="item in cats" :value="item.Id" :key="item.Id">${ item.Title }</i-option>
</i-select>
@ -47,7 +30,7 @@
</i-button>
</div>
<div class="modal_form">
<span class="span-lable">开发语言</span>
<span class="span-lable">添加标签</span>
<div style="display: inline-block;width: 241px">
<i-input type="text" v-model="lableTitle" placeholder="请输入标签名称"/>
</div>
@ -59,12 +42,6 @@
</Modal>
</div>
</body>
<style>
.v-note-wrapper {
height: 100%;
z-index: 99 !important;
}
</style>
<script>
var app = new Vue({
delimiters: ['${', '}'],
@ -139,28 +116,44 @@
if (!this.blog.BlogValue && this.blog.BlogHtml) {
this.blog.BlogValue = this.blog.BlogHtml
}
this.lables = this.blog.Lables
this.getCatas()
this.lables = this.blog.Lables
debugger
},
methods: {
okHandler (){
if(!this.blog.CategoryId || this.blog.CategoryId==0){
this.$Notice.warning({
title: '文章分类必须选择',
})
return
}
var _this = this
this.loading = true
this.loading = false
var tobj = {}
tobj.id = this.blog.Id
tobj.title = this.blog.Title
tobj.blogHtml = this.blog.BlogHtml
var regex = /(<([^>]+)>)/ig
tobj.blogDesc = tobj.blogHtml.replace(regex,"").substring(0,200)
tobj.catory = this.blog.CategoryId
tobj.blogValue = this.blog.BlogValue
tobj.labels = []
this.lables.forEach(el=>{
tobj.labels.push(el.Title)
})
$.post('/api/blog/edit', tobj,
function (data) {
_this.loading = false
if (data.Status == 0) {
storage.removeItem("blogHtml");
storage.removeItem("blogTitle");
layer.msg("保存成功", {icon: 6});
callback(true)
window.location.href = "/blog/{{.Blog.Id}}"
} else if (data.Status == 401) {
window.location.href = "login"
window.location.href = "/login"
} else if (data.Status == 500) {
layer.msg("保存失败", {icon: 6});
callback(false)
}
}, 'json')
},
addLable(){
@ -185,7 +178,7 @@
if (data.Status == 0) {
_this.cats = data.Data
} else if (data.Status == 401) {
window.location.href = "login"
window.location.href = "/login"
} else if (data.Status == 500) {
}
@ -228,16 +221,5 @@
},
}
})
function saveBlog() {
layer.open({
type: 2,
title: '发布文章',
shadeClose: true,
shade: 0.8,
area: ['420px', '280px'],
content: '/iframe/blog.html?id={{.Blog.Id}}' //iframe的url
});
}
</script>
</html>

102
views/iframe/blog.html

@ -1,102 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="码农随笔,个人随笔是一个面向IT技术人员,提供个人平时工作总结和在线记录学习笔记,个人技术博客,在线云笔记,码农笔录,最新的技术博客,www.aiprose.com">
<meta name="keywords"
content="码农随笔,个人随笔,博客,个人博客,个人笔记,技术博客,免费云笔记,云笔记,随笔,IT博客,谷歌地图,码农笔录,www.aiprose.com,aiprose.com,aiprose">
<link rel="stylesheet" href="//oss.aiprose.com/ali/sui/css/sui.min.css">
<script type="text/javascript" src="//oss.aiprose.com/ali/jquery/jquery.min.js"></script>
<script type="text/javascript" src="//oss.aiprose.com/ali/sui/js/sui.min.js"></script>
<title>发布博客 - 码农随笔</title>
<style>
.common {
margin: 10px 0;
}
.tag {
margin: 3px 0;
}
</style>
</head>
<body>
<div style="margin: 5px 10px">
<div class="common">
<span>开发语言:</span>
<span>
<select class="form-control " style="width: 150px;display: inline-block;height: 32px" id="catory">
{{range .Cats}}
<option value="{{.Id}}">{{.Title}}</option>
{{end}}
</select>
</span>
</div>
<div class="common">
<span style="flex: 1;height: 30px;line-height: 30px;">文章标签:</span>
<div class="tag-group tag-removable" data-toggle='tag' id="labels">
</div>
</div>
<div class="common">
<span>添加标签:</span>
<input type="text" placeholder="输入标签" class="input-xfat" style="height: 26px;" id="lable">
<button type="button" class="btn btn-primary" style="height: 26px;margin-top: -5px;" id="addBtn">添加</button>
</div>
<div class="common" style="text-align: center">
<button type="button" class="btn btn-primary btn-xl" id="saveBtn">保存</button>
<button type="button" class="btn btn-warning btn-xl" id="cacelBtn">取消</button>
</div>
</div>
</body>
<script>
$(function () {
if (parent.tobj.catory) {
$("#catory").val(parent.tobj.catory)
}
if (parent.tobj.labels) {
for (var i = 0; i < parent.tobj.labels.length; i++) {
var child = "<label class='tag tag-primary'>" + parent.tobj.labels[i] + "<a name='remove'><i class=\"iconfont icon-close\"></i></a> "
+ "<input type='checkbox' class='simple-tag' name='simple-tag-1' value='" + parent.tobj.labels[i] + "' checked='checked'/></label>"
$("#labels").append(child)
}
}
$("#addBtn").click(function () {
var temp = $("#lable").val()
if (temp.trim().length != 0) {
if ($("#labels").children().length > 5) {
layer.msg('5个标签还不够', function () {
});
return
}
var child = "<label class='tag tag-primary'>" + temp + "<a name='remove'><i class=\"iconfont icon-close\"></i></a> "
+ "<input type='checkbox' class='simple-tag' name='simple-tag-1' value='" + temp + "' checked='checked'/></label>"
$("#labels").append(child)
$("#lable").val("")
}
})
$("#saveBtn").click(function () {
parent.tobj.catory = $("#catory").val()
var tarr = []
$.each($(".simple-tag"), function () {
tarr.push($(this).val())
});
parent.tobj.labels = tarr
console.log(tarr)
parent.saveBlogCallback(function (flag) {
if (flag) {
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
})
})
$("#cacelBtn").click(function () {
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
})
</script>
</html>

77
views/iframe/note.html

@ -1,77 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="码农随笔,个人随笔是一个面向IT技术人员,提供个人平时工作总结和在线记录学习笔记,个人技术博客,在线云笔记,码农笔录,最新的技术博客,www.aiprose.com">
<meta name="keywords"
content="码农随笔,个人随笔,博客,个人博客,个人笔记,技术博客,免费云笔记,云笔记,随笔,IT博客,谷歌地图,码农笔录,www.aiprose.com,aiprose.com,aiprose">
<link rel="stylesheet" href="//oss.aiprose.com/ali/sui/css/sui.min.css">
<script type="text/javascript" src="//oss.aiprose.com/ali/jquery/jquery.min.js"></script>
<script type="text/javascript" src="//oss.aiprose.com/ali/sui/js/sui.min.js"></script>
<script type="text/javascript" src="/static/js/layer.js"></script>
<title>发布笔记 - 码农随笔</title>
<style>
.common {
margin: 15px 0;
display: flex;
height: 32px;
line-height: 32px;
}
</style>
</head>
<body>
<div style="margin: 20px 35px;">
<div class="common">
<span>所属文件夹:</span>
<span style="flex: 1">
<select class="form-control " style="display: inline-block;height: 32px" id="catory">
{{range .NoteColl}}
<option value="{{.Id}}">{{.Title}}</option>
{{end}}
</select>
</span>
</div>
<div class="common">
<span>新笔记名称:</span>
<input type="text" placeholder="输入标签" class="input-xfat" style="height: 32px;flex: 1" id="lable">
</div>
<div class="common" style="text-align: center">
<button type="button" class="btn btn-primary btn-lg btn-block" id="saveBtn">保存</button>
</div>
</div>
</body>
<script>
$(function () {
if (!{{.IsLogin}}) {
parent.location.href = "/login"
return
}else if ({{.NoteColl|len}} == 0) {
parent.location.href = "/me/note"
}
$("#saveBtn").click(function () {
var pid = $("#catory").val()
var title = $("#lable").val()
$.post('/api/note/save', {
pid: pid,
title: title
},
function (data) {
if (!data.Status) {
parent.addNoteCallback(data)
parent.layer.msg("保存成功", {icon: 6});
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
} else if (data.Status == 401) {
parent.location.href = "/login"
parent.layer.close(index);
} else {
layer.msg("服务器异常", {icon: 5});
}
}, 'json')
})
})
</script>
</html>

298
views/newblog.html

@ -1,101 +1,227 @@
{{template "header" .}}
<meta name="keywords" content="码农随笔,个人随笔,博客,个人博客,个人笔记,技术博客,免费云笔记,云笔记,随笔,IT博客,谷歌地图,码农笔录,www.aiprose.com,aiprose.com,aiprose">
<title>发布博客 - 码农随笔</title>
<script src="/static/js/wangEditor.min.js"></script>
<link rel="stylesheet" href="/static/editor/css/index.css">
<script src="/static/editor/mavon-editor.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
</head>
<body>
<div class="root-container">
<div class="root-container" id="vue-app">
<div class="blog-title">
<input type="text" id="blog-title" placeholder="请输入文章标题">
<button type="button" id="newBtn" class="layui-btn layui-btn-radius layui-btn-danger layui-btn-sm " style="border-radius: 12px">
发布文章
</button>
<i-input type="text" v-model="blog.Title" placeholder="请输入文章标题"/>
</div>
<div id="editor" class="editor">
<mavon-editor :externalLink="externalLink" :toolbars="toolbars" v-model="blog.BlogValue" @imgAdd="$imgAdd"
@save="saveHandler" @change="changeHandler" ref=md></mavon-editor>
</div>
<Modal
v-model="showModal"
title="发布文章"
:mask-closable="false">
<div class="modal_form">
<span class="span-lable">文章分类:</span>
<i-select v-model="blog.CategoryId" style="width:300px">
<i-option v-for="item in cats" :value="item.Id" :key="item.Id">${ item.Title }</i-option>
</i-select>
</div>
<div class="modal_form">
<span class="span-lable">文章标签:</span>
<i-button type="primary" ghost size="small" v-for="item,index in lables" :key="index" style="margin-left: 5px">${item.Title}
<Icon type="ios-close-circle-outline" @click="delLabel(index)"/>
</i-button>
</div>
<div class="modal_form">
<span class="span-lable">添加标签:</span>
<div style="display: inline-block;width: 241px">
<i-input type="text" v-model="lableTitle" placeholder="请输入标签名称"/>
</div>
<i-button type="primary" ghost @click="addLable">添加</i-button>
</div>
<div slot="footer">
<i-button type="error" size="large" long :loading="loading" @click="okHandler">保存</i-button>
</div>
</Modal>
</div>
</body>
<script>
var storage=window.localStorage
var E = window.wangEditor
var editor = new E('#editor')
editor.customConfig.uploadImgServer = '/file/upload'
// 或者 var editor = new E( document.getElementById('editor') )
editor.customConfig.uploadImgHooks = {
customInsert: function (insertImg, result, editor) {
insertImg(result.Data);
var app = new Vue({
delimiters: ['${', '}'],
el: '#vue-app',
components: {
'mavon-editor': MavonEditor.mavonEditor
},
data: {
loading: false,
lableTitle: '',
cats: [],
lables: [],
showModal: false,
blog: {
Title: '',
BlogValue: '',
BlogHtml: '',
CategoryId: 0
},
toolbars: {
bold: true, // 粗体
italic: true, // 斜体
header: true, // 标题
underline: true, // 下划线
strikethrough: true, // 中划线
mark: true, // 标记
superscript: true, // 上角标
subscript: true, // 下角标
quote: true, // 引用
ol: true, // 有序列表
ul: true, // 无序列表
link: true, // 链接
imagelink: true, // 图片链接
code: true, // code
table: true, // 表格
//fullscreen: true, // 全屏编辑
readmodel: true, // 沉浸式阅读
htmlcode: true, // 展示html源码
help: true, // 帮助
/* 1.3.5 */
undo: true, // 上一步
//redo: true, // 下一步
trash: true, // 清空
save: true, // 保存(触发events中的save事件)
/* 1.4.2 */
navigation: true, // 导航目录
/* 2.1.8 */
alignleft: true, // 左对齐
aligncenter: true, // 居中
alignright: true, // 右对齐
/* 2.2.1 */
subfield: true, // 单双栏模式
preview: true, // 预览
menu: true, // 预览
},
externalLink: {
// markdown_css: function() {
// // 这是你的markdown css文件路径
// return '/markdown/github-markdown.min.css';
// },
katex_css: function () {
// 这是你的katex配色方案路径路径
return '/katex/katex.min.css';
},
katex_js: function () {
// 这是你的katex.js路径
return '/katex/katex.min.js';
},
},
},
created() {
let item = window.localStorage.getItem("blogValue");
if(item){
this.blog.BlogValue = item
}
let itemTitle = window.localStorage.getItem("blogTilte");
if(itemTitle){
this.blog.Title = itemTitle
}
this.getCatas()
},
methods: {
okHandler (){
if(!this.blog.CategoryId || this.blog.CategoryId==0){
this.$Notice.warning({
title: '文章分类必须选择',
})
return
}
var _this = this
this.loading = true
var tobj = {}
tobj.title = this.blog.Title
window.localStorage.setItem("blogTilte",this.blog.Title);
tobj.blogHtml = this.blog.BlogHtml
var regex = /(<([^>]+)>)/ig
tobj.blogDesc = tobj.blogHtml.replace(regex,"").substring(0,200)
tobj.catory = this.blog.CategoryId
tobj.blogValue = this.blog.BlogValue
tobj.labels = []
this.lables.forEach(el=>{
tobj.labels.push(el.Title)
})
$.post('/api/blog/new', tobj,
function (data) {
_this.loading = false
if (data.Status == 0) {
window.localStorage.removeItem("blogValue");
window.localStorage.removeItem("blogTilte");
layer.msg("保存成功", {icon: 6});
window.location.href = "/blog/"+ data.Data
} else if (data.Status == 401) {
window.location.href = "/login"
} else if (data.Status == 500) {
layer.msg("保存失败", {icon: 6});
}
}, 'json')
},
addLable(){
if(!this.lableTitle){
this.$Notice.warning({
title: '请先输入标签名称',
})
return
}
var tobj = {}
tobj.Title = this.lableTitle
this.lables.push(tobj)
this.lableTitle = ''
},
delLabel(index){
this.lables.splice(index,1)
},
getCatas(){
var _this = this
$.get('/api/cats',
function (data) {
if (data.Status == 0) {
_this.cats = data.Data
} else if (data.Status == 401) {
window.location.href = "/login"
} else if (data.Status == 500) {
}
}, 'json')
},
$imgAdd(pos, $file) {
var _this = this
// 第一步.将图片上传到服务器.
var formdata = new FormData();
formdata.append('image', $file);
axios({
url: '/file/upload',
method: 'post',
data: formdata,
headers: {'Content-Type': 'multipart/form-data'},
}).then((resp) => {
_this.$refs.md.$img2Url(pos, resp.data.Data);
})
},
changeHandler(value, render) {
this.blog.BlogValue = value
this.blog.BlogHtml = render
window.localStorage.setItem("blogValue",value);
},
saveHandler(value, render) {
if (this.blog.Title.trim().length < 3) {
this.$Notice.warning({
title: '文章标题最少三个字',
})
return
}
if (this.blog.BlogValue.trim().length == 0) {
this.$Notice.warning({
title: '文章内容不能为空哦',
})
return
}
this.showModal = true
},
}
}
editor.create()
document.onkeydown = keyDown;
function keyDown(e) {
var currKey = 0, e = e || event || window.event;
currKey = e.keyCode || e.which || e.charCode;
if (currKey == 83 && (e.ctrlKey || e.metaKey)) {
saveBlog()
return
}
}
function saveBlog() {
var title = $("#blog-title").val();
if (title.trim().length < 3) {
layer.msg('文章标题最少三个字', function () {
});
return
}
tobj.title = $("#blog-title").val();
if (editor.txt.html().trim().length == 0) {
layer.msg('文章内容不能为空哦', function () {
});
return
}
tobj.blogHtml = editor.txt.html();
tobj.blogDesc = editor.txt.text().substring(0,200)
storage.setItem("blogHtml",tobj.blogHtml);
storage.setItem("blogTitle",tobj.title);
layer.open({
type: 2,
title: '发布文章',
shadeClose: true,
shade: 0.8,
area: ['420px', '280px'],
content: '/iframe/blog.html/' //iframe的url
});
}
var tobj = {}
$(function () {
var oldVal = storage.getItem("blogHtml");
editor.txt.html(oldVal);
var oldTitle = storage.getItem("blogTitle");
$("#blog-title").val(oldTitle);
var height = document.documentElement.clientHeight
$(".w-e-text-container").height(height - 50 - 40 - 1);
$("#newBtn").click(function () {
saveBlog()
})
})
function saveBlogCallback(callback) {
$.post('/api/blog/new', tobj,
function (data) {
if (data.Status == 0) {
storage.removeItem("blogHtml");
storage.removeItem("blogTitle");
layer.msg("保存成功", {icon: 6});
callback(true)
window.location.href = "/blog/"+ data.Data
} else if (data.Status == 401) {
window.location.href = "login"
} else if (data.Status == 500) {
layer.msg("保存失败", {icon: 6});
callback(false)
}
}, 'json')
}
</script>
</html>
Loading…
Cancel
Save