diff --git a/CHANGES.md b/CHANGES.md index 2a10ce9..7185679 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ ## 版本更新记录 +### v0.2.5 + +- 添加文档的草稿功能; +- 优化编辑页面退出时的提示; +- 优化个人中心和管理后台页面样式; + ### v0.2.4 - 优化文档编写页面结构 diff --git a/README.md b/README.md index 722bb6c..18e0bf6 100644 --- a/README.md +++ b/README.md @@ -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) ## 版本更新 diff --git a/app_admin/views.py b/app_admin/views.py index 4f2227d..8b2af08 100644 --- a/app_admin/views.py +++ b/app_admin/views.py @@ -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: diff --git a/app_doc/migrations/0006_auto_20191215_1910.py b/app_doc/migrations/0006_auto_20191215_1910.py new file mode 100644 index 0000000..9efc1d5 --- /dev/null +++ b/app_doc/migrations/0006_auto_20191215_1910.py @@ -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='文档状态'), + ), + ] diff --git a/app_doc/models.py b/app_doc/models.py index b85e962..2a1a3b9 100644 --- a/app_doc/models.py +++ b/app_doc/models.py @@ -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 diff --git a/app_doc/templatetags/doc_filter.py b/app_doc/templatetags/doc_filter.py index 809998a..553eee6 100644 --- a/app_doc/templatetags/doc_filter.py +++ b/app_doc/templatetags/doc_filter.py @@ -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') diff --git a/app_doc/views.py b/app_doc/views.py index 7cd1835..febccfc 100644 --- a/app_doc/views.py +++ b/app_doc/views.py @@ -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: diff --git a/docs/mrdoc-2019-12-15_204807.jpg b/docs/mrdoc-2019-12-15_204807.jpg new file mode 100644 index 0000000..d6ce4bf Binary files /dev/null and b/docs/mrdoc-2019-12-15_204807.jpg differ diff --git a/template/app_admin/admin_doc.html b/template/app_admin/admin_doc.html index d34713f..7945ed0 100644 --- a/template/app_admin/admin_doc.html +++ b/template/app_admin/admin_doc.html @@ -21,28 +21,35 @@
- +
- + - - + + {% load doc_filter %} {% for doc in docs %} - + {% if doc.status == 1 %} + + {% else %} + + {% endif %} diff --git a/template/app_admin/admin_doctemp.html b/template/app_admin/admin_doctemp.html index b92a3b5..9c45884 100644 --- a/template/app_admin/admin_doctemp.html +++ b/template/app_admin/admin_doctemp.html @@ -20,7 +20,7 @@
-
文档名称文档名称 上级文档 所属文集 创建人创建时间操作创建时间操作
{{ doc.name }} + {{ doc.name }} 已发布 + + {{ doc.name }} 草稿 + {{ doc.parent_doc|get_doc_parent }} {{ doc.top_doc|get_doc_top }} {{ doc.create_user }} {{ doc.create_time }} -{# 查看#} 修改 删除
+
@@ -41,7 +41,6 @@ diff --git a/template/app_admin/admin_project.html b/template/app_admin/admin_project.html index c2c0006..18121b6 100644 --- a/template/app_admin/admin_project.html +++ b/template/app_admin/admin_project.html @@ -20,7 +20,7 @@
-
{{ temp.create_user }} {{ temp.create_time }} -{# 查看#} 修改 删除
+
diff --git a/template/app_doc/create_base.html b/template/app_doc/create_base.html index ddeff88..549c3cf 100644 --- a/template/app_doc/create_base.html +++ b/template/app_doc/create_base.html @@ -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; + } } diff --git a/template/app_doc/create_doc.html b/template/app_doc/create_doc.html index 99c0e78..58009c3 100644 --- a/template/app_doc/create_doc.html +++ b/template/app_doc/create_doc.html @@ -49,7 +49,10 @@ + @@ -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({ diff --git a/template/app_doc/docs_base.html b/template/app_doc/docs_base.html index ae6a6e0..b5dd451 100644 --- a/template/app_doc/docs_base.html +++ b/template/app_doc/docs_base.html @@ -57,7 +57,7 @@
  • {% if docs.id|get_next_doc %}
    - {{ docs.name }} + {{ docs.name }}
    {% else %} - {{ docs.name }} + {{ docs.name }} {% endif %}
  • {% endfor %} diff --git a/template/app_doc/manage_doc.html b/template/app_doc/manage_doc.html index d904ab1..1d5fe43 100644 --- a/template/app_doc/manage_doc.html +++ b/template/app_doc/manage_doc.html @@ -20,35 +20,36 @@
    -
    -{# #} -{# #} -{# #} -{# #} -{# #} +
    - -{# #} + - - + + {% load doc_filter %} {% for doc in docs %} - + {% if doc.status == 1 %} + + {% else %} + + {% endif %} - - + + {% endfor %} diff --git a/template/app_doc/manage_doctemp.html b/template/app_doc/manage_doctemp.html index d196330..1b9efe6 100644 --- a/template/app_doc/manage_doctemp.html +++ b/template/app_doc/manage_doctemp.html @@ -20,7 +20,7 @@
    -
    文档名称文档内容文档名称 上级文档 所属文集创建时间操作创建时间操作
    {{ doc.name }} + {{ doc.name }} 已发布 + + {{ doc.name }} 草稿 + {{ doc.parent_doc|get_doc_parent }} {{ doc.top_doc|get_doc_top }}{{ doc.create_time }} -{# 查看#} - 修改 - 删除 - {{ doc.create_time }} + 修改 + 删除 +
    +
    diff --git a/template/app_doc/manage_project.html b/template/app_doc/manage_project.html index 4701b83..0f85461 100644 --- a/template/app_doc/manage_project.html +++ b/template/app_doc/manage_project.html @@ -20,7 +20,7 @@
    -
    +
    diff --git a/template/app_doc/modify_doc.html b/template/app_doc/modify_doc.html index 55cf05d..b53279d 100644 --- a/template/app_doc/modify_doc.html +++ b/template/app_doc/modify_doc.html @@ -44,7 +44,10 @@ + @@ -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({