v0.3.0修复Bug,添加epub下载功能
This commit is contained in:
parent
00e7c097c3
commit
f463f9efed
@ -1,5 +1,14 @@
|
||||
## 版本更新记录
|
||||
|
||||
### v0.3.0 2020-03-07
|
||||
|
||||
- 优化MD文件导出逻辑,修复文档中本地资源不存在引发异常的问题;
|
||||
- 个人中心文集管理页面文集MD文件导出的交互;
|
||||
- 去除首次请求的Cookie检查,避免正常文档产生404的问题;
|
||||
- 优化首页文集列表样式,修复文集名称过长的显示问题,添加文集的最新文档;
|
||||
- 添加文集的EPUB导出功能,支持全站启停文集的前台导出和作者对单一文集的前台导出控制;
|
||||
- 升级Layui版本至2.5.6
|
||||
|
||||
### v0.2.12
|
||||
|
||||
- 优化Markdown编辑器的扩展工具栏按钮,未选择文本时点击“楷”按钮,光标移动到span标签中间;
|
||||
|
||||
@ -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.12'
|
||||
VERSIONS = '0.3.0'
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
|
||||
@ -18,7 +18,9 @@ from django.urls import path,include,re_path
|
||||
from django.views.static import serve
|
||||
from django.conf import settings
|
||||
from django.contrib.sitemaps import views
|
||||
from app_doc.sitemaps import all_sitemaps as sitemaps
|
||||
from app_doc.sitemaps import all_sitemaps
|
||||
|
||||
sitemaps = all_sitemaps()
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
州的先生(zmister.com)自用并完全开源、基于Python编写的文档写作系统。
|
||||
|
||||
当前版本为:**v0.2.12**,版本发布时间为**2020-02-27**,更新记录详见:[CHANGES.md](./CHANGES.md)
|
||||
当前版本为:**v0.3.0**,版本发布时间为**2020-03-07**,更新记录详见:[CHANGES.md](./CHANGES.md)
|
||||
|
||||
MrDoc拥有以下特点:
|
||||
|
||||
@ -25,7 +25,7 @@ MrDoc拥有以下特点:
|
||||
- 提供文档模板功能,支持文档模板的创建、修改;
|
||||
- 仿GitBook文档阅读页面,支持文档阅读页面的字体缩放,字体类型修改,页面社交分享,良好的移动端阅读体验;
|
||||
- 支持三级目录层级显示;
|
||||
- 支持文集导出为markdown文本格式.md文件;
|
||||
- 支持文集后台导出为markdown文本格式.md文件、前台导出为EPUB电子书;
|
||||
- 基于文集进行权限控制,提供公开、私密、指定用户可见、访问码可见4种权限模式;
|
||||
|
||||
- 二次开发方便
|
||||
|
||||
@ -34,9 +34,25 @@ def open_register(function):
|
||||
def check_headers(function):
|
||||
def _inner(request,*args,**kwargs):
|
||||
metas = request.META
|
||||
if 'HTTP_COOKIE' not in metas:
|
||||
raise Http404
|
||||
elif 'HTTP_USER_AGENT' not in metas:
|
||||
# if 'HTTP_COOKIE' not in metas:
|
||||
# raise Http404
|
||||
if 'HTTP_USER_AGENT' not in metas:
|
||||
raise Http404
|
||||
return function(request, *args, **kwargs)
|
||||
return _inner
|
||||
|
||||
|
||||
# 开放前台文集导出
|
||||
def allow_report_file(function):
|
||||
def _inner(request,*args,**kwargs):
|
||||
try:
|
||||
status = SysSetting.objects.get(name='enable_project_report')
|
||||
except:
|
||||
# 如果不存在enable_project_report这个属性,那么表示是禁止导出的
|
||||
raise Http404
|
||||
# 启用导出
|
||||
if status.value == 'on':
|
||||
return function(request, *args, **kwargs)
|
||||
else:
|
||||
raise Http404
|
||||
return _inner
|
||||
@ -517,6 +517,7 @@ def admin_setting(request):
|
||||
beian_code = request.POST.get('beian_code',None) # 备案号
|
||||
enbale_email = request.POST.get("enable_email",None) # 启用邮箱
|
||||
enable_register_code = request.POST.get('enable_register_code',None) # 注册邀请码
|
||||
enable_project_report = request.POST.get('enable_project_report',None) # 文集导出
|
||||
# 更新开放注册状态
|
||||
SysSetting.objects.update_or_create(
|
||||
name='close_register',
|
||||
@ -547,6 +548,11 @@ def admin_setting(request):
|
||||
name = 'enable_register_code',
|
||||
defaults= {'value': enable_register_code, 'types':'basic'}
|
||||
)
|
||||
# 更新文集导出状态
|
||||
SysSetting.objects.update_or_create(
|
||||
name = 'enable_project_report',
|
||||
defaults={'value':enable_project_report,'types':'basic'}
|
||||
)
|
||||
|
||||
return render(request,'app_admin/admin_setting.html',locals())
|
||||
elif types == 'email':
|
||||
|
||||
26
app_doc/migrations/0009_projectreport.py
Normal file
26
app_doc/migrations/0009_projectreport.py
Normal file
@ -0,0 +1,26 @@
|
||||
# Generated by Django 2.1 on 2020-03-06 22:25
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app_doc', '0008_auto_20191221_1055'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ProjectReport',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('allow_epub', models.IntegerField(default=0, verbose_name='前台导出EPUB')),
|
||||
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app_doc.Project', unique=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '文集导出',
|
||||
'verbose_name_plural': '文集导出',
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -70,3 +70,17 @@ class DocTemp(models.Model):
|
||||
class Meta:
|
||||
verbose_name = '文档模板'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
# 文集导出模型
|
||||
class ProjectReport(models.Model):
|
||||
project = models.ForeignKey(Project,unique=True,on_delete=models.CASCADE)
|
||||
# 允许导出,默认为0-允许,1-不允许
|
||||
allow_epub = models.IntegerField(default=0,verbose_name="前台导出EPUB")
|
||||
|
||||
def __str__(self):
|
||||
self.project.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = '文集导出'
|
||||
verbose_name_plural = verbose_name
|
||||
@ -5,12 +5,23 @@
|
||||
# 博客地址:zmister.com
|
||||
# MrDoc文集文档导出相关功能代码
|
||||
from django.conf import settings
|
||||
from app_doc.models import *
|
||||
|
||||
import subprocess
|
||||
import datetime
|
||||
import datetime,time
|
||||
import re
|
||||
import os
|
||||
import os,sys
|
||||
import shutil
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
sys.path.extend([r'F:\pythonproject\MrDoc',])
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE","MrDoc.settings")
|
||||
application = get_wsgi_application()
|
||||
import django
|
||||
django.setup()
|
||||
from app_doc.models import *
|
||||
import traceback
|
||||
import time
|
||||
|
||||
# 导出MD文件压缩包
|
||||
class ReportMD():
|
||||
@ -80,7 +91,12 @@ class ReportMD():
|
||||
files.write(md_content_3)
|
||||
|
||||
# 压缩文件
|
||||
shutil.make_archive(self.project_path,'zip',self.project_path)
|
||||
md_file = shutil.make_archive(
|
||||
base_name=self.project_path,
|
||||
format='zip',
|
||||
root_dir=self.project_path
|
||||
)
|
||||
print(md_file)
|
||||
# 删除文件夹
|
||||
shutil.rmtree(self.project_path)
|
||||
|
||||
@ -106,7 +122,10 @@ class ReportMD():
|
||||
# 替换MD内容的静态文件链接
|
||||
md_content = md_content.replace(media_filename, "." + media_filename)
|
||||
# 复制静态文件到指定文件夹
|
||||
shutil.copy(settings.BASE_DIR + media_filename, self.media_path+sub_folder)
|
||||
try:
|
||||
shutil.copy(settings.BASE_DIR + media_filename, self.media_path+sub_folder)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
# 不存在本地静态文件,直接返回MD内容
|
||||
# else:
|
||||
# print("没有本地静态文件")
|
||||
@ -115,8 +134,571 @@ class ReportMD():
|
||||
else:
|
||||
return md_content
|
||||
|
||||
|
||||
# 导出EPUB
|
||||
class ReportEPUB():
|
||||
def __init__(self,project_id):
|
||||
self.project = Project.objects.get(id=project_id)
|
||||
self.base_path = settings.MEDIA_ROOT + '/report/{}/'.format(project_id)
|
||||
|
||||
# 创建相关目录
|
||||
if os.path.exists(self.base_path + '/OEBPS') is False:
|
||||
os.makedirs(self.base_path + '/OEBPS')
|
||||
if os.path.exists(self.base_path + '/OEBPS/Images') is False:
|
||||
os.makedirs(self.base_path + '/OEBPS/Images')
|
||||
if os.path.exists(self.base_path + '/OEBPS/Text') is False:
|
||||
os.makedirs(self.base_path + '/OEBPS/Text')
|
||||
if os.path.exists(self.base_path + '/OEBPS/Styles') is False:
|
||||
os.makedirs(self.base_path + '/OEBPS/Styles')
|
||||
if os.path.exists(self.base_path + '/META-INF') is False:
|
||||
os.makedirs(self.base_path + '/META-INF')
|
||||
|
||||
# 复制样式文件到相关目录
|
||||
shutil.copyfile(settings.BASE_DIR+'/static/report_epub/style.css',self.base_path + '/OEBPS/Styles/style.css')
|
||||
shutil.copyfile(settings.BASE_DIR+'/static/katex/katex.min.css',self.base_path + '/OEBPS/Styles/katex.css')
|
||||
shutil.copyfile(settings.BASE_DIR+'/static/editor.md/css/editormd.min.css/',self.base_path + '/OEBPS/Styles/editormd.css')
|
||||
# 复制封面图片到相关目录
|
||||
shutil.copyfile(settings.BASE_DIR+'/static/report_epub/epub_cover1.jpg',self.base_path + '/OEBPS/Images/epub_cover1.jpg')
|
||||
|
||||
# 将文档内容写入HTML文件
|
||||
def write_html(self, d, html_str):
|
||||
# 使用BeautifulSoup解析拼接好的HTML文本
|
||||
html_soup = BeautifulSoup(html_str, 'lxml')
|
||||
src_tag = html_soup.find_all(lambda tag: tag.has_attr("src")) # 查找所有包含src的标签
|
||||
code_tag = html_soup.find_all(name="code")
|
||||
# print(src_tag)
|
||||
|
||||
# 添加css样式标签
|
||||
style_link = html_soup.new_tag(name='link',href="../Styles/style.css",rel="stylesheet",type="text/css")
|
||||
katex_link = html_soup.new_tag(name='link',href='../Styles/katex.css',rel="stylesheet",type="text/css")
|
||||
editormd_link = html_soup.new_tag(name='link',href='../Styles/editormd.css',rel="stylesheet",type="text/css")
|
||||
html_soup.body.insert_before(style_link)
|
||||
html_soup.body.insert_before(katex_link)
|
||||
# html_soup.body.insert_before(editormd_link)
|
||||
|
||||
# 添加xlm标签声明
|
||||
# html_soup.html.insert_before('<?xml version="1.0" encoding="UTF-8"?>')
|
||||
# 添加html标签的xmlns属性
|
||||
html_soup.html['xmlns'] = "http://www.w3.org/1999/xhtml"
|
||||
|
||||
# 替换HTML文本中静态文件的相对链接为绝对链接
|
||||
for src in src_tag:
|
||||
if src['src'].startswith("/"):
|
||||
src_path = src['src'] # 媒体文件原始路径
|
||||
src_filename = src['src'].split("/")[-1] # 媒体文件名
|
||||
src['src'] = '../Images/' + src_filename # 媒体文件在EPUB中的路径
|
||||
# 复制文件到epub的Images文件夹
|
||||
try:
|
||||
shutil.copyfile(
|
||||
src= settings.BASE_DIR + src_path,
|
||||
dst= self.base_path + '/OEBPS/Images/' + src_filename
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
pass
|
||||
|
||||
# 替换code标签的内容
|
||||
# for code in code_tag:
|
||||
# code_str = code.get_text()
|
||||
# code.clear()
|
||||
# code['class'] = ''
|
||||
# code.string = code_str
|
||||
|
||||
# 创建写入临时HTML文件
|
||||
temp_file_path = self.base_path + '/OEBPS/Text/{0}.xhtml'.format(d.id)
|
||||
with open(temp_file_path, 'a+', encoding='utf-8') as htmlfile:
|
||||
htmlfile.write('<?xml version="1.0" encoding="UTF-8"?>' + str(html_soup))
|
||||
|
||||
# 生成文档HTML
|
||||
def generate_html(self):
|
||||
# 查询文档
|
||||
data = Doc.objects.filter(top_doc=self.project.id, parent_doc=0, status=1).order_by("sort")
|
||||
self.toc_list = [
|
||||
{
|
||||
'id': 0,
|
||||
'link': 'Text/toc_summary.xhtml',
|
||||
'pid': 0,
|
||||
'title': '目录'
|
||||
}
|
||||
]
|
||||
nav_str = '''<navMap>'''
|
||||
toc_summary_str = '''<ul>'''
|
||||
nav_num = 1
|
||||
# content.opf相关
|
||||
manifest = '''<item id="book_cover" href="Text/book_cover.xhtml" media-type="application/xhtml+xml"/>
|
||||
<item id="book_title" href="Text/book_title.xhtml" media-type="application/xhtml+xml"/>
|
||||
<item id="book_desc" href="Text/book_desc.xhtml" media-type="application/xhtml+xml"/>
|
||||
<item id="toc_summary" href="Text/toc_summary.xhtml" media-type="application/xhtml+xml"/>
|
||||
'''
|
||||
spine = '<itemref idref="book_cover" linear="no"/><itemref idref="book_title"/><itemref idref="book_desc"/><itemref idref="toc_summary"/>'
|
||||
|
||||
for d in data:
|
||||
# 拼接HTML字符串
|
||||
html_str = "<h1 style='page-break-before: always;'>{}</h1>".format(d.name)
|
||||
html_str += d.content
|
||||
self.write_html(d=d,html_str=html_str) # 生成HTML
|
||||
# 生成HTML的目录位置
|
||||
toc = {
|
||||
'id':d.id,
|
||||
'link':'{}.xhtml'.format(d.id),
|
||||
'pid':d.parent_doc,
|
||||
'title':d.name
|
||||
}
|
||||
self.toc_list.append(toc)
|
||||
|
||||
# nav
|
||||
toc_nav = '''<navPoint id="np_{nav_num}" playOrder="{nav_num}">
|
||||
<navLabel><text>{title}</text></navLabel>
|
||||
<content src="Text/{file}"/>
|
||||
'''.format(nav_num=nav_num,title=d.name,file=toc['link'])
|
||||
nav_str += toc_nav
|
||||
|
||||
# toc_summary
|
||||
toc_summary_str += '''<li><a href="./{}">{}</a>'''.format(toc['link'],toc['title'])
|
||||
# content.opf
|
||||
manifest += '<item id="{}" href="Text/{}.xhtml" media-type="application/xhtml+xml"/>'.format(d.id, d.id)
|
||||
spine += '<itemref idref="{}"/>'.format(d.id)
|
||||
|
||||
nav_num += 1
|
||||
|
||||
# 获取第二级文档
|
||||
data_2 = Doc.objects.filter(parent_doc=d.id,status=1).order_by("sort")
|
||||
if data_2.count() > 0:
|
||||
toc_summary_str += '<ul>'
|
||||
for d2 in data_2:
|
||||
html_str = "<h1>{}</h1>".format(d2.name)
|
||||
html_str += d2.content
|
||||
self.write_html(d=d2,html_str=html_str)
|
||||
# 生成HTML的目录位置
|
||||
toc = {
|
||||
'id': d2.id,
|
||||
'link': '{}.xhtml'.format(d2.id),
|
||||
'pid': d2.parent_doc,
|
||||
'title': d2.name
|
||||
}
|
||||
self.toc_list.append(toc)
|
||||
toc_nav = '''<navPoint id="np_{nav_num}" playOrder="{nav_num}">
|
||||
<navLabel><text>{title}</text></navLabel>
|
||||
<content src="Text/{file}"/>
|
||||
'''.format(nav_num=nav_num, title=d2.name, file=toc['link'])
|
||||
nav_str += toc_nav
|
||||
|
||||
# toc_summary
|
||||
toc_summary_str += '''<li><a href="./{}">{}</a>'''.format(toc['link'], toc['title'])
|
||||
# content.opf
|
||||
manifest += '<item id="{}" href="Text/{}.xhtml" media-type="application/xhtml+xml"/>'.format(d2.id, d2.id)
|
||||
spine += '<itemref idref="{}"/>'.format(d2.id)
|
||||
|
||||
nav_num += 1
|
||||
|
||||
# 获取第三级文档
|
||||
data_3 = Doc.objects.filter(parent_doc=d2.id,status=1).order_by("sort")
|
||||
if data_3.count() > 0:
|
||||
toc_summary_str += '<ul>'
|
||||
for d3 in data_3:
|
||||
html_str = "<h1>{}</h1>".format(d3.name)
|
||||
html_str += d3.content
|
||||
self.write_html(d=d3,html_str=html_str)
|
||||
# 生成HTML的目录位置
|
||||
toc = {
|
||||
'id': d3.id,
|
||||
'link': '{}.xhtml'.format(d3.id),
|
||||
'pid': d3.parent_doc,
|
||||
'title': d3.name
|
||||
}
|
||||
self.toc_list.append(toc)
|
||||
|
||||
toc_nav = '''<navPoint id="np_{nav_num}" playOrder="{nav_num}">
|
||||
<navLabel><text>{title}</text></navLabel>
|
||||
<content src="Text/{file}"/>
|
||||
</navPoint>
|
||||
'''.format(nav_num=nav_num, title=d3.name, file=toc['link'])
|
||||
nav_str += toc_nav
|
||||
|
||||
# toc_summary
|
||||
toc_summary_str += '''<li><a href="./{}">{}</a></li>'''.format(toc['link'], toc['title'])
|
||||
# content.opf
|
||||
manifest += '<item id="{}" href="Text/{}.xhtml" media-type="application/xhtml+xml"/>'.format(d3.id,
|
||||
d3.id)
|
||||
spine += '<itemref idref="{}"/>'.format(d3.id)
|
||||
|
||||
nav_num += 1
|
||||
|
||||
nav_str += "</navPoint>"
|
||||
if data_3.count() > 0:
|
||||
toc_summary_str += "</ul></li>"
|
||||
else:
|
||||
toc_summary_str += "</li>"
|
||||
|
||||
nav_str += "</navPoint>"
|
||||
if data_2.count() > 0:
|
||||
toc_summary_str += "</ul></li>"
|
||||
else:
|
||||
toc_summary_str += "</li>"
|
||||
|
||||
nav_str += '</navMap>'
|
||||
toc_summary_str += '</ul>'
|
||||
|
||||
# print(nav_str)
|
||||
# print(toc_summary_str)
|
||||
self.nav_str = nav_str
|
||||
self.toc_summary_str = toc_summary_str
|
||||
# self.config_json['toc'] = self.toc_list
|
||||
self.manifest = manifest
|
||||
self.spine = spine
|
||||
|
||||
# 生成书籍标题的描述HTML文件
|
||||
def generate_title_html(self):
|
||||
title_str = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>书籍标题</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
|
||||
<link href="../Styles/style.css" rel="stylesheet" type="text/css"/>
|
||||
</head>
|
||||
<body class="bookname">
|
||||
<div class="main">
|
||||
<h1 class="title"">{title}</h1>
|
||||
<p class="author"><b>{author} 著</b></p><br>
|
||||
<p class="author">{create_time}</p>
|
||||
<p class="book-src">本书籍由<a href='http://mrdoc.zmister.com'>MrDoc(mrdoc.zmister.com)</a>生成</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
'''.format(
|
||||
title=self.project.name,
|
||||
author=self.project.create_user,
|
||||
create_time = time.strftime('%Y{y}%m{m}%d{d}').format(y='年',m='月',d='日')
|
||||
)
|
||||
with open(self.base_path+'/OEBPS/Text/book_title.xhtml','a+',encoding='utf-8') as file:
|
||||
file.write(title_str)
|
||||
|
||||
desc_str = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>简介</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
|
||||
<link href="../Styles/style.css" rel="stylesheet" type="text/css"/>
|
||||
</head>
|
||||
<body class="bookdesc">
|
||||
<div class="main">
|
||||
<p class="title">书籍简介</p>
|
||||
<p class="subtitle">{desc}</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
'''.format(desc=self.project.intro)
|
||||
with open(self.base_path+'/OEBPS/Text/book_desc.xhtml','a+',encoding='utf-8') as file:
|
||||
file.write(desc_str)
|
||||
|
||||
# 生成元信息container.xml文件
|
||||
def generate_metainfo(self):
|
||||
xml = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container" >
|
||||
<rootfiles>
|
||||
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml" />
|
||||
</rootfiles>
|
||||
</container>
|
||||
'''
|
||||
folder = self.base_path + '/META-INF'
|
||||
with open(folder+'/container.xml','a+',encoding='utf-8') as metafile:
|
||||
metafile.write(xml)
|
||||
|
||||
# 生成元类型mimetype文件
|
||||
def generate_metatype(self):
|
||||
with open(self.base_path+'/mimetype','a+',encoding='utf-8') as metatype:
|
||||
metatype.write('application/epub+zip')
|
||||
|
||||
# 生成封面
|
||||
def generate_cover(self):
|
||||
xml_str = '''<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
||||
<head>
|
||||
<title>封面</title>
|
||||
<style type="text/css">
|
||||
svg {padding: 0pt; margin:0pt}
|
||||
body { text-align: center; padding:0pt; margin: 0pt; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 628 892" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<image height="892" width="628" xlink:href="../Images/epub_cover1.jpg"/>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
with open(self.base_path + '/OEBPS/Text/book_cover.xhtml','a+', encoding='utf-8') as cover:
|
||||
cover.write(xml_str)
|
||||
|
||||
# 生成文档目录.ncx文件
|
||||
def generate_toc_ncx(self):
|
||||
ncx = '''
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="zh-CN">
|
||||
<head>
|
||||
<meta name="dtb:uid" content="urn:uuid:12345"/>
|
||||
<meta name="dtb:depth" content="1"/>
|
||||
<meta name="dtb:totalPageCount" content="0"/>
|
||||
<meta name="dtb:maxPageNumber" content="0"/>
|
||||
</head>
|
||||
<docTitle>
|
||||
<text>{title}</text>
|
||||
</docTitle>
|
||||
{nav_map}
|
||||
</ncx>
|
||||
'''.format(title=self.project.name,nav_map=self.nav_str)
|
||||
|
||||
with open(self.base_path+'/OEBPS/toc.ncx','a+',encoding='utf-8') as file:
|
||||
file.write(ncx)
|
||||
|
||||
# 生成文档目录toc_summary.html文件
|
||||
def generate_toc_html(self):
|
||||
summary = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>目录</title>
|
||||
<style>
|
||||
body{margin: 0px;padding: 0px;}h1{text-align: center;padding: 0px;margin: 0px;}ul,li{list-style: none;}ul{padding-left:0px;}li>ul{padding-left: 2em;}
|
||||
a{text-decoration: none;color: #4183c4;text-decoration: none;font-size: 16px;line-height: 28px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>目 录</h1>
|
||||
%s
|
||||
</body>
|
||||
</html>
|
||||
''' % (self.toc_summary_str)
|
||||
|
||||
with open(self.base_path+'/OEBPS/Text/toc_summary.xhtml','a+',encoding='utf-8') as file:
|
||||
file.write(summary)
|
||||
|
||||
# 生成content.opf文件
|
||||
def generate_opf(self):
|
||||
content_info = '''<?xml version="1.0" encoding="utf-8" ?>
|
||||
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="uid" >
|
||||
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
||||
<dc:title>{title}</dc:title>
|
||||
<dc:language>zh</dc:language>
|
||||
<dc:creator>{creator}</dc:creator>
|
||||
<dc:identifier id="bookid">urn:uuid:12345</dc:identifier>
|
||||
<dc:publisher>MrDoc制作</dc:publisher>
|
||||
<dc:date opf:event="publication">{create_time}</dc:date>
|
||||
<dc:description>{desc}</dc:description>
|
||||
<meta name="cover" content="cover_img" />
|
||||
<meta name="output encoding" content="utf-8" />
|
||||
<meta name="primary-writing-mode" content="horizontal-lr" />
|
||||
</metadata>
|
||||
<manifest>
|
||||
{manifest}
|
||||
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/>
|
||||
<item id="css" href="stylesheet.css" media-type="text/css"/>
|
||||
<item id="cover_img" media-type="image/jpeg" href="Images/epub_cover1.jpg" />
|
||||
</manifest>
|
||||
<spine toc="ncx">
|
||||
{spine}
|
||||
</spine>
|
||||
<guide>
|
||||
<reference type="toc" title="目录" href="Text/toc_summary.xhtml" />
|
||||
<reference href="Text/book_cover.xhtml" type="cover" title="封面"/>
|
||||
</guide>
|
||||
</package>
|
||||
'''
|
||||
|
||||
with open(self.base_path+'/OEBPS/content.opf','a+',encoding='utf-8') as file:
|
||||
file.write(
|
||||
content_info.format(
|
||||
title = self.project.name,
|
||||
creator = self.project.create_user,
|
||||
create_time = str(datetime.date.today()),
|
||||
desc=self.project.intro,
|
||||
manifest=self.manifest,
|
||||
spine = self.spine,
|
||||
)
|
||||
)
|
||||
|
||||
# 生成epub文件
|
||||
def generate_epub(self):
|
||||
try:
|
||||
# 生成ZIP压缩文件
|
||||
zipfile_name = settings.MEDIA_ROOT + '/report/{}'.format(self.project.name)+'_'+str(int(time.time()))
|
||||
zip_name = shutil.make_archive(
|
||||
base_name = zipfile_name,
|
||||
format='zip',
|
||||
root_dir= settings.MEDIA_ROOT + '/report/{}'.format(self.project.id)
|
||||
)
|
||||
# print(zip_name)
|
||||
# 修改zip压缩文件后缀为EPUB
|
||||
os.rename(zip_name,zipfile_name+'.epub')
|
||||
# 删除生成的临时文件夹
|
||||
shutil.rmtree(self.base_path)
|
||||
return zipfile_name
|
||||
except Exception as e:
|
||||
if settings.DEBUG:
|
||||
print(traceback.print_exc())
|
||||
return None
|
||||
|
||||
def work(self):
|
||||
self.generate_html() # 生成HTML
|
||||
self.generate_metainfo() # 生成元信息
|
||||
self.generate_metatype() # 生成元类型
|
||||
self.generate_toc_ncx() # 生成目录ncx
|
||||
self.generate_toc_html() # 生成目录html
|
||||
self.generate_cover() # 生成封面html
|
||||
self.generate_title_html() # 生产书籍的标题页和简介页
|
||||
self.generate_opf() # 生成content.opf
|
||||
epub_file = self.generate_epub()
|
||||
return epub_file
|
||||
|
||||
# 导出Docx
|
||||
class ReportDocx():
|
||||
def __init__(self,project_id):
|
||||
self.project = Project.objects.get(id=project_id)
|
||||
self.base_path = settings.MEDIA_ROOT + '/report/{}/'.format(project_id)
|
||||
|
||||
self.content_str = ""
|
||||
self.doc_str = """<html xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
xmlns="http://www.w3.org/TR/REC-html40">
|
||||
<head><meta http-equiv=Content-Type content="text/html; charset=utf-8">
|
||||
<style type="text/css">
|
||||
table
|
||||
{
|
||||
border-collapse: collapse;
|
||||
border: none;
|
||||
width: 100%;
|
||||
}
|
||||
td,tr
|
||||
{
|
||||
border: solid #CCC 1px;
|
||||
padding:3px;
|
||||
font-size:9pt;
|
||||
}
|
||||
.codestyle{
|
||||
word-break: break-all;
|
||||
mso-highlight:rgb(252, 252, 252);
|
||||
padding-left: 5px; background-color: rgb(252, 252, 252); border: 1px solid rgb(225, 225, 232);
|
||||
}
|
||||
img {
|
||||
width:100;
|
||||
}
|
||||
/*预格式*/
|
||||
pre {
|
||||
padding: 10px;
|
||||
background: #f6f6f6;
|
||||
border: 1px solid #ddd;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
white-space: -moz-pre-wrap;
|
||||
white-space: -o-pre-wrap;
|
||||
|
||||
}
|
||||
/*块代码*/
|
||||
pre code {
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
pre ol {
|
||||
padding-left: 2.5em;
|
||||
margin: 0;
|
||||
}
|
||||
/*行内代码*/
|
||||
code {
|
||||
border: 1px solid #ddd;
|
||||
background: #f6f6f6;
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
}
|
||||
/* 引用块 */
|
||||
blockquote {
|
||||
color: #666;
|
||||
border-left: 4px solid #ddd;
|
||||
padding-left: 20px;
|
||||
margin-left: 0;
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
}
|
||||
/* 表格 */
|
||||
table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
word-break: normal;
|
||||
word-break: keep-all;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
thead {
|
||||
display: table-header-group;
|
||||
vertical-align: middle;
|
||||
border-color: inherit;
|
||||
}
|
||||
table thead tr {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
table th, table td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
/*公式*/
|
||||
p.editormd-tex {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<meta name=ProgId content=Word.Document>
|
||||
<meta name=Generator content="Microsoft Word 11">
|
||||
<meta name=Originator content="Microsoft Word 11">
|
||||
<xml><w:WordDocument><w:View>Print</w:View></xml></head>
|
||||
<body>
|
||||
"""
|
||||
|
||||
def work(self):
|
||||
# 拼接HTML字符串
|
||||
data = Doc.objects.filter(top_doc=self.project.id,parent_doc=0).order_by("sort")
|
||||
for d in data:
|
||||
# print(d.name,d.content)
|
||||
self.content_str += "<h1 style='page-break-before: always;'>{}</h1>".format(d.name)
|
||||
self.content_str += d.content
|
||||
# 获取第二级文档
|
||||
data_2 = Doc.objects.filter(parent_doc=d.id).order_by("sort")
|
||||
for d2 in data_2:
|
||||
self.content_str += "<h1>{}</h1>".format(d2.name)
|
||||
self.content_str += d2.content
|
||||
# 获取第三级文档
|
||||
data_3 = Doc.objects.filter(parent_doc=d2.id).order_by("sort")
|
||||
for d3 in data_3:
|
||||
# print(d3.name,d3.content)
|
||||
self.content_str += "<h1>{}</h1>".format(d3.name)
|
||||
self.content_str += d3.content
|
||||
|
||||
# 使用BeautifulSoup解析拼接好的HTML文本
|
||||
soup = BeautifulSoup(self.content_str,'lxml')
|
||||
src_tag = soup.find_all(lambda tag:tag.has_attr("src")) # 查找所有包含src的标签
|
||||
print(src_tag)
|
||||
|
||||
# 替换HTML文本中静态文件的相对链接为绝对链接
|
||||
for src in src_tag:
|
||||
if src['src'].startswith("/"):
|
||||
src['src'] = settings.BASE_DIR + src['src']
|
||||
|
||||
is_folder = os.path.exists(self.base_path)
|
||||
# 创建文件夹
|
||||
if is_folder is False:
|
||||
os.mkdir(self.base_path)
|
||||
temp_file_name = str(datetime.datetime.today()).replace(':', '-').replace(' ', '-').replace('.', '')
|
||||
temp_file_path = self.base_path + '/{0}.docx'.format(temp_file_name)
|
||||
|
||||
with open(temp_file_path, 'a+', encoding='utf-8') as htmlfile:
|
||||
htmlfile.write(self.doc_str + self.content_str + "</body></html>")
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = ReportMD(
|
||||
project_id=7
|
||||
)
|
||||
# app = ReportMD(
|
||||
# project_id=7
|
||||
# )
|
||||
# app.work()
|
||||
app = ReportEPUB(project_id=20)
|
||||
app.work()
|
||||
# app = ReportDocx(project_id=20)
|
||||
# app.work()
|
||||
@ -41,16 +41,18 @@ class DocSitemap(Sitemap):
|
||||
def lastmod(self,obj):
|
||||
return obj.modify_time
|
||||
|
||||
all_sitemaps = {}
|
||||
all_sitemaps['home'] = HomeSitemap()
|
||||
for project in Project.objects.filter(role=0):
|
||||
|
||||
info_dict = {
|
||||
'queryset': Doc.objects.filter(status=1,top_doc=project.id),
|
||||
}
|
||||
# sitemap = GenericSitemap(info_dict,priority=0.6)
|
||||
sitemap = DocSitemap(pro=project.id)
|
||||
|
||||
# dict key is provided as 'section' in sitemap index view
|
||||
all_sitemaps[str(project.id)] = sitemap
|
||||
# print(all_sitemaps)
|
||||
def all_sitemaps():
|
||||
all_sitemap = {}
|
||||
all_sitemap['home'] = HomeSitemap()
|
||||
all_project = ProjectSitemap()
|
||||
# print("所有文集:",all_project.items())
|
||||
for project in all_project.items():
|
||||
# for project in Project.objects.filter(role=0):
|
||||
info_dict = {
|
||||
'queryset': Doc.objects.filter(status=1,top_doc=project.id),
|
||||
}
|
||||
# sitemap = GenericSitemap(info_dict,priority=0.6)
|
||||
sitemap = DocSitemap(pro=project.id)
|
||||
all_sitemap[str(project.id)] = sitemap
|
||||
# print(all_sitemaps)
|
||||
return all_sitemap
|
||||
@ -10,3 +10,20 @@ register = template.Library()
|
||||
@register.filter(name='get_doc_count')
|
||||
def get_doc_count(value):
|
||||
return Doc.objects.filter(top_doc=int(value)).count()
|
||||
|
||||
# 获取文集下最新的文档及其修改时间
|
||||
@register.filter(name='get_new_doc')
|
||||
def get_new_doc(value):
|
||||
new_doc = Doc.objects.filter(top_doc=int(value),status=1).order_by('-modify_time').first()
|
||||
return new_doc
|
||||
|
||||
# 获取文集的开放导出状态
|
||||
@register.filter(name='get_report_status')
|
||||
def get_report_status(value):
|
||||
try:
|
||||
project = Project.objects.get(id=int(value))
|
||||
status = ProjectReport.objects.get(project=project).allow_epub
|
||||
except Exception as e:
|
||||
# print(repr(e))
|
||||
status = 0
|
||||
return status
|
||||
|
||||
@ -11,7 +11,9 @@ urlpatterns = [
|
||||
path('manage_project',views.manage_project,name="manage_project"), # 管理文集
|
||||
path('del_project/',views.del_project,name='del_project'), # 删除文集
|
||||
path('report_project_md/',views.report_md,name='report_md'), # 导出文集MD文件
|
||||
path('report_project_file/',views.report_file,name='report_file'), # 导出文集文件(epub、docx等)
|
||||
path('modify_pro_role/<int:pro_id>/',views.modify_project_role,name="modify_pro_role"),# 修改文集权限
|
||||
path('modify_pro_download/<int:pro_id>/', views.modify_project_download, name="modify_pro_download"), # 修改文集前台下载权限
|
||||
path('check_viewcode/',views.check_viewcode,name='check_viewcode'),# 文集访问码验证
|
||||
#################文档相关
|
||||
path('project/<int:pro_id>/<int:doc_id>/', views.doc, name='doc'), # 文档浏览页
|
||||
|
||||
100
app_doc/views.py
100
app_doc/views.py
@ -11,7 +11,7 @@ from django.db.models import Q
|
||||
import datetime
|
||||
import traceback
|
||||
from app_doc.report_utils import *
|
||||
from app_admin.decorators import check_headers
|
||||
from app_admin.decorators import check_headers,allow_report_file
|
||||
|
||||
|
||||
# 文集列表
|
||||
@ -19,11 +19,11 @@ def project_list(request):
|
||||
# 登录用户
|
||||
if request.user.is_authenticated:
|
||||
project_list = Project.objects.filter(
|
||||
Q(role=0) | Q(role=2,role_value__contains=str(request.user.username)) | Q(create_user=request.user)
|
||||
Q(role__in=[0,3]) | Q(role=2,role_value__contains=str(request.user.username)) | Q(create_user=request.user)
|
||||
)
|
||||
else:
|
||||
# 非登录用户只显示公开文集
|
||||
project_list = Project.objects.filter(role=0)
|
||||
# 非登录用户只显示公开文集和需要访问码的文集
|
||||
project_list = Project.objects.filter(role__in=[0,3])
|
||||
return render(request, 'app_doc/pro_list.html', locals())
|
||||
|
||||
|
||||
@ -61,6 +61,12 @@ def project_index(request,pro_id):
|
||||
# 获取文集信息
|
||||
project = Project.objects.get(id=int(pro_id))
|
||||
|
||||
# 获取问价文集前台下载权限
|
||||
try:
|
||||
allow_epub_download = ProjectReport.objects.get(project=project).allow_epub
|
||||
except ObjectDoesNotExist:
|
||||
allow_epub_download = 0
|
||||
|
||||
# 私密文集并且访问者非创建者
|
||||
if project.role == 1 and request.user != project.create_user:
|
||||
return render(request,'404.html')
|
||||
@ -91,8 +97,9 @@ def project_index(request,pro_id):
|
||||
return render(request,'app_doc/project_doc_search.html',locals())
|
||||
return render(request, 'app_doc/project.html', locals())
|
||||
except Exception as e:
|
||||
print(traceback.print_exc())
|
||||
print(repr(e))
|
||||
if settings.DEBUG:
|
||||
print(traceback.print_exc())
|
||||
print(repr(e))
|
||||
return HttpResponse('请求出错')
|
||||
|
||||
|
||||
@ -121,7 +128,10 @@ def modify_project(request):
|
||||
# 修改文集权限
|
||||
@login_required()
|
||||
def modify_project_role(request,pro_id):
|
||||
pro = Project.objects.get(id=pro_id)
|
||||
try:
|
||||
pro = Project.objects.get(id=pro_id)
|
||||
except ObjectDoesNotExist:
|
||||
return Http404
|
||||
if (pro.create_user != request.user) and (request.user.is_superuser is False):
|
||||
return render(request,'403.html')
|
||||
else:
|
||||
@ -236,6 +246,34 @@ def manage_project(request):
|
||||
return HttpResponse('方法不允许')
|
||||
|
||||
|
||||
# 修改文集前台下载权限
|
||||
@login_required()
|
||||
def modify_project_download(request,pro_id):
|
||||
try:
|
||||
pro = Project.objects.get(id=pro_id)
|
||||
except ObjectDoesNotExist:
|
||||
return Http404
|
||||
if (pro.create_user != request.user) and (request.user.is_superuser is False):
|
||||
return render(request,'403.html')
|
||||
else:
|
||||
if request.method == 'GET':
|
||||
return render(request,'app_doc/manage_project_download.html',locals())
|
||||
elif request.method == 'POST':
|
||||
download_epub = request.POST.get('download_epub',None)
|
||||
# print("epub状态:",download_epub)
|
||||
if download_epub == 'on':
|
||||
epub_status = 1
|
||||
else:
|
||||
epub_status = 0
|
||||
ProjectReport.objects.update_or_create(
|
||||
project = pro,defaults={'allow_epub':epub_status}
|
||||
)
|
||||
return render(request,'app_doc/manage_project_download.html',locals())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 文档浏览页页
|
||||
@require_http_methods(['GET'])
|
||||
def doc(request,pro_id,doc_id):
|
||||
@ -270,6 +308,8 @@ def doc(request,pro_id,doc_id):
|
||||
try:
|
||||
doc = Doc.objects.get(id=int(doc_id),status=1)
|
||||
except ObjectDoesNotExist:
|
||||
if settings.DEBUG:
|
||||
print(traceback.print_exc())
|
||||
return render(request, '404.html')
|
||||
# 获取文集下一级文档
|
||||
project_docs = Doc.objects.filter(top_doc=doc.top_doc, parent_doc=0, status=1).order_by('sort')
|
||||
@ -456,7 +496,7 @@ def manage_doc(request):
|
||||
doc_status = request.GET.get('status','all')
|
||||
if len(doc_status) == 0:
|
||||
doc_status = 'all'
|
||||
print('status:', doc_status,type(doc_status))
|
||||
# print('status:', doc_status,type(doc_status))
|
||||
# 返回所有文档
|
||||
if doc_status == 'all':
|
||||
doc_list = Doc.objects.filter(create_user=request.user).order_by('-modify_time')
|
||||
@ -675,8 +715,50 @@ def report_md(request):
|
||||
return JsonResponse({'status':True,'data':md_file})
|
||||
else:
|
||||
return JsonResponse({'status':False,'data':'无权限'})
|
||||
except:
|
||||
except Exception as e:
|
||||
if settings.DEBUG:
|
||||
print(traceback.print_exc())
|
||||
return JsonResponse({'status':False,'data':'文集不存在'})
|
||||
|
||||
else:
|
||||
return Http404
|
||||
|
||||
# 导出文集文件
|
||||
@allow_report_file
|
||||
def report_file(request):
|
||||
if request.method == 'POST':
|
||||
report_type = request.POST.get('types',None)
|
||||
if report_type in ['epub']:
|
||||
pro_id = request.POST.get('pro_id')
|
||||
try:
|
||||
project = Project.objects.get(id=int(pro_id))
|
||||
# 公开的文集 - 可以直接导出
|
||||
if project.role == 0:
|
||||
report_project = ReportEPUB(
|
||||
project_id=project.id
|
||||
).work()
|
||||
# print(report_project)
|
||||
report_file_path = report_project.split('media',maxsplit=1)[-1]
|
||||
epub_file = '/media' + report_file_path + '.epub'
|
||||
return JsonResponse({'status':True,'data':epub_file})
|
||||
# 私密文集 - 拥有者可导出
|
||||
elif project.role == 1:
|
||||
pass
|
||||
# 指定用户可见文集 - 指定用户可导出
|
||||
elif project.role == 2:
|
||||
pass
|
||||
# 访问码可见文集 - 通过验证即可导出
|
||||
elif project.role == 3:
|
||||
pass
|
||||
else:
|
||||
return JsonResponse({'status':False,'data':'不存在的文集权限'})
|
||||
except ObjectDoesNotExist:
|
||||
return JsonResponse({'status':False,'data':'文集不存在'})
|
||||
except Exception as e:
|
||||
if settings.DEBUG:
|
||||
print(traceback.print_exc())
|
||||
return JsonResponse({'status':False,'data':'系统异常'})
|
||||
else:
|
||||
return JsonResponse({'status':False,'data':'不支持的类型'})
|
||||
else:
|
||||
return Http404
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 299 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(clearInterval(e.timer),e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['<button class="layui-icon '+u+'" lay-type="sub">'+("updown"===n.anim?"":"")+"</button>",'<button class="layui-icon '+u+'" lay-type="add">'+("updown"===n.anim?"":"")+"</button>"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['<div class="'+c+'"><ul>',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("<li"+(n.index===e?' class="layui-this"':"")+"></li>")}),i.join("")}(),"</ul></div>"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a<n.index&&e.slide("sub",n.index-a)})},m.prototype.slide=function(e,i){var n=this,l=n.elemItem,u=n.config,c=u.index,m=u.elem.attr("lay-filter");n.haveSlide||("sub"===e?(n.subIndex(i),l.eq(u.index).addClass(d),setTimeout(function(){l.eq(c).addClass(r),l.eq(u.index).addClass(r)},50)):(n.addIndex(i),l.eq(u.index).addClass(s),setTimeout(function(){l.eq(c).addClass(o),l.eq(u.index).addClass(o)},50)),setTimeout(function(){l.removeClass(a+" "+d+" "+s+" "+o+" "+r),l.eq(u.index).addClass(a),n.haveSlide=!1},300),n.elemInd.find("li").eq(u.index).addClass(a).siblings().removeClass(a),n.haveSlide=!0,layui.event.call(this,t,"change("+m+")",{index:u.index,prevIndex:c,item:l.eq(u.index)}))},m.prototype.events=function(){var e=this,i=e.config;i.elem.data("haveEvents")||(i.elem.on("mouseenter",function(){clearInterval(e.timer)}).on("mouseleave",function(){e.autoplay()}),i.elem.data("haveEvents",!0))},n.render=function(e){var i=new m(e);return i},e(t,n)});
|
||||
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
;layui.define("jquery",function(e){"use strict";var a=layui.$,l="http://www.layui.com/doc/modules/code.html";e("code",function(e){var t=[];e=e||{},e.elem=a(e.elem||".layui-code"),e.about=!("about"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr("lay-encode")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")),c.html('<ol class="layui-code-ol"><li>'+o.replace(/[\r\t\n]+/g,"</li><li>")+"</li></ol>"),c.find(">.layui-code-h3")[0]||c.prepend('<h3 class="layui-code-h3">'+(c.attr("lay-title")||e.title||"code")+(e.about?'<a href="'+l+'" target="_blank">layui.code</a>':"")+"</h3>");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss");
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon "></i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="<cite>加载更多</cite>",h=l('<div class="layui-flow-more"><a href="javascript:;">'+d+"</a></div>");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;s<t.lazyimg.elem.length;s++){var v=t.lazyimg.elem.eq(s),y=a?function(){return v.offset().top-n.offset().top+m}():v.offset().top;if(c(v,f),i=s,y>u)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)});
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon "></i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="<cite>加载更多</cite>",h=l('<div class="layui-flow-more"><a href="javascript:;">'+d+"</a></div>");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),!i&&f.width()&&(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;s<t.lazyimg.elem.length;s++){var v=t.lazyimg.elem.eq(s),y=a?function(){return v.offset().top-n.offset().top+m}():v.offset().top;if(c(v,f),i=s,y>u)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)});
|
||||
File diff suppressed because one or more lines are too long
2
static/layui/lay/modules/jquery.js
vendored
2
static/layui/lay/modules/jquery.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
;layui.define(function(e){"use strict";var a=document,t="getElementById",n="getElementsByTagName",i="laypage",r="layui-disabled",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if("object"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups="groups"in a?0|a.groups:5;a.layout="object"==typeof a.layout?a.layout:["prev","page","next"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits="object"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev="prev"in a?a.prev:"上一页",a.next="next"in a?a.next:"下一页";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?'<a href="javascript:;" class="layui-laypage-prev'+(1==a.curr?" "+r:"")+'" data-page="'+(a.curr-1)+'">'+a.prev+"</a>":""}(),page:function(){var e=[];if(a.count<1)return"";n>1&&a.first!==!1&&0!==t&&e.push('<a href="javascript:;" class="layui-laypage-first" data-page="1" title="首页">'+(a.first||1)+"</a>");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r<t-1&&(r=u-t+1),a.first!==!1&&r>2&&e.push('<span class="layui-laypage-spr">…</span>');r<=u;r++)r===a.curr?e.push('<span class="layui-laypage-curr"><em class="layui-laypage-em" '+(/^#/.test(a.theme)?'style="background-color:'+a.theme+';"':"")+"></em><em>"+r+"</em></span>"):e.push('<a href="javascript:;" data-page="'+r+'">'+r+"</a>");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1<a.pages&&e.push('<span class="layui-laypage-spr">…</span>'),0!==t&&e.push('<a href="javascript:;" class="layui-laypage-last" title="尾页" data-page="'+a.pages+'">'+(a.last||a.pages)+"</a>")),e.join("")}(),next:function(){return a.next?'<a href="javascript:;" class="layui-laypage-next'+(a.curr==a.pages?" "+r:"")+'" data-page="'+(a.curr+1)+'">'+a.next+"</a>":""}(),count:'<span class="layui-laypage-count">共 '+a.count+" 条</span>",limit:function(){var e=['<span class="layui-laypage-limits"><select lay-ignore>'];return layui.each(a.limits,function(t,n){e.push('<option value="'+n+'"'+(n===a.limit?"selected":"")+">"+n+" 条/页</option>")}),e.join("")+"</select></span>"}(),refresh:['<a href="javascript:;" data-page="'+a.curr+'" class="layui-laypage-refresh">','<i class="layui-icon layui-icon-refresh"></i>',"</a>"].join(""),skip:function(){return['<span class="layui-laypage-skip">到第','<input type="text" min="1" value="'+a.curr+'" class="layui-input">','页<button type="button" class="layui-laypage-btn">确定</button>',"</span>"].join("")}()};return['<div class="layui-box layui-laypage layui-laypage-'+(a.theme?/^#/.test(a.theme)?"molv":a.theme:"default")+'" id="layui-laypage-'+a.index+'">',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join("")}(),"</div>"].join("")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n]("button")[0],l=e[n]("input")[0],p=e[n]("select")[0],c=function(){var e=0|l.value.replace(/\s|\D/g,"");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;o<y;o++)"a"===r[o].nodeName.toLowerCase()&&s.on(r[o],"click",function(){var e=0|this.getAttribute("data-page");e<1||e>i.pages||(i.curr=e,t.render())});p&&s.on(p,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,"click",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n]("input")[0];t&&s.on(t,"keyup",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\D/.test(n)&&(this.value=n.replace(/\D/,"")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t]("layui-laypage-"+i.index);n.jump(s),i.hash&&!e&&(location.hash="!"+i.hash+"="+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent("on"+a,function(a){a.target=a.srcElement,t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)});
|
||||
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
;layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)});
|
||||
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
;layui.define("jquery",function(e){"use strict";var a=layui.jquery,i={config:{},index:layui.rate?layui.rate.index+1e4:0,set:function(e){var i=this;return i.config=a.extend({},i.config,e),i},on:function(e,a){return layui.onevent.call(this,n,e,a)}},l=function(){var e=this,a=e.config;return{setvalue:function(a){e.setvalue.call(e,a)},config:a}},n="rate",t="layui-rate",o="layui-icon-rate",s="layui-icon-rate-solid",u="layui-icon-rate-half",r="layui-icon-rate-solid layui-icon-rate-half",c="layui-icon-rate-solid layui-icon-rate",f="layui-icon-rate layui-icon-rate-half",v=function(e){var l=this;l.index=++i.index,l.config=a.extend({},l.config,i.config,e),l.render()};v.prototype.config={length:5,text:!1,readonly:!1,half:!1,value:0,theme:""},v.prototype.render=function(){var e=this,i=e.config,l=i.theme?'style="color: '+i.theme+';"':"";i.elem=a(i.elem),parseInt(i.value)!==i.value&&(i.half||(i.value=Math.ceil(i.value)-i.value<.5?Math.ceil(i.value):Math.floor(i.value)));for(var n='<ul class="layui-rate" '+(i.readonly?"readonly":"")+">",u=1;u<=i.length;u++){var r='<li class="layui-inline"><i class="layui-icon '+(u>Math.floor(i.value)?o:s)+'" '+l+"></i></li>";i.half&&parseInt(i.value)!==i.value&&u==Math.ceil(i.value)?n=n+'<li><i class="layui-icon layui-icon-rate-half" '+l+"></i></li>":n+=r}n+="</ul>"+(i.text?'<span class="layui-inline">'+i.value+"星":"")+"</span>";var c=i.elem,f=c.next("."+t);f[0]&&f.remove(),e.elemTemp=a(n),i.span=e.elemTemp.next("span"),i.setText&&i.setText(i.value),c.html(e.elemTemp),c.addClass("layui-inline"),i.readonly||e.action()},v.prototype.setvalue=function(e){var a=this,i=a.config;i.value=e,a.render()},v.prototype.action=function(){var e=this,i=e.config,l=e.elemTemp,n=l.find("i").width();l.children("li").each(function(e){var t=e+1,v=a(this);v.on("click",function(e){if(i.value=t,i.half){var o=e.pageX-a(this).offset().left;o<=n/2&&(i.value=i.value-.5)}i.text&&l.next("span").text(i.value+"星"),i.choose&&i.choose(i.value),i.setText&&i.setText(i.value)}),v.on("mousemove",function(e){if(l.find("i").each(function(){a(this).addClass(o).removeClass(r)}),l.find("i:lt("+t+")").each(function(){a(this).addClass(s).removeClass(f)}),i.half){var c=e.pageX-a(this).offset().left;c<=n/2&&v.children("i").addClass(u).removeClass(s)}}),v.on("mouseleave",function(){l.find("i").each(function(){a(this).addClass(o).removeClass(r)}),l.find("i:lt("+Math.floor(i.value)+")").each(function(){a(this).addClass(s).removeClass(f)}),i.half&&parseInt(i.value)!==i.value&&l.children("li:eq("+Math.floor(i.value)+")").children("i").addClass(u).removeClass(c)})})},v.prototype.events=function(){var e=this;e.config},i.render=function(e){var a=new v(e);return l.call(a)},e(n,i)});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
||||
;layui.define("jquery",function(t){"use strict";var e=layui.$,i={fixbar:function(t){var i,n,a="layui-fixbar",o="layui-fixbar-top",r=e(document),l=e("body");t=e.extend({showHeight:200},t),t.bar1=t.bar1===!0?"":t.bar1,t.bar2=t.bar2===!0?"":t.bar2,t.bgcolor=t.bgcolor?"background-color:"+t.bgcolor:"";var c=[t.bar1,t.bar2,""],g=e(['<ul class="'+a+'">',t.bar1?'<li class="layui-icon" lay-type="bar1" style="'+t.bgcolor+'">'+c[0]+"</li>":"",t.bar2?'<li class="layui-icon" lay-type="bar2" style="'+t.bgcolor+'">'+c[1]+"</li>":"",'<li class="layui-icon '+o+'" lay-type="top" style="'+t.bgcolor+'">'+c[2]+"</li>","</ul>"].join("")),s=g.find("."+o),u=function(){var e=r.scrollTop();e>=t.showHeight?i||(s.show(),i=1):i&&(s.hide(),i=0)};e("."+a)[0]||("object"==typeof t.css&&g.css(t.css),l.append(g),u(),g.find("li").on("click",function(){var i=e(this),n=i.attr("lay-type");"top"===n&&e("html,body").animate({scrollTop:0},200),t.click&&t.click.call(this,n)}),r.on("scroll",function(){clearTimeout(n),n=setTimeout(function(){u()},100)}))},countdown:function(t,e,i){var n=this,a="function"==typeof e,o=new Date(t).getTime(),r=new Date(!e||a?(new Date).getTime():e).getTime(),l=o-r,c=[Math.floor(l/864e5),Math.floor(l/36e5)%24,Math.floor(l/6e4)%60,Math.floor(l/1e3)%60];a&&(i=e);var g=setTimeout(function(){n.countdown(t,r+1e3,i)},1e3);return i&&i(l>0?c:[0,0,0,0],e,g),l<=0&&clearTimeout(g),g},timeAgo:function(t,e){var i=this,n=[[],[]],a=(new Date).getTime()-new Date(t).getTime();return a>6912e5?(a=new Date(t),n[0][0]=i.digit(a.getFullYear(),4),n[0][1]=i.digit(a.getMonth()+1),n[0][2]=i.digit(a.getDate()),e||(n[1][0]=i.digit(a.getHours()),n[1][1]=i.digit(a.getMinutes()),n[1][2]=i.digit(a.getSeconds())),n[0].join("-")+" "+n[1].join(":")):a>=864e5?(a/1e3/60/60/24|0)+"天前":a>=36e5?(a/1e3/60/60|0)+"小时前":a>=12e4?(a/1e3/60|0)+"分钟前":a<0?"未来":"刚刚"},digit:function(t,e){var i="";t=String(t),e=e||2;for(var n=t.length;n<e;n++)i+="0";return t<Math.pow(10,e)?i+(0|t):t},toDateString:function(t,e){var i=this,n=new Date(t||new Date),a=[i.digit(n.getFullYear(),4),i.digit(n.getMonth()+1),i.digit(n.getDate())],o=[i.digit(n.getHours()),i.digit(n.getMinutes()),i.digit(n.getSeconds())];return e=e||"yyyy-MM-dd HH:mm:ss",e.replace(/yyyy/g,a[0]).replace(/MM/g,a[1]).replace(/dd/g,a[2]).replace(/HH/g,o[0]).replace(/mm/g,o[1]).replace(/ss/g,o[2])},escape:function(t){return String(t||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")},event:function(t,n,a){n=i.event[t]=e.extend(!0,i.event[t],n)||{},e("body").on(a||"click","*["+t+"]",function(){var i=e(this),a=i.attr(t);n[a]&&n[a].call(this,i)})}};!function(t,e,i){"$:nomunge";function n(){a=e[l](function(){o.each(function(){var e=t(this),i=e.width(),n=e.height(),a=t.data(this,g);(i!==a.w||n!==a.h)&&e.trigger(c,[a.w=i,a.h=n])}),n()},r[s])}var a,o=t([]),r=t.resize=t.extend(t.resize,{}),l="setTimeout",c="resize",g=c+"-special-event",s="delay",u="throttleWindow";r[s]=250,r[u]=!0,t.event.special[c]={setup:function(){if(!r[u]&&this[l])return!1;var e=t(this);o=o.add(e),t.data(this,g,{w:e.width(),h:e.height()}),1===o.length&&n()},teardown:function(){if(!r[u]&&this[l])return!1;var e=t(this);o=o.not(e),e.removeData(g),o.length||clearTimeout(a)},add:function(e){function n(e,n,o){var r=t(this),l=t.data(this,g)||{};l.w=n!==i?n:r.width(),l.h=o!==i?o:r.height(),a.apply(this,arguments)}if(!r[u]&&this[l])return!1;var a;return t.isFunction(e)?(a=e,n):(a=e.handler,void(e.handler=n))}}}(e,window),t("util",i)});
|
||||
/** layui-v2.5.6 MIT License By https://www.layui.com */
|
||||
;layui.define("jquery",function(e){"use strict";var t=layui.$,i={fixbar:function(e){var i,n,a="layui-fixbar",o="layui-fixbar-top",r=t(document),l=t("body");e=t.extend({showHeight:200},e),e.bar1=e.bar1===!0?"":e.bar1,e.bar2=e.bar2===!0?"":e.bar2,e.bgcolor=e.bgcolor?"background-color:"+e.bgcolor:"";var c=[e.bar1,e.bar2,""],u=t(['<ul class="'+a+'">',e.bar1?'<li class="layui-icon" lay-type="bar1" style="'+e.bgcolor+'">'+c[0]+"</li>":"",e.bar2?'<li class="layui-icon" lay-type="bar2" style="'+e.bgcolor+'">'+c[1]+"</li>":"",'<li class="layui-icon '+o+'" lay-type="top" style="'+e.bgcolor+'">'+c[2]+"</li>","</ul>"].join("")),g=u.find("."+o),s=function(){var t=r.scrollTop();t>=e.showHeight?i||(g.show(),i=1):i&&(g.hide(),i=0)};t("."+a)[0]||("object"==typeof e.css&&u.css(e.css),l.append(u),s(),u.find("li").on("click",function(){var i=t(this),n=i.attr("lay-type");"top"===n&&t("html,body").animate({scrollTop:0},200),e.click&&e.click.call(this,n)}),r.on("scroll",function(){clearTimeout(n),n=setTimeout(function(){s()},100)}))},countdown:function(e,t,i){var n=this,a="function"==typeof t,o=new Date(e).getTime(),r=new Date(!t||a?(new Date).getTime():t).getTime(),l=o-r,c=[Math.floor(l/864e5),Math.floor(l/36e5)%24,Math.floor(l/6e4)%60,Math.floor(l/1e3)%60];a&&(i=t);var u=setTimeout(function(){n.countdown(e,r+1e3,i)},1e3);return i&&i(l>0?c:[0,0,0,0],t,u),l<=0&&clearTimeout(u),u},timeAgo:function(e,t){var i=this,n=[[],[]],a=(new Date).getTime()-new Date(e).getTime();return a>26784e5?(a=new Date(e),n[0][0]=i.digit(a.getFullYear(),4),n[0][1]=i.digit(a.getMonth()+1),n[0][2]=i.digit(a.getDate()),t||(n[1][0]=i.digit(a.getHours()),n[1][1]=i.digit(a.getMinutes()),n[1][2]=i.digit(a.getSeconds())),n[0].join("-")+" "+n[1].join(":")):a>=864e5?(a/1e3/60/60/24|0)+"天前":a>=36e5?(a/1e3/60/60|0)+"小时前":a>=18e4?(a/1e3/60|0)+"分钟前":a<0?"未来":"刚刚"},digit:function(e,t){var i="";e=String(e),t=t||2;for(var n=e.length;n<t;n++)i+="0";return e<Math.pow(10,t)?i+(0|e):e},toDateString:function(e,t){var i=this,n=new Date(e||new Date),a=[i.digit(n.getFullYear(),4),i.digit(n.getMonth()+1),i.digit(n.getDate())],o=[i.digit(n.getHours()),i.digit(n.getMinutes()),i.digit(n.getSeconds())];return t=t||"yyyy-MM-dd HH:mm:ss",t.replace(/yyyy/g,a[0]).replace(/MM/g,a[1]).replace(/dd/g,a[2]).replace(/HH/g,o[0]).replace(/mm/g,o[1]).replace(/ss/g,o[2])},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")},event:function(e,n,a){var o=t("body");return a=a||"click",n=i.event[e]=t.extend(!0,i.event[e],n)||{},i.event.UTIL_EVENT_CALLBACK=i.event.UTIL_EVENT_CALLBACK||{},o.off(a,"*["+e+"]",i.event.UTIL_EVENT_CALLBACK[e]),i.event.UTIL_EVENT_CALLBACK[e]=function(){var i=t(this),a=i.attr(e);"function"==typeof n[a]&&n[a].call(this,i)},o.on(a,"*["+e+"]",i.event.UTIL_EVENT_CALLBACK[e]),n}};!function(e,t,i){"$:nomunge";function n(){a=t[l](function(){o.each(function(){var t=e(this),i=t.width(),n=t.height(),a=e.data(this,u);(i!==a.w||n!==a.h)&&t.trigger(c,[a.w=i,a.h=n])}),n()},r[g])}var a,o=e([]),r=e.resize=e.extend(e.resize,{}),l="setTimeout",c="resize",u=c+"-special-event",g="delay",s="throttleWindow";r[g]=250,r[s]=!0,e.event.special[c]={setup:function(){if(!r[s]&&this[l])return!1;var t=e(this);o=o.add(t),e.data(this,u,{w:t.width(),h:t.height()}),1===o.length&&n()},teardown:function(){if(!r[s]&&this[l])return!1;var t=e(this);o=o.not(t),t.removeData(u),o.length||clearTimeout(a)},add:function(t){function n(t,n,o){var r=e(this),l=e.data(this,u)||{};l.w=n!==i?n:r.width(),l.h=o!==i?o:r.height(),a.apply(this,arguments)}if(!r[s]&&this[l])return!1;var a;return e.isFunction(t)?(a=t,n):(a=t.handler,void(t.handler=n))}}}(t,window),e("util",i)});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -50,7 +50,7 @@
|
||||
.project-item{
|
||||
/*float: left;*/
|
||||
/*width: 200px;*/
|
||||
height: 140px;
|
||||
height: 170px;
|
||||
margin-top: 20px;
|
||||
margin-left: 20px;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
BIN
static/report_epub/epub_cover1.jpg
Normal file
BIN
static/report_epub/epub_cover1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
65
static/report_epub/style.css
Normal file
65
static/report_epub/style.css
Normal file
@ -0,0 +1,65 @@
|
||||
.bookname, .bookdesc {
|
||||
text-align: center;
|
||||
}
|
||||
/*预格式*/
|
||||
pre {
|
||||
padding: 10px;
|
||||
background: #f6f6f6;
|
||||
border: 1px solid #ddd;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
white-space: -moz-pre-wrap;
|
||||
white-space: -o-pre-wrap;
|
||||
|
||||
}
|
||||
/*块代码*/
|
||||
pre code {
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
pre ol {
|
||||
padding-left: 2.5em;
|
||||
margin: 0;
|
||||
}
|
||||
/*行内代码*/
|
||||
code {
|
||||
border: 1px solid #ddd;
|
||||
background: #f6f6f6;
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
}
|
||||
/* 引用块 */
|
||||
blockquote {
|
||||
color: #666;
|
||||
border-left: 4px solid #ddd;
|
||||
padding-left: 20px;
|
||||
margin-left: 0;
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
}
|
||||
/* 表格 */
|
||||
table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
word-break: normal;
|
||||
word-break: keep-all;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
thead {
|
||||
display: table-header-group;
|
||||
vertical-align: middle;
|
||||
border-color: inherit;
|
||||
}
|
||||
table thead tr {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
table th, table td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
/*公式*/
|
||||
p.editormd-tex {
|
||||
text-align: center;
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}{% endblock %} - 后台管理 - MrDoc</title>
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'layui/css/layui.css' %}?version={{mrdoc_version}}" rel="stylesheet">
|
||||
<style>
|
||||
.logo img{
|
||||
height: 30px;
|
||||
@ -54,12 +54,12 @@
|
||||
<li class="layui-nav-item layui-nav-itemed">
|
||||
<a href="{% url 'user_manage' %}"><i class="layui-icon layui-icon-user"></i> 用户管理</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-nav-itemed">
|
||||
<a href="{% url 'sys_setting' %}"><i class="layui-icon layui-icon-set-sm"></i> 站点设置</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-nav-itemed">
|
||||
<a href="{% url 'register_code_manage' %}"><i class="layui-icon layui-icon-engine"></i> 注册码管理</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-nav-itemed">
|
||||
<a href="{% url 'sys_setting' %}"><i class="layui-icon layui-icon-set-sm"></i> 站点设置</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
@ -82,7 +82,7 @@
|
||||
</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>
|
||||
{% block custom_script %}
|
||||
{% endblock %}
|
||||
|
||||
@ -37,13 +37,13 @@
|
||||
<div class="layui-form-mid layui-word-aux">开启此选项,新用户注册将需要填写注册码</div>
|
||||
</div>
|
||||
|
||||
<!--<div class="layui-form-item">-->
|
||||
<!--<label class="layui-form-label">启用文集导出</label>-->
|
||||
<!--<div class="layui-input-inline">-->
|
||||
<!--<input type="checkbox" name="enable_project_report" lay-skin="switch" lay-text="开启|关闭" {% if enable_project_report %}checked{% endif %}>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="layui-form-mid layui-word-aux">开启此选项,文集允许导出为EPUB和DOCX等格式文件,文集拥有者可进行进一步控制文集是否开放导出</div>-->
|
||||
<!--</div>-->
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">文集导出</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="checkbox" name="enable_project_report" lay-skin="switch" lay-text="开启|关闭" {% if enable_project_report %}checked{% endif %}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">开启此选项,文集允许导出为EPUB和DOCX等格式文件,文集拥有者可进行进一步控制文集是否开放导出</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">启用邮箱</label>
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
<style>
|
||||
body{
|
||||
background-color: #fafafa;
|
||||
text-align: center;
|
||||
/*text-align: center;*/
|
||||
}
|
||||
.container{
|
||||
display: flex;
|
||||
@ -55,7 +55,8 @@
|
||||
<form class="layui-form" action="" method='POST'>
|
||||
{% csrf_token %}
|
||||
<div class="layui-form-item">
|
||||
<h4>你正在访问:<strong><u>{{ project.name }}</u></strong></h4>
|
||||
<h4>你正在访问:</h4><br>
|
||||
<strong><u>{{ project.name }}</u></strong>
|
||||
<br><span style='color:red;margin-bottom: 10px;'>{{ errormsg }}</span>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
<meta http-equiv="Cache-Control" content="max-age=7200" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<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 href="{% static 'layui/css/layui.css' %}?version={{mrdoc_version}}" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.css' %}?version={{mrdoc_version}}" />
|
||||
<link href="{% static 'mrdoc.css' %}?version={{mrdoc_version}}" rel="stylesheet">
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
<style>
|
||||
@ -160,7 +160,7 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="{% static 'mrdoc.js' %}"></script>
|
||||
<script src="{% static 'mrdoc.js?version={{mrdoc_version}}' %}"></script>
|
||||
{% block custom_script %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
||||
@ -88,7 +88,6 @@
|
||||
|
||||
{% block custom_script %}
|
||||
<script>
|
||||
|
||||
//选择文集
|
||||
form.on('select(project)', function(data){
|
||||
console.log(data.value); //得到被选中的值
|
||||
@ -154,8 +153,8 @@
|
||||
'project':$("#project").val(),
|
||||
'parent_doc':$("#parent-doc").val(),
|
||||
'doc_name':$("#doc-name").val(),
|
||||
//'content':editor.getHTML(),//获取editor解析的HTML
|
||||
'content':editor.getPreviewedHTML(),//获取预览的HTML
|
||||
'content':editor.getHTML(),//获取editor解析的HTML
|
||||
//'content':editor.getPreviewedHTML(),//获取预览的HTML
|
||||
'pre_content':editor.getMarkdown(),
|
||||
'sort':$("#sort").val(),
|
||||
}
|
||||
@ -188,7 +187,7 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
//保存文档草稿
|
||||
//保存草稿
|
||||
saveDoc = function(){
|
||||
var data = {
|
||||
'project':$("#project").val(),
|
||||
|
||||
@ -11,11 +11,11 @@
|
||||
<meta name="keywords" content="{% block keyword %}{% endblock %}mrdoc"/>
|
||||
<meta name="description" content="{% block description %}{% endblock %}" />
|
||||
<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 href="{% static 'layui/css/layui.css' %}?version={{mrdoc_version}}" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.css' %}?version={{mrdoc_version}}" />
|
||||
<!--<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="stylesheet" href="{% static 'katex/katex.min.css' %}?version={{mrdoc_version}}" />
|
||||
<link rel="stylesheet" href="{% static 'share.js/css/share.min.css' %}?version={{mrdoc_version}}" />
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
<link href="{% static 'mrdoc.css' %}?version={{mrdoc_version}}" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
@ -61,7 +61,7 @@
|
||||
<dd>
|
||||
<a href="{% url 'manage_doc' %}">
|
||||
<i class="layui-icon layui-icon-app layui-hide-md"></i>
|
||||
<span class="layui-hide-xs">管理文档</span>
|
||||
<span class="layui-hide-xs">个人中心</span>
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}{% endblock %} - 个人中心 - MrDoc</title>
|
||||
<link href="{% static 'layui/css/layui.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'layui/css/layui.css' %}?version={{mrdoc_version}}" rel="stylesheet">
|
||||
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
|
||||
<style>
|
||||
.logo img{
|
||||
@ -75,7 +75,7 @@
|
||||
</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>
|
||||
var form = layui.form;
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
<col width="400">
|
||||
<col width="50">
|
||||
<col width="100">
|
||||
<col width="50">
|
||||
<col width="100">
|
||||
<col width="150">
|
||||
</colgroup>
|
||||
@ -35,7 +36,8 @@
|
||||
<th>文集简介</th>
|
||||
<th>文档数量</th>
|
||||
<th>创建时间</th>
|
||||
<th>权限</th>
|
||||
<th>前台下载</th>
|
||||
<th>阅读权限</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -47,6 +49,13 @@
|
||||
{% load project_filter %}
|
||||
<td>{{ pro.id | get_doc_count }}</td>
|
||||
<td>{{ pro.create_time }}</td>
|
||||
<td>
|
||||
{% if pro.id|get_report_status == 1 %}
|
||||
<span>允许</span> <a href="{% url 'modify_pro_download' pro.id %}" title="修改前台下载"><i class="layui-icon layui-icon-edit"></i></a>
|
||||
{% else %}
|
||||
<span>禁止</span> <a href="{% url 'modify_pro_download' pro.id %}" title="修改前台下载"><i class="layui-icon layui-icon-edit"></i></a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<div class="layui-input-inline">
|
||||
{% if pro.role == 0 %}
|
||||
@ -56,7 +65,7 @@
|
||||
{% elif pro.role == 2 %}
|
||||
<i class="layui-icon layui-icon-group"></i> 指定用户可见 <a href="{% url 'modify_pro_role' pro.id %}" title="修改文集权限"><i class="layui-icon layui-icon-edit"></i></a>
|
||||
{% elif pro.role == 3 %}
|
||||
<i class="layui-icon layui-icon-password"></i> 访问码可见 <a href="{% url 'modify_pro_role' pro.id %}" title="修改文集权限"><i class="layui-icon layui-icon-edit"></i></a>
|
||||
<i class="layui-icon layui-icon-key"></i> 访问码可见 <a href="{% url 'modify_pro_role' pro.id %}" title="修改文集权限"><i class="layui-icon layui-icon-edit"></i></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
@ -218,9 +227,14 @@
|
||||
title:"下载导出文档",
|
||||
area:"300px",
|
||||
id:"downloadMd",
|
||||
content:'<p style="text-align:center;color:red;">请尽快下载,避免失效!</p><br><a class="layui-btn layui-btn-fluid" href="'+ download_link + '" download="mrdoc_report_md.zip" >点击下载文件(zip)</a>',
|
||||
content:'<p style="text-align:center;color:red;">请尽快下载,避免失效!</p><br><a class="layui-btn layui-btn-fluid download-md-link" href="'+ download_link + '" download="mrdoc_report_md.zip" >点击下载文件(zip)</a>',
|
||||
//btn:['确定','取消'], //添加按钮
|
||||
//btnAlign:'c', //按钮居中
|
||||
success: function (layero, index) {
|
||||
$(layero).find('.download-md-link').click(function () {
|
||||
layer.close(index);
|
||||
})
|
||||
}
|
||||
})
|
||||
};
|
||||
//修改文集权限
|
||||
|
||||
54
template/app_doc/manage_project_download.html
Normal file
54
template/app_doc/manage_project_download.html
Normal file
@ -0,0 +1,54 @@
|
||||
{% extends 'app_doc/manage_base.html' %}
|
||||
{% load staticfiles %}
|
||||
{% block title %}文集下载状态管理{% endblock %}
|
||||
{% block content %}
|
||||
{% if enable_project_report %}
|
||||
{% else %}
|
||||
<blockquote class="layui-elem-quote">当前站点未启用前台文集下载功能,修改操作将在功能启用后生效!</blockquote>
|
||||
{% endif %}
|
||||
<div class="layui-row" style="margin-bottom: 10px;padding-left:15px;">
|
||||
<span class="layui-breadcrumb" lay-separator=">">
|
||||
<a href="{% url 'manage_project' %}">文集管理</a>
|
||||
<a><cite>下载状态管理</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layui-card-header" style="margin-bottom: 10px;">
|
||||
|
||||
<div class="layui-row">
|
||||
<span style="font-size:18px;">修改文集前台下载导出权限
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
<form action="{% url 'modify_pro_download' pro.id %}" method="post" class="layui-form">
|
||||
{% csrf_token %}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">文集名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" required value="{{pro.name}}" disabled class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
{% load project_filter %}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">EPUB下载</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="download_epub"
|
||||
{% if pro.id|get_report_status == 1 %} checked {%endif%}
|
||||
lay-skin="switch" lay-text="允许|禁止">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="formDemo">立即修改</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block custom_script %}
|
||||
<script>
|
||||
var form = layui.form;
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
@ -108,8 +108,8 @@
|
||||
'project':$("#project").val(),
|
||||
'parent_doc':$("#parent-doc").val(),
|
||||
'doc_name':$("#doc-name").val(),
|
||||
//'content':editor.getHTML(),
|
||||
'content':editor.getPreviewedHTML(),
|
||||
'content':editor.getHTML(),
|
||||
//'content':editor.getPreviewedHTML(),
|
||||
'pre_content':editor.getMarkdown(),
|
||||
'sort':$("#sort").val(),
|
||||
}
|
||||
@ -126,7 +126,7 @@
|
||||
}
|
||||
});
|
||||
};
|
||||
//保存文档草稿
|
||||
//保存草稿
|
||||
saveDoc = function(){
|
||||
var data = {
|
||||
'doc_id':{{ doc.id }},
|
||||
|
||||
@ -23,15 +23,18 @@
|
||||
<!-- 主体 -->
|
||||
<div class="layui-container project-list-content" style="display:flex;flex-wrap:wrap;">
|
||||
<!-- 遍历文集列表 -->
|
||||
{% load project_filter %}
|
||||
{% for p in project_list %}
|
||||
<div class="project-item layui-col-md3 layui-col-xs12">
|
||||
<a href="{% url 'pro_index' p.id %}">
|
||||
<a href="{% url 'pro_index' p.id %}" title="{{p.name}}">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<div class="layui-card-header" style="overflow:hidden;white-space: nowrap;text-overflow: ellipsis;">
|
||||
{% if p.role == 1 %}
|
||||
<strong><i class="layui-icon layui-icon-password"></i> {{ p.name }}</strong>
|
||||
{% elif p.role == 2 %}
|
||||
<strong><i class="layui-icon layui-icon-user"></i> {{ p.name }}</strong>
|
||||
{% elif p.role == 3 %}
|
||||
<strong><i class="layui-icon layui-icon-key"></i> {{ p.name }}</strong>
|
||||
{% else %}
|
||||
<strong>{{ p.name }}</strong>
|
||||
{% endif %}
|
||||
@ -39,6 +42,7 @@
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<p>作者:{{p.create_user}}</p>
|
||||
<p>最新:<u>{{p.id | get_new_doc}}</u></p>
|
||||
<p class="tooltip">简介:
|
||||
{% if p.intro == "" %}
|
||||
<span class="">此文集没有填写简介</span>
|
||||
|
||||
@ -57,4 +57,50 @@
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% if enable_project_report %}
|
||||
<div class="layui-row">
|
||||
<h3>文集下载:</h3>
|
||||
<p>
|
||||
<span class="layui-breadcrumb" lay-separator="|">
|
||||
{% if allow_epub_download == 1 %}
|
||||
<a href="javascript:void(0);" onclick="reportFile('{{project.id}}','epub')"><i class="fa fa-download"></i> <u>EPUB电子书</u></a>
|
||||
{% else %}
|
||||
<a>文集作者未开放此文集的任何格式下载!</a>
|
||||
{% endif %}
|
||||
<!--<a href=""><i class="fa fa-download"></i> <u>DOCX文档</u></a>-->
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<script>
|
||||
reportFile = function(pro_id,types){
|
||||
var data = {'pro_id':pro_id,'types':types};
|
||||
$.post("{% url 'report_file' %}",data,function(r){
|
||||
if(r.status){
|
||||
//文件下载提示
|
||||
downloadFile(r.data)
|
||||
}else{
|
||||
layer.msg("导出文件出错")
|
||||
}
|
||||
})
|
||||
}
|
||||
//下载文件弹出框
|
||||
downloadFile = function(download_link){
|
||||
layer.open({
|
||||
type:1,
|
||||
title:"下载导出文档",
|
||||
area:"300px",
|
||||
id:"downloadMd",
|
||||
content:'<p style="text-align:center;color:red;">请尽快下载,避免失效!</p><br><a class="layui-btn layui-btn-fluid download-md-link" href="'+ download_link + '" download="" >点击下载文件</a>',
|
||||
//btn:['确定','取消'], //添加按钮
|
||||
//btnAlign:'c', //按钮居中
|
||||
success: function (layero, index) {
|
||||
$(layero).find('.download-md-link').click(function () {
|
||||
layer.close(index);
|
||||
})
|
||||
}
|
||||
})
|
||||
};
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
Loading…
x
Reference in New Issue
Block a user