添加文档草稿功能以及一些样式优化

This commit is contained in:
yangjian 2019-12-15 20:54:16 +08:00
parent c58131cd9e
commit f231bc7241
18 changed files with 169 additions and 55 deletions

View File

@ -1,5 +1,11 @@
## 版本更新记录
### v0.2.5
- 添加文档的草稿功能;
- 优化编辑页面退出时的提示;
- 优化个人中心和管理后台页面样式;
### v0.2.4
- 优化文档编写页面结构

View File

@ -1,9 +1,15 @@
# MrDoc - 一个简单的文档写作应用
**PC端文档阅读界面**
![Mrdoc首页](./docs/mrdoc_2019080101.gif)
**手机端文档阅读界面:**
![移动端](./docs/mrdoc-2019-12-15_204807.jpg)
## 介绍
一个简单的MarkDown文档写作系统。
基于Python的一个简单文档写作系统。
MrDoc拥有以下特点
@ -12,11 +18,13 @@ MrDoc拥有以下特点
- 提供文档模板功能,支持文档模板的创建、修改;
- 仿GitBook文档阅读页面支持文档阅读页面的字体缩放字体类型修改
- 支持三级目录层级显示;
- 支持文集导出为markdown文本格式.md文件
- 使用方便、二次开发修改也方便;
在开发过程中参考和借鉴了GitBook、ShowDoc、Wordbook等应用的功能和样式。
当前版本为:**v0.2.5**,更多更新记录详见:[CHANGES.md](./CHANGES.md)
## 软件架构
后端基于Python Web框架Django
@ -109,9 +117,6 @@ python manage.py runserver
加入MrDoc交流QQ群群号为735507293入群密码mrdoc
## 版本更新日志
版本更新日志详见:[CHANGES.md](./CHANGES.md)
## 版本更新

View File

@ -302,7 +302,7 @@ def admin_doc(request):
if request.method == 'GET':
kw = request.GET.get('kw','')
if kw == '':
doc_list = Doc.objects.all()
doc_list = Doc.objects.all().order_by('-modify_time')
paginator = Paginator(doc_list, 10)
page = request.GET.get('page', 1)
try:
@ -312,7 +312,7 @@ def admin_doc(request):
except EmptyPage:
docs = paginator.page(paginator.num_pages)
else:
doc_list = Doc.objects.filter(pre_content__icontains=kw)
doc_list = Doc.objects.filter(pre_content__icontains=kw).order_by('-modify_time')
paginator = Paginator(doc_list, 10)
page = request.GET.get('page', 1)
try:

View File

@ -0,0 +1,22 @@
# Generated by Django 2.1 on 2019-12-15 19:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app_doc', '0005_auto_20190727_1232'),
]
operations = [
migrations.AlterModelOptions(
name='doc',
options={'verbose_name': '文档', 'verbose_name_plural': '文档'},
),
migrations.AddField(
model_name='doc',
name='status',
field=models.IntegerField(choices=[(0, 0), (1, 1)], default=1, verbose_name='文档状态'),
),
]

View File

@ -27,6 +27,8 @@ class Doc(models.Model):
create_user = models.ForeignKey(User,on_delete=models.CASCADE)
create_time = models.DateTimeField(auto_now_add=True)
modify_time = models.DateTimeField(auto_now=True)
# 文档状态说明0表示草稿状态1表示发布状态
status = models.IntegerField(choices=((0,0),(1,1)),default=1,verbose_name='文档状态')
def __str__(self):
return self.name

View File

@ -8,7 +8,7 @@ register = template.Library()
# 获取文档的子文档
@register.filter(name='get_next_doc')
def get_next_doc(value):
return Doc.objects.filter(parent_doc=value).order_by('sort')
return Doc.objects.filter(parent_doc=value,status=1).order_by('sort')
# 获取文档的所属文集
@register.filter(name='get_doc_top')

View File

@ -49,7 +49,7 @@ def project_index(request,pro_id):
# 获取搜索词
kw = request.GET.get('kw','')
# 获取文集下所有一级文档
project_docs = Doc.objects.filter(top_doc=int(pro_id), parent_doc=0).order_by('sort')
project_docs = Doc.objects.filter(top_doc=int(pro_id), parent_doc=0, status=1).order_by('sort')
if kw != '':
search_result = Doc.objects.filter(top_doc=int(pro_id),pre_content__icontains=kw)
# if search_result.count() == 0:
@ -149,9 +149,9 @@ def doc(request,pro_id,doc_id):
# 获取文集信息
project = Project.objects.get(id=int(pro_id))
# 获取文档内容
doc = Doc.objects.get(id=int(doc_id))
doc = Doc.objects.get(id=int(doc_id),status=1)
# 获取文集下一级文档
project_docs = Doc.objects.filter(top_doc=doc.top_doc, parent_doc=0).order_by('sort')
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())
else:
return HttpResponse('参数错误')
@ -181,6 +181,7 @@ def create_doc(request):
doc_content = request.POST.get('content','')
pre_content = request.POST.get('pre_content','')
sort = request.POST.get('sort','')
status = request.POST.get('status',1)
if project != '' and doc_name != '' and project != '-1':
doc = Doc.objects.create(
name=doc_name,
@ -189,7 +190,8 @@ def create_doc(request):
parent_doc= int(parent_doc) if parent_doc != '' else 0,
top_doc= int(project),
sort = sort if sort != '' else 99,
create_user=request.user
create_user=request.user,
status = status
)
return JsonResponse({'status':True,'data':doc.id})
else:
@ -225,6 +227,7 @@ def modify_doc(request,doc_id):
doc_content = request.POST.get('content', '') # 文档内容
pre_content = request.POST.get('pre_content', '') # 文档Markdown格式内容
sort = request.POST.get('sort', '') # 文档排序
status = request.POST.get('status',1) # 文档状态
if doc_id != '' and project != '' and doc_name != '' and project != '-1':
# 更新文档内容
Doc.objects.filter(id=int(doc_id)).update(
@ -233,7 +236,8 @@ def modify_doc(request,doc_id):
pre_content=pre_content,
parent_doc=int(parent_doc) if parent_doc != '' else 0,
sort=sort if sort != '' else 99,
modify_time = datetime.datetime.now()
modify_time = datetime.datetime.now(),
status = status
)
return JsonResponse({'status': True,'data':'修改成功'})
else:
@ -266,7 +270,7 @@ 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)
doc_list = Doc.objects.filter(create_user=request.user,content__icontains=search_kw).order_by('-modify_time')
paginator = Paginator(doc_list, 10)
page = request.GET.get('page', 1)
try:
@ -277,7 +281,7 @@ def manage_doc(request):
docs = paginator.page(paginator.num_pages)
docs.kw = search_kw
else:
doc_list = Doc.objects.filter(create_user=request.user)
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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -21,28 +21,35 @@
</div>
<!-- 表格数据 -->
<div class="layui-row" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="">
<thead>
<tr>
<th>文档名称</th>
<th>文档名称</th>
<th>上级文档</th>
<th>所属文集</th>
<th>创建人</th>
<th>创建时间</th>
<th>操作</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% load doc_filter %}
{% for doc in docs %}
<tr>
<td>{{ doc.name }}</td>
{% 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>
</td>
{% else %}
<td>
<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>
<td>{{ doc.top_doc|get_doc_top }}</td>
<td>{{ doc.create_user }}</td>
<td>{{ doc.create_time }}</td>
<td>
{# <a href="javascript:void(0);" onclick="insertTemp('{{temp.id}}');">查看</a>#}
<a href="{% url 'modify_doc' doc_id=doc.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
<a href="javascript:void(0);" onclick="delDoc('{{doc.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
</td>

View File

@ -20,7 +20,7 @@
</form>
</div>
<div class="layui-row" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="">
<colgroup>
<col width="200">
<col width="200">
@ -41,7 +41,6 @@
<td>{{ temp.create_user }}</td>
<td>{{ temp.create_time }}</td>
<td>
{# <a href="javascript:void(0);" onclick="insertTemp('{{temp.id}}');">查看</a>#}
<a href="{% url 'modify_doctemp' doctemp_id=temp.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
<a href="javascript:void(0);" onclick="delTemp('{{temp.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
</td>

View File

@ -20,7 +20,7 @@
</form>
</div>
<div class="layui-row" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="">
<colgroup>
<col width="100">
<col width="300">

View File

@ -36,6 +36,7 @@
});
var layer = layui.layer;
var form = layui.form;
var md_changed = false; //初始化一个变量,用于判断编辑器是否修改
//初始化editormd
var editor = editormd("editor-md", {
width : "100%",
@ -65,6 +66,9 @@
imageUpload : true, //开启图片上传
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "{% url 'upload_doc_img' %}",
onchange:function(){
md_changed = true
},
});
//粘贴上传图片
$("#editor-md").on('paste', function (ev) {
@ -92,9 +96,11 @@
});
//未保存离开提示
window.onbeforeunload =function() {
   // code...
//return null;
return 1
   if(md_changed){
return 1;
}else{
return null;
}
}
</script>
<script src="{% static 'mrdoc.js' %}"></script>

View File

@ -49,7 +49,10 @@
</label>
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="createDoc()">保存文档</button>
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="saveDoc()">保存草稿</button>
</label>
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="createDoc()">发布文档</button>
</label>
</div>
</div>
@ -134,7 +137,7 @@
$.post("{% url 'create_doc' %}",data,function(r){
if(r.status){
//创建成功
layer.msg('保存成功',function(){
layer.msg('发布成功',function(){
window.location.href = "{% url 'pro_list' %}";
});
}else{
@ -144,6 +147,38 @@
});
}
};
//保存文档草稿
saveDoc = function(){
var data = {
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'content':editor.getHTML(),
'pre_content':editor.getMarkdown(),
'sort':$("#sort").val(),
'status':0
}
console.log(data)
if(data.doc_name == ""){
layer.msg('请输入文档标题!');
}
else if(data.project == ""){
layer.msg('请选择文集!');
}
else{
$.post("{% url 'create_doc' %}",data,function(r){
if(r.status){
//创建成功
layer.msg('保存成功',function(){
window.location.href = "/modify_doc/"+r.data+"/";
});
}else{
//创建失败
layer.msg('保存失败:'+r.data);
}
});
}
};
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({

View File

@ -57,7 +57,7 @@
<li>
{% if docs.id|get_next_doc %}
<div style="display:flex;justify-content:space-between;">
<a href="{% url 'doc' pro_id=docs.top_doc doc_id=docs.id %}">{{ docs.name }}</a>
<a href="{% url 'doc' pro_id=docs.top_doc doc_id=docs.id %}" title="{{docs.name}}">{{ docs.name }}</a>
<i class="fa fa-chevron-left switch-toc" style="padding:15px;"></i>
</div>
<ul class="sub-menu toc-close">
@ -66,23 +66,23 @@
<li>
{% if node.id|get_next_doc %}
<div style="display:flex;justify-content:space-between;">
<a href="{% url 'doc' pro_id=node.top_doc doc_id=node.id %}">{{ node.name }}</a>
<a href="{% url 'doc' pro_id=node.top_doc doc_id=node.id %}" title="{{node.name}}">{{ node.name }}</a>
<i class="fa fa-chevron-left switch-toc" style="padding:15px;"></i>
</div>
<ul class="sub-menu toc-close">
<!-- 三级目录 -->
{% for doc in node.id|get_next_doc %}
<li><a href="{% url 'doc' pro_id=doc.top_doc doc_id=doc.id %}">{{ doc.name }}</a></li>
<li><a href="{% url 'doc' pro_id=doc.top_doc doc_id=doc.id %}" title="{{doc.name}}">{{ doc.name }}</a></li>
{% endfor %}
</ul>
{% else %}
<a href="{% url 'doc' pro_id=node.top_doc doc_id=node.id %}">{{ node.name }}</a>
<a href="{% url 'doc' pro_id=node.top_doc doc_id=node.id %}" title="{{node.name}}">{{ node.name }}</a>
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<a href="{% url 'doc' pro_id=docs.top_doc doc_id=docs.id %}">{{ docs.name }}</a>
<a href="{% url 'doc' pro_id=docs.top_doc doc_id=docs.id %}" title="{{docs.name}}">{{ docs.name }}</a>
{% endif %}
</li>
{% endfor %}

View File

@ -20,35 +20,36 @@
</form>
</div>
<div class="layui-row" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="line">
{# <colgroup>#}
{# <col width="200">#}
{# <col width="200">#}
{# <col>#}
{# </colgroup>#}
<table class="layui-table" id="doctemp-list" lay-skin="">
<thead>
<tr>
<th>文档名称</th>
{# <th>文档内容</th>#}
<th>文档名称</th>
<th>上级文档</th>
<th>所属文集</th>
<th>创建时间</th>
<th>操作</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% load doc_filter %}
{% for doc in docs %}
<tr>
<td>{{ doc.name }}</td>
{% 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>
</td>
{% else %}
<td>
<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>
<td>{{ doc.top_doc|get_doc_top }}</td>
<td>{{ doc.create_time }}</td>
<td>
{# <a href="javascript:void(0);" onclick="insertTemp('{{temp.id}}');">查看</a>#}
<a href="{% url 'modify_doc' doc_id=doc.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
<a href="javascript:void(0);" onclick="delDoc('{{doc.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
</td>
<td>{{ doc.create_time }}</td>
<td>
<a href="{% url 'modify_doc' doc_id=doc.id %}" target="_blank" class="layui-btn layui-btn-warm layui-btn-xs">修改</a>
<a href="javascript:void(0);" onclick="delDoc('{{doc.id}}');" class="layui-btn layui-btn-danger layui-btn-xs">删除</a>
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -20,7 +20,7 @@
</form>
</div>
<div class="layui-row" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="">
<colgroup>
<col width="200">
<col width="200">

View File

@ -20,7 +20,7 @@
</form>
</div>
<div class="layui-row" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="line">
<table class="layui-table" id="doctemp-list" lay-skin="">
<colgroup>
<col width="100">
<col width="400">

View File

@ -44,7 +44,10 @@
<button class="layui-btn layui-btn-primary layui-btn-sm" id="sel-doctemp">插入模板</button>
</label>
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="createDoc()">保存</button>
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="saveDoc()">保存草稿</button>
</label>
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="createDoc()">发布文档</button>
</label>
</div>
</div>
@ -76,7 +79,7 @@
}
});
});
//保存文档
//发布文档
createDoc = function(){
var data = {
'doc_id':{{ doc.id }},
@ -99,6 +102,30 @@
}
});
};
//保存文档草稿
saveDoc = function(){
var data = {
'doc_id':{{ doc.id }},
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'content':editor.getHTML(),
'pre_content':editor.getMarkdown(),
'sort':$("#sort").val(),
'status':0
}
$.post("{% url 'modify_doc' doc_id=doc.id %}",data,function(r){
if(r.status){
//修改成功
layer.msg('保存成功',function(){
window.location.href = "{% url 'modify_doc' doc.id %}";
});
}else{
//修改失败
layer.msg('保存失败');
}
});
};
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({