diff --git a/CHANGES.md b/CHANGES.md
index b10d43f..caaf5e4 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,16 @@
## 版本更新记录
+### v0.5.6 2020-07-31
+
+- 修复Markdown编辑器插入图片、表格、音视频等内容时光标丢失的问题;
+- 优化重构搜索功能,支持在搜索界面进行文集和文档搜索;
+- 优化文档页面排版显示;
+- 优化文档页面代码块超长超宽代码样式;
+- 优化移动复制文档弹出框大纲超长的样式;
+- 优化epub和PDF格式文件导出;
+- 优化编辑器界面排版布局;
+- 优化文档三级目录渲染错误的问题;
+
### v0.5.5 2020-07-20
- 禁用编辑器页面的列表目录和下拉目录语法解析
diff --git a/MrDoc/settings.py b/MrDoc/settings.py
index 9c5a2b9..094dd5c 100644
--- a/MrDoc/settings.py
+++ b/MrDoc/settings.py
@@ -40,7 +40,7 @@ SECRET_KEY = '5&71mt9@^58zdg*_!t(x6g14q*@84d%ptr%%s6e0l50zs0we3d'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = CONFIG.getboolean('site','debug')
-VERSIONS = '0.5.5'
+VERSIONS = '0.5.6'
ALLOWED_HOSTS = ['*']
diff --git a/README.md b/README.md
index 4d661d9..bf707c0 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,16 @@
## MrDoc觅道文档 - 记录文档,汇聚思想 - [English](./README_ENG.md)
-  
+  

+
打赏项目:
+微信|
+支付宝|
+QQ|
+PayPal|
+
+
### 介绍
`MrDoc` 是基于`Python`开发的在线文档系统,适合作为个人和小型团队的文档、知识和笔记管理工具。致力于成为全平台(Web端、桌面端、移动端)的私有化在线文档部署方案。
diff --git a/README_ENG.md b/README_ENG.md
index f833c0c..905c446 100644
--- a/README_ENG.md
+++ b/README_ENG.md
@@ -1,10 +1,17 @@
## MrDoc - Writing documents, gathering ideas
-  
+  

+Sponsor:
+WeChat|
+AliPay|
+QQ|
+PayPal|
+
+
### Introduce
`Mrdoc` is an online document system developed based on python. It is suitable for individuals and small teams to manage documents, knowledge and notes. It is committed to become a private online document deployment solution for the whole platform (web, desktop, mobile).
diff --git a/app_admin/views.py b/app_admin/views.py
index f224f04..d372d0a 100644
--- a/app_admin/views.py
+++ b/app_admin/views.py
@@ -317,7 +317,7 @@ def admin_project(request):
if request.method == 'GET':
search_kw = request.GET.get('kw','')
if search_kw == '':
- project_list = Project.objects.all()
+ project_list = Project.objects.all().order_by('-create_time')
paginator = Paginator(project_list,20)
page = request.GET.get('page',1)
try:
diff --git a/app_doc/report_utils.py b/app_doc/report_utils.py
index 89df28c..9120ba5 100644
--- a/app_doc/report_utils.py
+++ b/app_doc/report_utils.py
@@ -275,6 +275,7 @@ class ReportEPUB():
seque_tag = html_soup.select('.sequence-diagram') # 查找所有时序图标签
echart_tag = html_soup.select('.echart') # 查找所有echart图表标签
code_tag = html_soup.find_all(name="code") # 查找code代码标签
+ iframe_tag = html_soup.find_all(name='iframe') # 查找iframe
# 添加css样式标签
style_link = html_soup.new_tag(name='link',href="../Styles/style.css",rel="stylesheet",type="text/css")
@@ -290,6 +291,12 @@ class ReportEPUB():
# 添加html标签的xmlns属性
html_soup.html['xmlns'] = "http://www.w3.org/1999/xhtml"
+ # 替换iframe视频为视频URL链接文本
+ for iframe in iframe_tag:
+ iframe_src = iframe.get('src')
+ iframe.name = 'p'
+ iframe.string = "本格式不支持iframe视频显示,视频地址为:{}".format(iframe_src)
+
# 替换HTML文本中静态文件的相对链接为绝对链接
for src in src_tag:
if src['src'].startswith("/"):
@@ -908,7 +915,7 @@ class ReportPDF():
- 本文档由觅道文档(MrDoc)生成
+ 本文档由MrDoc觅道文档生成
{project_name}
diff --git a/app_doc/templatetags/doc_filter.py b/app_doc/templatetags/doc_filter.py
index 4cafdd6..a631bd0 100644
--- a/app_doc/templatetags/doc_filter.py
+++ b/app_doc/templatetags/doc_filter.py
@@ -2,6 +2,7 @@
# 文档自定义模板过滤器
from app_doc.models import *
from django import template
+import re
register = template.Library()
@@ -129,4 +130,32 @@ def get_doc_previous(value):
return previous.id
except Exception as e:
import traceback
- print(traceback.print_exc())
\ No newline at end of file
+ print(traceback.print_exc())
+
+
+# 获取内容的关键词上下文
+@register.filter(name='get_key_context')
+def get_key_context(value,args):
+ # print(value,args)
+ # re_result = re.findall(args, value, flags=re.IGNORECASE)
+ value = value.replace('\n','')
+ p = re.compile(args,flags=re.IGNORECASE)
+ value_list = []
+ for m in p.finditer(value):
+ # print(value,m,m.start(),m.group(),)
+ # print( m.start(), m.group())
+ start_point = m.start() - 20
+ if start_point < 0:
+ start_point = 0
+ end_point = m.end()+20
+ # print(start_point,end_point)
+ # print(value[start_point:end_point])
+ value_list.append(value[start_point:end_point])
+ # print(value_list)
+ if len(value_list) > 0:
+ r = "…".join(value_list)
+ if len(r) > 200:
+ r = r[0:200]
+ else:
+ r = value[0:200]
+ return r
\ No newline at end of file
diff --git a/app_doc/urls.py b/app_doc/urls.py
index 8725f4b..c00f9dd 100644
--- a/app_doc/urls.py
+++ b/app_doc/urls.py
@@ -32,6 +32,7 @@ urlpatterns = [
path('move_doc/', views.move_doc, name='move_doc'), # 移动文档
path('doc_recycle/', views.doc_recycle,name='doc_recycle'), # 文档回收站
path('fast_pub_doc/',views.fast_publish_doc,name='fast_pub_doc'), # 一键发布文档
+ path('download_doc_md/
/',views.download_doc_md,name='download_doc_md'), # 下载文档Markdown文件
#################文档模板相关
path('manage_doctemp/',views.manage_doctemp,name='manage_doctemp'), # 文档模板列表
path('create_doctemp/',views.create_doctemp,name="create_doctemp"), # 创建文档模板
@@ -44,4 +45,5 @@ urlpatterns = [
path('manage_attachment/',views.manage_attachment,name='manage_attachment'), # 附件管理
################其他功能相关
path('upload_doc_img/',util_upload_img.upload_img,name="upload_doc_img"), # 上传图片
+ path('search/',views.search,name="search"), # 搜索功能
]
\ No newline at end of file
diff --git a/app_doc/views.py b/app_doc/views.py
index 3ecbb6e..dda562c 100644
--- a/app_doc/views.py
+++ b/app_doc/views.py
@@ -1339,7 +1339,7 @@ def get_pro_doc_tree(request):
'level': 3
}
sec_item['children'].append(item)
- top_item['children'].append(sec_item)
+ top_item['children'].append(sec_item)
else:
top_item['children'].append(sec_item)
doc_list.append(top_item)
@@ -1471,6 +1471,7 @@ def genera_project_file(request):
return JsonResponse({'status': True, 'data': epub_file})
except Exception as e:
+ logger.exception("生成EPUB出错")
return JsonResponse({'status': False, 'data': '生成出错'})
# 导出PDF
elif report_type in ['pdf']:
@@ -1865,4 +1866,135 @@ def manage_attachment(request):
attachment_list.append(item)
return JsonResponse({'status':True,'data':attachment_list})
else:
- return JsonResponse({'status':False,'data':'无效参数'})
\ No newline at end of file
+ return JsonResponse({'status':False,'data':'无效参数'})
+
+
+# 搜索
+def search(request):
+ kw = request.GET.get('kw', None)
+ search_type = request.GET.get('type', 'doc') # 搜索类型,默认文档doc
+ date_type = request.GET.get('d_type', 'recent')
+ date_range = request.GET.get('d_range', 'all') # 时间范围,默认不限,all
+ project_range = request.GET.get('p_range', 0) # 文集范围,默认不限,all
+
+ # 处理时间范围
+ if date_type == 'recent':
+ if date_range == 'recent1': # 最近1天
+ start_date = datetime.datetime.now() - datetime.timedelta(days=1)
+ elif date_range == 'recent7': # 最近7天
+ start_date = datetime.datetime.now() - datetime.timedelta(days=7)
+ elif date_range == 'recent30': # 最近30天
+ start_date = datetime.datetime.now() - datetime.timedelta(days=30)
+ elif date_range == 'recent365': # 最近一年
+ start_date = datetime.datetime.now() - datetime.timedelta(days=365)
+ else:
+ start_date = datetime.datetime.strptime('1900-01-01', '%Y-%m-%d')
+ end_date = datetime.datetime.now()
+ elif date_type == 'day':
+ try:
+ date_list = date_range.split('|')
+ start_date = datetime.datetime.strptime(date_list[0], '%Y-%m-%d')
+ end_date = datetime.datetime.strptime(date_list[1], '%Y-%m-%d')
+ except:
+ start_date = datetime.datetime.now() - datetime.timedelta(days=1)
+ end_date = datetime.datetime.now()
+
+ # 是否时间筛选
+ if date_range == 'all':
+ is_date_range = False
+ else:
+ is_date_range = True
+
+ # 是否认证
+ if request.user.is_authenticated:
+ is_auth = True
+ else:
+ is_auth = False
+
+ # 存在搜索关键词
+ if kw:
+ # 搜索文档
+ if search_type == 'doc':
+ if is_auth:
+ colla_list = [i.project.id for i in ProjectCollaborator.objects.filter(user=request.user)] # 用户的协作文集
+ open_list = [i.id for i in Project.objects.filter(role=0)] # 公开文集
+ view_list = list(set(open_list).union(set(colla_list))) # 合并上述两个文集ID列表
+
+ data_list = Doc.objects.filter(
+ Q(top_doc__in=view_list), # 包含用户可浏览到的文集
+ Q(create_time__gte=start_date, create_time__lte=end_date), # 筛选创建时间
+ Q(name__icontains=kw) | Q(content__icontains=kw) # 筛选文档标题和内容中包含搜索词
+ ).order_by('-create_time')
+ else:
+ view_list = [i.id for i in Project.objects.filter(role=0)]
+ data_list = Doc.objects.filter(
+ Q(top_doc__in=view_list),
+ Q(create_time__gte=start_date, create_time__lte=end_date), # 筛选创建时间
+ Q(name__icontains=kw) | Q(content__icontains=kw) # 筛选文档标题和内容中包含搜索词
+ ).order_by('-create_time')
+
+ # 搜索文集
+ elif search_type == 'pro':
+ # 认证用户
+ if is_auth:
+ colla_list = [i.project.id for i in ProjectCollaborator.objects.filter(user=request.user)] # 用户的协作文集
+ # 查询所有可显示的文集
+ data_list = Project.objects.filter(
+ Q(role=0) | \
+ Q(role=2, role_value__contains=str(request.user.username)) | \
+ Q(create_user=request.user) | \
+ Q(id__in=colla_list),
+ Q(create_time__gte=start_date, create_time__lte=end_date), # 筛选创建时间
+ Q(name__icontains=kw) | Q(intro__icontains=kw) # 筛选文集名称和简介包含搜索词
+ ).order_by('-create_time')
+ # 游客
+ else:
+ data_list = Project.objects.filter(
+ Q(role=0),
+ Q(name__icontains=kw) | Q(intro__icontains=kw),
+ Q(create_time__gte=start_date, create_time__lte=end_date), # 筛选创建时间
+ ).order_by("-create_time")
+
+ # 搜索标签
+ # elif search_type == 'tag':
+ # pass
+ else:
+ return render(request, 'app_doc/search.html')
+
+ # 分页处理
+ paginator = Paginator(data_list, 12)
+ page = request.GET.get('page', 1)
+ try:
+ datas = paginator.page(page)
+ except PageNotAnInteger:
+ datas = paginator.page(1)
+ except EmptyPage:
+ datas = paginator.page(paginator.num_pages)
+ return render(request, 'app_doc/search_result.html', locals())
+
+ # 否则跳转到搜索首页
+ else:
+ return render(request,'app_doc/search.html')
+
+# 文档Markdown文件下载
+@require_http_methods(['GET',"POST"])
+def download_doc_md(request,doc_id):
+ if request.user.is_authenticated:
+ if request.user.is_superuser:
+ try:
+ doc = Doc.objects.get(id=doc_id)
+ except ObjectDoesNotExist:
+ return JsonResponse({'status':False,'data':'文档不存在'})
+ else:
+ try:
+ doc = Doc.objects.get(id=doc_id,create_user = request.user)
+ except ObjectDoesNotExist:
+ return JsonResponse({'status':False,'data':'文档不存在'})
+ else:
+ return render(request,'404.html')
+
+ response = HttpResponse(content_type='text/plain')
+ response['Content-Disposition'] = 'attachment; filename={}.md'.format(doc.name)
+ response.write(doc.pre_content)
+
+ return response
diff --git a/static/mrdoc.css b/static/mrdoc.css
index 399ca5c..9d2efe3 100644
--- a/static/mrdoc.css
+++ b/static/mrdoc.css
@@ -188,7 +188,7 @@ body, html {
.project-title{
font-size: 20px;
font-weight: 700;
- margin:20px;
+ margin:0 20px;
text-align: center;
}
.doc-summary {
@@ -356,12 +356,12 @@ li.active > a,li.active > div > a{
}
/* 返回顶部 */
.toTop {
- width: 70px;
- height: 70px;
+ width: 50px;
+ height: 50px;
border-radius: 50%;
background: #f6f6f6;
text-align: center;
- line-height: 70px;
+ line-height: 50px;
/*返回顶部标签固定定位*/
position: fixed;
right: 35px;
diff --git a/static/search/home_btn.svg b/static/search/home_btn.svg
new file mode 100644
index 0000000..7d76bff
--- /dev/null
+++ b/static/search/home_btn.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/search/mrdoc_logo_300.png b/static/search/mrdoc_logo_300.png
new file mode 100644
index 0000000..b54dd90
Binary files /dev/null and b/static/search/mrdoc_logo_300.png differ
diff --git a/static/search/mrdoc_search_logo.svg b/static/search/mrdoc_search_logo.svg
new file mode 100644
index 0000000..94de7d3
--- /dev/null
+++ b/static/search/mrdoc_search_logo.svg
@@ -0,0 +1,39 @@
+
\ No newline at end of file
diff --git a/static/search/mrdoc_search_logo_2.svg b/static/search/mrdoc_search_logo_2.svg
new file mode 100644
index 0000000..52b858f
--- /dev/null
+++ b/static/search/mrdoc_search_logo_2.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/static/search/search.svg b/static/search/search.svg
new file mode 100644
index 0000000..c370075
--- /dev/null
+++ b/static/search/search.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/search/search_btn.svg b/static/search/search_btn.svg
new file mode 100644
index 0000000..7e8e55b
--- /dev/null
+++ b/static/search/search_btn.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/template/app_admin/admin_project.html b/template/app_admin/admin_project.html
index 9d63e00..4b1770d 100644
--- a/template/app_admin/admin_project.html
+++ b/template/app_admin/admin_project.html
@@ -44,7 +44,7 @@
{% for pro in projects %}
- | {{ pro.name }} |
+ {{ pro.name }} |
{{ pro.intro }} |
{% load project_filter %}
{{ pro.id | get_doc_count }} |
@@ -64,9 +64,9 @@
{{ pro.create_time }} |
{{ pro.create_user }} |
-
+
修改
diff --git a/template/app_doc/create_base_2.html b/template/app_doc/create_base_2.html
index e86f720..eb41624 100644
--- a/template/app_doc/create_base_2.html
+++ b/template/app_doc/create_base_2.html
@@ -112,6 +112,13 @@
.layui-colla-content{
padding: 0px;
}
+ /* 预览代码宽度 */
+ ol.linenums li{
+ width: max-content;
+ }
+ #doc-tree{
+ margin-bottom: 5px;
+ }
+
+
diff --git a/template/app_doc/docs_base.html b/template/app_doc/docs_base.html
index 2132631..b85dc18 100644
--- a/template/app_doc/docs_base.html
+++ b/template/app_doc/docs_base.html
@@ -79,12 +79,26 @@
.markdown-body h6{
font-size: .85em;
}
+ .markdown-body p img{
+ max-width: 350px;
+ }
#url_qrcode img{
margin: auto;
}
#share{
background-color: #333;
}
+ /* 文档代码块样式 */
+ ol.linenums li{
+ width: max-content;
+ }
+ pre.linenums{
+ max-height: 400px;
+ }
+ li.L1, li.L3, li.L5, li.L7, li.L9 {
+ background: none !important;
+ }
+
/* layui弹出框颜色 */
.layui-tab-brief>.layui-tab-more li.layui-this:after, .layui-tab-brief>.layui-tab-title .layui-this:after{
border-bottom: 2px solid #333;
@@ -136,7 +150,7 @@
@@ -156,11 +170,9 @@
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -499,6 +529,43 @@
+
+
+
+
+
+ - 微信
+ - 支付宝
+ - QQ支付
+ - PayPal
+ - 项目源码
+
+
+
+
+
+
+{% block custom_script %}
+
+
+
+ {% if debug %}
+ {% else %}
+ {{ static_code | safe }}
+ {% endif %}
+
+{% endblock %}
+
+ |