新增Word文档(.docx)导入、优化文档编辑器和站点样式

This commit is contained in:
yangjian 2020-12-26 22:41:12 +08:00
parent fa535aee57
commit ef1f3b4baa
13 changed files with 312 additions and 191 deletions

View File

@ -7,6 +7,10 @@
- [升级]同步Vditor组件版本至3.7.1
- [新增]富文本编辑器iceEditor;
- [优化]Vditor编辑模式下移动端输入体验;
- [新增]文集图标配置功能;
- [新增]Word(.docx格式)文档导入功能;
- [优化]文档编辑器界面样式和交互;
### v0.6.2 2020-12

View File

@ -14,6 +14,8 @@ from app_doc.util_upload_img import upload_generation_dir
from django.db import transaction
from django.conf import settings
from loguru import logger
import mammoth
from markdownify import markdownify
# 导入Zip文集
class ImportZipProject():
@ -142,6 +144,63 @@ class ImportZipProject():
else:
return md_content
# 导入Word文档(.docx)
class ImportDocxDoc():
def __init__(self,docx_file_path,editor_mode,create_user):
self.docx_file_path = docx_file_path # docx文件绝对路径
self.tmp_img_dir = self.docx_file_path.split('.')
self.create_user = create_user
self.editor_mode = int(editor_mode)
# 转存docx文件中的图片
def convert_img(self,image):
with image.open() as image_bytes:
file_suffix = image.content_type.split("/")[1]
file_time_name = str(time.time())
dir_name = upload_generation_dir() # 获取当月文件夹名称
# 图片在媒体文件夹内的路径,形如 /202012/12542542.jpg
copy2_filename = dir_name + '/' + file_time_name + '.' + file_suffix
# 文件的绝对路径 形如/home/MrDoc/media/202012/12542542.jpg
new_media_file_path = settings.MEDIA_ROOT + copy2_filename
# 图片文件的相对url路径
new_media_filename = '/media' + copy2_filename
# 图片数据写入数据库
Image.objects.create(
user=self.create_user,
file_path=new_media_filename,
file_name=file_time_name + '.' + file_suffix,
remark='本地上传',
)
with open(new_media_file_path, 'wb') as f:
f.write(image_bytes.read())
return {"src": new_media_filename}
# 转换docx文件内容为HTML和Markdown
def convert_docx(self):
# 读取Word文件
with open(self.docx_file_path, "rb") as docx_file:
# 转化Word文档为HTML
result = mammoth.convert_to_html(docx_file, convert_image=mammoth.images.img_element(self.convert_img))
# 获取HTML内容
html = result.value
if self.editor_mode in [1,2]:
# 转化HTML为Markdown
md = markdownify(html, heading_style="ATX")
return md
else:
return html
def run(self):
try:
result = self.convert_docx()
os.remove(self.docx_file_path)
return {'status':True,'data':result}
except:
os.remove(self.docx_file_path)
return {'status':False,'data':'读取异常'}
if __name__ == '__main__':
imp = ImportZipProject()
imp.read_zip(r"D:\Python XlsxWriter模块中文文档_2020-06-16.zip")

View File

@ -35,6 +35,7 @@ urlpatterns = [
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/<int:doc_id>/',views.download_doc_md,name='download_doc_md'), # 下载文档Markdown文件
path('import/doc_docx/',views_import.import_doc_docx,name="import_doc_docx"), # 导入docx文档
#################文档分享相关
path('share_doc/', views.share_doc, name='share_doc'), # 私密文档分享
path('share_doc_check/', views.share_doc_check, name='share_doc_check'), # 私密文档验证

View File

@ -315,9 +315,14 @@ def project_index(request,pro_id):
new_docs = Doc.objects.filter(top_doc=pro_id,status=1).order_by('-modify_time')[:5]
# markdown文本生成摘要不带markdown标记
remove_markdown_tag(new_docs)
# 获取文集的文档目录
toc_list,toc_cnt = get_pro_toc(pro_id)
# toc_list,toc_cnt = ([],1000)
# 获取文集的协作成员
colla_user_list = ProjectCollaborator.objects.filter(project=project)
# 获取文集的协作用户信息
if request.user.is_authenticated: # 对登陆用户查询其协作文档信息
colla_user = ProjectCollaborator.objects.filter(project=project,user=request.user).count()
@ -922,11 +927,11 @@ def create_doc(request):
status = request.POST.get('status',1) # 文档状态
open_children = request.POST.get('open_children', False) # 展示下级目录
show_children = request.POST.get('show_children', False) # 展示下级目录
if open_children == 'true':
if open_children == 'on':
open_children = True
else:
open_children = False
if show_children == 'true':
if show_children == 'on':
show_children = True
else:
show_children = False
@ -1028,11 +1033,11 @@ def modify_doc(request,doc_id):
status = request.POST.get('status',1) # 文档状态
open_children = request.POST.get('open_children',False) # 展示下级目录
show_children = request.POST.get('show_children', False) # 展示下级目录
if open_children == 'true':
if open_children == 'on':
open_children = True
else:
open_children = False
if show_children == 'true':
if show_children == 'on':
show_children = True
else:
show_children = False

View File

@ -10,6 +10,7 @@ from django.http.response import JsonResponse,Http404,HttpResponseNotAllowed,Htt
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.views.decorators.csrf import csrf_exempt
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage,InvalidPage # 后端分页
from django.core.exceptions import PermissionDenied,ObjectDoesNotExist
from app_doc.models import Project,Doc,DocTemp
@ -116,3 +117,45 @@ def project_doc_sort(request):
Doc.objects.filter(id=c2['id']).update(sort=n2,parent_doc=c1['id'],status=doc_status)
return JsonResponse({'status':True,'data':'ok'})
# 导入docx文档
@login_required()
@csrf_exempt
@require_POST
def import_doc_docx(request):
file_type = request.POST.get('type', None)
editor_mode = request.POST.get('editor_mode',1)
# 上传Zip压缩文件
if file_type == 'docx':
import_file = request.FILES.get('import_doc_docx', None)
if import_file:
file_name = import_file.name
# 限制文件大小在50mb以内
if import_file.size > 52428800:
return JsonResponse({'status': False, 'data': '文件大小超出限制'})
# 限制文件格式为.zip
if file_name.endswith('.docx'):
if os.path.exists(os.path.join(settings.MEDIA_ROOT, 'import_temp')) is False:
os.mkdir(os.path.join(settings.MEDIA_ROOT, 'import_temp'))
temp_file_name = str(time.time()) + '.docx'
temp_file_path = os.path.join(settings.MEDIA_ROOT, 'import_temp/' + temp_file_name)
with open(temp_file_path, 'wb+') as docx_file:
for chunk in import_file:
docx_file.write(chunk)
if os.path.exists(temp_file_path):
import_file = ImportDocxDoc(
docx_file_path=temp_file_path,
editor_mode=editor_mode,
create_user=request.user
).run()
return JsonResponse(import_file)
else:
return JsonResponse({'status': False, 'data': '上传失败'})
else:
return JsonResponse({'status': False, 'data': '仅支持.docx格式'})
else:
return JsonResponse({'status': False, 'data': '无有效文件'})
else:
return JsonResponse({'status': False, 'data': '参数错误'})

View File

@ -9,4 +9,6 @@ requests==2.24.0
whoosh==2.7.4
django-haystack==3.0
Markdown==3.3.3
jieba==0.42.1
jieba==0.42.1
mammoth==1.4.13
markdownify==0.6.0

View File

@ -520,6 +520,9 @@ input#doc-name,input#doctemp-name{
display: none;
}
.doc-summary .layui-nav{
padding: 0;
}
.mrdoc-import-doc-list{
margin-bottom: 10px;
}
@ -529,7 +532,7 @@ input#doc-name,input#doctemp-name{
border-radius:2px;
box-shadow:0 2px 4px rgba(0,0,0,.12);
box-sizing:border-box;
margin-right: 5px;
margin-right: 2px;
padding-right: 5px;
}
.mrdoc-import-doc-item a{
@ -557,6 +560,21 @@ input#doc-name,input#doctemp-name{
background-color: #f2f2f2 !important;
color: #333 !important;
}
.mrdoc-import-doc-child .layui-form-checkbox[lay-skin=primary]{
margin-left: 10px;
padding-left: 20px;
}
.mrdoc-import-doc-child .layui-form-checkbox[lay-skin=primary] i{
width: 14px;
height: 14px;
line-height: 14px;
}
.layui-form-checked[lay-skin=primary] i {
border-color: #2176ff!important;
background-color: #2176ff;
color: #fff;
}
.layui-nav-bar{
height: 0px !important;
}

View File

@ -530,6 +530,51 @@ upload_attach.render({
field:'attachment_upload',
})
// 按钮上传docx文档
var upload_docx_doc = layui.upload;
upload_docx_doc.render({
elem:"#import-doc-docx",
url:"/import/doc_docx/",
data:{'type':'docx','editor_mode':editor_mode},
before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(1); //上传loading
},
accept: 'file', //允许上传的文件类型
exts:'docx',
field:'import_doc_docx',
done: function(res, index, upload){ //上传后的回调
//上传成功,刷新页面
if(res.status){
if(editor_mode == 3){
editor.addValue(res.data)
}else if(editor_mode == 1){
editor.insertValue(res.data);
}else if(editor_mode == 2){
editor.setValue(res.data);
}
layer.closeAll();
layer.msg("导入成功");
}else{
layer.closeAll('loading');
layer.msg(res.data)
}
},
error:function(){
layer.closeAll('loading'); //关闭loading
layer.msg("系统异常,请稍后再试!")
},
});
$("#doc-tag-set").click(function(){
layer.open({
type:1,
title:"文档标签设置",
content:$("#doc-tag-div"),
area:['300px'],
btn:['确定']
})
});
// 粘贴表格文本框侦听paste粘贴事件
// 列宽的函数
function columnWidth(rows, columnIndex) {

View File

@ -18,33 +18,51 @@
{% block left_opera %}
<div class="layui-form" style="padding: 0 10px 10px 10px;" lay-filter="left_form">
<div class="layui-row">
<div class="layui-btn-container" style="margin-bottom: 0px;">
<button class="layui-btn layui-btn-primary layui-btn-sm mrdoc-btn-default" id="sel-doctemp" title="导入模板内容">
导入模板
</button>
<input type="file" id="insert-local-file" onchange="insertLocalFile(this)" style="display:none;">
<button class="layui-btn layui-btn-primary layui-btn-sm mrdoc-btn-default" id="sel-local" onclick="selectLocalFile()" title="导入本地文本文件内容">
导入文本
</button>
<button class="layui-btn layui-btn-primary layui-btn-sm mrdoc-btn-default" id="doc-cache-btn" title="查看浏览器缓存">
本地缓存
</button>
</div>
<div class="layui-form-item">
<label class="layui-form-label" style="padding-left: 0px;">编辑器切换</label>
<div class="layui-input-block">
<select name="select_editor_mode" lay-verify="required" lay-filter="select_editor_mode">
<option value="1">EditorMD(Markdown)</option>
<option value="2">Vditor(Markdown)</option>
<option value="3">iceEditor(富文本)</option>
</select>
</div>
</div>
<div class="layui-row">
<ul class="layui-nav mrdoc-import-doc-list">
<li class="layui-nav-item mrdoc-import-doc-item">
<a href="javascript:;">导入</a>
<dl class="layui-nav-child mrdoc-import-doc-child"> <!-- 二级菜单 -->
<dd><a href="javascript:void(0);" id="sel-doctemp">
<svg t="1608814405819" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3399" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M0 0h475.904v335.36H0z" fill="#52adff" p-id="3400"></path><path d="M591.36 667.050667H1024V1024H591.36z" fill="#1892ff" p-id="3401"></path><path d="M0 450.730667h475.904V1024H0z" fill="#83c5fd" p-id="3402"></path><path d="M591.36 0H1024v551.68H591.36z" fill="#52afff" p-id="3403"></path></svg>
文档模板</a>
</dd>
<input type="file" id="insert-local-file" onchange="insertLocalFile(this)" style="display:none;">
<dd><a href="javascript:void(0);" id="sel-local" onclick="selectLocalFile()">
<svg t="1608814859854" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4936" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M967.610182 280.878545v626.455273a113.361455 113.361455 0 0 1-113.361455 113.384727H173.870545A113.361455 113.361455 0 0 1 60.509091 907.333818V113.594182A113.291636 113.291636 0 0 1 173.847273 0.209455h513.093818l280.669091 280.599272v0.069818z" fill="#2475FE" p-id="4937"></path><path d="M686.964364 167.493818V0.069818l280.669091 280.669091h-167.214546A113.361455 113.361455 0 0 1 687.010909 167.330909l-0.069818 0.139636z" fill="#8AB3F7" p-id="4938"></path><path d="M346.763636 425.402182h311.901091v58.740363H346.786909v-58.740363z m185.134546 58.740363v256.791273h-58.647273V484.212364h58.647273v-0.069819z" fill="#FFFFFF" p-id="4939"></path></svg>
文本文件</a></dd>
<dd><a href="javascript:void(0);" id="doc-cache-btn">
<svg t="1608814983993" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6507" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M0 0h1024v1024H0z" fill="#D8D8D8" fill-opacity="0" p-id="6508"></path><path d="M58.514286 220.7744h819.2a58.514286 58.514286 0 0 1 58.514285 58.514286v367.381943a117.028571 117.028571 0 0 1-117.028571 117.028571H175.542857a117.028571 117.028571 0 0 1-117.028571-117.028571V220.7744z" fill="#005DE8" opacity=".2" p-id="6509"></path><path d="M402.373486 193.653029m29.257143 0l104.360228 0q29.257143 0 29.257143 29.257142l0 22.9376q0 29.257143-29.257143 29.257143l-104.360228 0q-29.257143 0-29.257143-29.257143l0-22.9376q0-29.257143 29.257143-29.257142Z" fill="#FFDB00" p-id="6510"></path><path d="M245.467429 193.653029m29.257142 0l134.582858 0q29.257143 0 29.257142 29.257142l0 22.9376q0 29.257143-29.257142 29.257143l-134.582858 0q-29.257143 0-29.257142-29.257143l0-22.9376q0-29.257143 29.257142-29.257142Z" fill="#3289FF" p-id="6511"></path><path d="M194.852571 175.542857c48.830171 0 90.667886 29.9008 108.222172 72.411429H877.714286a58.514286 58.514286 0 0 1 58.514285 58.514285V732.306286a58.514286 58.514286 0 0 1-58.514285 58.514285H117.028571a58.514286 58.514286 0 0 1-58.514285-58.514285V234.057143a58.514286 58.514286 0 0 1 58.514285-58.514286h77.824z" fill="#005DE8" p-id="6512"></path><path d="M221.827657 617.033143c16.852114 0 33.440914-3.159771 44.763429-7.3728v-44.500114a124.5184 124.5184 0 0 1-42.130286 6.582857c-25.8048 0-37.390629-9.479314-37.390629-48.713143 0-37.390629 10.269257-49.7664 36.600686-49.7664 15.008914 0 28.437943 2.369829 40.813714 6.846171V435.6096c-11.322514-4.213029-27.121371-6.582857-45.026742-6.582857-54.769371 0-89.790171 23.434971-89.790172 94.0032 0 76.624457 36.337371 94.0032 92.16 94.0032z m132.183772-147.192686c-10.269257 0-25.541486 0.526629-36.337372 2.369829v41.866971a172.909714 172.909714 0 0 1 29.227886-2.369828l7.519086 0.146285c14.628571 0.643657 18.666057 3.8912 19.338971 16.442515h-29.227886c-41.340343 0-60.035657 12.112457-60.035657 44.763428 0 30.544457 18.695314 43.973486 48.449829 43.973486 25.014857 0 37.127314-8.689371 41.340343-15.798857l3.949714 13.165714h45.290057v-96.636343c0-33.1776-19.748571-47.9232-69.514971-47.9232z m-5.266286 110.065372c-10.269257 0-15.798857-1.8432-15.798857-9.216 0-7.723886 4.213029-10.357029 17.086171-10.737372l23.727543-0.058514v11.0592c-3.949714 5.002971-12.639086 8.952686-25.014857 8.952686z m174.577371 37.127314c13.165714 0 30.017829-2.106514 38.180572-5.5296v-39.760457a74.986057 74.986057 0 0 1-28.437943 4.739657c-21.855086 0-32.914286-6.582857-32.914286-33.1776 0-26.331429 11.585829-33.704229 31.861029-33.704229 9.742629 0 18.168686 1.053257 27.648 4.476343v-40.5504c-9.479314-2.896457-23.698286-3.949714-36.337372-3.949714-46.343314 0-73.728 15.272229-73.728 73.728s27.384686 73.728 73.728 73.728z m158.5152-147.456c-23.9616 0-37.390629 7.636114-43.973485 17.905371V414.281143h-50.029715V614.4h50.029715v-92.16c1.8432-7.636114 7.3728-13.165714 20.2752-13.165714 15.798857 0 20.2752 2.896457 20.2752 20.538514V614.4h50.029714v-96.109714c0-34.494171-13.165714-48.713143-46.606629-48.713143z m209.334857 64.512c0-43.446857-13.692343-64.512-64.248685-64.512-47.133257 0-74.517943 15.272229-74.517943 73.728s27.384686 73.728 72.148114 73.728c28.174629 0 50.819657-5.266286 59.509029-11.322514v-36.864c-8.426057 5.002971-30.281143 10.269257-49.503086 10.269257-18.168686 0-29.4912-5.002971-32.387657-17.378743l87.420343-5.266286c0.789943-2.106514 1.579886-10.795886 1.579885-22.381714z m-89.263542-6.319543c1.053257-17.642057 8.426057-21.591771 25.278171-21.591771 15.798857 0 19.748571 7.3728 19.748571 18.168685l-45.026742 3.423086z" fill="#FFFFFF" p-id="6513"></path></svg>
文档缓存</a></dd>
<dd><a href="javascript:void(0);" id="import-doc-docx">
<svg t="1608815050013" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7356" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M535.119473 0h69.599248v95.247413C729.226717 96.331138 853.614299 93.92286 977.881468 96.331138a40.459078 40.459078 0 0 1 44.914393 45.516463c2.047037 234.566322 0 469.614299 1.204139 703.819379-1.204139 24.082785 2.287865 50.694262-11.318909 72.248354-16.978363 12.041392-38.893697 10.837253-58.761994 12.041392h-349.200376V1023.518344h-72.248354C354.980245 990.886171 177.490122 960.541863 0 928.752587V95.488241C178.33302 63.578551 356.786453 32.511759 535.119473 0z" fill="#2A5699" p-id="7357"></path><path d="M604.718721 131.010348H988.598307v761.979304H604.718721v-95.247413h302.479774v-48.165569H604.718721v-59.002822h302.479774v-48.16557H604.718721v-59.002822h302.479774v-48.165569H604.718721v-60.206961h302.479774V428.673565H604.718721v-60.206961h302.479774v-46.96143H604.718721v-59.604892h302.479774V214.336783H604.718721zM240.827846 341.373471c22.156162-1.324553 44.19191-2.287865 66.348071-3.492003 15.533396 80.4365 31.30762 160.632173 48.165569 240.827845 13.125118-82.724365 27.695202-165.087488 41.783632-247.571025 23.239887-0.842897 46.479774-2.167451 69.719661-3.612418-26.370649 115.356538-49.369708 231.796802-78.148636 346.430856-19.386642 10.355597-48.165569 0-71.52587 1.204139C301.034807 596.169332 283.093133 517.779868 269.245532 438.667921c-13.606773 76.944497-31.30762 153.16651-46.841016 229.508937-22.39699-1.204139-44.793979-2.528692-67.311383-4.094073-19.266228-104.760113-42.024459-208.918156-60.206962-313.919097 19.868297-0.963311 39.857008-1.806209 60.206962-2.528693 12.041392 75.860771 25.648166 151.360301 36.124177 227.341487 16.135466-77.907808 32.873001-155.695202 49.610536-233.603011z" fill="#FFFFFF" p-id="7358"></path></svg>
Word文档(.docx)</a></dd>
</dl>
</li>
<li class="layui-nav-item mrdoc-import-doc-item">
<a href="javascript:;">编辑器</a>
<dl class="layui-nav-child mrdoc-import-doc-child"> <!-- 二级菜单 -->
<dd><a href="?pid={{pid}}&eid=1">EditorMD{% if editor_mode == 1 %}<span class="layui-badge-dot layui-bg-blue"></span>{% endif %}</a></dd>
<dd><a href="?pid={{pid}}&eid=2">Vditor{% if editor_mode == 2 %}<span class="layui-badge-dot layui-bg-blue"></span>{% endif %}</a></dd>
<dd><a href="?pid={{pid}}&eid=3">iceEditor{% if editor_mode == 3 %}<span class="layui-badge-dot layui-bg-blue"></span>{% endif %}</a></dd>
</dl>
</li>
<li class="layui-nav-item mrdoc-import-doc-item">
<a href="javascript:;">其他配置</a>
<dl class="layui-nav-child mrdoc-import-doc-child"> <!-- 二级菜单 -->
<dd><a href="javascript:void(0);" id="doc-tag-set">
<svg t="1608950408113" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4040" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M828.952381 0H195.047619C141.165714 0 97.52381 43.641905 97.52381 97.52381v926.47619l414.47619-170.666667 414.47619 170.666667V97.52381c0-53.881905-43.641905-97.52381-97.523809-97.52381z" fill="#8BAFFF" p-id="4041"></path><path d="M567.832381 191.146667c-91.91619 106.300952-148.72381 257.219048-150.918095 435.931428C415.939048 695.344762 341.333333 828.952381 390.095238 902.095238l121.904762-48.761905 414.47619 170.666667V434.224762c-90.697143-118.979048-221.866667-197.973333-358.643809-243.078095z" fill="#2C6BDB" p-id="4042"></path><path d="M97.52381 170.666667v853.333333l353.523809-146.285714s-36.571429-70.704762-34.133333-250.636191c2.194286-178.712381 59.001905-329.630476 150.918095-435.931428C397.409524 135.070476 217.965714 131.657143 97.52381 170.666667zM926.47619 434.224762V121.904762c0-24.380952 0-73.142857-31.939047-96.548572-128.487619 8.533333-242.346667 68.266667-326.704762 165.790477C704.609524 236.251429 835.779048 315.245714 926.47619 434.224762z" fill="#4480EA" p-id="4043"></path></svg>
文档标签</a></dd>
<dd><input type="checkbox" name="open-children" title="展开下级目录" lay-skin="primary"></dd>
<dd><input type="checkbox" name="show-children" title="显示下级文档" lay-skin="primary"></dd>
</dl>
</li>
</ul>
<hr>
<!-- 选择文集 -->
<div class="layui-col-md12" style="margin-bottom: 10px;">
<div class="layui-input-inblock">
<select name="pro_id" lay-verify="required" lay-filter="project" id="project">
<select name="pro_id" lay-verify="required" lay-filter="project" id="project" lay-search>
<option value="">请选择一个文集(必选)</option>
<option value="-1">新建文集</option>
<!-- 自己的文集 -->
@ -96,71 +114,18 @@
</div>
<hr>
<!-- 标签输入框 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
<h2 class="layui-colla-title">标签</h2>
<div class="layui-colla-content">
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
<input name="tagsinput" id="tagsinputval" class="tagsinput" data-role="tagsinput" value="" placeholder="输入标签名">
</div>
</div>
</div>
</div>
<!-- 文档下级目录展开设置 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
<h2 class="layui-colla-title">下级目录</h2>
<div class="layui-colla-content layui-show">
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
{%if doc.open_children %}
<input type="radio" name="open-children" value="true" title="展开" checked>
<input type="radio" name="open-children" value="false" title="收起">
{% else %}
<input type="radio" name="open-children" value="true" title="展开">
<input type="radio" name="open-children" value="false" title="收起" checked>
{% endif %}
</div>
</div>
</div>
</div>
<!-- 显示下级文档 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
<h2 class="layui-colla-title">文档内显示下级文档</h2>
<div class="layui-colla-content layui-show">
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
{%if doc.show_children %}
<input type="radio" name="show-children" value="true" title="显示" checked>
<input type="radio" name="show-children" value="false" title="隐藏">
{% else %}
<input type="radio" name="show-children" value="true" title="显示">
<input type="radio" name="show-children" value="false" title="隐藏" checked>
{% endif %}
</div>
</div>
</div>
</div>
<!-- 发布按钮 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
<h2 class="layui-colla-title">发布</h2>
<div class="layui-colla-content layui-show">
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
<div class="layui-row">
<button class="layui-btn layui-btn-fluid layui-btn-primary" id="save_doc" title="保存当前内容为草稿文档">
<i class="fa fa-save"></i> 保存文档
</button>
</div>
<div class="layui-row">
<button class="layui-btn layui-btn-fluid layui-btn-normal" id="pub_doc" title="发布当前内容">
<i class="fa fa-save"></i> 发布文档
</button>
</div>
<div class="layui-colla-content layui-show" style="padding: 10px;background-color: #fff;">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-primary" id="save_doc" title="保存当前内容为草稿文档">
<i class="fa fa-save"></i> 保存文档
</button>
<button class="layui-btn layui-btn-normal" id="pub_doc" title="发布当前内容">
<i class="layui-icon layui-icon-release"></i> 发布文档
</button>
</div>
</div>
</div>
@ -321,8 +286,8 @@
'sort':$("#sort").val(),
'editor_mode':'{{editor_mode}}',
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
'show_children':$('input:radio[name="show-children"]:checked').val(),
'open_children':$('input:checkbox[name="open-children"]:checked').val(),
'show_children':$('input:checkbox[name="show-children"]:checked').val(),
}
// console.log(data)
if(data.doc_name == ""){

View File

@ -40,42 +40,54 @@
{% endif %}
</div>
<div class="doc-form-label" style="margin-bottom: 10px;">
<a class="layui-btn layui-btn-xs layui-btn-normal" target="_blank" href="{% url 'doc' doc.top_doc doc.id %}" style="background-color: #2176ff;">
<i class="fa fa-book"></i> 查看
</a>
<button class="layui-btn layui-btn-xs layui-btn-normal" id="doc-history">
<i class="fa fa-history"></i> 历史
</button>
<button class="layui-btn layui-btn-xs layui-btn-normal" id="doc-cache-btn">
<i class="fa fa-history"></i> 缓存
</button>
</div>
<div class="layui-form-item">
<label class="layui-form-label" style="padding-left: 0px;">编辑器切换</label>
<div class="layui-input-block">
<select name="select_editor_mode" lay-verify="required" lay-filter="select_editor_mode">
<option value="1">EditorMD(Markdown)</option>
<option value="2">Vditor(Markdown)</option>
<option value="3">iceEditor(富文本)</option>
</select>
</div>
</div>
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label" style="margin-right:0px;">
<button class="layui-btn layui-btn-primary layui-btn-sm mrdoc-btn-default" id="sel-doctemp" title="插入文档模板">
<i class="fa fa-clipboard"></i> 选择模板
</button>
</label>
<label class="doc-form-label" style="margin-right:0px;">
<ul class="layui-nav mrdoc-import-doc-list">
<li class="layui-nav-item mrdoc-import-doc-item">
<a href="javascript:;">查看</a>
<dl class="layui-nav-child mrdoc-import-doc-child"> <!-- 二级菜单 -->
<dd><a target="_blank" href="{% url 'doc' doc.top_doc doc.id %}">
文档</a></dd>
<dd><a href="javascript:void(0);" id="doc-history">文档历史</a></dd>
</dl>
</li>
<li class="layui-nav-item mrdoc-import-doc-item">
<a href="javascript:;">导入</a>
<dl class="layui-nav-child mrdoc-import-doc-child"> <!-- 二级菜单 -->
<dd><a href="javascript:void(0);" id="sel-doctemp">
<svg t="1608814405819" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3399" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M0 0h475.904v335.36H0z" fill="#52adff" p-id="3400"></path><path d="M591.36 667.050667H1024V1024H591.36z" fill="#1892ff" p-id="3401"></path><path d="M0 450.730667h475.904V1024H0z" fill="#83c5fd" p-id="3402"></path><path d="M591.36 0H1024v551.68H591.36z" fill="#52afff" p-id="3403"></path></svg>
文档模板</a>
</dd>
<input type="file" id="insert-local-file" onchange="insertLocalFile(this)" style="display:none;">
<button class="layui-btn layui-btn-primary layui-btn-sm mrdoc-btn-default" id="sel-local" onclick="selectLocalFile()" title="插入本地文本文件内容">
<i class="fa fa-upload"></i> 导入文本
</button>
</label>
</div>
<dd><a href="javascript:void(0);" id="sel-local" onclick="selectLocalFile()">
<svg t="1608814859854" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4936" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M967.610182 280.878545v626.455273a113.361455 113.361455 0 0 1-113.361455 113.384727H173.870545A113.361455 113.361455 0 0 1 60.509091 907.333818V113.594182A113.291636 113.291636 0 0 1 173.847273 0.209455h513.093818l280.669091 280.599272v0.069818z" fill="#2475FE" p-id="4937"></path><path d="M686.964364 167.493818V0.069818l280.669091 280.669091h-167.214546A113.361455 113.361455 0 0 1 687.010909 167.330909l-0.069818 0.139636z" fill="#8AB3F7" p-id="4938"></path><path d="M346.763636 425.402182h311.901091v58.740363H346.786909v-58.740363z m185.134546 58.740363v256.791273h-58.647273V484.212364h58.647273v-0.069819z" fill="#FFFFFF" p-id="4939"></path></svg>
文本文件</a></dd>
<dd><a href="javascript:void(0);" id="doc-cache-btn">
<svg t="1608814983993" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6507" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M0 0h1024v1024H0z" fill="#D8D8D8" fill-opacity="0" p-id="6508"></path><path d="M58.514286 220.7744h819.2a58.514286 58.514286 0 0 1 58.514285 58.514286v367.381943a117.028571 117.028571 0 0 1-117.028571 117.028571H175.542857a117.028571 117.028571 0 0 1-117.028571-117.028571V220.7744z" fill="#005DE8" opacity=".2" p-id="6509"></path><path d="M402.373486 193.653029m29.257143 0l104.360228 0q29.257143 0 29.257143 29.257142l0 22.9376q0 29.257143-29.257143 29.257143l-104.360228 0q-29.257143 0-29.257143-29.257143l0-22.9376q0-29.257143 29.257143-29.257142Z" fill="#FFDB00" p-id="6510"></path><path d="M245.467429 193.653029m29.257142 0l134.582858 0q29.257143 0 29.257142 29.257142l0 22.9376q0 29.257143-29.257142 29.257143l-134.582858 0q-29.257143 0-29.257142-29.257143l0-22.9376q0-29.257143 29.257142-29.257142Z" fill="#3289FF" p-id="6511"></path><path d="M194.852571 175.542857c48.830171 0 90.667886 29.9008 108.222172 72.411429H877.714286a58.514286 58.514286 0 0 1 58.514285 58.514285V732.306286a58.514286 58.514286 0 0 1-58.514285 58.514285H117.028571a58.514286 58.514286 0 0 1-58.514285-58.514285V234.057143a58.514286 58.514286 0 0 1 58.514285-58.514286h77.824z" fill="#005DE8" p-id="6512"></path><path d="M221.827657 617.033143c16.852114 0 33.440914-3.159771 44.763429-7.3728v-44.500114a124.5184 124.5184 0 0 1-42.130286 6.582857c-25.8048 0-37.390629-9.479314-37.390629-48.713143 0-37.390629 10.269257-49.7664 36.600686-49.7664 15.008914 0 28.437943 2.369829 40.813714 6.846171V435.6096c-11.322514-4.213029-27.121371-6.582857-45.026742-6.582857-54.769371 0-89.790171 23.434971-89.790172 94.0032 0 76.624457 36.337371 94.0032 92.16 94.0032z m132.183772-147.192686c-10.269257 0-25.541486 0.526629-36.337372 2.369829v41.866971a172.909714 172.909714 0 0 1 29.227886-2.369828l7.519086 0.146285c14.628571 0.643657 18.666057 3.8912 19.338971 16.442515h-29.227886c-41.340343 0-60.035657 12.112457-60.035657 44.763428 0 30.544457 18.695314 43.973486 48.449829 43.973486 25.014857 0 37.127314-8.689371 41.340343-15.798857l3.949714 13.165714h45.290057v-96.636343c0-33.1776-19.748571-47.9232-69.514971-47.9232z m-5.266286 110.065372c-10.269257 0-15.798857-1.8432-15.798857-9.216 0-7.723886 4.213029-10.357029 17.086171-10.737372l23.727543-0.058514v11.0592c-3.949714 5.002971-12.639086 8.952686-25.014857 8.952686z m174.577371 37.127314c13.165714 0 30.017829-2.106514 38.180572-5.5296v-39.760457a74.986057 74.986057 0 0 1-28.437943 4.739657c-21.855086 0-32.914286-6.582857-32.914286-33.1776 0-26.331429 11.585829-33.704229 31.861029-33.704229 9.742629 0 18.168686 1.053257 27.648 4.476343v-40.5504c-9.479314-2.896457-23.698286-3.949714-36.337372-3.949714-46.343314 0-73.728 15.272229-73.728 73.728s27.384686 73.728 73.728 73.728z m158.5152-147.456c-23.9616 0-37.390629 7.636114-43.973485 17.905371V414.281143h-50.029715V614.4h50.029715v-92.16c1.8432-7.636114 7.3728-13.165714 20.2752-13.165714 15.798857 0 20.2752 2.896457 20.2752 20.538514V614.4h50.029714v-96.109714c0-34.494171-13.165714-48.713143-46.606629-48.713143z m209.334857 64.512c0-43.446857-13.692343-64.512-64.248685-64.512-47.133257 0-74.517943 15.272229-74.517943 73.728s27.384686 73.728 72.148114 73.728c28.174629 0 50.819657-5.266286 59.509029-11.322514v-36.864c-8.426057 5.002971-30.281143 10.269257-49.503086 10.269257-18.168686 0-29.4912-5.002971-32.387657-17.378743l87.420343-5.266286c0.789943-2.106514 1.579886-10.795886 1.579885-22.381714z m-89.263542-6.319543c1.053257-17.642057 8.426057-21.591771 25.278171-21.591771 15.798857 0 19.748571 7.3728 19.748571 18.168685l-45.026742 3.423086z" fill="#FFFFFF" p-id="6513"></path></svg>
文档缓存</a></dd>
<dd><a href="javascript:void(0);" id="import-doc-docx">
<svg t="1608815050013" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7356" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M535.119473 0h69.599248v95.247413C729.226717 96.331138 853.614299 93.92286 977.881468 96.331138a40.459078 40.459078 0 0 1 44.914393 45.516463c2.047037 234.566322 0 469.614299 1.204139 703.819379-1.204139 24.082785 2.287865 50.694262-11.318909 72.248354-16.978363 12.041392-38.893697 10.837253-58.761994 12.041392h-349.200376V1023.518344h-72.248354C354.980245 990.886171 177.490122 960.541863 0 928.752587V95.488241C178.33302 63.578551 356.786453 32.511759 535.119473 0z" fill="#2A5699" p-id="7357"></path><path d="M604.718721 131.010348H988.598307v761.979304H604.718721v-95.247413h302.479774v-48.165569H604.718721v-59.002822h302.479774v-48.16557H604.718721v-59.002822h302.479774v-48.165569H604.718721v-60.206961h302.479774V428.673565H604.718721v-60.206961h302.479774v-46.96143H604.718721v-59.604892h302.479774V214.336783H604.718721zM240.827846 341.373471c22.156162-1.324553 44.19191-2.287865 66.348071-3.492003 15.533396 80.4365 31.30762 160.632173 48.165569 240.827845 13.125118-82.724365 27.695202-165.087488 41.783632-247.571025 23.239887-0.842897 46.479774-2.167451 69.719661-3.612418-26.370649 115.356538-49.369708 231.796802-78.148636 346.430856-19.386642 10.355597-48.165569 0-71.52587 1.204139C301.034807 596.169332 283.093133 517.779868 269.245532 438.667921c-13.606773 76.944497-31.30762 153.16651-46.841016 229.508937-22.39699-1.204139-44.793979-2.528692-67.311383-4.094073-19.266228-104.760113-42.024459-208.918156-60.206962-313.919097 19.868297-0.963311 39.857008-1.806209 60.206962-2.528693 12.041392 75.860771 25.648166 151.360301 36.124177 227.341487 16.135466-77.907808 32.873001-155.695202 49.610536-233.603011z" fill="#FFFFFF" p-id="7358"></path></svg>
Word文档(.docx)</a></dd>
</dl>
</li>
<li class="layui-nav-item mrdoc-import-doc-item">
<a href="javascript:;">编辑器</a>
<dl class="layui-nav-child mrdoc-import-doc-child"> <!-- 二级菜单 -->
<dd><a href="?pid={{pid}}&eid=1">EditorMD{% if editor_mode == 1 %}<span class="layui-badge-dot layui-bg-blue"></span>{% endif %}</a></dd>
<dd><a href="?pid={{pid}}&eid=2">Vditor{% if editor_mode == 2 %}<span class="layui-badge-dot layui-bg-blue"></span>{% endif %}</a></dd>
<dd><a href="?pid={{pid}}&eid=3">iceEditor{% if editor_mode == 3 %}<span class="layui-badge-dot layui-bg-blue"></span>{% endif %}</a></dd>
</dl>
</li>
<li class="layui-nav-item mrdoc-import-doc-item">
<a href="javascript:;">其他配置</a>
<dl class="layui-nav-child mrdoc-import-doc-child"> <!-- 二级菜单 -->
<dd><a href="javascript:void(0);" id="doc-tag-set">
<svg t="1608950408113" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4040" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20"><defs><style type="text/css"></style></defs><path d="M828.952381 0H195.047619C141.165714 0 97.52381 43.641905 97.52381 97.52381v926.47619l414.47619-170.666667 414.47619 170.666667V97.52381c0-53.881905-43.641905-97.52381-97.523809-97.52381z" fill="#8BAFFF" p-id="4041"></path><path d="M567.832381 191.146667c-91.91619 106.300952-148.72381 257.219048-150.918095 435.931428C415.939048 695.344762 341.333333 828.952381 390.095238 902.095238l121.904762-48.761905 414.47619 170.666667V434.224762c-90.697143-118.979048-221.866667-197.973333-358.643809-243.078095z" fill="#2C6BDB" p-id="4042"></path><path d="M97.52381 170.666667v853.333333l353.523809-146.285714s-36.571429-70.704762-34.133333-250.636191c2.194286-178.712381 59.001905-329.630476 150.918095-435.931428C397.409524 135.070476 217.965714 131.657143 97.52381 170.666667zM926.47619 434.224762V121.904762c0-24.380952 0-73.142857-31.939047-96.548572-128.487619 8.533333-242.346667 68.266667-326.704762 165.790477C704.609524 236.251429 835.779048 315.245714 926.47619 434.224762z" fill="#4480EA" p-id="4043"></path></svg>
文档标签</a></dd>
<dd><input type="checkbox" name="open-children" title="展开下级目录" lay-skin="primary" {%if doc.open_children %}checked{% endif %}></dd>
<dd><input type="checkbox" name="show-children" title="显示下级文档" lay-skin="primary" {%if doc.show_children %}checked{% endif %}></dd>
</dl>
</li>
</ul>
<div class="layui-col-md12" style="margin-bottom: 10px;">
<div class="layui-input-inblock">
@ -106,54 +118,6 @@
</div>
<hr>
<!-- 标签输入框 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
<h2 class="layui-colla-title">标签</h2>
<div class="layui-colla-content layui-show">
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
<input name="tagsinput" id="tagsinputval" class="tagsinput" data-role="tagsinput" value="{{doc_tags}}" placeholder="输入标签名">
</div>
</div>
</div>
</div>
<!-- 文档下级目录展开设置 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
<h2 class="layui-colla-title">下级目录</h2>
<div class="layui-colla-content layui-show">
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
{%if doc.open_children %}
<input type="radio" name="open-children" value="true" title="展开" checked>
<input type="radio" name="open-children" value="false" title="收起">
{% else %}
<input type="radio" name="open-children" value="true" title="展开">
<input type="radio" name="open-children" value="false" title="收起" checked>
{% endif %}
</div>
</div>
</div>
</div>
<!-- 显示下级文档 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
<h2 class="layui-colla-title">文档内显示下级文档</h2>
<div class="layui-colla-content layui-show">
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
{%if doc.show_children %}
<input type="radio" name="show-children" value="true" title="显示" checked>
<input type="radio" name="show-children" value="false" title="隐藏">
{% else %}
<input type="radio" name="show-children" value="true" title="显示">
<input type="radio" name="show-children" value="false" title="隐藏" checked>
{% endif %}
</div>
</div>
</div>
</div>
<!-- 发布按钮 -->
<div class="layui-collapse" style="margin-top: 10px;margin-bottom: 10px;">
<div class="layui-colla-item">
@ -162,13 +126,13 @@
<div class="layui-row layui-col-space5" style="padding: 5px;background-color: #fff;">
<div class="layui-row" style="margin-top: 5px;">
<button class="layui-btn layui-btn-primary layui-btn-fluid mrdoc-btn-default" id="modify_save_doc" title="保存当前内容为草稿文档">
<i class="fa fa-save"></i> 保存草稿
<i class="fa fa-save"></i> 保存草稿
</button>
</div>
<div class="layui-row" style="margin-top: 5px;">
<button class="layui-btn layui-btn-normal layui-btn-fluid" id="modify_pub_doc" title="发布当前内容">
<i class="fa fa-save"></i> 发布文档
<i class="layui-icon layui-icon-release"></i> 发布文档
</button>
</div>
@ -318,8 +282,8 @@
'sort':$("#sort").val(),
'editor_mode':'{{editor_mode}}',
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
'show_children':$('input:radio[name="show-children"]:checked').val(),
'open_children':$('input:checkbox[name="open-children"]:checked').val(),
'show_children':$('input:checkbox[name="show-children"]:checked').val(),
}
$.post("{% url 'modify_doc' doc_id=doc.id %}",data,function(r){
layer.closeAll("loading");

View File

@ -129,4 +129,11 @@
<div class="layui-col-md12" style="margin: 10px;">
<span style="font-size: 12px;color:mediumvioletred;">警告MrDoc仅支持3级目录显示若移动的下级文档层级在目标文集中超过3层将不会显示在文集目录中</span>
</div>
</div>
<!-- 文档标签DIV -->
<div id="doc-tag-div" style="display: none;">
<div class="layui-row layui-col-space5" style="padding: 10px;background-color: #fff;">
<input name="tagsinput" id="tagsinputval" class="tagsinput" data-role="tagsinput" value="{{doc_tags}}" placeholder="输入标签名">
</div>
</div>

View File

@ -203,7 +203,7 @@
layer.open({
type:1,
title:'修改'+ user + '的协作权限',
area:'300px;',
area:'400px;',
id:'modifyProColla',//配置ID
content:$('#modify-pro-colla-layer'),
btn:['确定','取消'], //添加按钮
@ -273,10 +273,10 @@
{% endfor %}
</select>
<div class="layui-form-item">
<div class="layui-input-inline">
<input type="radio" name="add-role" value="0" title="初级权限" checked>
<input type="radio" name="add-role" value="1" title="高级权限" >
</div>
<!-- <div class="layui-input-inline"> -->
<input type="radio" name="add-role" value="0" title="初级权限 - 可新建文档,修改、删除自己创建的文档" checked>
<input type="radio" name="add-role" value="1" title="高级权限 - 可操作所有文档" >
<!-- </div> -->
</div>
</div>
</div>
@ -284,10 +284,10 @@
<div id="modify-pro-colla-layer" style="display:none;">
<div style="margin:10px;" class="layui-form">
<div class="layui-form-item">
<div class="layui-input-inline">
<input type="radio" name="modify-role" value="0" title="初级权限" checked>
<input type="radio" name="modify-role" value="1" title="高级权限" >
</div>
<!-- <div class="layui-input-inline"> -->
<input type="radio" name="modify-role" value="0" title="初级权限 - 可新建文档,修改、删除自己创建的文档" checked>
<input type="radio" name="modify-role" value="1" title="高级权限 - 可操作所有文档" >
<!-- </div> -->
</div>
</div>
</div>

View File

@ -22,10 +22,10 @@
{% block content_head %}
<h1>{{ project.name }}</h1><hr>
<p style="" class="project-doc-content-head">
<!-- <p style="" class="project-doc-content-head">
<i class="fa fa-user"></i> {% trans "创建人:" %}{% if project.create_user.first_name != '' %} {{project.create_user.first_name}} {% else %} {{project.create_user}}{% endif %}
&nbsp;&nbsp;&nbsp;&nbsp;<i class="fa fa-timer"></i> {% trans "创建于:" %}{{ project.create_time }}
</p>
</p> -->
{% endblock %}
{% block page_content %}
@ -132,6 +132,14 @@
{% endblock %}
{% block doc_bottom_block %}
<span >
<i class="layui-icon layui-icon-user"></i>
<span tooltip="文集创建者">{% if project.create_user.first_name != '' %} {{project.create_user.first_name}} {% else %} {{project.create_user.username}}{% endif %}</span>
{% for colla in colla_user_list %}
,<span tooltip="文集成员">{% if colla.user.first_name != '' %} {{colla.user.first_name}} {% else %} {{colla.user.username}}{% endif %}</span>
{% endfor %}
</span>
<button id="share" class="doc-bottom-btn" tooltip="分享本文档" style="padding-left: 20px;">
<i class="fa fa-share-alt" ></i> {% trans "分享" %}
</button>