修复Bug和优化功能样式

This commit is contained in:
yangjian 2020-02-24 21:05:08 +08:00
parent f2f4a97c37
commit 44ad624a3a
12 changed files with 202 additions and 43 deletions

View File

@ -1,5 +1,17 @@
## 版本更新记录
### v0.2.11 2020-02-24
- 修复:删除文档导致其子文档找不到父级文档从而产生异常的Bug
- 优化管理员界面文档管理的筛选功能,支持按文档状态进行筛选;
- 优化修改文档后的跳转判断;
- 优化文档阅读页面、新建文档页面和修改页面的无序列表样式;
- 优化文档阅读页面指定语言的代码块样式去除prism代码高亮插件避免其与editormd的样式冲突
- 更改文档保存的HTML内容为预览时的HTMl而非editormd渲染的HTML
- 添加Markdown编辑器对流程图和序列图的支持
- 添加Markdown编辑器对部分HTML标签的识别和解析
### v0.2.10 2020-02-22
- 优化修改文档页面的文档状态提示;

View File

@ -25,7 +25,7 @@ SECRET_KEY = '5&71mt9@^58zdg*_!t(x6g14q*@84d%ptr%%s6e0l50zs0we3d'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
VERSIONS = '0.2.10'
VERSIONS = '0.2.11'
ALLOWED_HOSTS = ['*']

View File

@ -8,7 +8,7 @@
州的先生zmister.com自用并完全开源、基于Python编写的文档写作系统。
当前版本为:**v0.2.10**,版本发布时间为**2020-02-22**,更新记录详见:[CHANGES.md](./CHANGES.md)
当前版本为:**v0.2.11**,版本发布时间为**2020-02-24**,更新记录详见:[CHANGES.md](./CHANGES.md)
MrDoc拥有以下特点

View File

@ -4,7 +4,7 @@ from django.http import HttpResponseForbidden
from django.contrib.auth.decorators import login_required # 登录需求装饰器
from django.views.decorators.http import require_http_methods,require_GET,require_POST # 视图请求方法装饰器
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage,InvalidPage # 后端分页
from django.core.exceptions import PermissionDenied
from django.core.exceptions import PermissionDenied,ObjectDoesNotExist
from app_doc.models import Project,Doc,DocTemp
from django.contrib.auth.models import User
from django.db.models import Q
@ -267,7 +267,10 @@ def doc(request,pro_id,doc_id):
return redirect('/check_viewcode/?to={}'.format(request.path))
# 获取文档内容
doc = Doc.objects.get(id=int(doc_id),status=1)
try:
doc = Doc.objects.get(id=int(doc_id),status=1)
except ObjectDoesNotExist:
return render(request, '404.html')
# 获取文集下一级文档
project_docs = Doc.objects.filter(top_doc=doc.top_doc, parent_doc=0, status=1).order_by('sort')
return render(request,'app_doc/doc.html',locals())
@ -366,11 +369,19 @@ def modify_doc(request,doc_id):
@login_required()
def del_doc(request):
try:
# 获取文档ID
doc_id = request.POST.get('doc_id',None)
if doc_id:
doc = Doc.objects.get(id=doc_id)
# 查询文档
try:
doc = Doc.objects.get(id=doc_id)
except ObjectDoesNotExist:
return JsonResponse({'status': False, 'data': '文档不存在'})
if request.user == doc.create_user:
# 删除
doc.delete()
# 修改其子文档为顶级文档
Doc.objects.filter(parent_doc=doc_id).update(parent_doc=0)
return JsonResponse({'status': True, 'data': '删除完成'})
else:
return JsonResponse({'status': False, 'data': '非法请求'})
@ -384,9 +395,41 @@ def del_doc(request):
@login_required()
def manage_doc(request):
if request.method == 'GET':
# 文档内容搜索参数
search_kw = request.GET.get('kw',None)
if search_kw:
doc_list = Doc.objects.filter(create_user=request.user,content__icontains=search_kw).order_by('-modify_time')
# 已发布文档数量
published_doc_cnt = Doc.objects.filter(
create_user=request.user, status=1
).count()
# 草稿文档数量
draft_doc_cnt = Doc.objects.filter(
create_user=request.user, status=0
).count()
# 所有文档数量
all_cnt = published_doc_cnt + draft_doc_cnt
# 获取文档状态筛选参数
doc_status = request.GET.get('status', 'all')
# 查询文档
if doc_status == 'all':
doc_list = Doc.objects.filter(
create_user=request.user,
content__icontains=search_kw
).order_by('-modify_time')
elif doc_status == 'published':
doc_list = Doc.objects.filter(
create_user=request.user,
content__icontains=search_kw,
status = 1
).order_by('-modify_time')
elif doc_status == 'draft':
doc_list = Doc.objects.filter(
create_user=request.user,
content__icontains=search_kw,
status = 0
).order_by('-modify_time')
# 分页处理
paginator = Paginator(doc_list, 10)
page = request.GET.get('page', 1)
try:
@ -396,13 +439,39 @@ def manage_doc(request):
except EmptyPage:
docs = paginator.page(paginator.num_pages)
docs.kw = search_kw
docs.status = doc_status
else:
doc_list = Doc.objects.filter(create_user=request.user).order_by('-modify_time')
all_cnt = doc_list.count() # 所有文档数量
published_doc_cnt = Doc.objects.filter(create_user=request.user,status=1).count() # 已发布文档数量
draft_doc_cnt = Doc.objects.filter(create_user=request.user,status=0).count() # 草稿文档数据
pro_list = Project.objects.filter(create_user=request.user)
# 已发布文档数量
published_doc_cnt = Doc.objects.filter(
create_user=request.user,status=1
).count()
# 草稿文档数量
draft_doc_cnt = Doc.objects.filter(
create_user=request.user,status=0
).count()
# 所有文档数量
all_cnt = published_doc_cnt + draft_doc_cnt
# 获取文档状态筛选参数
doc_status = request.GET.get('status','all')
if len(doc_status) == 0:
doc_status = 'all'
print('status:', doc_status,type(doc_status))
# 返回所有文档
if doc_status == 'all':
doc_list = Doc.objects.filter(create_user=request.user).order_by('-modify_time')
# 返回已发布文档
elif doc_status == 'published':
doc_list = Doc.objects.filter(
create_user=request.user,status=1
).order_by('-modify_time')
# 返回草稿文档
elif doc_status == 'draft':
doc_list = Doc.objects.filter(
create_user=request.user, status=0
).order_by('-modify_time')
else:
doc_list = Doc.objects.filter(create_user=request.user).order_by('-modify_time')
# 分页处理
paginator = Paginator(doc_list, 10)
page = request.GET.get('page', 1)
try:
@ -411,6 +480,7 @@ def manage_doc(request):
docs = paginator.page(1)
except EmptyPage:
docs = paginator.page(paginator.num_pages)
docs.status = doc_status
return render(request,'app_doc/manage_doc.html',locals())
else:
return HttpResponse('方法不允许')
@ -549,16 +619,26 @@ def get_pro_doc(request):
if request.method == 'POST':
pro_id = request.POST.get('pro_id','')
if pro_id != '':
# 获取文集所有文档的id、name和parent_doc3个字段
doc_list = Doc.objects.filter(top_doc=int(pro_id)).values_list('id','name','parent_doc').order_by('parent_doc')
item_list = []
# 遍历文档
for doc in doc_list:
# 如果文档为顶级文档
if doc[2] == 0:
# 将其数据添加到列表中
item = [
doc[0],doc[1],doc[2],''
]
item_list.append(item)
# 如果文档不是顶级文档
else:
parent = Doc.objects.get(id=doc[2])
# 查询文档的上级文档
try:
parent = Doc.objects.get(id=doc[2])
except ObjectDoesNotExist:
return JsonResponse({'status':False,'data':'文档id不存在'})
# 如果文档上级文档的上级是顶级文档,那么将其添加到列表
if parent.parent_doc == 0: # 只要二级目录
item = [
doc[0],doc[1],doc[2],parent.name+' --> '

View File

@ -72,7 +72,8 @@
<div class="layui-footer" style="text-align:center;">
<!-- 底部固定区域 -->
© 2019 <a href="http://mrdoc.zmister.com" target="_blank">MrDoc</a> - 一个简单的文档系统
© <a href="https://gitee.com/zmister/MrDoc" target="_blank">MrDoc 2019-2020</a>&nbsp;-&nbsp;
当前版本:<a href="https://gitee.com/zmister/MrDoc/tree/{{mrdoc_version}}/" target="_blank">{{mrdoc_version}}</a>
</div>
</div>

View File

@ -23,6 +23,9 @@
.markdown-body ol li{
list-style-type: decimal;
}
.markdown-body ol ol ul,.markdown-body ol ul ul,.markdown-body ul ol ul,.markdown-body ul ul ul li{
list-style-type: square;
}
</style>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
@ -44,7 +47,7 @@
</div>
<!-- 主体结束 -->
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script src="{% static 'jquery/3.1.1/jquery.min.js' %}"></script>
<script src="{% static 'layui/layui.all.js' %}"></script>
<script src="{% static 'editor.md/editormd.min.js' %}"></script>
<script>
@ -58,11 +61,11 @@
var editor = editormd("editor-md", {
width : "100%",
height : "1000px;",
placeholder : "开始使用Markdown书写MrDoc文档……\n编辑器支持粘贴上传图片",
placeholder : "开始使用Markdown书写MrDoc文档,编辑器支持以下功能:\n1.粘贴上传图片\n2.六级标题\n3.代码高亮\n4.本地图片和外链图片\n5.表格\n6.多级列表和任务列表\n7.Katex公式\n8.流程图\n9.时序图\n……",
toolbarIcons : function() {
return [
"undo", "redo", "|",
"bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|",
"bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase","kaiSpan", "|",
"h1", "h2", "h3", "h4", "h5", "h6", "|",
"list-ul", "list-ol", "hr", "|",
"link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime", "emoji", "html-entities", "pagebreak", "|",
@ -70,9 +73,42 @@
"help"
]
},
//自定义工具栏添加楷体按钮
toolbarIconTexts : {
kaiSpan : "楷"
},
//设置自定义工具栏按钮的事件
toolbarHandlers : {
/**
* @param {Object} cm CodeMirror对象
* @param {Object} icon 图标按钮jQuery元素对象
* @param {Object} cursor CodeMirror的光标对象可获取光标所在行和位置
* @param {String} selection 编辑器选中的文本
*/
kaiSpan : function(cm, icon, cursor, selection) {
//var cursor = cm.getCursor(); //获取当前光标对象同cursor参数
//var selection = cm.getSelection(); //获取当前选中的文本同selection参数
// 替换选中文本,如果没有选中文本,则直接插入
cm.replaceSelection('<span style="font-family:楷体">' + selection + "</span>");
// 如果当前没有选中的文本,将光标移到要输入的位置
if(selection === "") {
cm.setCursor(cursor.line, cursor.ch + 1);
}
// this == 当前editormd实例
//console.log("testIcon =>", this, cm, icon, cursor, selection);
},
},
//设置语言
lang : {
toolbar : {
kaiSpan : "添加楷体span标签",
}
},
//配置项
pageBreak : true, //分页符
path : "/static/editor.md/lib/",
saveHTMLToTextarea : true,
atLink : false,//禁用@链接
tex : true,//开启科学公式
tocm : true,//开启下拉目录
taskList : true,//开启任务列表
@ -80,7 +116,10 @@
tocContainer: '',
tocDropdown : false,
emoji : true,//开启Emoji
flowChart : true, //开启流程图
sequenceDiagram : true, //开启序列图
imageUpload : true, //开启图片上传
htmlDecode : "link,style,script,iframe|on*", //解析部分HTML标签
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "{% url 'upload_doc_img' %}",
onchange:function(){

View File

@ -138,7 +138,8 @@
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'content':editor.getHTML(),
//'content':editor.getHTML(),//获取editor解析的HTML
'content':editor.getPreviewedHTML(),//获取预览的HTML
'pre_content':editor.getMarkdown(),
'sort':$("#sort").val(),
}

View File

@ -29,11 +29,11 @@
{% block page_content %}
{# {{ doc.content | safe }} #}
<style>
<!--<style>
div.editormd-toc-menu ul.markdown-toc-list li,ul.markdown-toc-list > li > ul li{
list-style: none;
<!--list-style: none;
}
</style>
</style>-->
<textarea id="" style="display: none;">{{ doc.pre_content }}</textarea>
{% endblock %}

View File

@ -13,21 +13,35 @@
<title>{% block title %}{% endblock %} - MrDoc</title>
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.css' %}" />
<link rel="stylesheet" href="{% static 'prism/prism.css' %}" />
<!--<link rel="stylesheet" href="{% static 'prism/prism.css' %}" />-->
<link rel="stylesheet" href="{% static 'katex/katex.min.css' %}" />
<link rel="stylesheet" href="{% static 'share.js/css/share.min.css' %}" />
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
<link href="{% static 'mrdoc.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<style>
/*一级无序li显示实心圆点*/
.doc-content ul li{
list-style:disc;
}
/*二级无序li显示空心圆点*/
.doc-content ul > li > ul > li{
list-style-type: circle;
}
/*有序li显示数字*/
.doc-content ol li{
list-style-type: decimal;
}
.doc-content ol ol ul,.doc-content ol ul ul,.doc-content ul ol ul,.doc-content ul ul ul {
list-style-type: square;
}
/* 三级及以下无序li显示小方块 */
.doc-content ul ul ul li{
list-style-type: square;
}
/* 下拉目录隐藏li样式 */
.editormd-toc-menu ul.markdown-toc-list li{
list-style:none;
}
</style>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
@ -173,9 +187,9 @@
<div class="toTop"><i class="layui-icon layui-icon-top" style="font-size: 50px;"></i></div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script src="{% static 'jquery/3.1.1/jquery.min.js' %}"></script>
<script src="{% static 'layui/layui.all.js' %}"></script>
<script src="{% static 'prism/prism.js' %}"></script>
<!--<script src="{% static 'prism/prism.js' %}"></script>-->
<script src="{% static 'editor.md/lib/marked.min.js' %}"></script>
<script src="{% static 'editor.md/lib/prettify.min.js' %}"></script>
<script src="{% static 'editor.md/lib/raphael.min.js' %}"></script>
@ -213,12 +227,13 @@
//解析Markdown为HTML
editormd.markdownToHTML("content", {
htmlDecode : "style,script,iframe",
emoji : true,
taskList : true,
emoji : true, //emoji表情
taskList : true, // 任务列表
tex : true, // 科学公式
flowChart : true, // 流程图
sequenceDiagram : true, // 默认不解析
sequenceDiagram : true, // 时序图
tocm : true, //目录
atLink : false,//禁用@链接
//tocContainer : "#toc-container"
});
//为当前页面的目录链接添加蓝色样式

View File

@ -14,6 +14,10 @@
.layui-btn a{
color:white;
}
/* 管理文档 文档状态条件筛选 */
.doc_status_condition > a.current{
color: #000!important;
}
</style>
</head>
<body class="layui-layout-body">
@ -66,7 +70,8 @@
<div class="layui-footer" style="text-align:center;">
<!-- 底部固定区域 -->
© <a href="/">MrDoc 2019</a>
© <a href="https://gitee.com/zmister/MrDoc" target="_blank">MrDoc 2019-2020</a>&nbsp;-&nbsp;
当前版本:<a href="https://gitee.com/zmister/MrDoc/tree/{{mrdoc_version}}/" target="_blank">{{mrdoc_version}}</a>
</div>
</div>

View File

@ -4,14 +4,20 @@
{% block content %}
<div class="layui-card-header" style="margin-bottom: 10px;">
<div class="layui-row">
<span style="font-size:18px;">文档管理
</span>
<span style="font-size:18px;">文档管理</span>
{% if search_kw %} - 搜索“{{search_kw}}”的结果{% endif %}
</div>
</div>
<div class="layui-row">
<form action="{% url 'manage_doc' %}" method="get">
<div class="layui-form-item">
<div class="layui-input-inline">
<span class="layui-breadcrumb doc_status_condition" lay-separator="|">
<a href="{% url 'manage_doc' %}?status=all" class="{% if doc_status == 'all' %}current{% endif %}">全部({{all_cnt}}</a>
<a href="{% url 'manage_doc' %}?status=published" class="{% if doc_status == 'published' %}current{% endif %}">已发布({{published_doc_cnt}}</a>
<a href="{% url 'manage_doc' %}?status=draft" class="{% if doc_status == 'draft' %}current{% endif %}">草稿({{draft_doc_cnt}}</a>
<input name="status" value="{% if doc_status == 'all' %}all{% elif doc_status == 'published' %}published{% elif doc_status == 'draft' %}draft{% endif %}" hidden>
</span>
<div class="layui-input-inline" style="float:inherit;">
<input type="text" name="kw" id="kw" placeholder="输入文档内容" autocomplete="off" class="layui-input">
</div>
<button class="layui-btn layui-btn-normal" type="submit">搜索</button>
@ -21,14 +27,12 @@
</div>
<div class="layui-row">
<form action="{% url 'manage_doc' %}" method="get" class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">状态筛选</label>
<div class="layui-input-block">
<input type="radio" name="doc_status" value="全部" title="全部({{all_cnt}}" checked>
<input type="radio" name="doc_status" value="已发布" title="已发布({{published_doc_cnt}}" disabled>
<input type="radio" name="doc_status" value="草稿" title="草稿({{draft_doc_cnt}}" disabled>
</div>
<!--<span class="layui-breadcrumb doc_status_condition" lay-separator="|">-->
<!--<a href="{% url 'manage_doc' %}?status=all" class="{% if doc_status == 'all' %}current{% endif %}">全部({{all_cnt}}</a>-->
<!--<a href="{% url 'manage_doc' %}?status=published" class="{% if doc_status == 'published' %}current{% endif %}">已发布({{published_doc_cnt}}</a>-->
<!--<a href="{% url 'manage_doc' %}?status=draft" class="{% if doc_status == 'draft' %}current{% endif %}">草稿({{draft_doc_cnt}}</a>-->
<!--</span>-->
</div>
</form>
@ -50,11 +54,11 @@
<tr>
{% if doc.status == 1 %}
<td>
<a href="{% url 'doc' doc.top_doc doc.id %}" target="_blank" title="查看文档:{{doc.name}}">{{ doc.name }} <span class="layui-badge layui-bg-black">已发布</span></a>
<a href="{% url 'doc' doc.top_doc doc.id %}" target="_blank" title="查看文档:{{doc.name}}">{{ doc.name }} —— <span class="layui-badge layui-bg-black">已发布</span></a>
</td>
{% else %}
<td>
<a href="{% url 'modify_doc' doc.id %}" target="_blank" title="修改文档:{{doc.name}}">{{ doc.name }} <span class="layui-badge">草稿</span></a>
<a href="{% url 'modify_doc' doc.id %}" target="_blank" title="修改文档:{{doc.name}}">{{ doc.name }} —— <span class="layui-badge">草稿</span></a>
</td>
{% endif %}
<td>{{ doc.parent_doc|get_doc_parent }}</td>
@ -74,13 +78,13 @@
<div class="pagination">
<span class="step-links">
{% if docs.has_previous %}
<a href="?page={{ docs.previous_page_number }}&kw={{docs.kw}}" class="layui-btn layui-btn-normal layui-btn-xs">上一页</a>
<a href="?page={{ docs.previous_page_number }}&kw={{docs.kw}}&status={{docs.status}}" class="layui-btn layui-btn-normal layui-btn-xs">上一页</a>
{% endif %}
<span class="current">
当前页: {{ docs.number }} 共 {{ docs.paginator.num_pages }} 页
</span>
{% if docs.has_next %}
<a href="?page={{ docs.next_page_number }}&kw={{docs.kw}}" class="layui-btn layui-btn-normal layui-btn-xs">下一页</a>
<a href="?page={{ docs.next_page_number }}&kw={{docs.kw}}&status={{docs.status}}" class="layui-btn layui-btn-normal layui-btn-xs">下一页</a>
{% endif %}
</span>
</div>

View File

@ -108,7 +108,8 @@
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'content':editor.getHTML(),
//'content':editor.getHTML(),
'content':editor.getPreviewedHTML(),
'pre_content':editor.getMarkdown(),
'sort':$("#sort").val(),
}
@ -116,6 +117,7 @@
if(r.status){
//修改成功
layer.msg('发布成功,即将跳转',function(){
md_changed = false;
window.location.href = "{% url 'doc' pro_id=doc.top_doc doc_id=doc.id %}";
});
}else{