优化HTML模板、新增富文本编辑器、更新Vditor组件版本

This commit is contained in:
yangjian 2020-12-13 15:43:59 +08:00
parent 67c68e33ef
commit 2361475806
39 changed files with 4312 additions and 2994 deletions

View File

@ -1,5 +1,13 @@
## 版本更新记录
### v0.6.3 2021-01
- [优化]文档编辑页面HTML模板
- [修复]文档编辑器插入图片的异常;
- [升级]同步Vditor组件版本至3.7.1
- [新增]富文本编辑器iceEditor;
- [优化]Vditor编辑模式下移动端输入体验;
### v0.6.2 2020-12
- [优化]个人中心和后台管理页面加载页面时间;

View File

@ -67,7 +67,7 @@
- 个人信息管理:修改昵称、修改电子邮箱、切换文档编辑器;
- **文档书写**
- `Editor.md`、`Vditor`编辑器加持,自由选择、自由切换;
- `Markdown` 、富文本两种编辑模式,`Editor.md``Vditor``iceEditor`三种编辑器加持,自由选择、自由切换;
- 图片、附件、科学公式、音视频、思维导图、流程图、Echart图表
- 文档排序、文档上级设置、文档模板插入;
- 标签设置;

View File

@ -71,7 +71,7 @@ class Doc(models.Model):
modify_time = models.DateTimeField(auto_now=True)
# 文档状态说明0表示草稿状态1表示发布状态2表示删除状态
status = models.IntegerField(choices=((0,0),(1,1)),default=1,verbose_name='文档状态')
# 编辑器模式1表示Editormd编辑器2表示Vditor编辑器
# 编辑器模式1表示Editormd编辑器2表示Vditor编辑器3表示iceEditor编辑器
editor_mode = models.IntegerField(default=1,verbose_name='编辑器模式')
open_children = models.BooleanField(default=False,verbose_name="展开下级目录")

View File

@ -44,7 +44,10 @@ def upload_img(request):
result = base_img_upload(base_img,dir_name,request.user)
# 上传图片URL地址
elif url_img:
result = url_img_upload(url_img,dir_name,request.user)
if url_img.startswith("data:image"):# 以URL形式上传的BASE64编码图片
result = base_img_upload(url_img, dir_name, request.user)
else:
result = url_img_upload(url_img,dir_name,request.user)
else:
result = {"success": 0, "message": "上传出错"}
return HttpResponse(json.dumps(result), content_type="application/json")

View File

@ -3,6 +3,7 @@ from django.shortcuts import render,redirect
from django.http.response import JsonResponse,Http404,HttpResponseNotAllowed,HttpResponse
from django.http import HttpResponseForbidden
from django.contrib.auth.decorators import login_required # 登录需求装饰器
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods,require_GET,require_POST # 视图请求方法装饰器
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage,InvalidPage # 后端分页
from django.core.exceptions import PermissionDenied,ObjectDoesNotExist
@ -885,10 +886,7 @@ def create_doc(request):
# 获取用户的编辑器模式
try:
user_opt = UserOptions.objects.get(user=request.user)
if user_opt.editor_mode == 1:
editor_mode = 1
elif user_opt.editor_mode == 2:
editor_mode = 2
editor_mode = user_opt.editor_mode
except ObjectDoesNotExist:
editor_mode = 1
if request.method == 'GET':
@ -898,11 +896,7 @@ def create_doc(request):
project_list = Project.objects.filter(create_user=request.user) # 自己创建的文集列表
colla_project_list = ProjectCollaborator.objects.filter(user=request.user) # 协作的文集列表
doctemp_list = DocTemp.objects.filter(create_user=request.user).values('id','name','create_time')
# 根据编辑器模式返回不同的模板
if editor_mode == 1:
return render(request, 'app_doc/editor/create_doc.html', locals())
elif editor_mode == 2:
return render(request, 'app_doc/editor/create_doc_vditor.html', locals())
return render(request, 'app_doc/editor/create_doc.html', locals())
except Exception as e:
logger.exception("访问创建文档页面出错")
return render(request,'404.html')
@ -975,10 +969,7 @@ def modify_doc(request,doc_id):
# 获取用户的编辑器模式
try:
user_opt = UserOptions.objects.get(user=request.user)
if user_opt.editor_mode == 1:
editor_mode = 1
elif user_opt.editor_mode == 2:
editor_mode = 2
editor_mode = user_opt.editor_mode
except ObjectDoesNotExist:
editor_mode = 1
if request.method == 'GET':
@ -1002,11 +993,7 @@ def modify_doc(request,doc_id):
doc_list = Doc.objects.filter(top_doc=project.id)
doctemp_list = DocTemp.objects.filter(create_user=request.user)
history_list = DocHistory.objects.filter(doc=doc).order_by('-create_time')
# 获取用户的编辑器模式
if editor_mode == 1:
return render(request, 'app_doc/editor/modify_doc.html', locals())
elif editor_mode == 2:
return render(request, 'app_doc/editor/modify_doc_vditor.html', locals())
return render(request, 'app_doc/editor/modify_doc.html', locals())
else:
return render(request,'403.html')
@ -1687,17 +1674,11 @@ def create_doctemp(request):
# 获取用户的编辑器模式
try:
user_opt = UserOptions.objects.get(user=request.user)
if user_opt.editor_mode == 1:
editor_mode = 1
elif user_opt.editor_mode == 2:
editor_mode = 2
editor_mode = user_opt.editor_mode
except ObjectDoesNotExist:
editor_mode = 1
doctemps = DocTemp.objects.filter(create_user=request.user)
if editor_mode == 1:
return render(request,'app_doc/editor/create_doctemp.html',locals())
else:
return render(request, 'app_doc/editor/create_doctemp_vditor.html', locals())
return render(request,'app_doc/editor/create_doctemp.html',locals())
elif request.method == 'POST':
try:
name = request.POST.get('name','')
@ -1709,7 +1690,7 @@ def create_doctemp(request):
create_user=request.user
)
doctemp.save()
return JsonResponse({'status':True,'data':'创建成功'})
return JsonResponse({'status':True,'data':doctemp.id})
else:
return JsonResponse({'status':False,'data':'模板标题不能为空'})
except Exception as e:
@ -1729,17 +1710,11 @@ def modify_doctemp(request,doctemp_id):
# 获取用户的编辑器模式
try:
user_opt = UserOptions.objects.get(user=request.user)
if user_opt.editor_mode == 1:
editor_mode = 1
elif user_opt.editor_mode == 2:
editor_mode = 2
editor_mode = user_opt.editor_mode
except ObjectDoesNotExist:
editor_mode = 1
doctemps = DocTemp.objects.filter(create_user=request.user)
if editor_mode == 1:
return render(request,'app_doc/editor/modify_doctemp.html',locals())
else:
return render(request, 'app_doc/editor/modify_doctemp_vditor.html', locals())
return render(request,'app_doc/editor/modify_doctemp.html',locals())
else:
return HttpResponse('非法请求')
except Exception as e:
@ -2344,6 +2319,7 @@ def manage_img_group(request):
# 附件管理
@login_required()
@csrf_exempt
@require_http_methods(['GET',"POST"])
def manage_attachment(request):
# 文件大小 字节转换
@ -2459,7 +2435,7 @@ def manage_attachment(request):
return JsonResponse({'status':True,'data':'删除成功'})
elif types in [2,'2']:
attachment_list = []
attachments = Attachment.objects.filter(user=request.user)
attachments = Attachment.objects.filter(user=request.user).order_by('-create_time')
for a in attachments:
item = {
'filename':a.file_name,

23
static/iceEditor/LICENSE Normal file
View File

@ -0,0 +1,23 @@
MIT License
Copyright (c) 2015 https://www.iceui.net
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
http://www.opensource.org/licenses/mit-license.php

423
static/iceEditor/README.md Normal file
View File

@ -0,0 +1,423 @@
# iceEditor富文本编辑器
#### 官方
+ iceEditor 官方网站 [https://www.iceui.net/iceEditor.html](https://www.iceui.net/iceEditor.html)
+ iceEditor 示例文档 [https://www.iceui.net/iceEditor/doc.html](https://www.iceui.net/iceEditor/doc.html)
#### 介绍
iceEditor是一款简约风格的富文本编辑器体型十分娇小无任何依赖整个编辑器只有一个文件功能却很不平凡简约的唯美设计简洁、极速、使用它的时候不需要引用jQuery、font、css……等文件因为整个编辑器只是一个Js支持上传图片、附件支持添加音乐、视频
iceEditor官方群324415936
#### 优点
+ 纯原生开发,无任何依赖,冰清玉洁
+ 响应式布局,适应任何分辨率的设备
+ 整个编辑器只有一个文件,高效便捷
+ 简约的唯美设计,简洁、极速
#### 最新更新
# iceEditor v1.1.8
+ **2020-11-06**
+ [新增] 富文本粘贴按钮
+ [修复] 粘贴时或者文件上传造成多余的p、br标签BUG
+ [修复] 分割线样式消失BUG
+ **2020-10-23**
+ [新增] filterTag标签过滤
+ [新增] filterStyle样式过滤
+ [新增] word粘贴
+ [新增] 富文本粘贴
+ [新增] 粘贴图片
+ [新增] 粘贴时,网络图片下载到本地
+ [新增] 上传图片和附件的监听方法
# iceEditor v1.1.7
+ **2020-09-25**
+ [修复] line的样式问题
+ **2020-09-09**
+ [增加] 增加禁用输入方法
+ [增加] 增加启用输入方法
+ [增加] 增加监听输入方法
+ **2020-09-02**
+ [修复] ajax进度条报错问题
+ **2020-07-27**
+ [修改] 将所有的语义标签、文字大小、颜色、粗体、删除线、斜体……全部改为span标签使用style定义样式
+ [增加] 将当前光标位置样式,同步到菜单高亮上
+ [增加] ajax一系列配置项
+ [增加] 插入表情功能以及配置项
+ **2020-07-25**
+ [修复] 源码视图下p标签错位
+ [修复] 源码视图下粘贴出现多余的p标签
+ [查看其它更新](https://www.iceui.net/iceEditor/update.html)
#### 提示
[iceui](https://gitee.com/iceui/iceui) 前端框架已经已集成该编辑器。
#### 注意
iceEditor.js的引用禁止放在head标签内请尽量放在body中或body后面
#### 引入
+ 下载下来直接引入iceEditor.js即可放在body中或body后面
+ 推荐引入下面的cdn加速链接
+ CDN最新版https://cdn.jsdelivr.net/gh/iceuinet/iceEditor@latest/src/iceEditor.min.js
+ 需要CDN历史版请更改@后面的版本号最低为1.1.6版本
+ 历史版https://cdn.jsdelivr.net/gh/iceuinet/iceEditor@1.1.6/src/iceEditor.min.js
#### 使用
```html
<!-- 也可以直接使用textarea放在form表单中可以直接提交 -->
<!-- <textarea id="editor" name="content"> 欢迎使用iceEditor富文本编辑器 </textarea> -->
<div id="editor"> 欢迎使用iceEditor富文本编辑器 </div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/iceuinet/iceEditor/src/iceEditor.min.js"></script>
```
```javascript
//第一步:创建实例化对象
var e = new ice.editor('content');
//第二步:配置图片或附件上传提交表单的路径
//如果你的项目使用的php开发可直接使用upload.php文件
//其它的编程语言需要你单独处理,后期我会放出.net java等语言代码
//具体与你平常处理multipart/form-data类型的表单一样
//唯一需要注意的就是处理表单成功后要返回json格式字符串不能包含其它多余的信息
//url文件的地址
//name文件的名称包含后缀
//error上传成功为0其它为错误信息将以弹窗形式提醒用户
//例如批量上传了两张图片:
//[
// {url:'/upload/img/153444.jpg', name:'153444.jpg', error:0},
// {url:'/upload/img/153445.jpg', name:'153445.jpg', error:'禁止该文件类型上传'}
//]
e.uploadUrl="/iceEditor/src/upload.php";
//第三步:配置菜单(默认加载全部,无需配置)
e.menu = [
'backColor', //字体背景颜色
'fontSize', //字体大小
'foreColor', //字体颜色
'bold', //粗体
'italic', //斜体
'underline', //下划线
'strikeThrough', //删除线
'justifyLeft', //左对齐
'justifyCenter', //居中对齐
'justifyRight', //右对齐
'indent', //增加缩进
'outdent', //减少缩进
'insertOrderedList', //有序列表
'insertUnorderedList', //无序列表
'superscript', //上标
'subscript', //下标
'createLink', //创建连接
'unlink', //取消连接
'hr', //水平线
'table', //表格
'files', //附件
'music', //音乐
'video', //视频
'insertImage', //图片
'removeFormat', //格式化样式
'code', //源码
'line' //菜单分割线
];
//第四步:创建
e.create();
```
#### 设置编辑器尺寸
```javascript
var e = new ice.editor('content');
e.width='700px'; //宽度
e.height='300px'; //高度
e.create();
```
#### 禁用编辑器
```javascript
//初始化过程中的禁用方式
var e = new ice.editor('content');
e.disabled=true;
e.create();
//通过方法禁用输入
e.inputDisabled();
//取消禁用,恢复输入状态
e.inputEnable();
```
#### 获取内容
```javascript
var e = new ice.editor('content');
console.log(e.getHTML()); //获取HTML格式内容
console.log(e.getText()); //获取Text格式内容
console.log(e.getValue()); //同getHTML只是为了好记
```
#### 设置内容
```javascript
var e = new ice.editor('content');
e.setValue('hello world');
```
#### 追加内容
```javascript
var e = new ice.editor('content');
e.addValue('hello world');
```
#### 监听输入内容
```javascript
var e = new ice.editor('content');
//htmlhtml格式
//text纯文本格式
e.inputCallback(function(html,text){
//console.log(this.getHTML()) 方法内的this为e对象html等价于this.getHTML()
console.log(html);
});
```
#### 禁用截图粘贴功能
```javascript
var e = new ice.editor('content');
e.screenshot=false;
```
#### 禁用截图粘贴直接上传功能
```javascript
//禁用后将默认以base64格式显示图片
var e = new ice.editor('content');
e.screenshotUpload=false;
```
#### 网络图片自动下载到本地
```javascript
var e = new ice.editor('content');
e.imgAutoUpload=false;
```
#### 开启富文本粘贴可粘贴Word
```javascript
var e = new ice.editor('content');
e.pasteText=false;
```
#### 配置插入表情的表情列表
```javascript
var e = new ice.editor('content');
//type分两种img和text类型img为图片表情content为图片的地址类型text为文字表情content为文字表情
//以下是简单示例收集于网络由某网友整理仅供参考如有版权侵犯请您及时联系我QQ308018629我将及时处理
//如果您有推荐的开源免费的表情可联系我或者进入官方QQ群324415936我将表情内置到编辑器中
e.face=[{
title: '新浪',
type: 'img',
list: [
{title:'嘻嘻',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/0b/tootha_thumb.gif'},
{title:'哈哈',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6a/laugh.gif'},
{title:'可爱',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/14/tza_thumb.gif'},
{title:'可怜',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/af/kl_thumb.gif'},
{title:'挖鼻屎',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/a0/kbsa_thumb.gif'},
{title:'吃惊',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/f4/cj_thumb.gif'},
{title:'害羞',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6e/shamea_thumb.gif'},
{title:'挤眼',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c3/zy_thumb.gif'},
{title:'闭嘴',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/29/bz_thumb.gif'},
{title:'鄙视',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/71/bs2_thumb.gif'},
{title:'爱你',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6d/lovea_thumb.gif'},
{title:'泪',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/9d/sada_thumb.gif'},
{title:'偷笑',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/19/heia_thumb.gif'},
{title:'亲亲',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/8f/qq_thumb.gif'},
{title:'生病',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/b6/sb_thumb.gif'},
{title:'太开心',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/58/mb_thumb.gif'},
{title:'懒得理你',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/17/ldln_thumb.gif'},
{title:'右哼哼',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/98/yhh_thumb.gif'},
{title:'左哼哼',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6d/zhh_thumb.gif'},
{title:'嘘',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/a6/x_thumb.gif'},
{title:'衰',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/af/cry.gif'},
{title:'委屈',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/73/wq_thumb.gif'},
{title:'吐',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/9e/t_thumb.gif'},
{title:'打哈欠',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/f3/k_thumb.gif'},
{title:'抱抱',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/27/bba_thumb.gif'},
{title:'怒',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/7c/angrya_thumb.gif'},
{title:'疑问',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/5c/yw_thumb.gif'},
{title:'馋嘴',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/a5/cza_thumb.gif'},
{title:'拜拜',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/70/88_thumb.gif'},
{title:'思考',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/e9/sk_thumb.gif'},
{title:'汗',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/24/sweata_thumb.gif'},
{title:'困',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/7f/sleepya_thumb.gif'},
{title:'睡觉',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6b/sleepa_thumb.gif'},
{title:'钱',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/90/money_thumb.gif'},
{title:'失望',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/0c/sw_thumb.gif'},
{title:'酷',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/40/cool_thumb.gif'},
{title:'花心',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/8c/hsa_thumb.gif'},
{title:'哼',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/49/hatea_thumb.gif'},
{title:'鼓掌',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/36/gza_thumb.gif'},
{title:'晕',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/d9/dizzya_thumb.gif'},
{title:'悲伤',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/1a/bs_thumb.gif'},
{title:'抓狂',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/62/crazya_thumb.gif'},
{title:'黑线',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/91/h_thumb.gif'},
{title:'阴险',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6d/yx_thumb.gif'},
{title:'怒骂',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/89/nm_thumb.gif'},
{title:'心',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/40/hearta_thumb.gif'},
{title:'伤心',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/ea/unheart.gif'},
{title:'ok',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/d6/ok_thumb.gif'},
{title:'耶',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/d9/ye_thumb.gif'},
{title:'good',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/d8/good_thumb.gif'},
{title:'不要',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c7/no_thumb.gif'},
{title:'赞',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/d0/z2_thumb.gif'},
{title:'来',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/40/come_thumb.gif'},
{title:'弱',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/d8/sad_thumb.gif'},
{title:'蜡烛',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/91/lazu_thumb.gif'},
{title:'蛋糕',content:'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6a/cake.gif'}
]
}, {
title: '文字',
type: 'text',
list: [
{title:'开心',content:'(^_^)'},
{title:'受不了',content:'(>_<)'},
{title:'鄙视',content:'(¬、¬)'},
{title:'难过',content:'(*><*)'},
{title:'可爱',content:'(。◕‿◕。)'},
{title:'无奈',content:'╮(╯_╰)╭'},
{title:'惊喜',content:'╰(*°▽°*)╯'},
{title:'听音乐',content:'♪(^∇^*)'},
{title:'害羞',content:'(✿◡‿◡)'},
{title:'睡啦',content:'(∪。∪)..zzZ'},
{title:'臭美',content:'(o≖◡≖)'},
{title:'流汗',content:'(ーー゛)'}
]
}];
e.create();
```
#### ajax回调
```javascript
var e = new ice.editor('content');
//ajax的xhr设置
e.ajax.xhr = function(xhr){};
//ajax超时回调
e.ajax.timeout = function(xhr){};
//ajax成功回调
e.ajax.success = function(res,xhr){};
//ajax失败回调
e.ajax.error = function(res,xhr){};
//ajax不管成功失败都调用
e.ajax.complete = function(res,xhr){};
//ajax进度回调
e.ajax.progress = function(percent,evt,xhr){};
//上传附件
e.filesUpload.success = function(res){}; //成功
e.filesUpload.error = function(res,xhr){}; //失败
e.filesUpload.complete = function(res,xhr){}; //不管成功失败都调用
//上传图片
e.imgUpload.success = function(res){}; //成功
e.imgUpload.error = function(res,xhr){}; //失败
e.imgUpload.complete = function(res,xhr){}; //不管成功失败都调用
```
#### 插件开发
```javascript
var e = new ice.editor('content');
e.addValue('hello world');
//┌────────────────────────────────────────────────────────────────────────
//│ e.plugin(options)传参说明
//│────────────────────────────────────────────────────────────────────────
//│ options {json}
//│ ├ name {string} [必填]菜单唯一的name可配置menu项显示与顺序
//│ ├ menu {string} [必填]展示在菜单栏上的按钮,可为图标或者文字
//│ ├ data {string} execCommand的命令
//│ ├ id {string} 菜单按钮上的id
//│ ├ css {string} 菜单按钮上的class
//│ ├ style {string} 该插件的style以css文件中的样式形式书写
//│ ├ dropdown {string} 下拉菜单里的html如果定义了popup则该参数失效
//│ ├ popup {json} 弹窗json
//│ │ ├ width {int} 弹窗的宽度
//│ │ ├ height {int} 弹窗的高度
//│ │ ├ title {string} 弹窗上的标题
//│ │ └ content {string} 弹窗的内容可为html
//│ ├ click {function} 按钮点击事件
//│ └ success {function} 插件安装成功后会自动执行该方法
//└────────────────────────────────────────────────────────────────────────
//下拉菜单类型
e.plugin({
menu:'代码语言',
name:'codeLanguages',
dropdown:`
<div class="iceEditor-codeLanguages" style="padding:10px 20px;">
<div>前端请引用iceCode.js</div>
<select>
<option disabled selected>代码语言</option>
<option value ="php">php</option>
<option value ="js">js</option>
<option value="html">html</option>
<option value="java">java</option>
</select>
</div>`,
success:function(e,z){
//获取content中的按钮
var select = e.getElementsByTagName('select')[0];
//设置点击事件
select.onchange=function(){
var str = z.getSelectHTML().replace(/<\s*\/p\s*>/ig,"\r\n").replace(/<[^>]+>/ig,'').trim();
var pre = z.c('pre');
pre.className = 'iceCode:'+select.value;
pre.innerHTML = str.length?str:"\r\n";
z.setHTML(pre,true);
select.getElementsByTagName('option')[0].selected = true;
}
}
});
//function方式
e.plugin({
menu:'function方式',
name:'click',
click:function(e,z){
z.setText('hello world');
}
});
//execCommand命令
e.plugin({
menu:'删除命令',
name:'del',
data:'delete'
});
//下拉菜单类型
e.plugin({
menu:'下拉菜单',
name:'dropdown',
dropdown:'<div class="iceEditor-exec" data="copy" style="padding:10px 20px;">复制选中的文字</div>',
});
//弹出层类型
e.plugin({
menu:'弹窗演示',
name:'popup',
style:'.demo-p{margin-bottom:10px}.demo-button{padding:0 10px}',
popup:{
width:230,
height:120,
title:'我是一个demo',
content:'<p class="demo-p">在光标处插入hello world!</p> <button class="demo-button" type="button">确定</button>',
},
success:function(e,z){
//获取content中的按钮
var btn = e.getElementsByTagName('button')[0];
//设置点击事件
btn.onclick=function(){
z.setText('hello world');
//关闭本弹窗
e.close()
}
}
});
e.create();
```

File diff suppressed because one or more lines are too long

20
static/iceEditor/src/iceEditor.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,188 @@
<?php
/**
*------------------------------------------------------------------------------------*
* 功能iceEditor编辑器上传
*------------------------------------------------------------------------------------*
* 作者ice
* 官方www.iceui.net
* 时间2018-04-25
* 更新时间时间2020-10-22
* 更新内容:增加网络图片下载到本地
* 版权声明该版权完全归官方www.iceui.net所有可转载和个人学习使用但请务必保留版权
*------------------------------------------------------------------------------------*
*/
/*********************** 基本参数 ***********************/
header("Content-Type: text/html; charset=utf-8");
header("X-Powered-By: uz");
date_default_timezone_set('PRC');
session_start();
/*********************** 基本参数 ***********************/
/*********************** 上传项配置区 开始 ***********************/
//获取域名
$http = (isHttps() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'];
// 绝对路径
define('URL',str_ireplace(str_replace("/","\\",$_SERVER['PHP_SELF']),'',__FILE__));
//上传目录
$dir = isset($_SESSION['upload_path'])?$_SESSION['upload_path']:'/upload/files/'.date("Ymd").'/';
//上传控件名称
$field = 'file';
//支持上传的文件格式
$type = ['jpg','jpeg','png','gif','bmp','exe','flv','swf','mkv','avi','rm','rmvb','mpeg','mpg','ogg','ogv','mov','wmv','mp4','webm','mp3','wav','mid','rar','zip','tar','gz','7z','bz2','cab','iso','chm','doc','docx','xls','xlsx','ppt','pptx','pdf','txt','md','xml','torrent'];
//上传文件存储大小的限制-默认30M
$maxSize = 30 * 102400;
//上传文件的名称命名方式,默认以'time'方式命名
//time 将以时间戳+数字排序
//fileName 将以文件原来的名称命名如果该文件含有中文则自动改为time形式命名
//填写其它字符串(禁止填写中文),将以该字符串形式命名,如果为批量上传,则将该字符串后面添加数字排序防止重名
$rename = 'time';
/*********************** 上传项配置区 结束 ***********************/
//如果设置的上传目录不存在,则创建
if (!file_exists(URL.$dir)) {
@mkdir(URL.$dir,0777,true);
}
//定义用来返回上传文件成功后的URL连接的JSON格式
$url = [];
//网络图片下载到本地
if(isset($_POST['iceEditor-img']) && $_POST['iceEditor-img']){
$fileExt = file_ext($_POST['iceEditor-img']);
$img = @file_get_contents($_POST['iceEditor-img']);
if(!$img){
$url['error'] = 1;
$url['url'] = '';
}else{
$info = pathinfo($_POST['iceEditor-img']);
$name = file_rename($info['basename']);
//判断文件类型是否允许上传
if (!$img || !in_array($fileExt,['jpg','jpeg','png','gif','bmp'])){
$url['error'] = 1;
$url['url'] = '';
}
if(file_put_contents(URL.$dir.$name, $img)){
$url['error'] = 0;
$url['url'] = $http.$dir.$name;
}
}
echo json_encode($url);
exit;
}
//获取批量上传的数组键值,也就是说上传的文件数量
$keys = array_keys($_FILES[$field]['name']);
//通过遍历来处理上传的文件
foreach ($keys as $key){
//获取文件的类型
$fileType = $_FILES[$field]['type'][$key];
$name = $_FILES[$field]['name'][$key];
//用来处理截图数据
if($name == 'blob'){
$ext = explode('/',$fileType);
$name .= '.'.$ext[1];
}
//获取文件的名称
$fileName = file_pre($name);
//获取文件的后缀名称
$fileExt = file_ext($name);
//重命名
$name = file_rename($name,$key);
$error = 0;
//判断文件类型是否允许上传
if (!in_array($fileExt,$type)){
$error = '该文件类型禁止上传';
}
//判断文件大小是否超出
if ($_FILES[$field]["size"][$key] > $maxSize){
$error = '该文件太大禁止上传';
}
//获取文件的完整url地址
$url[$key]['url'] = $http.$dir.$name;
$url[$key]['name'] = $fileName.'.'.$fileExt;
$url[$key]['error'] = $error;
if(!$error){
//将上传的文件移动到指定目录
move_uploaded_file($_FILES[$field]["tmp_name"][$key],URL.$dir.$name);
}
}
//判断当前协议是否为HTTPS
function isHttps() {
if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
return true;
} elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
return true;
} elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
return true;
}
return false;
}
//获取文件后缀名,不包含 .
function file_ext($name) {
return strtolower(substr(strrchr($name, '.'), 1));
}
//获取文件的前缀,不包含 .
function file_pre($name) {
return substr($name, 0, strrpos($name, '.'));
}
//重命名
function file_rename($name,$key=1) {
global $rename;
//获取文件的名称
$fileName = file_pre($name);
//获取文件的后缀名称
$fileExt = file_ext($name);
if($rename == 'time'){
$name = time()+$key.'.'.$fileExt; //以时间戳加排序数字重命名,防止重复
}elseif($rename == 'fileName' || $rename == ''){
//如果文件名含有中文,则以时间戳加排序数字重命名,防止出错
if(preg_match("/([\x81-\xfe][\x40-\xfe])/", $fileName, $match)){
$name = time()+$key.'.'.$fileExt;
}else{
//以文件原来的名称
$name = $fileName.'.'.$fileExt;
}
}else{
//自定义重命名,如果该上传为批量,则自定义的命名后面添加排序数字
if($key>0){
$name = $rename.$key.'.'.$fileExt;
}else{
$name = $rename.'.'.$fileExt;
}
}
return $name;
}
//输出最终数据;
echo json_encode($url);
exit;
?>

130
static/iceEditor/update.txt Normal file
View File

@ -0,0 +1,130 @@
#1 更新日志
# iceEditor v1.1.8
+ 2020-11-06
+ [新增] 富文本粘贴按钮
+ [修复] 粘贴时或者文件上传造成多余的p、br标签BUG
+ [修复] 分割线样式消失BUG
+ 2020-10-23
+ [新增] filterTag标签过滤
+ [新增] filterStyle样式过滤
+ [新增] word粘贴
+ [新增] 富文本粘贴
+ [新增] 粘贴图片
+ [新增] 粘贴时,网络图片下载到本地
+ [新增] 上传图片和附件的监听方法
# iceEditor v1.1.7
+ 2020-09-25
+ [修复] line的样式问题
+ 2020-09-09
+ [增加] 增加禁用输入方法
+ [增加] 增加启用输入方法
+ [增加] 增加监听输入方法
+ 2020-09-02
+ [修复] ajax进度条报错问题
+ 2020-07-27
+ [修改] 将所有的语义标签、文字大小、颜色、粗体、删除线、斜体……全部改为span标签使用style定义样式
+ [增加] 将当前光标位置样式,同步到菜单高亮上
+ [增加] ajax一系列配置项
+ [增加] 插入表情功能以及配置项
+ 2020-07-25
+ [修复] 源码视图下p标签错位
+ [修复] 源码视图下粘贴出现多余的p标签
# iceEditor v1.1.6
+ 2020-06-22
+ [修复] 上传网络图片链接width和height为0的BUG
+ 2020-06-20
+ [修复] textarea内容中的pre代码格式
+ [新增] 新增代码语言(扩展)
+ 2020-06-17
+ [优化] 添加a链接可选择新窗口打开
+ [优化] 下拉菜单点击exec命令菜单后弹窗消失
+ [优化] 新增pre标签下粘贴代码
+ [优化] 查看源码所造成的一些BUG
+ 2020-06-16
+ [优化] 编辑内容时结尾出现多余的p标签
+ [修复] 处于源码视图中获取到的textarea内容被转义BUG
+ [修复] setValue设置编辑器内容时如果容器使用的textarea给它赋值
+ 2020-06-02
+ [优化] 点击下拉菜单,菜单随之关闭
+ [优化] 删除线功能取消strike标签html5已经废弃改为style样式控制
+ [修改] 创建链接弹窗方式
+ [修改] 添加音乐弹窗方式
# iceEditor v1.1.5
+ 2020-05-29
+ [新增] QQ、微信……截图直接粘贴功能默认开启此功能不需要可关闭配置项screenshot
+ [新增] 截图直接上传至服务器功能默认开启此功能不需要可关闭配置项screenshotUpload
+ [重写] 图片、附件上传的核心方法由iframe方式改为ajax
+ [修改] upload.php文件支持存储截图的blob对象
+ 2020-05-22
+ [修复] 拖拽编辑器的高度时造成鼠标丢失焦点BUG
+ 2020-05-18
+ [修复] 视频上传type未定义BUG
+ [修复] 图片上传完成后造成的iframe为空报错
# iceEditor v1.1.5
+ 2020-05-29
+ [新增] QQ、微信……截图直接粘贴功能默认开启此功能不需要可关闭配置项screenshot
+ [新增] 截图直接上传至服务器功能默认开启此功能不需要可关闭配置项screenshotUpload
+ [重写] 图片、附件上传的核心方法由iframe方式改为ajax
+ [修改] upload.php文件支持存储截图的blob对象
+ 2020-05-22
+ [修复] 拖拽编辑器的高度时造成鼠标丢失焦点BUG
+ 2020-05-18
+ [修复] 视频上传type未定义BUG
+ [修复] 图片上传完成后造成的iframe为空报错
# iceEditor v1.1.4
+ 2020-04-22
+ [新增] 插件机制,可更好的定制开发菜单栏(开发文档努力写作中,后续贴出,以下贴出简单示例)
+ [新增] 配置项css可自由设计编辑器的风格样式
+ [修复] 粘贴文本造成换行BUG
+ [修复] 上个版本升级造成的个别样式错误
+ [重写] 菜单栏内核,转为插件设计
+ [优化] 一些逻辑代码,提升加载速度
+ [优化] 样式代码,精简一部分多余样式
+ 2020-04-21
+ [修复] 代码查看模式粘贴代码造成空白的BUG
# iceEditor v1.1.3
+ 2020-04-20
+ [新增] 添加视频解析功能可直接添加b站和优酷的播放地址链接其它视频平台将会陆续添加
+ [优化] 编辑器样式,全部添加前缀,防止污染
+ [修复] 附件和图片上传失败所造成的BUG
+ [修复] upload.php文件返回json格式
+ 2020-04-17
+ [修复] 复制粘贴被转义BUG
+ 2020-04-15
+ [修复] Mac firefox下无法使用BUG
+ [修复] dome文件中A标签未闭合BUG
+ [修改] 默认取消编辑器的光标聚焦
+ [修改] 编辑器添加默认字体大小
+ 2020-04-10
+ [修复] Windows firefox下无法使用BUG
+ [修复] uploadUrl没配置的情况下造成死循环BUG
+ [修复] 图片与附件上传关闭弹窗时造成打开其它页面BUG
# iceEditor v1.1.2
+ 2020-04-01
+ [精简] 一部分代码
+ [修复] 粘贴内容BUG
+ [优化] 代码样式
+ [优化] 上传图片和上传附件方法
+ [优化] 设置html方法
+ [优化] 初始化数据代码
# iceEditor v1.1.1
+ 2018-11-12
+ [修复] 粘贴替换编辑器内所有内容BUG
# iceEditor v1.1.0
+ 2018-03-13
+ [精简] 代码,优化加载性能
+ [重写] 图片上传工具解决form嵌套问题
+ [重写] 附件上传工具解决form嵌套问题
+ [添加] 附件和图片上传提交地址的配置项
+ [修复] 复制文本没有段落格式BUG

View File

@ -75,7 +75,7 @@ function changeSidebar(){
}else{
$("body").removeClass("big-page");
}
}
};
// 监听文档div点击
document.querySelector('.doc-body').addEventListener('click', function (e) {
var screen_width = window.matchMedia('(max-width: 768px)');

View File

@ -189,3 +189,418 @@ function createMarkdownDividerRow(cellCount) {
}
return '| ' + dividerCells.join(" ");
}
// 文档浏览器缓存
function autoCacheDoc(){
setInterval(() => {
if(editor_mode == 1){
var editor_value = editor.getMarkdown()
}else if(editor_mode == 2){
var editor_value = editor.getValue()
}else if(editor_mode == 3){
var editor_value = editor.getHTML()
}
window.localStorage.setItem('mrdoc_doc_cache',editor_value)
}, 10000);
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
if(editor_mode == 1){
editor.insertValue(editor_cache)
}else if(editor_mode == 2){
editor.setValue(editor_cache)
}else if(editor_mode == 3){
editor.setValue(editor_cache)
}
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
//修改预览div中a标签链接新窗口打开
$('div.editormd-preview').on('click','a',function(e){
e.target.target = '_blank';
});
$("#editor-md").on('click','a',function(e){
e.target.target = '_blank';
})
/*
小屏幕下的文集大纲显示处理
*/
//监听浏览器宽度的改变
window.onresize = function(){
changeSidebar();
};
function changeSidebar(){
// 获取匹配指定的媒体查询
var screen_width = window.matchMedia('(max-width: 768px)');
//判断匹配状态
if(screen_width.matches){
//如果匹配到,切换侧边栏
console.log('小屏幕')
$("body").addClass("big-page");
}else{
$("body").removeClass("big-page");
}
};
// 监听文档div点击
document.querySelector('.doc-body').addEventListener('click', function (e) {
var screen_width = window.matchMedia('(max-width: 768px)');
// 小屏下收起左侧文集大纲
if(screen_width.matches){
// console.log("点击了div")
changeSidebar();
}
});
/*
切换隐藏侧边栏
*/
// 初始化左侧文集大纲状态
function init_sidebar(){
var screen_width = window.matchMedia('(max-width: 768px)');
if(screen_width.matches){}else{
// 读取浏览器存储
bgpage_status = window.localStorage.getItem('bgpage')
console.log("左侧大纲状态:",bgpage_status)
if(bgpage_status === null){ // 如果没有值,则默认展开
$("body").toggleClass("big-page");
}else if(bgpage_status === '1'){ // 如果值为1则默认展开
if($("body").hasClass("big-page")){}else{
$("body").toggleClass("big-page");
}
}
else{ // 否则收起
if($("body").hasClass("big-page")){
$("body").toggleClass("big-page");
}else{
window.localStorage.setItem('bgpage','0')
}
}
}
}
init_sidebar();
// 切换侧边栏
$(function(){
$(".js-toolbar-action").click(toggleSidebar);
});
//切换侧边栏显示隐藏
function toggleSidebar(){
console.log("切换侧边栏")
$("body").toggleClass("big-page");
if(window.localStorage.getItem('bgpage') === '1'){
window.localStorage.setItem('bgpage','0')
}else{
window.localStorage.setItem('bgpage','1')
}
return false;
}
//监听图片Tab选项卡切换
element.on('tab(img-tab)', function(data){
//console.log(this); //当前Tab标题所在的原始DOM元素
//console.log(data.index); //得到当前Tab的所在下标
//console.log(data.elem); //得到当前的Tab大容器
if(data.index == 1){
layer.load(1);
console.log('选择图片')
$("#select-img-group").empty(); //删除已有分组按钮
//请求新的分组数据
$.post("/manage_image_group/",{'types':3},function(r){
if(r.status){
group_btn_str = ''
for(var i in r.data){
group_btn_str += '<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="switchImgGroup(' + r.data[i].group_id +')">' + r.data[i].group_name + '(' + r.data[i].group_cnt + ')</button>'
};
$("#select-img-group").append(group_btn_str)
}
});
//请求全部图片数据
$.post("/manage_image/",{'types':2,'group_id':0},function(r){
if(r.status){
//调用分页显示
laypage.render({
elem: 'select-img-page',//分页的div
count: r.data.length, //数据总数
limit:15, //单页数
jump: function(obj){
//渲染HTML
document.getElementById('select-img').innerHTML = function(){
var arr = []
var thisData = r.data.concat().splice(obj.curr*obj.limit - obj.limit, obj.limit);
layui.each(thisData, function(index, item){
arr.push('<li class="select-img-list"><img class="select-img-list-i" onclick="insertImg(this);" src="' + item.path + '" title="' + item.name + '"data-url="' + item.path +'" /></li>');
});
return arr.join('');
}();
}
});
layer.closeAll("loading");
}else{
layer.closeAll("loading");
layer.msg("获取图片失败")
}
})
}
});
// 插入选择的图片到编辑器
insertImg = function(e){
console.log(e);
if(editor_mode == 3){
editor.addValue('<img src="' + e.getAttribute('data-url') + '" />')
}else{
editor.insertValue("\n![](" + e.getAttribute('data-url') + ")");
editor.focus()
}
};
// 按钮点击插入输入框图片链接
insertImgUrl = function(){
if(editor_mode == 3){
editor.addValue('<img src="' + $("#img_url_input").val() + '" />')
}else{
editor.insertValue("\n![](" + $("#img_url_input").val() + ")");
editor.focus()
}
$("#img_url_input").val("")
layer.closeAll();
};
// 切换图片分组
switchImgGroup = function(e){
layer.load(1);
$.post("/manage_image/", {
'types': 2,
'group_id': e
},
function(r) {
if (r.status) {
//调用分页显示
laypage.render({
elem: 'select-img-page',//分页的div
count: r.data.length,//数据总数
limit: 15,//单页数
jump: function(obj) {
//渲染HTML
document.getElementById('select-img').innerHTML = function() {
var arr = []
var thisData = r.data.concat().splice(obj.curr * obj.limit - obj.limit, obj.limit);
layui.each(thisData,
function(index, item) {
arr.push('<li class="select-img-list"><img class="select-img-list-i" onclick="insertImg(this);" src="' + item.path + '" title="' + item.name + '"data-url="' + item.path + '" /></li>');
});
return arr.join('');
} ();
}
});
layer.closeAll("loading"); //关闭加载提示
} else {
layer.closeAll("loading");
layer.msg("获取分组图片失败")
}
})
};
// 插入选择的附件到编辑器
insertAttach = function(e){
if(editor_mode == 3){ // ice富文本编辑器
editor.addValue('<a href= "/media/' + $(e).data('path') + '" download="' + $(e).data('name') + '">' + '[附件]' + $(e).data('name') + '</a>')
}else{
editor.insertValue("\n[【附件】"+ $(e).data('name') + "](/media/" + $(e).data('path') + ")");
}
layer.closeAll();
};
// 插入音视频到编辑器
insertMultimedia = function(e){
if(e === 'audio'){
editor.insertValue("\n![=audio](" + $("#audio_input").val() + ")");
}else if(e === 'video'){
editor.insertValue("\n![=video](" + $("#video_input").val() + ")");
}else if(e === 'video_iframe'){
editor.insertValue("\n![=video_iframe](" + $("#video_iframe_input").val() + ")");
}
$("#audio_input").val('')
$("#video_input").val('')
$("#video_iframe_input").val('')
layer.closeAll();
editor.focus()
};
//按钮选择上传图片
var upload = layui.upload;
upload.render({
elem: '#upload_img',
url: '/upload_doc_img/',
before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(1); //上传loading
},
done: function(res, index, upload){ //上传后的回调
//上传成功
if(res.success == 1){
if(editor_mode == 3){
editor.addValue('<img src="' + res.url + '" />')
}else{
editor.insertValue("\n![](" + res.url + ")");
}
layer.closeAll();
layer.msg("上传成功");
}else{
layer.closeAll();
layer.msg(res.message)
}
},
error:function(){
layer.closeAll('loading'); //关闭loading
layer.msg("系统异常,请稍后再试!")
},
accept: 'images', //允许上传的文件类型
acceptMime:'image/*',
field:'manage_upload',
});
// 按钮选择上传附件
var upload_attach = layui.upload;
upload_attach.render({
elem: '#upload_attachment',
url: '/manage_attachment/',
data:{types:0},
before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(1); //上传loading
},
done: function(res, index, upload){ //上传后的回调
//上传成功,刷新页面
if(res.status){
if(editor_mode == 3){
editor.addValue('<a href= "/media/' + res.data.url + '" download="' + res.data.name + '">' + '[附件]' + res.data.name + '</a>')
}else{
editor.insertValue("\n[【附件】"+ res.data.name + "](/media/" + res.data.url + ")");
}
layer.closeAll();
layer.msg("上传成功");
}else{
layer.closeAll('loading');
layer.msg(res.data)
}
},
error:function(){
layer.closeAll('loading'); //关闭loading
layer.msg("系统异常,请稍后再试!")
},
accept: 'file', //允许上传的文件类型
field:'attachment_upload',
})
// 粘贴表格文本框侦听paste粘贴事件
// 列宽的函数
function columnWidth(rows, columnIndex) {
return Math.max.apply(null, rows.map(function(row) {
return row[columnIndex].length
}))
};
// 检查是否是个表格
function looksLikeTable(data) {
return true
};
// 编辑器侦听paste粘贴事件
var pasteExcel = document.getElementById('pasteExcel')
pasteExcel.addEventListener("paste", function(event) {
console.log('粘贴Excel')
var clipboard = event.clipboardData
var data = clipboard.getData('text/plain')
data = data.replace(/(?:[\n\u0085\u2028\u2029]|\r\n?)$/, '');
if(looksLikeTable(data)) {
event.preventDefault()
}else{
return
}
// 行
var rows = data.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(function(row) {
console.log(row)
return row.split("\t")
})
// 列对齐
var colAlignments = []
// 列宽
var columnWidths = rows[0].map(function(column, columnIndex) {
var alignment = "l"
var re = /^(\^[lcr])/i
var m = column.match(re)
if (m) {
var align = m[1][1].toLowerCase()
if (align === "c") {
alignment = "c"
} else if (align === "r") {
alignment = "r"
}
}
colAlignments.push(alignment)
column = column.replace(re, "")
rows[0][columnIndex] = column
return columnWidth(rows, columnIndex)
})
var markdownRows = rows.map(function(row, rowIndex) {
return "| " + row.map(function(column, index) {
return column + Array(columnWidths[index] - column.length + 1).join(" ")
}).join(" | ") + " |"
row.map
})
markdownRows.splice(1, 0, "|" + columnWidths.map(function(width, index) {
var prefix = ""
var postfix = ""
var adjust = 0
var alignment = colAlignments[index]
if (alignment === "r") {
postfix = ":"
adjust = 1
} else if (alignment == "c") {
prefix = ":"
postfix = ":"
adjust = 2
}
return prefix + Array(columnWidths[index] + 3 - adjust).join("-") + postfix
}).join("|") + "|")
event.target.value = markdownRows.join("\n")
return false
});

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

View File

@ -41,7 +41,11 @@
{% endblock %}
{% block page_content %}
{% if doc.editor_mode == 3 %}
{{ doc.pre_content | safe }}
{% else %}
<textarea style="display: none;">{{ doc.pre_content }}</textarea>
{% endif %}
{% endblock %}
{% block doc_bottom_block %}

View File

@ -0,0 +1,259 @@
{% load static %}
{% load i18n %}
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edgechrome=1">
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{% block title %}{% endblock %} - {% if site_name != None and site_name != '' %}{{site_name}} {% else %}站点标题{% endif %}</title>
<link href="{% static 'layui/css/layui.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link rel="stylesheet" href="{% static 'editor.md/css/font-awesome.min.css' %}?version={{mrdoc_version}}" />
{% if editor_mode == 1 %}
<!-- Editor.MD编辑器样式表 -->
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.css' %}?version={{mrdoc_version}}" />
<link rel="stylesheet" href="{% static 'katex/katex.min.css' %}?version={{mrdoc_version}}" />
{% elif editor_mode == 2 %}
<!-- Vditor编辑器样式表 -->
<link rel="stylesheet" href="{% static 'vditor/dist/index.css' %}?version={{mrdoc_version}}" />
{% endif %}
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
<link href="{% static 'mrdoc/mrdoc.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link href="{% static 'mrdoc/mrdoc-editor.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link href="{% static 'tagsInput/tagsinput.css' %}" rel="stylesheet" type="text/css"/>
<style>
</style>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body class="big-page">
<div class="doc layui-fluid" style="padding-left:0px;">
<!-- 左侧工具栏 -->
<div class="doc-summary">
<div class="project-title"><i class="fa fa-edit"></i> {% trans "MrDoc文档编辑器" %}<br>
<span style="font-size: 14px;">你正在:{{editor_type }}</span>
</div>
<hr>
{% block left_opera %}
{% endblock %}
</div>
<!-- 左侧工具栏结束 -->
<!-- 右侧编辑器栏 -->
<div class="doc-body">
<!-- 文档导航 -->
<div class="doc-header" role="navigation">
<a class="btn pull-left js-toolbar-action" aria-label="" href="javascript:void(0);" title="切换侧边栏">
<i class="fa fa-align-justify"></i>
</a>
<!-- 顶部工具栏 -->
{% block head_toolbar %}
{% endblock %}
<a class="btn pull-right" aria-label="" href="{% url 'pro_list' %}">
<i class="fa fa-home"></i> <span class="layui-hide-xs">首页</span>
</a>
</div>
<!-- 文档主体 -->
<div class="doc-body-content" style="padding-left: 15px;">
<div class="mrdoc-body-content-div">
<!-- 文档内容 -->
<div class="mrdoc-editor-content">
<!-- 正文开始 -->
<div class="markdown-body" id="content">
{% block content %}
{% endblock %}
</div>
<!-- 正文结束 -->
</div>
</div>
</div>
</div>
<!-- 右侧编辑器结束 -->
</div>
{% block custom_div %}
{% endblock %}
<!-- 选择和上传图片div -->
<div id="upload-img" style="display:none;margin:20px;">
<div class="layui-tab" lay-filter="img-tab">
<ul class="layui-tab-title">
<li class="layui-this">上传图片</li>
<li>选择图片</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-row">
<button class="layui-btn layui-btn-primary layui-btn-fluid" id="upload_img"><i class="layui-icon layui-icon-upload"></i> 上传图片</button>
</div>
<fieldset class="layui-elem-field layui-field-title" style="text-align: center;">
<legend style="font-size: 12px;">或 插入外链图片链接</legend>
</fieldset>
<div class="layui-row" style="margin-top: 10px;">
<input type="text" class="layui-input" placeholder="输入图片URL" id="img_url_input" style="margin-bottom: 5px;"/>
<button type="button" class="layui-btn layui-btn-primary" onclick="insertImgUrl()">插入图片链接</button>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-row" id="select-img-group">
</div><hr>
<div class="layui-row" id="select-img"></div>
<div id="select-img-page"></div>
</div>
</div>
</div>
</div>
<!-- 选择和上传附件div -->
<div id="upload-attach" style="display:none;margin:20px;">
<span>* 仅支持 {% if attachment_suffix and attachment_suffix != '' %}{{attachment_suffix}}{% else %}zip{% endif %} 格式文件,文件大小不超过 {% if attachment_size and attachment_size != '' %}{{attachment_size}}{% else %}50{% endif %}MB</span>
<div style="margin: 10px 0 0 10px;">
<button class="layui-btn layui-btn-primary layui-btn-sm" id="upload_attachment"><i class="layui-icon layui-icon-upload"></i> 上传附件</button>
<a class="layui-btn layui-btn-primary layui-btn-sm" href="{% url 'manage_attachment' %}" target="_blank"><i class="fa fa-cubes"></i> 管理附件</a>
</div>
<table class="layui-table" id="attach_table" style="margin: 10px;width:90%;">
<thead>
<th>附件名称</th>
<th>附件大小</th>
<th>上传时间</th>
<th>操作</th>
</thead>
<tbody>
</tbody>
</table>
<div id="select-attach-page"></div>
</div>
<!-- 添加表格div -->
<div id="layer-table" style="display: none;margin: 10px;">
<div class="layui-tab" lay-filter="table-tab" id="insert-table-div">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="generaTable">生成表格</li>
<li lay-id="pasteTable">粘贴表格</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show" >
<div class="layui-row" style="margin: 10px;">
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-input-inline" style="width: 50px;">
<input type="number" placeholder="行" id="row" class="layui-input" value="3">
</div>
<div class="layui-form-mid">x</div>
<div class="layui-input-inline" style="width: 50px;">
<input type="number" placeholder="列" id="col" class="layui-input" value="3">
</div>
<div class="layui-form-mid" style="width: 100px;">
<button class="layui-btn layui-btn-normal layui-btn-xs" onclick="addtable(1)" >生成表格</button>
</div>
</div>
</div>
</div>
<div class="layui-row" style="margin:10px;" id="TableGroup"></div>
</div>
<div class="layui-tab-item" >
<textarea placeholder="粘贴Excel或在线电子表格的内容" class="layui-textarea" style="height: 200px;" id="pasteExcel"></textarea>
</div>
</div>
</div>
</div>
<!-- 添加音视频div -->
<div id="insertMultimedia" style="display: none;margin:10px;">
<div class="layui-row">
<fieldset class="layui-elem-field">
<legend>插入音频链接</legend>
<div class="layui-field-box">
<input class="layui-input" type="url" id="audio_input" placeholder="填入音频文件链接支持文件后缀格式为mp3、wav、flac、m4a" style="margin-bottom: 5px;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" onclick="insertMultimedia('audio')"><i class="fa fa-music"></i> 插入音频</button>
</div>
</fieldset>
</div>
<div class="layui-row">
<fieldset class="layui-elem-field">
<legend>插入视频链接</legend>
<div class="layui-field-box">
<input class="layui-input" type="url" id="video_input" placeholder="填入视频文件链接支持文件后缀格式为mp4、m4v、ogg、ogv、webm" style="margin-bottom: 5px;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" onclick="insertMultimedia('video')"><i class="fa fa-video-camera"></i> 插入视频</button>
</div>
</fieldset>
</div>
<div class="layui-row">
<fieldset class="layui-elem-field">
<legend>插入视频网站链接</legend>
<div class="layui-field-box">
<input class="layui-input" type="url" id="video_iframe_input" placeholder="填入视频网站视频播放页链接支持YouTube、优酷、QQ视频、Facebook、哔哩哔哩、TED网站" style="margin-bottom: 5px;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" onclick="insertMultimedia('video_iframe')"><i class="fa fa-youtube-play"></i> 插入视频网站视频</button>
</div>
</fieldset>
</div>
</div>
<!-- 文档本地缓存div -->
<div class="layui-form" id="doc-cache-div" style="display: none;">
<div style="margin: 5px;">
<textarea name="desc" id="doc-cache-content" class="layui-textarea" style="height: 350px;" disabled></textarea>
</div>
</div>
<script src="{% static 'jquery/3.1.1/jquery.min.js' %}"></script>
<script src="{% static 'layui/layui.all.js' %}"></script>
<script>
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
var tree = layui.tree;
var layer = layui.layer;
var form = layui.form;
var element = layui.element;
var laypage = layui.laypage;
var md_changed = false; //初始化一个变量,用于判断编辑器是否修改
var screen_width = window.matchMedia('(max-width: 768px)'); // 获取屏幕宽度
var editor_mode = {{ editor_mode }};
</script>
<!-- 标签输入 -->
<script src="{% static '/tagsInput/tagsinput.js' %}" type="text/javascript" charset="utf-8"></script>
<!-- 加载编辑器 -->
{% if editor_mode == 1 %}
<!-- Editor.MD编辑器 -->
<script src="{% static 'mindmap/d3@5.js' %}"></script>
<script src="{% static 'mindmap/transform.min.js' %}"></script>
<script src="{% static 'mindmap/view.min.js' %}"></script>
<script src="{% static 'editor.md/editormd.js' %}?version={{mrdoc_version}}"></script>
{% include 'app_doc/editor/tpl_editor_editormd.html' %}
{% elif editor_mode == 2 %}
<!-- Vditor编辑器 -->
<script src="{% static 'vditor/dist/index.min.js' %}?version={{mrdoc_version}}"></script>
{% include 'app_doc/editor/tpl_editor_vditor.html' %}
{% elif editor_mode == 3 %}
<!-- iceEditor富文本编辑器 -->
<script src="{% static 'iceEditor/src/iceEditor.min.js' %}?version={{mrdoc_version}}"></script>
{% include 'app_doc/editor/tpl_editor_ice.html' %}
{% endif %}
<script>
//未保存离开提示
window.onbeforeunload =function() {
   if(md_changed){
return 1;
}else{
return null;
}
};
</script>
<script src="{% static 'mrdoc/mrdoc.editor.js' %}?version={{mrdoc_version}}"></script>
<script src="{% static 'mrdoc/mrdoc.js' %}?version={{mrdoc_version}}"></script>
{% block custom_script %}
{% endblock %}
</body>
</html>

View File

@ -1,552 +0,0 @@
{% load static %}
{% load i18n %}
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edgechrome=1">
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{% block title %}{% endblock %} - {% if site_name != None and site_name != '' %}{{site_name}} {% else %}站点标题{% endif %}</title>
<link href="{% static 'layui/css/layui.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link rel="stylesheet" href="{% static 'editor.md/css/font-awesome.min.css' %}?version={{mrdoc_version}}" />
<link rel="stylesheet" href="{% static 'vditor/dist/index.css' %}?version={{mrdoc_version}}" />
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
<link href="{% static 'mrdoc/mrdoc.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link href="{% static 'mrdoc/mrdoc-editor.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link href="{% static 'tagsInput/tagsinput.css' %}" rel="stylesheet" type="text/css"/>
<style>
</style>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="doc layui-fluid" style="padding-left:0px;">
<!-- 左侧工具栏 -->
<div class="doc-summary">
{% include 'app_doc/editor/tpl_left_top.html' %}
{% block left_opera %}
{% endblock %}
</div>
<!-- 左侧工具栏结束 -->
<!-- 右侧编辑器栏 -->
<div class="doc-body">
<!-- 文档导航 -->
<div class="doc-header" role="navigation">
<a class="btn pull-left js-toolbar-action" aria-label="" href="javascript:void(0);" title="切换侧边栏">
<i class="fa fa-align-justify"></i>
</a>
<!-- 顶部工具栏 -->
{% block head_toolbar %}
{% endblock %}
<a class="btn pull-right" aria-label="" href="{% url 'pro_list' %}">
<i class="fa fa-home"></i> <span class="layui-hide-xs">首页</span>
</a>
</div>
<!-- 文档主体 -->
<div class="doc-body-content" style="padding-left: 15px;">
<div class="mrdoc-body-content-div">
<!-- 文档内容 -->
<div class="mrdoc-editor-content">
<!-- 正文开始 -->
<div class="markdown-body" id="content">
{% block content %}
{% endblock %}
</div>
<!-- 正文结束 -->
</div>
</div>
</div>
</div>
<!-- 右侧编辑器结束 -->
</div>
<script src="{% static 'jquery/3.1.1/jquery.min.js' %}"></script>
<script src="{% static 'layui/layui.all.js' %}"></script>
<script src="{% static 'vditor/dist/index.min.js' %}?version={{mrdoc_version}}"></script>
<script src="{% static 'mrdoc/mrdoc.editor.js' %}"></script>
<script src="{% static 'mrdoc/mrdoc.js' %}?version={{mrdoc_version}}"></script>
<!-- 标签输入 -->
<script src="{% static '/tagsInput/tagsinput.js' %}" type="text/javascript" charset="utf-8"></script>
<script>
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
var tree = layui.tree;
//加载页面时执行一次
changeSidebar();
//监听浏览器宽度的改变
window.onresize = function(){
changeSidebar();
};
function changeSidebar(){
// 获取匹配指定的媒体查询
var screen_width = window.matchMedia('(max-width: 768px)');
//判断匹配状态
if(screen_width.matches){
//如果匹配到,切换侧边栏
//console.log('小屏幕')
$("body").addClass("big-page");
}else{
$("body").removeClass("big-page");
}
}
</script>
<!-- 切换隐藏侧边栏 -->
<script>
// 切换侧边栏
$(function(){
$(".js-toolbar-action").click(toggleSidebar);
});
//切换侧边栏显示隐藏
function toggleSidebar(){
console.log("切换侧边栏")
$("body").toggleClass("big-page");
return false;
}
</script>
<!-- 展开收起左边目录 -->
<script>
$(function(){
$(".switch-toc").click(SwitchToc);
});
function SwitchToc(i){
var $me = $(this);
$(this).parent().next("ul").toggleClass("toc-close"); //切换展开收起样式
$(this).toggleClass("fa-chevron-left fa-chevron-down");//切换图标
};
</script>
<script>
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
var layer = layui.layer;
var form = layui.form;
var element = layui.element;
var laypage = layui.laypage;
var md_changed = false; //初始化一个变量,用于判断编辑器是否修改
//初始化vditor
layer.load(1)
var editor = new Vditor('editor-md',{
"cdn":"{% static 'vditor' %}",
"toolbar": [
"emoji","headings","bold","italic","strike","link","|",
"list","ordered-list","check","outdent","indent","|",
"quote","line","code","inline-code","insert-before","insert-after","|",
// "upload",
{
name: 'insert-img',
tipPosition: 's',
tip: '图片',
className: 'right',
tipPosition:'nw',
icon:'<svg t="1599747832593" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4027" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><defs><style type="text/css"></style></defs><path d="M864.05 128.46H129.97c-17.68 0-32 14.33-32 32v639.61c0 17.67 14.32 32 32 32h734.08c17.68 0 32-14.33 32-32V160.46c0-17.67-14.32-32-32-32z m-32 639.61H161.97V192.46h670.08v575.61z" p-id="4028"></path><path d="M795.58 691.57a32.007 32.007 0 0 1-27.33 15.34H225.77c-12.01 0-23-6.72-28.48-17.4a31.988 31.988 0 0 1 2.5-33.28l125.3-174.17c10.17-14.13 29.78-17.54 44.12-7.67l101.77 70.03 129.73-165.51a31.995 31.995 0 0 1 28.21-12.11 31.99 31.99 0 0 1 25.42 17.2L796.7 660.26a32.018 32.018 0 0 1-1.12 31.31z" p-id="4029"></path><path d="M320.03 321.34a64.03 64.83 0 1 0 128.06 0 64.03 64.83 0 1 0-128.06 0Z" p-id="4030"></path></svg>',
click () {
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加图片',
area:['800px','600px'],
id:'uploadImg',//配置ID,
content:$('#upload-img'),
})
},
},
// "record",
{
name: 'insert-attachment',
tipPosition: 's',
tip: '附件',
className: 'right',
tipPosition:'nw',
icon:'<svg t="1599964518089" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4929" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><defs><style type="text/css"></style></defs><path d="M633.553 251.102c15.993-12.795 38.385-12.795 55.978 1.6 15.993 15.993 15.993 38.384 0 54.378L347.264 647.747c-22.39 20.792-22.39 57.577 0 81.568 20.792 22.391 57.578 22.391 81.568 0l401.444-403.042c55.978-55.979 55.978-148.742 0-204.72s-148.742-55.979-204.72 0l-47.982 47.98-12.795 12.796-369.455 369.455c-91.165 91.165-91.165 236.708 0 327.872 91.164 91.165 236.707 91.165 327.872 0L894.25 511.8c6.397-3.199 9.596-7.997 12.795-12.795 15.993-15.994 38.385-15.994 54.378 0s15.994 38.385 0 54.379l-3.198 3.199c-3.2 1.599-6.398 6.397-9.597 9.596L577.574 934.035c-119.953 119.953-316.676 119.953-436.63 0s-119.952-316.676 0-436.63l430.233-431.83c86.366-86.367 227.111-86.367 315.077 0 86.366 86.366 86.366 227.11 0 315.076L483.21 783.694c-52.78 52.78-139.145 52.78-190.325 0-52.78-52.78-52.78-139.146 0-190.326l340.667-342.266z m0 0" fill="#333333" p-id="4930"></path></svg>',
click () {
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加附件',
area:['800px','600px'],
id:'uploadAttach',//配置ID,
content:$('#upload-attach'),
success: function(layero, index){
layer.load(1);
$.post('{% url "manage_attachment" %}',{types:2},function(r){
$("#attach_table tbody").empty()
if(r.status){
//调用分页显示
laypage.render({
elem: 'select-attach-page',//分页的div
count: r.data.length, //数据总数
limit:10, //单页数
jump: function(obj){
//渲染HTML
$("#attach_table tbody").empty();
var thisData = r.data.concat().splice(obj.curr*obj.limit - obj.limit, obj.limit);
layui.each(thisData, function(k, v){
var row = "<tr><td>" + v.filename + "</td><td>"+ v.filesize +"</td><td>"+ v.filetime +"</td><td><button class='layui-btn layui-btn-normal layui-btn-sm' data-name='"+ v.filename +"' data-path='"+ v.filepath +"' onclick='insertAttach(this)'>选择</button></td></tr>"
// arr.push(row);
$("#attach_table tbody").append(row)
});
}
});
layer.closeAll("loading");//关闭加载提示
}else{
layer.closeAll("loading");//关闭加载提示
layer.msg("获取附件失败,请稍后重试!")
}
})
}
})
},
},
"table","|","undo","redo","|","fullscreen","edit-mode",
{
name: "more",
toolbar: [
"both",
"code-theme",
"content-theme",
"export",
"outline",
"preview",
"devtools",
"info",
"help",
],
}],
"height":800,
"width":'100%',
"mode":"sv",
"placeholder":"道友,开始吧……",
"counter":{
enable:true, // 启用计数
},
"cache": {
"enable": false, // 禁用缓存
},
"preview": {
"markdown": {
"autoSpace": true,// 自动空格
"chinesePunct": true,// 矫正标点
"mark": true,//Mark标记
},
"hljs":{
"lineNumber":true,//代码行号
}
},
"after":function(){
layer.closeAll('loading');
},
"input":function(){
autoCacheDoc();
},
"upload":{
// fieldName:"editormd-image-file[]",
url:"{% url 'upload_doc_img' %}",
linkToImgUrl:"{% url 'upload_doc_img' %}",
linkToImgCallback(responseText){
// console.log(responseText)
},
handler(files){//自定义粘贴上传图片
console.log(files)
var reader = new FileReader();
reader.onload = function (event) {
var base64 = event.target.result;
//ajax上传图片
layer.load(1);
$.post("{% url 'upload_doc_img' %}",{base:base64}, function (ret) {
layer.msg(ret.message);
if (ret.success === 1) {
//新一行的图片显示
layer.closeAll("loading");
editor.insertValue("\n![](" + ret.url + ")");
editor.focus()
}else{
layer.closeAll("loading");
layer.msg("粘贴图片失败!")
}
});
}; // data url!
var url = reader.readAsDataURL(files[0]);
}
}
});
//未保存离开提示
window.onbeforeunload =function() {
   if(md_changed){
return 1;
}else{
return null;
}
};
//监听图片Tab选项卡切换
element.on('tab(img-tab)', function(data){
//console.log(this); //当前Tab标题所在的原始DOM元素
//console.log(data.index); //得到当前Tab的所在下标
//console.log(data.elem); //得到当前的Tab大容器
if(data.index == 1){
layer.load(1);
console.log('选择图片')
$("#select-img-group").empty(); //删除已有分组按钮
//请求新的分组数据
$.post("{% url 'manage_img_group' %}",{'types':3},function(r){
if(r.status){
group_btn_str = ''
for(var i in r.data){
group_btn_str += '<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="switchImgGroup(' + r.data[i].group_id +')">' + r.data[i].group_name + '(' + r.data[i].group_cnt + ')</button>'
};
$("#select-img-group").append(group_btn_str)
}
});
//请求全部图片数据
$.post("{% url 'manage_image' %}",{'types':2,'group_id':0},function(r){
if(r.status){
//调用分页显示
laypage.render({
elem: 'select-img-page',//分页的div
count: r.data.length, //数据总数
limit:15, //单页数
jump: function(obj){
//渲染HTML
document.getElementById('select-img').innerHTML = function(){
var arr = []
var thisData = r.data.concat().splice(obj.curr*obj.limit - obj.limit, obj.limit);
layui.each(thisData, function(index, item){
arr.push('<li class="select-img-list"><img class="select-img-list-i" onclick="insertImg(this);" src="' + item.path + '" title="' + item.name + '"data-url="' + item.path +'" /></li>');
});
return arr.join('');
}();
}
});
layer.closeAll("loading");
}else{
layer.closeAll("loading");
layer.msg("获取图片失败")
}
})
}
});
// 插入选择的图片到编辑器
insertImg = function(e){
// console.log(e);
editor.insertValue("\n![](" + e.getAttribute('data-url') + ")");
editor.focus()
};
// 按钮点击插入输入框图片链接
insertImgUrl = function(){
editor.insertValue("\n![](" + $("#img_url_input").val() + ")");
$("#img_url_input").val("")
layer.closeAll();
editor.focus()
};
// 切换图片分组
switchImgGroup = function(e){
layer.load(1);
$.post("{% url 'manage_image' %}", {
'types': 2,
'group_id': e
},
function(r) {
if (r.status) {
//调用分页显示
laypage.render({
elem: 'select-img-page',//分页的div
count: r.data.length,//数据总数
limit: 15,//单页数
jump: function(obj) {
//渲染HTML
document.getElementById('select-img').innerHTML = function() {
var arr = []
var thisData = r.data.concat().splice(obj.curr * obj.limit - obj.limit, obj.limit);
layui.each(thisData,
function(index, item) {
arr.push('<li class="select-img-list"><img class="select-img-list-i" onclick="insertImg(this);" src="' + item.path + '" title="' + item.name + '" /></li>');
});
return arr.join('');
} ();
}
});
layer.closeAll("loading"); //关闭加载提示
} else {
layer.closeAll("loading");
layer.msg("获取分组图片失败")
}
})
};
// 插入选择的附件到编辑器
insertAttach = function(e){
editor.insertValue("\n[【附件】"+ $(e).data('name') + "](/media/" + $(e).data('path') + ")");
layer.closeAll();
}
// 插入音视频到编辑器
insertMultimedia = function(e){
if(e === 'audio'){
editor.insertValue("\n![=audio](" + $("#audio_input").val() + ")");
}else if(e === 'video'){
editor.insertValue("\n![=video](" + $("#video_input").val() + ")");
}else if(e === 'video_iframe'){
editor.insertValue("\n![=video_iframe](" + $("#video_iframe_input").val() + ")");
}
$("#audio_input").val('')
$("#video_input").val('')
$("#video_iframe_input").val('')
layer.closeAll();
editor.focus()
}
</script>
{% block custom_script %}
{% endblock %}
</body>
{% block custom_div %}
{% endblock %}
{% include 'app_doc/editor/tpl_editor_div.html' %}
<script>
//按钮选择上传图片
var upload = layui.upload;
upload.render({
elem: '#upload_img',
url: '{% url "upload_doc_img" %}',
before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(1); //上传loading
},
done: function(res, index, upload){ //上传后的回调
//上传成功
if(res.success == 1){
editor.insertValue("\n![](" + res.url + ")");
layer.closeAll();
layer.msg("上传成功");
}else{
layer.closeAll();
layer.msg(res.message)
}
},
error:function(){
layer.closeAll('loading'); //关闭loading
layer.msg("系统异常,请稍后再试!")
},
accept: 'images', //允许上传的文件类型
acceptMime:'image/*',
field:'manage_upload',
});
// 按钮选择上传附件
var upload_attach = layui.upload;
upload_attach.render({
elem: '#upload_attachment',
url: '{% url "manage_attachment" %}',
data:{types:0,csrfmiddlewaretoken: '{{ csrf_token }}'},
before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(1); //上传loading
},
done: function(res, index, upload){ //上传后的回调
//上传成功,刷新页面
if(res.status){
editor.insertValue("\n[【附件】"+ res.data.name + "](/media/" + res.data.url + ")");
layer.closeAll();
layer.msg("上传成功");
}else{
layer.closeAll('loading');
layer.msg("上传出错,请重试!")
}
},
error:function(){
layer.closeAll('loading'); //关闭loading
layer.msg("系统异常,请稍后再试!")
},
accept: 'file', //允许上传的文件类型
field:'attachment_upload',
})
// 粘贴表格文本框侦听paste粘贴事件
// 列宽的函数
function columnWidth(rows, columnIndex) {
return Math.max.apply(null, rows.map(function(row) {
return row[columnIndex].length
}))
};
// 检查是否是个表格
function looksLikeTable(data) {
return true
};
// 编辑器侦听paste粘贴事件
var pasteExcel = document.getElementById('pasteExcel')
pasteExcel.addEventListener("paste", function(event) {
console.log('粘贴Excel')
var clipboard = event.clipboardData
var data = clipboard.getData('text/plain')
data = data.replace(/(?:[\n\u0085\u2028\u2029]|\r\n?)$/, '');
if(looksLikeTable(data)) {
event.preventDefault()
}else{
return
}
// 行
var rows = data.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(function(row) {
console.log(row)
return row.split("\t")
})
// 列对齐
var colAlignments = []
// 列宽
var columnWidths = rows[0].map(function(column, columnIndex) {
var alignment = "l"
var re = /^(\^[lcr])/i
var m = column.match(re)
if (m) {
var align = m[1][1].toLowerCase()
if (align === "c") {
alignment = "c"
} else if (align === "r") {
alignment = "r"
}
}
colAlignments.push(alignment)
column = column.replace(re, "")
rows[0][columnIndex] = column
return columnWidth(rows, columnIndex)
})
var markdownRows = rows.map(function(row, rowIndex) {
return "| " + row.map(function(column, index) {
return column + Array(columnWidths[index] - column.length + 1).join(" ")
}).join(" | ") + " |"
row.map
})
markdownRows.splice(1, 0, "|" + columnWidths.map(function(width, index) {
var prefix = ""
var postfix = ""
var adjust = 0
var alignment = colAlignments[index]
if (alignment === "r") {
postfix = ":"
adjust = 1
} else if (alignment == "c") {
prefix = ":"
postfix = ":"
adjust = 2
}
return prefix + Array(columnWidths[index] + 3 - adjust).join("-") + postfix
}).join("|") + "|")
event.target.value = markdownRows.join("\n")
return false
});
</script>
</html>

View File

@ -1,40 +1,143 @@
{% extends 'app_doc/editor/create_base_2.html' %}
{% extends 'app_doc/editor/create_base.html' %}
{% load static %}
{% load i18n %}
{% block title %}新建文档 - Editormd编辑模式{% endblock %}
{% block title %}新建文档{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
<div class="layui-form" style="padding: 0 10px 10px 10px;">
<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="导入模板内容">
<i class="fa fa-clipboard"></i>
</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="导入本地文本文件内容">
<i class="fa fa-upload"></i>
</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" style="padding: 0 10px 10px 10px;">
<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-col-md12" style="margin-bottom: 10px;">
<div class="layui-input-inblock">
<select name="pro_id" lay-verify="required" lay-filter="project" id="project">
<option value="">请选择一个文集(必选)</option>
<option value="-1">新建文集</option>
<!-- 自己的文集 -->
<optgroup label="自有文集" id="self-project">
{% for p in project_list %}
{% if p.role == 1 %}
<option value="{{ p.id }}">[私密]《{{ p.name }}》</option>
{% elif p.role == 2 %}
<option value="{{ p.id }}" >[指定用户]《{{ p.name }}》</option>
{% elif p.role == 3 %}
<option value="{{ p.id }}" >[访问码]《{{ p.name }}》</option>
{% else %}
<option value="{{ p.id }}" >[公开]《{{ p.name }}》</option>
{% endif %}
{% endfor %}
</optgroup>
<!-- 协作的文集 -->
{% if colla_project_list.count > 0 %}
<optgroup label="协作文集">
{% for p in colla_project_list %}
<option value="{{ p.project.id }}">[协作]《{{ p.project.name }}》</option>
{% endfor %}
</optgroup>
{% endif %}
</select>
</div>
</div>
{% include 'app_doc/editor/tpl_left_create_custom.html' %}
<!-- 设置文档排序 -->
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<span>点击文档树选择上级(可选)或</span>
<button class="layui-btn layui-btn-xs layui-btn-primary" id="clearParentDoc">取消上级</button>
<input type="text" id="parent-doc" hidden>
</div>
<div class="layui-col-md12">
<input type="number" class="layui-input" placeholder="输入文档排序值默认99" id="sort">
</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" style="max-height: 400px;overflow: hidden;overflow-y: scroll;overflow-x: scroll;">
<div id="doc-tree"></div>
</div>
</div>
</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;">
<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>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block content %}
@ -49,8 +152,9 @@
</div>
</div>
<div id="editor-md" class="layui-col-xs12">
{% if editor_mode == 1 %}
<textarea style="display:none;"></textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
{% endif %}
</div>
{% endblock %}
@ -59,258 +163,244 @@
{% endblock %}
{% block custom_script %}
<script>
var tree = layui.tree;
//选择文集
form.on('select(project)', function(data){
console.log('选择文集:',data.value); //得到被选中的值
if(data.value == -1){ //新建文集
layer.open({
type:1,
title:'新建文集',
area:'300px;',
id:'createPro',//配置ID
content: $('#create-project-div'),
btn:['确定','取消'], //添加按钮
btnAlign:'c', //按钮居中
yes:function (index,layero) {
data = {
'pname':$("#pname").val(),
'desc':$("#desc").val(),
'role':$("#project-role").val(),
}
$.post("{% url 'create_project' %}",data,function(r){
if(r.status){
//创建成功更新文集select
$("#self-project").append("<option value="+r.data.id+">《"+r.data.name+"》</option>");
form.render();
layer.close(index)
}else{
//创建失败,提示
console.log(r)
<script>
var tree = layui.tree;
//选择文集
form.on('select(project)', function(data){
console.log('选择文集:',data.value); //得到被选中的值
if(data.value == -1){ //新建文集
layer.open({
type:1,
title:'新建文集',
area:'300px;',
id:'createPro',//配置ID
content: $('#create-project-div'),
btn:['确定','取消'], //添加按钮
btnAlign:'c', //按钮居中
yes:function (index,layero) {
data = {
'pname':$("#pname").val(),
'desc':$("#desc").val(),
'role':$("#project-role").val(),
}
})
},
});
}else{//获取文集的下级文档
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':data.value},function(r){
if(r.status){
var doc_tree = tree.render({
elem:"#doc-tree",
id:'docTree',
// showCheckbox:true,
onlyIconControl:true,
data:r.data,
text: {
defaultNodeName: '未命名' //节点默认名称
,none: '文集暂无文档' //数据为空时的提示文本
},
click: function(obj){
//console.log(obj.data); //得到当前点击的节点数据
// console.log(obj.state); //得到当前节点的展开状态open、close、normal
// console.log(obj.elem); //得到当前节点元素
if(obj.data.level != 3){
$('#parent-doc').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("你选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
$.post("{% url 'create_project' %}",data,function(r){
if(r.status){
//创建成功更新文集select
$("#self-project").append("<option value="+r.data.id+">《"+r.data.name+"》</option>");
form.render();
layer.close(index)
}else{
layer.msg("第三级文档不能作为上级文档")
//创建失败,提示
console.log(r)
}
})
},
});
}else{//获取文集的下级文档
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':data.value},function(r){
if(r.status){
var doc_tree = tree.render({
elem:"#doc-tree",
id:'docTree',
// showCheckbox:true,
onlyIconControl:true,
data:r.data,
text: {
defaultNodeName: '未命名' //节点默认名称
,none: '文集暂无文档' //数据为空时的提示文本
},
click: function(obj){
//console.log(obj.data); //得到当前点击的节点数据
// console.log(obj.state); //得到当前节点的展开状态open、close、normal
// console.log(obj.elem); //得到当前节点元素
if(obj.data.level != 3){
$('#parent-doc').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("你选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("第三级文档不能作为上级文档")
}
}
}
});
}else{
layer.msg("获取下级文档失败!")
}
});
}
});
//带pid参数自动选择文集
var sel_pro_list = $('dl.layui-anim dd');
for(var i = 0;i < sel_pro_list.length; i++){
if(sel_pro_list[i].getAttribute('lay-value') == '{{pid}}'){
var sel_pro = 'dd[lay-value=' + sel_pro_list[i].getAttribute('lay-value') + ']';
$('#project').siblings("div.layui-form-select").find('dl').find(sel_pro).click();
}
};
//发布文档
createDoc = function(status){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
var data = {
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'doc_tag':$("#tagsinputval").val(),
'content':editor.getHTML(),//获取editor解析的HTML
'pre_content':editor.getMarkdown(),
'sort':$("#sort").val(),
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
}
// console.log(data)
if(data.doc_name == ""){
layer.msg('请输入文档标题!');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
else if(data.project == ""){
layer.msg('请选择文集!');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
else{
//发布按钮设为禁用
$("#create_doc").attr({"disabled":"disabled"});
layer.load(); // 加载提示
$.post("{% url 'create_doc' %}",data,function(r){
if(r.status){
//创建成功
layer.closeAll("loading"); //关闭加载层
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
if(status === 1){
layer.msg('发布成功,即将跳转到文档页面',function(){
md_changed = false;
//跳转到发布的文档
window.location.href = "/project-" + r.data.pro + "/doc-" + r.data.doc
});
}else{
layer.msg('保存成功,即将跳转到文档编辑页面',function(){
md_changed = false;
//跳转到文档修改
window.location.href = "/modify_doc/"+r.data.doc+"/";
});
layer.msg("获取下级文档失败!")
}
});
}
});
//带pid参数自动选择文集
var sel_pro_list = $('dl.layui-anim dd');
for(var i = 0;i < sel_pro_list.length; i++){
if(sel_pro_list[i].getAttribute('lay-value') == '{{pid}}'){
var sel_pro = 'dd[lay-value=' + sel_pro_list[i].getAttribute('lay-value') + ']';
$('#project').siblings("div.layui-form-select").find('dl').find(sel_pro).click();
}
};
//发布文档
createDoc = function(status){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
if(editor_mode == 1){
var content = editor.getHTML()
var pre_content = editor.getMarkdown()
}else if(editor_mode == 2){
var content = editor.getHTML()
var pre_content = editor.getValue()
}else if(editor_mode == 3){
var content = editor.getHTML()
var pre_content = editor.getHTML()
}
var data = {
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'doc_tag':$("#tagsinputval").val(),
'content':content,
'pre_content':pre_content,
'sort':$("#sort").val(),
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
}
// console.log(data)
if(data.doc_name == ""){
layer.msg('请输入文档标题!');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
else if(data.project == ""){
layer.msg('请选择文集!');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
else{
//发布按钮设为禁用
$("#create_doc").attr({"disabled":"disabled"});
layer.load(); // 加载提示
$.post("{% url 'create_doc' %}",data,function(r){
if(r.status){
//创建成功
layer.closeAll("loading"); //关闭加载层
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
if(status === 1){
layer.msg('发布成功,即将跳转到文档页面',function(){
md_changed = false;
//跳转到发布的文档
window.location.href = "/project-" + r.data.pro + "/doc-" + r.data.doc
});
}else{
layer.msg('保存成功,即将跳转到文档编辑页面',function(){
md_changed = false;
//跳转到文档修改
window.location.href = "/modify_doc/"+r.data.doc+"/";
});
}
}else{
//创建失败
layer.closeAll("loading"); //关闭加载层
layer.msg('发布文档失败:'+r.data);
//恢复按钮状态
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
});
}
};
$("#pub_doc").click(function(){
createDoc(1);
})
$("#save_doc").click(function(){
createDoc(0);
})
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({
type: 1,
id:'temp-div',
content: $('#doctemp-list'),
//area:['530px','300px'],
area:['50%','50%'],
});
});
//清除所选上级文档
$("#clearParentDoc").click(function(){
$('#parent-doc').val("");
$("span.layui-tree-txt").each(function(i){
var $me = $(this)
$me.removeClass('selected-parent-doc')
});
layer.msg("你取消了当前文档的上级文档")
});
//插入模板
insertTemp = function(doctemp_id){
$.post("{% url 'get_doctemp' %}",{'doctemp_id':doctemp_id},function(r){
if(r.status){
if(editor_mode == 1){
editor.insertValue(r.data);
}else if(editor_mode == 2){
editor.setValue(r.data);
}
layer.closeAll()
}else{
//创建失败
layer.closeAll("loading"); //关闭加载层
layer.msg('发布文档失败:'+r.data);
//恢复按钮状态
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
layer.msg(r.data)
}
});
}
};
$("#pub_doc").click(function(){
createDoc(1);
})
$("#save_doc").click(function(){
createDoc(0);
})
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({
type: 1,
id:'temp-div',
content: $('#doctemp-list'),
//area:['530px','300px'],
area:['50%','50%'],
});
});
//清除所选上级文档
$("#clearParentDoc").click(function(){
$('#parent-doc').val("");
$("span.layui-tree-txt").each(function(i){
var $me = $(this)
$me.removeClass('selected-parent-doc')
});
layer.msg("你取消了当前文档的上级文档")
});
//插入模板
insertTemp = function(doctemp_id){
$.post("{% url 'get_doctemp' %}",{'doctemp_id':doctemp_id},function(r){
if(r.status){
editor.insertValue(r.data);
layer.closeAll()
}else{
layer.msg(r.data)
}
});
};
//插入本地文本文件
function insertLocalFile(input) {
var file = input.files[0];
//filename = file.name.split(".")[0]; // 文件名
//支持chrome IE10
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function() {
console.log(this.result);
editor.insertValue(this.result);
}
reader.readAsText(file);
}
//支持IE 7 8 9 10
else if (typeof window.ActiveXObject != 'undefined'){
var xmlDoc;
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
}
//支持FF
else if (document.implementation && document.implementation.createDocument) {
var xmlDoc;
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
} else {
alert('error');
}
};
//选择本地文本文件
function selectLocalFile(){
$("#insert-local-file").trigger("click");
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
};
//插入本地文本文件
function insertLocalFile(input) {
var file = input.files[0];
//filename = file.name.split(".")[0]; // 文件名
//支持chrome IE10
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function() {
console.log(this.result);
if(editor_mode == 1){
editor.insertValue(this.result);
}else if(editor_mode == 2){
editor.setValue(this.result)
}else if(editor_mode == 3){
editor.addValue(this.result)
}
}
})
}else{
layer.msg("暂无本地缓存")
}
})
</script>
reader.readAsText(file);
}
//支持IE 7 8 9 10
else if (typeof window.ActiveXObject != 'undefined'){
var xmlDoc;
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
}
//支持FF
else if (document.implementation && document.implementation.createDocument) {
var xmlDoc;
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
} else {
alert('error');
}
};
//选择本地文本文件
function selectLocalFile(){
$("#insert-local-file").trigger("click");
};
</script>
{% endblock %}

View File

@ -1,320 +0,0 @@
{% extends 'app_doc/editor/create_base_vditor.html' %}
{% load static %}
{% load i18n %}
{% block title %}新建文档 - Vditor编辑模式{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
<div class="layui-form" style="padding: 0 10px 10px 10px;">
<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="插入模板内容">
<i class="fa fa-clipboard"></i> 导入模板
</button>
<button class="layui-btn layui-btn-primary layui-btn-sm mrdoc-btn-default" id="doc-cache-btn" 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="插入本地文本文件内容">
<i class="fa fa-upload"></i> 导入文本
</button> -->
</div>
<!-- 选择文集 -->
{% include 'app_doc/editor/tpl_left_create_custom.html' %}
</div>
</div>
{% endblock %}
{% block content %}
<div class="create-doc-form">
<div class="layui-form">
<!-- 标题 -->
<div style="padding-bottom:10px;">
<div class="layui-input-block" style="margin-left:0px;">
<input type="text" name="doc-name" id="doc-name" required lay-verify="required" placeholder="请输入文档标题……" autocomplete="off" class="layui-input">
</div>
</div>
</div>
</div>
<div id="editor-md" class="layui-col-xs12">
<textarea style="display:none;"></textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
</div>
{% endblock %}
{% block custom_div %}
{% include 'app_doc/editor/tpl_editor_div_doc.html' %}
{% endblock %}
{% block custom_script %}
<script>
var tree = layui.tree;
//选择文集
form.on('select(project)', function(data){
console.log('选择文集:',data.value); //得到被选中的值
if(data.value == -1){ //新建文集
layer.open({
type:1,
title:'新建文集',
area:'300px;',
id:'createPro',//配置ID
content: $('#create-project-div'),
btn:['确定','取消'], //添加按钮
btnAlign:'c', //按钮居中
yes:function (index,layero) {
data = {
'pname':$("#pname").val(),
'desc':$("#desc").val(),
'role':$("#project-role").val(),
}
$.post("{% url 'create_project' %}",data,function(r){
if(r.status){
//创建成功更新文集select
$("#self-project").append("<option value="+r.data.id+">《"+r.data.name+"》</option>");
form.render();
layer.close(index)
}else{
//创建失败,提示
console.log(r)
}
})
},
});
}else{//获取文集的下级文档
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':data.value},function(r){
if(r.status){
var doc_tree = tree.render({
elem:"#doc-tree",
id:'docTree',
// showCheckbox:true,
onlyIconControl:true,
data:r.data,
text: {
defaultNodeName: '未命名' //节点默认名称
,none: '文集暂无文档' //数据为空时的提示文本
},
click: function(obj){
//console.log(obj.data); //得到当前点击的节点数据
// console.log(obj.state); //得到当前节点的展开状态open、close、normal
// console.log(obj.elem); //得到当前节点元素
if(obj.data.level != 3){
$('#parent-doc').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("你选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("第三级文档不能作为上级文档")
}
}
});
}else{
layer.msg("获取下级文档失败!")
}
});
}
});
//带pid参数自动选择文集
var sel_pro_list = $('dl.layui-anim dd');
for(var i = 0;i < sel_pro_list.length; i++){
if(sel_pro_list[i].getAttribute('lay-value') == '{{pid}}'){
var sel_pro = 'dd[lay-value=' + sel_pro_list[i].getAttribute('lay-value') + ']';
$('#project').siblings("div.layui-form-select").find('dl').find(sel_pro).click();
}
};
//新建文档 - 发布和保存
createDoc = function(status){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
var data = {
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'doc_tag':$("#tagsinputval").val(),
'content':editor.getHTML(),//获取editor解析的HTML
'pre_content':editor.getValue(),
'sort':$("#sort").val(),
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
}
console.log(data)
if(data.doc_name == ""){
layer.msg('请输入文档标题!');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
else if(data.project == ""){
layer.msg('请选择文集!');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
else{
//发布按钮设为禁用
$("#create_doc").attr({"disabled":"disabled"});
layer.load(); // 加载提示
$.post("{% url 'create_doc' %}",data,function(r){
if(r.status){
//创建成功
layer.closeAll("loading"); //关闭加载层
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
if(status === 1){
layer.msg('发布成功,即将跳转到文档页面',function(){
md_changed = false;
//跳转到发布的文档
window.location.href = "/project-" + r.data.pro + "/doc-" + r.data.doc
});
}else{
layer.msg('保存成功,即将跳转到文档编辑页面',function(){
md_changed = false;
//跳转到文档修改
window.location.href = "/modify_doc/"+r.data.doc+"/";
});
}
}else{
//创建失败
layer.closeAll("loading"); //关闭加载层
layer.msg('发布文档失败:'+r.data);
//恢复按钮状态
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
});
}
};
$("#pub_doc").click(function(){
createDoc(1);
})
$("#save_doc").click(function(){
createDoc(0);
})
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({
type: 1,
id:'temp-div',
content: $('#doctemp-list'),
area:['50%','50%'],
});
});
//清除所选上级文档
$("#clearParentDoc").click(function(){
$('#parent-doc').val("");
$("span.layui-tree-txt").each(function(i){
var $me = $(this)
$me.removeClass('selected-parent-doc')
});
layer.msg("你取消了当前文档的上级文档")
});
//插入模板
insertTemp = function(doctemp_id){
$.post("{% url 'get_doctemp' %}",{'doctemp_id':doctemp_id},function(r){
if(r.status){
console.log(r.data)
// editor.insertValue(r.data);
editor.setValue(r.data);
layer.closeAll()
}else{
layer.msg(r.data)
}
});
};
//插入本地文本文件
function insertLocalFile(input) {
var file = input.files[0];
//filename = file.name.split(".")[0]; // 文件名
//支持chrome IE10
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function() {
console.log(this.result);
editor.insertValue(this.result);
}
reader.readAsText(file);
}
//支持IE 7 8 9 10
else if (typeof window.ActiveXObject != 'undefined'){
var xmlDoc;
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
// xmlDoc.load(input.value);
// console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
}
//支持FF
else if (document.implementation && document.implementation.createDocument) {
var xmlDoc;
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
} else {
alert('error');
}
};
//选择本地文本文件
function selectLocalFile(){
$("#insert-local-file").trigger("click");
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
</script>
{% endblock %}

View File

@ -1,22 +1,50 @@
{% extends 'app_doc/editor/create_base_2.html' %}
{% extends 'app_doc/editor/create_base.html' %}
{% load static %}
{% load i18n %}
{% block title %}新建文档模板{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
{% include 'app_doc/editor/tpl_left_create_doctemp_custom.html' %}
<div class="layui-form" style="padding: 10px;">
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-fluid" onclick="createDocTemp()">
<i class="fa fa-save"></i> 保存模板
</button>
</label>
</div>
</div>
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-primary layui-btn-fluid" id="doc-cache-btn">
<i class="fa fa-save"></i> 本地缓存
</button>
</label>
</div>
<!-- 已有模板 -->
<div class="layui-row">
<div class="layui-card">
<div class="layui-card-header">现有模板</div>
<div class="layui-card-body">
{% for temp in doctemps %}
<li><a href="{% url 'modify_doctemp' temp.id %}" target="_blank" title="点击查看修改《{{temp.name}}》的内容"><i class="fa fa-file"></i> {{temp.name}}</a></li>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}
@ -30,7 +58,6 @@
</div>
<div id="editor-md">
<textarea style="display:none;"></textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
</div>
{% endblock %}
@ -40,10 +67,15 @@
createDocTemp = function(){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
layer.load();
layer.load(1);
if(editor_mode == 1){
var content = editor.getMarkdown()
}else if(editor_mode == 2){
var content = editor.getValue()
}
var data = {
'name':$("#doctemp-name").val(),
'content':editor.getMarkdown(),
'content':content,
}
$.post("{% url 'create_doctemp' %}",data,function(r){
if(r.status){
@ -52,7 +84,7 @@
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
layer.msg('保存成功',function(){
md_changed = false;
window.location.href = "{% url 'manage_doctemp' %}";
window.location.href = '/modify_doctemp/' + r.data + '/';
});
}else{
//创建失败
@ -63,41 +95,5 @@
}
});
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
</script>
{% endblock %}

View File

@ -1,103 +0,0 @@
{% extends 'app_doc/editor/create_base_vditor.html' %}
{% load static %}
{% load i18n %}
{% block title %}新建文档模板{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
{% include 'app_doc/editor/tpl_left_create_doctemp_custom.html' %}
{% endblock %}
{% block content %}
<div class="create-doc-form">
<div class="layui-form" style="padding-bottom:10px;">
<div class="layui-input-block" style="margin-left:0px;">
<input type="text" name="doc-name" id="doctemp-name" required lay-verify="required" placeholder="请输入模板标题" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div id="editor-md">
<textarea style="display:none;"></textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
</div>
{% endblock %}
{% block custom_script %}
<script>
//保存文档模板
createDocTemp = function(){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
layer.load();
var data = {
'name':$("#doctemp-name").val(),
'content':editor.getValue(),
}
$.post("{% url 'create_doctemp' %}",data,function(r){
if(r.status){
//创建成功
layer.closeAll("loading");
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
layer.msg('保存成功',function(){
md_changed = false;
window.location.href = "{% url 'manage_doctemp' %}";
});
}else{
//创建失败
layer.closeAll("loading");
layer.msg('保存失败');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
});
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
</script>
{% endblock %}

View File

@ -1,10 +1,10 @@
{% extends 'app_doc/editor/create_base_2.html' %}
{% extends 'app_doc/editor/create_base.html' %}
{% load static %}
{% load i18n %}
{% block title %}修改文档{% endblock %}
{% block custom_style %}
<style>
<style>
ul li{
list-style:disc;
}
@ -18,61 +18,147 @@
{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
<div class="layui-form" style="padding:0 10px 10px 10px;">
<div class="layui-row">
<div class="doc-form-label" style="margin-bottom: 10px;">
{% if doc.status == 0 %}
<strong>*当前文档状态:草稿</strong>
{% elif doc.status == 1 %}
<strong>*当前文档状态:已发布 </strong>
{% endif %}
</div>
<div class="layui-form" style="padding:0 10px 10px 10px;">
<div class="layui-row">
<div class="doc-form-label" style="margin-bottom: 10px;">
{% if doc.status == 0 %}
<strong>*当前文档状态:草稿</strong>
{% elif doc.status == 1 %}
<strong>*当前文档状态:已发布 </strong>
{% 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-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> 选择模板
<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>
</label>
<label class="doc-form-label" style="margin-right:0px;">
<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 class="layui-btn layui-btn-xs layui-btn-normal" id="doc-cache-btn">
<i class="fa fa-history"></i> 缓存
</button>
</label>
</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;">
<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>
<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">
<option value="{{ project.id }}">{{ project.name }}</option>
</select>
</div>
</div>
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<span>点击文档树选择上级(可选)或</span>
<button class="layui-btn layui-btn-xs layui-btn-primary" id="clearParentDoc">取消上级</button>
<input type="text" id="parent-doc" hidden>
</div>
<div class="layui-col-md12">
<input type="number" class="layui-input" placeholder="输入文档排序值默认99" id="sort" value="{{doc.sort}}">
</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" style="max-height: 400px;overflow: hidden;overflow-y: scroll;overflow-x: scroll;">
<div id="doc-tree"></div>
</div>
</div>
</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;">
<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> 保存为草稿
</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> 发布文档
</button>
</div>
<div class="layui-row" style="margin-top: 5px;">
<button class="layui-btn layui-btn-warm layui-btn-fluid" onclick="moveDoc()" title="复制或移动此文档到其他文集"><i class="fa fa-copy"></i> 复制/移动文档</button>
</div>
<div class="layui-row" style="margin-top: 5px;">
<button class="layui-btn layui-btn-danger layui-btn-fluid" onclick="delDoc()" title="删除此文档"><i class="fa fa-trash"></i> 删除文档</button>
</div>
</div>
</div>
</div>
</div>
</div>
{% include 'app_doc/editor/tpl_left_modify_custom.html' %}
</div>
</div>
{% endblock %}
{% block content %}
@ -86,8 +172,13 @@
</div>
</div>
<div id="editor-md">
{% if editor_mode == 1 %}
<textarea style="display:none;">{{ doc.pre_content }}</textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
{% elif editor_mode == 3 %}
{{ doc.pre_content | safe }}
{% else %}
{{ doc.pre_content }}
{% endif %}
</div>
{% endblock %}
@ -96,343 +187,318 @@
{% endblock %}
{% block custom_script %}
<script>
//获取文档数和上级文档信息
$(function(){
layer.load(1);
var doc_parent_id = '{{ doc.parent_doc }}';
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':$("#project").val()},function(r){
if(r.status){
<script>
//获取文档数和上级文档信息
$(function(){
layer.load(1);
var doc_parent_id = '{{ doc.parent_doc }}';
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':$("#project").val()},function(r){
if(r.status){
layer.closeAll("loading");
var doc_tree = tree.render({
elem:"#doc-tree",
id:'docTree',
onlyIconControl:true,
data:r.data,
click: function(obj){
if(obj.data.level != 3){
console.log(obj.data.id,doc_parent_id)
if(obj.data.id != '{{ doc.id }}' ){
$('#parent-doc').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("你选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("不可选择自己作为上级")
};
}else{
layer.msg("第三级文档不能作为上级文档")
};
}
});
$('#parent-doc').val(doc_parent_id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == doc_parent_id){
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("获取下级文档失败!")
}
});
});
// 修改文档
modifyDoc = function(status){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
layer.load(1);
if(editor_mode == 1){
var content = editor.getHTML()
var pre_content = editor.getMarkdown()
}else if(editor_mode == 2){
var content = editor.getHTML()
var pre_content = editor.getValue()
}else if(editor_mode == 3){
var content = editor.getHTML()
var pre_content = editor.getHTML()
}
var data = {
'doc_id':'{{ doc.id }}',
'project':$("#project").val(),
'doc_tag':$("#tagsinputval").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'content':content,
'pre_content':pre_content,
'sort':$("#sort").val(),
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
}
$.post("{% url 'modify_doc' doc_id=doc.id %}",data,function(r){
layer.closeAll("loading");
var doc_tree = tree.render({
elem:"#doc-tree",
id:'docTree',
onlyIconControl:true,
data:r.data,
click: function(obj){
if(obj.data.level != 3){
console.log(obj.data.id,doc_parent_id)
if(obj.data.id != '{{ doc.id }}' ){
$('#parent-doc').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("你选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
if(r.status){
//修改成功
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
if(status === 1){
layer.msg('发布成功,即将跳转',function(){
md_changed = false;
window.location.href = "{% url 'doc' pro_id=doc.top_doc doc_id=doc.id %}";
});
}else{
//修改成功
layer.msg('保存成功',function(){
md_changed = false;
window.location.href = "{% url 'modify_doc' doc.id %}";
});
}
}else{
//修改失败
layer.msg('保存失败');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
});
};
$("#modify_save_doc").click(function(){
modifyDoc(0);
})
$("#modify_pub_doc").click(function(){
modifyDoc(1);
})
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({
type: 1,
id:'temp-div',
content: $('#doctemp-list'),
area:['530px','400px'],
});
});
//插入模板
insertTemp = function(doctemp_id){
layer.load();
$.post("{% url 'get_doctemp' %}",{'doctemp_id':doctemp_id},function(r){
if(r.status){
editor.insertValue(r.data);
layer.closeAll()
}else{
layer.closeAll("loading");
layer.msg(r.data)
}
});
};
//插入本地文本文件
function insertLocalFile(input) {
var file = input.files[0];
//filename = file.name.split(".")[0]; // 文件名
//支持chrome IE10
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function() {
console.log(this.result);
editor.insertValue(this.result);
}
reader.readAsText(file);
}
//支持IE 7 8 9 10
else if (typeof window.ActiveXObject != 'undefined'){
var xmlDoc;
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
}
//支持FF
else if (document.implementation && document.implementation.createDocument) {
var xmlDoc;
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
} else {
alert('error');
}
};
//选择本地文本文件
function selectLocalFile(){
$("#insert-local-file").trigger("click");
};
// 查看历史记录
$("#doc-history").click(function(){
layer.open({
type: 1,
title:'查看当前文档的历史版本',
id:'history-div',
content: $('#history-list'),
area:['530px','300px'],
});
});
//清除所选上级文档
$("#clearParentDoc").click(function(){
$('#parent-doc').val("");
$("span.layui-tree-txt").each(function(i){
var $me = $(this)
$me.removeClass('selected-parent-doc')
});
});
// 插入历史版本
insertHistory = function(doc_id,history_id){
layer.load(1);
var url = "{% url 'diff_doc' 0 1 %}";
url = url.replace(0,doc_id).replace(1,history_id)
$.post(url,function(r){
layer.closeAll("loading");
if(r.status){
editor.setMarkdown(r.data);
}else{
layer.msg(r.data)
}
});
};
// 删除文档
delDoc = function(doc_id){
layer.open({
type:1,
title:'删除文档',
area:'300px;',
id:'delPro',//配置ID
content:'<div style="margin-left:10px;">警告:此操作将删除此文档!</div>',
btn:['确定','取消'], //添加按钮
btnAlign:'c', //按钮居中
yes:function (index,layero) {
layer.load(1);
data = {
'doc_id':'{{ doc.id }}',
};
$.post("{% url 'del_doc' %}",data,function(r){
layer.closeAll('loading')
if(r.status){
//修改成功
layer.msg("文档已删除,即将跳转至文集")
// window.location.reload();
window.location.href = "{% url 'pro_index' doc.top_doc %}"
//layer.close(index)
}else{
//修改失败,提示
// console.log(r)
layer.msg(r.data)
}
})
},
});
};
// 移动文档
moveDoc = function(doc_id){
layer.open({
type:1,
title:'复制或移动此文档到指定文集',
id:'moveDoc',
area:'450px;',
content:$('#move-project'),
success:function(layero,index){
form.render(null, 'move-projects'); // 重新渲染弹出框的表单
// 移动文集 - 侦听选择文集 - 获取文集的文档
form.on('select(moveProject)', function(data){
// console.log(data.value); //得到被选中的值
$('#move-parent-id').val(0);
//获取文集的下级文档
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':data.value},function(r){
if(r.status){
var doc_tree = tree.render({
elem:"#move-doc-tree",
id:'moveDocTree',
onlyIconControl:true,
data:r.data,
text: {
defaultNodeName: '未命名' //节点默认名称
,none: '文集暂无文档' //数据为空时的提示文本
},
click: function(obj){
if(obj.data.level != 3){
$('#move-parent-id').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("第三级文档不能作为上级文档")
}
}
});
}else{
layer.msg("不可选择自己作为上级")
};
}else{
layer.msg("第三级文档不能作为上级文档")
};
}
});
$('#parent-doc').val(doc_parent_id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == doc_parent_id){
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("获取下级文档失败!")
}
});
});
// 修改文档
modifyDoc = function(status){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
layer.load(1);
var data = {
'doc_id':'{{ doc.id }}',
'project':$("#project").val(),
'doc_tag':$("#tagsinputval").val(),
'parent_doc':$("#parent-doc").val(),
'doc_name':$("#doc-name").val(),
'content':editor.getHTML(),
'pre_content':editor.getMarkdown(),
'sort':$("#sort").val(),
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
}
$.post("{% url 'modify_doc' doc_id=doc.id %}",data,function(r){
layer.closeAll("loading");
if(r.status){
//修改成功
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
if(status === 1){
layer.msg('发布成功,即将跳转',function(){
md_changed = false;
window.location.href = "{% url 'doc' pro_id=doc.top_doc doc_id=doc.id %}";
layer.msg("获取下级文档失败!")
}
});
});
}else{
//修改成功
layer.msg('保存成功',function(){
md_changed = false;
window.location.href = "{% url 'modify_doc' doc.id %}";
});
}
}else{
//修改失败
layer.msg('保存失败');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
});
};
$("#modify_save_doc").click(function(){
modifyDoc(0);
})
$("#modify_pub_doc").click(function(){
modifyDoc(1);
})
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({
type: 1,
id:'temp-div',
content: $('#doctemp-list'),
area:['530px','400px'],
});
});
//插入模板
insertTemp = function(doctemp_id){
layer.load();
$.post("{% url 'get_doctemp' %}",{'doctemp_id':doctemp_id},function(r){
if(r.status){
editor.insertValue(r.data);
layer.closeAll()
}else{
layer.closeAll("loading");
layer.msg(r.data)
}
});
};
//插入本地文本文件
function insertLocalFile(input) {
var file = input.files[0];
//filename = file.name.split(".")[0]; // 文件名
//支持chrome IE10
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function() {
console.log(this.result);
editor.insertValue(this.result);
}
reader.readAsText(file);
}
//支持IE 7 8 9 10
else if (typeof window.ActiveXObject != 'undefined'){
var xmlDoc;
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
}
//支持FF
else if (document.implementation && document.implementation.createDocument) {
var xmlDoc;
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
} else {
alert('error');
}
};
//选择本地文本文件
function selectLocalFile(){
$("#insert-local-file").trigger("click");
};
// 查看历史记录
$("#doc-history").click(function(){
layer.open({
type: 1,
title:'查看当前文档的历史版本',
id:'history-div',
content: $('#history-list'),
area:['530px','300px'],
});
});
//清除所选上级文档
$("#clearParentDoc").click(function(){
$('#parent-doc').val("");
$("span.layui-tree-txt").each(function(i){
var $me = $(this)
$me.removeClass('selected-parent-doc')
});
});
// 插入历史版本
insertHistory = function(doc_id,history_id){
layer.load(1);
var url = "{% url 'diff_doc' 0 1 %}";
url = url.replace(0,doc_id).replace(1,history_id)
$.post(url,function(r){
layer.closeAll("loading");
if(r.status){
editor.setMarkdown(r.data);
}else{
layer.msg(r.data)
}
});
};
// 删除文档
delDoc = function(doc_id){
layer.open({
type:1,
title:'删除文档',
area:'300px;',
id:'delPro',//配置ID
content:'<div style="margin-left:10px;">警告:此操作将删除此文档!</div>',
btn:['确定','取消'], //添加按钮
btnAlign:'c', //按钮居中
yes:function (index,layero) {
layer.load(1);
data = {
'doc_id':'{{ doc.id }}',
};
$.post("{% url 'del_doc' %}",data,function(r){
layer.closeAll('loading')
if(r.status){
//修改成功
layer.msg("文档已删除,即将跳转至文集")
// window.location.reload();
window.location.href = "{% url 'pro_index' doc.top_doc %}"
//layer.close(index)
}else{
//修改失败,提示
// console.log(r)
layer.msg(r.data)
}
})
},
});
};
// 移动文档
moveDoc = function(doc_id){
layer.open({
type:1,
title:'复制或移动此文档到指定文集',
id:'moveDoc',
area:'450px;',
content:$('#move-project'),
success:function(layero,index){
form.render(null, 'move-projects'); // 重新渲染弹出框的表单
// 移动文集 - 侦听选择文集 - 获取文集的文档
form.on('select(moveProject)', function(data){
// console.log(data.value); //得到被选中的值
$('#move-parent-id').val(0);
//获取文集的下级文档
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':data.value},function(r){
if(r.status){
var doc_tree = tree.render({
elem:"#move-doc-tree",
id:'moveDocTree',
onlyIconControl:true,
data:r.data,
text: {
defaultNodeName: '未命名' //节点默认名称
,none: '文集暂无文档' //数据为空时的提示文本
},
click: function(obj){
if(obj.data.level != 3){
$('#move-parent-id').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("第三级文档不能作为上级文档")
}
}
});
}else{
layer.msg("获取下级文档失败!")
}
});
});
},
})
};
// 提交移动文档
submitMoveDoc = function(){
var data = {
move_type:$("input:radio[name='move-type']:checked").val(),
pro_id:$("#moveProject").val(),
parent_id:$("#move-parent-id").val(),
doc_id:'{{doc.id}}'
};
if(data.pro_id === ''){
layer.msg("必须选择一个文集")
return
}
console.log(data)
layer.load(1)
$.post("{% url 'move_doc' %}",data,function(r){
layer.closeAll('loading')
if(r.status){
window.location.href = '/project-'+r.data.pro_id + '/doc-' + r.data.doc_id + '/'
}else{
layer.msg(r.data)
}
});
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
};
// 提交移动文档
submitMoveDoc = function(){
var data = {
move_type:$("input:radio[name='move-type']:checked").val(),
pro_id:$("#moveProject").val(),
parent_id:$("#move-parent-id").val(),
doc_id:'{{doc.id}}'
};
if(data.pro_id === ''){
layer.msg("必须选择一个文集")
return
}
console.log(data)
layer.load(1)
$.post("{% url 'move_doc' %}",data,function(r){
layer.closeAll('loading')
if(r.status){
window.location.href = '/project-'+r.data.pro_id + '/doc-' + r.data.doc_id + '/'
}else{
layer.msg(r.data)
}
});
</script>
};
</script>
{% endblock %}

View File

@ -1,438 +0,0 @@
{% extends 'app_doc/editor/create_base_vditor.html' %}
{% load static %}
{% load i18n %}
{% block title %}修改文档{% endblock %}
{% block custom_style %}
<style>
ul li{
list-style:disc;
}
ul > li > ul > li{
list-style-type: circle;
}
ol li{
list-style-type: decimal;
}
</style>
{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doc' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文档</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
<div class="layui-form" style="padding:0 10px 10px 10px;">
<div class="layui-row">
<div class="doc-form-label" style="margin-bottom: 10px;">
{% if doc.status == 0 %}
<strong>*当前文档状态:草稿</strong>
{% elif doc.status == 1 %}
<strong>*当前文档状态:已发布 </strong>
{% 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-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;">
<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>
{% include 'app_doc/editor/tpl_left_modify_custom.html' %}
</div>
</div>
{% endblock %}
{% block content %}
<div class="create-doc-form">
<div class="layui-form">
<!-- 标题 -->
<div class="layui-input-block" style="margin-left:0;">
<input type="text" name="doc-name" id="doc-name" required lay-verify="required" placeholder="请输入文档标题" value="{{ doc.name }}" class="layui-input">
</div>
<br>
</div>
</div>
<div id="editor-md">
<textarea style="display:none;">{{ doc.pre_content }}</textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
</div>
{% endblock %}
{% block custom_div %}
{% include 'app_doc/editor/tpl_editor_div_doc.html' %}
{% endblock %}
{% block custom_script %}
<script>
//获取文档数和上级文档信息
$(function(){
layer.load(1);
var doc_parent_id = '{{ doc.parent_doc }}';
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':$("#project").val()},function(r){
if(r.status){
layer.closeAll("loading");
var doc_tree = tree.render({
elem:"#doc-tree",
id:'docTree',
onlyIconControl:true,
data:r.data,
click: function(obj){
if(obj.data.level != 3){
console.log(obj.data.id,doc_parent_id)
if(obj.data.id != '{{ doc.id }}' ){
$('#parent-doc').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("你选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("不可选择自己作为上级")
};
}else{
layer.msg("第三级文档不能作为上级文档")
};
}
});
$('#parent-doc').val(doc_parent_id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == doc_parent_id){
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("获取下级文档失败!")
}
});
});
//修改文档
modifyDoc = function(status){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
layer.load(1);
var data = {
'doc_id':'{{ doc.id }}',
'project':$("#project").val(),
'parent_doc':$("#parent-doc").val(),
'doc_tag':$("#tagsinputval").val(),
'doc_name':$("#doc-name").val(),
'content':editor.getHTML(),
'pre_content':editor.getValue(),
'sort':$("#sort").val(),
'status':status,
'open_children':$('input:radio[name="open-children"]:checked').val(),
};
$.post("{% url 'modify_doc' doc_id=doc.id %}",data,function(r){
layer.closeAll("loading");
if(r.status){
//修改成功
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
if(status === 1){
layer.msg('发布成功,即将跳转',function(){
md_changed = false;
window.location.href = "{% url 'doc' pro_id=doc.top_doc doc_id=doc.id %}";
});
}else{
//修改成功
layer.msg('保存成功',function(){
md_changed = false;
window.location.href = "{% url 'modify_doc' doc.id %}";
});
}
}else{
//修改失败
layer.msg('修改失败');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
});
};
$("#modify_save_doc").click(function(){
modifyDoc(0);
})
$("#modify_pub_doc").click(function(){
modifyDoc(1);
})
//选择文档模板
$("#sel-doctemp").click(function(){
layer.open({
type: 1,
id:'temp-div',
content: $('#doctemp-list'),
area:['530px','400px'],
});
});
//插入模板
insertTemp = function(doctemp_id){
layer.load();
$.post("{% url 'get_doctemp' %}",{'doctemp_id':doctemp_id},function(r){
if(r.status){
editor.insertValue(r.data);
layer.closeAll()
}else{
layer.closeAll("loading");
layer.msg(r.data)
}
});
};
//插入本地文本文件
function insertLocalFile(input) {
var file = input.files[0];
//filename = file.name.split(".")[0]; // 文件名
//支持chrome IE10
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function() {
console.log(this.result);
editor.insertValue(this.result);
}
reader.readAsText(file);
}
//支持IE 7 8 9 10
else if (typeof window.ActiveXObject != 'undefined'){
var xmlDoc;
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
}
//支持FF
else if (document.implementation && document.implementation.createDocument) {
var xmlDoc;
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(input.value);
console.log(xmlDoc.xml);
editor.insertValue(xmlDoc.xml);
} else {
alert('error');
}
};
//选择本地文本文件
function selectLocalFile(){
$("#insert-local-file").trigger("click");
};
// 查看历史记录
$("#doc-history").click(function(){
layer.open({
type: 1,
title:'查看当前文档的历史版本',
id:'history-div',
content: $('#history-list'),
area:['530px','300px'],
});
});
//清除所选上级文档
$("#clearParentDoc").click(function(){
$('#parent-doc').val("");
$("span.layui-tree-txt").each(function(i){
var $me = $(this)
$me.removeClass('selected-parent-doc')
});
});
// 插入历史版本
insertHistory = function(doc_id,history_id){
layer.load(1);
var url = "{% url 'diff_doc' 0 1 %}";
url = url.replace(0,doc_id).replace(1,history_id)
$.post(url,function(r){
layer.closeAll("loading");
if(r.status){
editor.setMarkdown(r.data);
}else{
layer.msg(r.data)
}
});
};
// 删除文档
delDoc = function(doc_id){
layer.open({
type:1,
title:'删除文档',
area:'300px;',
id:'delPro',//配置ID
content:'<div style="margin-left:10px;">警告:此操作将删除此文档!</div>',
btn:['确定','取消'], //添加按钮
btnAlign:'c', //按钮居中
yes:function (index,layero) {
layer.load(1);
data = {
'doc_id':'{{ doc.id }}',
};
$.post("{% url 'del_doc' %}",data,function(r){
layer.closeAll('loading')
if(r.status){
//修改成功
layer.msg("文档已删除,即将跳转至文集")
// window.location.reload();
window.location.href = "{% url 'pro_index' doc.top_doc %}"
//layer.close(index)
}else{
//修改失败,提示
// console.log(r)
layer.msg(r.data)
}
})
},
});
};
// 移动文档
moveDoc = function(doc_id){
layer.open({
type:1,
title:'复制或移动此文档到指定文集',
id:'moveDoc',
area:'450px;',
content:$('#move-project'),
success:function(layero,index){
form.render(null, 'move-projects'); // 重新渲染弹出框的表单
// 移动文集 - 侦听选择文集 - 获取文集的文档
form.on('select(moveProject)', function(data){
// console.log(data.value); //得到被选中的值
$('#move-parent-id').val(0);
//获取文集的下级文档
$.post("{% url 'get_pro_doc_tree' %}",{'pro_id':data.value},function(r){
if(r.status){
var doc_tree = tree.render({
elem:"#move-doc-tree",
id:'moveDocTree',
onlyIconControl:true,
data:r.data,
text: {
defaultNodeName: '未命名' //节点默认名称
,none: '文集暂无文档' //数据为空时的提示文本
},
click: function(obj){
if(obj.data.level != 3){
$('#move-parent-id').val(obj.data.id);// 设置上级文档
$("div.layui-tree-set").each(function(i){
var $me = $(this)
if($me.data('id') == obj.data.id){
// console.log('点击了')
layer.msg("选择了上级文档:"+obj.data.title)
$me.find('span.layui-tree-txt').first().addClass('selected-parent-doc')
}else{
$me.find('span.layui-tree-txt').first().removeClass('selected-parent-doc')
}
});
}else{
layer.msg("第三级文档不能作为上级文档")
}
}
});
}else{
layer.msg("获取下级文档失败!")
}
});
});
},
})
};
// 提交移动文档
submitMoveDoc = function(){
var data = {
move_type:$("input:radio[name='move-type']:checked").val(),
pro_id:$("#moveProject").val(),
parent_id:$("#move-parent-id").val(),
doc_id:'{{doc.id}}'
};
if(data.pro_id === ''){
layer.msg("必须选择一个文集")
return
}
console.log(data)
layer.load(1)
$.post("{% url 'move_doc' %}",data,function(r){
layer.closeAll('loading')
if(r.status){
window.location.href = '/project-'+r.data.pro_id + '/doc-' + r.data.doc_id + '/'
}else{
layer.msg(r.data)
}
});
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
</script>
{% endblock %}

View File

@ -1,25 +1,52 @@
{% extends 'app_doc/editor/create_base_2.html' %}
{% extends 'app_doc/editor/create_base.html' %}
{% load static %}
{% load i18n %}
{% block title %}修改文档模板{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'create_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
{% include 'app_doc/editor/tpl_left_modify_doctemp_custom.html' %}
<div class="layui-form" style="padding: 10px;">
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-fluid" onclick="modifyDocTemp()">
<i class="fa fa-save"></i> 保存模板
</button>
</label>
</div>
</div>
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-primary layui-btn-fluid" id="doc-cache-btn">
<i class="fa fa-save"></i> 本地缓存
</button>
</label>
</div>
<!-- 已有模板 -->
<div class="layui-row">
<div class="layui-card">
<div class="layui-card-header">现有模板</div>
<div class="layui-card-body">
{% for temp in doctemps %}
<li><a href="{% url 'modify_doctemp' temp.id %}" target="_blank" title="点击查看修改《{{temp.name}}》的内容"><i class="fa fa-file"></i> {{temp.name}}</a></li>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="create-doc-form">
<div class="layui-form" style="padding-bottom:10px;">
@ -30,7 +57,6 @@
</div>
<div id="editor-md">
<textarea style="display:none;">{{doctemp.content}}</textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
</div>
{% endblock %}
@ -41,10 +67,15 @@
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
layer.load(1);
if(editor_mode == 1){
var content = editor.getMarkdown()
}else if(editor_mode == 2){
var content = editor.getValue()
}
var data = {
'doctemp_id':'{{ doctemp.id }}',
'name':$("#doctemp-name").val(),
'content':editor.getMarkdown(),
'content':content,
}
$.post("{% url 'modify_doctemp' doctemp_id=doctemp.id %}",data,function(r){
layer.closeAll("loading");
@ -53,7 +84,7 @@
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
layer.msg('修改成功,即将跳转',function(){
md_changed = false;
window.location.href = "{% url 'manage_doctemp' %}";
window.location.href = '/modify_doctemp/'+ '{{ doctemp.id }}/';
});
}else{
//创建失败
@ -63,41 +94,6 @@
}
});
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
</script>
{% endblock %}

View File

@ -1,103 +0,0 @@
{% extends 'app_doc/editor/create_base_vditor.html' %}
{% load static %}
{% load i18n %}
{% block title %}修改文档模板 - {{doctemp.name}}{% endblock %}
{% block head_toolbar %}
<a class="btn pull-left" aria-label="" href="{% url 'create_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-plus-square"></i> <span class="layui-hide-xs">新建模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_doctemp' %}?pid={{project.id}}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理模板</span>
</a>
<a class="btn pull-left" aria-label="" href="{% url 'manage_project' %}" target="_blank">
<i class="fa fa-cubes"></i> <span class="layui-hide-xs">管理文集</span>
</a>
{% endblock %}
{% block left_opera %}
{% include 'app_doc/editor/tpl_left_modify_doctemp_custom.html' %}
{% endblock %}
{% block content %}
<div class="create-doc-form">
<div class="layui-form" style="padding-bottom:10px;">
<div class="layui-input-block" style="margin-left:0px;">
<input type="text" name="doc-name" id="doctemp-name" required lay-verify="required" value="{{doctemp.name}}" placeholder="请输入模板名称" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div id="editor-md">
<textarea style="display:none;">{{doctemp.content}}</textarea>
<textarea class="editormd-html-textarea" name="$id-html-code"></textarea>
</div>
{% endblock %}
{% block custom_script %}
<script>
//修改文档模板
modifyDocTemp = function(){
$('button.layui-btn').attr("disabled",true);
$('button.layui-btn').addClass('layui-btn-disabled');
layer.load(1);
var data = {
'doctemp_id':'{{ doctemp.id }}',
'name':$("#doctemp-name").val(),
'content':editor.getValue(),
}
$.post("{% url 'modify_doctemp' doctemp_id=doctemp.id %}",data,function(r){
layer.closeAll("loading");
if(r.status){
//修改成功
window.localStorage.removeItem('mrdoc_doc_cache') // 清空文档缓存
layer.msg('修改成功,即将跳转',function(){
md_changed = false;
window.location.href = "{% url 'manage_doctemp' %}";
});
}else{
//创建失败
layer.msg('保存失败');
$('button.layui-btn').attr("disabled",false);
$('button.layui-btn').removeClass('layui-btn-disabled');
}
});
};
// 查看本地文档缓存
$("#doc-cache-btn").click(function(){
var editor_cache = window.localStorage.getItem('mrdoc_doc_cache') // 获取文档缓存内容
if(editor_cache === null){
var editor_cache_cnt = 0
}else{
var editor_cache_cnt = editor_cache.replace(/\s+|[\r\n]/g,"").length
}
if(editor_cache_cnt > 5){ // 文档缓存去除空格换行后长度大于5
console.log("存在文档缓存")
$("#doc-cache-content").val(editor_cache)
layer.open({
title:"浏览器文档缓存",
type:1,
id:'doc-cache',
area:['500px','500px'],
content:$('#doc-cache-div'),
btn:['使用缓存',"删除缓存"],
success : function(index, layero) { // 成功弹出后回调
form.render();
},
yes:function(index, layero){
editor.setValue(editor_cache)
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
autoCacheDoc();
},
btn2:function(index,layero){
window.localStorage.removeItem('mrdoc_doc_cache')
layer.closeAll()
}
})
}else{
layer.msg("暂无本地缓存")
}
})
</script>
{% endblock %}

View File

@ -1,123 +0,0 @@
{% load i18n %}
<!-- 选择和上传图片div -->
<div id="upload-img" style="display:none;margin:20px;">
<div class="layui-tab" lay-filter="img-tab">
<ul class="layui-tab-title">
<li class="layui-this">上传图片</li>
<li>选择图片</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-row">
<button class="layui-btn layui-btn-primary layui-btn-fluid" id="upload_img"><i class="layui-icon layui-icon-upload"></i> 上传图片</button>
</div>
<fieldset class="layui-elem-field layui-field-title" style="text-align: center;">
<legend style="font-size: 12px;">或 插入外链图片链接</legend>
</fieldset>
<div class="layui-row" style="margin-top: 10px;">
<input type="text" class="layui-input" placeholder="输入图片URL" id="img_url_input" style="margin-bottom: 5px;"/>
<button type="button" class="layui-btn layui-btn-primary" onclick="insertImgUrl()">插入图片链接</button>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-row" id="select-img-group">
</div><hr>
<div class="layui-row" id="select-img"></div>
<div id="select-img-page"></div>
</div>
</div>
</div>
</div>
<!-- 选择和上传附件div -->
<div id="upload-attach" style="display:none;margin:20px;">
<span>* 仅支持 {% if attachment_suffix and attachment_suffix != '' %}{{attachment_suffix}}{% else %}zip{% endif %} 格式文件,文件大小不超过 {% if attachment_size and attachment_size != '' %}{{attachment_size}}{% else %}50{% endif %}MB</span>
<div style="margin: 10px 0 0 10px;">
<button class="layui-btn layui-btn-primary layui-btn-sm" id="upload_attachment"><i class="layui-icon layui-icon-upload"></i> 上传附件</button>
<a class="layui-btn layui-btn-primary layui-btn-sm" href="{% url 'manage_attachment' %}" target="_blank"><i class="fa fa-cubes"></i> 管理附件</a>
</div>
<table class="layui-table" id="attach_table" style="margin: 10px;width:90%;">
<thead>
<th>附件名称</th>
<th>附件大小</th>
<th>上传时间</th>
<th>操作</th>
</thead>
<tbody>
</tbody>
</table>
<div id="select-attach-page"></div>
</div>
<!-- 添加表格div -->
<div id="layer-table" style="display: none;margin: 10px;">
<div class="layui-tab" lay-filter="table-tab" id="insert-table-div">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="generaTable">生成表格</li>
<li lay-id="pasteTable">粘贴表格</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show" >
<div class="layui-row" style="margin: 10px;">
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-input-inline" style="width: 50px;">
<input type="number" placeholder="行" id="row" class="layui-input" value="3">
</div>
<div class="layui-form-mid">x</div>
<div class="layui-input-inline" style="width: 50px;">
<input type="number" placeholder="列" id="col" class="layui-input" value="3">
</div>
<div class="layui-form-mid" style="width: 100px;">
<button class="layui-btn layui-btn-normal layui-btn-xs" onclick="addtable(1)" >生成表格</button>
</div>
</div>
</div>
</div>
<div class="layui-row" style="margin:10px;" id="TableGroup"></div>
</div>
<div class="layui-tab-item" >
<textarea placeholder="粘贴Excel或在线电子表格的内容" class="layui-textarea" style="height: 200px;" id="pasteExcel"></textarea>
</div>
</div>
</div>
</div>
<!-- 添加音视频div -->
<div id="insertMultimedia" style="display: none;margin:10px;">
<div class="layui-row">
<fieldset class="layui-elem-field">
<legend>插入音频链接</legend>
<div class="layui-field-box">
<input class="layui-input" type="url" id="audio_input" placeholder="填入音频文件链接支持文件后缀格式为mp3、wav、flac、m4a" style="margin-bottom: 5px;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" onclick="insertMultimedia('audio')"><i class="fa fa-music"></i> 插入音频</button>
</div>
</fieldset>
</div>
<div class="layui-row">
<fieldset class="layui-elem-field">
<legend>插入视频链接</legend>
<div class="layui-field-box">
<input class="layui-input" type="url" id="video_input" placeholder="填入视频文件链接支持文件后缀格式为mp4、m4v、ogg、ogv、webm" style="margin-bottom: 5px;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" onclick="insertMultimedia('video')"><i class="fa fa-video-camera"></i> 插入视频</button>
</div>
</fieldset>
</div>
<div class="layui-row">
<fieldset class="layui-elem-field">
<legend>插入视频网站链接</legend>
<div class="layui-field-box">
<input class="layui-input" type="url" id="video_iframe_input" placeholder="填入视频网站视频播放页链接支持YouTube、优酷、QQ视频、Facebook、哔哩哔哩、TED网站" style="margin-bottom: 5px;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" onclick="insertMultimedia('video_iframe')"><i class="fa fa-youtube-play"></i> 插入视频网站视频</button>
</div>
</fieldset>
</div>
</div>
<!-- 文档本地缓存div模板 -->
<div class="layui-form" id="doc-cache-div" style="display: none;">
<div style="margin: 5px;">
<textarea name="desc" id="doc-cache-content" class="layui-textarea" style="height: 350px;" disabled></textarea>
</div>
</div>

View File

@ -1,148 +1,7 @@
{% load static %}
{% load i18n %}
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edgechrome=1">
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{% block title %}{% endblock %} - {% if site_name != None and site_name != '' %}{{site_name}} {% else %}站点标题{% endif %}</title>
<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 'katex/katex.min.css' %}?version={{mrdoc_version}}" />
<link rel="icon" href="{% static 'favicon_16.png' %}"/>
<link href="{% static 'mrdoc/mrdoc.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link href="{% static 'mrdoc/mrdoc-editor.css' %}?version={{mrdoc_version}}" rel="stylesheet">
<link href="{% static 'tagsInput/tagsinput.css' %}" rel="stylesheet" type="text/css"/>
<style>
</style>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="doc layui-fluid" style="padding-left:0px;">
<!-- 左侧工具栏 -->
<div class="doc-summary">
{% include 'app_doc/editor/tpl_left_top.html' %}
{% block left_opera %}
{% endblock %}
</div>
<!-- 左侧工具栏结束 -->
<!-- 右侧编辑器栏 -->
<div class="doc-body">
<!-- 文档导航 -->
<div class="doc-header" role="navigation">
<a class="btn pull-left js-toolbar-action" aria-label="" href="javascript:void(0);" title="切换侧边栏">
<i class="fa fa-align-justify"></i>
</a>
<!-- 顶部工具栏 -->
{% block head_toolbar %}
{% endblock %}
<a class="btn pull-right" aria-label="" href="{% url 'pro_list' %}">
<i class="fa fa-home"></i> <span class="layui-hide-xs">首页</span>
</a>
</div>
<!-- 文档主体 -->
<div class="doc-body-content" style="padding-left: 15px;">
<div class="mrdoc-body-content-div">
<!-- 文档内容 -->
<div class="mrdoc-editor-content">
<!-- 正文开始 -->
<div class="markdown-body" id="content">
{% block content %}
{% endblock %}
</div>
<!-- 正文结束 -->
</div>
</div>
</div>
</div>
<!-- 右侧编辑器结束 -->
</div>
<script>
// 视频iframe域名白名单
var iframe_whitelist = '{{ iframe_whitelist }}'.split(',')
</script>
<script src="{% static 'jquery/3.1.1/jquery.min.js' %}"></script>
<script src="{% static 'layui/layui.all.js' %}"></script>
<!-- 脑图开始 -->
<script src="{% static 'mindmap/d3@5.js' %}"></script>
<script src="{% static 'mindmap/transform.min.js' %}"></script>
<script src="{% static 'mindmap/view.min.js' %}"></script>
<!-- 脑图结束 -->
<script src="{% static 'editor.md/editormd.js' %}?version={{mrdoc_version}}"></script>
<!-- <script src="{% static 'editor.md/editormd.min.js' %}"></script> -->
<script src="{% static 'mrdoc/mrdoc.editor.js' %}"></script>
<script src="{% static 'mrdoc/mrdoc.js' %}?version={{mrdoc_version}}"></script>
<!-- 标签输入 -->
<script src="{% static '/tagsInput/tagsinput.js' %}" type="text/javascript" charset="utf-8"></script>
<script>
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
// console.log('{{ iframe_whitelist }}')
var tree = layui.tree;
//加载页面时执行一次
changeSidebar();
//监听浏览器宽度的改变
window.onresize = function(){
changeSidebar();
};
function changeSidebar(){
// 获取匹配指定的媒体查询
var screen_width = window.matchMedia('(max-width: 768px)');
//判断匹配状态
if(screen_width.matches){
//如果匹配到,切换侧边栏
//console.log('小屏幕')
$("body").addClass("big-page");
}else{
$("body").removeClass("big-page");
}
}
</script>
<!-- 切换隐藏侧边栏 -->
<script>
// 切换侧边栏
$(function(){
$(".js-toolbar-action").click(toggleSidebar);
});
//切换侧边栏显示隐藏
function toggleSidebar(){
console.log("切换侧边栏")
$("body").toggleClass("big-page");
return false;
}
</script>
<!-- 展开收起左边目录 -->
<script>
$(function(){
$(".switch-toc").click(SwitchToc);
});
function SwitchToc(i){
var $me = $(this);
$(this).parent().next("ul").toggleClass("toc-close"); //切换展开收起样式
$(this).toggleClass("fa-chevron-left fa-chevron-down");//切换图标
};
</script>
<script>
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
var layer = layui.layer;
var form = layui.form;
var element = layui.element;
var laypage = layui.laypage;
var md_changed = false; //初始化一个变量,用于判断编辑器是否修改
//初始化editormd
var editor = editormd("editor-md", {
@ -518,143 +377,3 @@
editor.focus()
}
</script>
</body>
<!-- 自定义DIV模板 -->
{% block custom_div %}
{% endblock %}
{% include 'app_doc/editor/tpl_editor_div.html' %}
<!-- 自定义JS脚本 -->
{% block custom_script %}
{% endblock %}
<script>
//按钮选择上传图片
var upload = layui.upload;
upload.render({
elem: '#upload_img',
url: '{% url "upload_doc_img" %}',
before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(1); //上传loading
},
done: function(res, index, upload){ //上传后的回调
//上传成功
if(res.success == 1){
editor.insertValue("\n![](" + res.url + ")");
layer.closeAll();
layer.msg("上传成功");
}else{
layer.closeAll();
layer.msg(res.message)
}
},
error:function(){
layer.closeAll('loading'); //关闭loading
layer.msg("系统异常,请稍后再试!")
},
accept: 'images', //允许上传的文件类型
acceptMime:'image/*',
field:'manage_upload',
});
// 按钮选择上传附件
var upload_attach = layui.upload;
upload_attach.render({
elem: '#upload_attachment',
url: '{% url "manage_attachment" %}',
data:{types:0,csrfmiddlewaretoken: '{{ csrf_token }}'},
before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(1); //上传loading
},
done: function(res, index, upload){ //上传后的回调
//上传成功,刷新页面
if(res.status){
editor.insertValue("\n[【附件】"+ res.data.name + "](/media/" + res.data.url + ")");
layer.closeAll();
layer.msg("上传成功");
}else{
layer.closeAll('loading');
layer.msg("上传出错,请重试!")
}
},
accept: 'file', //允许上传的文件类型
field:'attachment_upload',
})
// 粘贴表格文本框侦听paste粘贴事件
// 列宽的函数
function columnWidth(rows, columnIndex) {
return Math.max.apply(null, rows.map(function(row) {
return row[columnIndex].length
}))
};
// 检查是否是个表格
function looksLikeTable(data) {
return true
};
// 表格输入框侦听paste粘贴事件
var pasteExcel = document.getElementById('pasteExcel')
pasteExcel.addEventListener("paste", function(event) {
console.log('粘贴Excel')
var clipboard = event.clipboardData
var data = clipboard.getData('text/plain')
data = data.replace(/(?:[\n\u0085\u2028\u2029]|\r\n?)$/, '');
if(looksLikeTable(data)) {
event.preventDefault()
}else{
return
}
// 行
var rows = data.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(function(row) {
console.log(row)
return row.split("\t")
})
// 列对齐
var colAlignments = []
// 列宽
var columnWidths = rows[0].map(function(column, columnIndex) {
var alignment = "l"
var re = /^(\^[lcr])/i
var m = column.match(re)
if (m) {
var align = m[1][1].toLowerCase()
if (align === "c") {
alignment = "c"
} else if (align === "r") {
alignment = "r"
}
}
colAlignments.push(alignment)
column = column.replace(re, "")
rows[0][columnIndex] = column
return columnWidth(rows, columnIndex)
})
var markdownRows = rows.map(function(row, rowIndex) {
return "| " + row.map(function(column, index) {
return column + Array(columnWidths[index] - column.length + 1).join(" ")
}).join(" | ") + " |"
row.map
})
markdownRows.splice(1, 0, "|" + columnWidths.map(function(width, index) {
var prefix = ""
var postfix = ""
var adjust = 0
var alignment = colAlignments[index]
if (alignment === "r") {
postfix = ":"
adjust = 1
} else if (alignment == "c") {
prefix = ":"
postfix = ":"
adjust = 2
}
return prefix + Array(columnWidths[index] + 3 - adjust).join("-") + postfix
}).join("|") + "|")
event.target.value = markdownRows.join("\n")
return false
});
</script>
</html>

View File

@ -0,0 +1,96 @@
<script>
var editor = new ice.editor("editor-md");
editor.height='600px';
editor.plugin({
name:"attachments",
menu:'<div title="添加附件"><svg t="1607826716758" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3230" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M385.706667 914.773333c-75.093333 0-146.773333-30.72-201.386667-81.92S102.4 706.56 102.4 631.466667s30.72-146.773333 81.92-201.386667l252.586667-252.586667c112.64-112.64 293.546667-112.64 402.773333 0 112.64 112.64 112.64 293.546667 0 402.773334l-252.586667 252.586666c-54.613333 54.613333-126.293333 81.92-201.386666 81.92z m252.586666-716.8c-47.786667 0-92.16 17.066667-129.706666 54.613334l-252.586667 252.586666c-34.133333 34.133333-54.613333 81.92-54.613333 129.706667s20.48 95.573333 54.613333 129.706667S337.92 819.2 385.706667 819.2s95.573333-20.48 129.706666-54.613333l252.586667-252.586667c71.68-71.68 71.68-187.733333 0-259.413333-37.546667-37.546667-85.333333-54.613333-129.706667-54.613334z" fill="#0A0B09" p-id="3231"></path><path d="M426.666667 648.533333c-13.653333 0-27.306667-3.413333-37.546667-13.653333-20.48-20.48-20.48-51.2 0-71.68l204.8-204.8c20.48-20.48 51.2-20.48 71.68 0 20.48 20.48 20.48 51.2 0 71.68l-204.8 204.8c-10.24 6.826667-23.893333 13.653333-34.133333 13.653333z" fill="#0A0B09" p-id="3232"></path></svg></div>',
click:function(e,z){
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加附件',
area:['800px','600px'],
id:'uploadAttach',//配置ID,
content:$('#upload-attach'),
success: function(layero, index){
layer.load(1);
$.post('{% url "manage_attachment" %}',{types:2},function(r){
$("#attach_table tbody").empty()
if(r.status){
//调用分页显示
laypage.render({
elem: 'select-attach-page',//分页的div
count: r.data.length, //数据总数
limit:10, //单页数
jump: function(obj){
//渲染HTML
$("#attach_table tbody").empty();
var thisData = r.data.concat().splice(obj.curr*obj.limit - obj.limit, obj.limit);
layui.each(thisData, function(k, v){
var row = "<tr><td>" + v.filename + "</td><td>"+ v.filesize +"</td><td>"+ v.filetime +"</td><td><button class='layui-btn layui-btn-normal layui-btn-sm' data-name='"+ v.filename +"' data-path='"+ v.filepath +"' onclick='insertAttach(this)'>选择</button></td></tr>"
// arr.push(row);
$("#attach_table tbody").append(row)
});
}
});
layer.closeAll("loading");//关闭加载提示
}else{
layer.closeAll("loading");//关闭加载提示
layer.msg("获取附件失败,请稍后重试!")
}
})
}
})
}
});
editor.plugin({
name:'image',
menu:'<div title="添加图片"><svg t="1607829798978" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4249" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M822 891H202c-68.37 0-124-55.63-124-124V257c0-68.37 55.63-124 124-124h620c68.37 0 124 55.63 124 124v510c0 68.37-55.63 124-124 124zM202 201c-30.88 0-56 25.12-56 56v510c0 30.88 25.12 56 56 56h620c30.88 0 56-25.12 56-56V257c0-30.88-25.12-56-56-56H202z" fill="#040000" p-id="4250"></path><path d="M723 344m-56 0a56 56 0 1 0 112 0 56 56 0 1 0-112 0Z" fill="#040000" p-id="4251"></path><path d="M879.22 779.01l-157.3-121.43c-12.51-9.66-29.17-11.49-43.48-4.79l-95.48 44.72c-43.49 20.37-95.16 6.68-122.86-32.54L357.31 519.41c-16.08-22.77-47.29-29.18-71.04-14.58L141.8 593.6l-35.6-57.94 144.46-88.78c54.23-33.33 125.47-18.7 162.19 33.29l102.79 145.56a30.966 30.966 0 0 0 38.47 10.19l95.48-44.72c37.48-17.56 81.11-12.75 113.88 12.54l157.3 121.43-41.55 53.84z" fill="#040000" p-id="4252"></path></svg></div>',
click:function(e,z){
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加图片',
area:['800px','600px'],
id:'uploadImg',//配置ID,
content:$('#upload-img'),
})
}
})
editor.menu = [
'backColor', //字体背景颜色
'fontSize', //字体大小
'foreColor', //字体颜色
'bold', //粗体
'italic', //斜体
'underline', //下划线
'strikeThrough', //删除线
'justifyLeft', //左对齐
'justifyCenter', //居中对齐
'justifyRight', //右对齐
'indent', //增加缩进
'outdent', //减少缩进
'insertOrderedList', //有序列表
'insertUnorderedList', //无序列表
'superscript', //上标
'subscript', //下标
'createLink', //创建连接
'unlink', //取消连接
'hr', //水平线
'table', //表格
'image', //图片
'attachments', //附件
'music', //音乐
'video', //视频
'removeFormat', //格式化样式
'code', //源码
'line' //菜单分割线
]
editor.create();
autoCacheDoc();
</script>

View File

@ -0,0 +1,257 @@
<!-- Vditor编辑器 -->
{% load static %}
<script>
//初始化vditor编辑器
layer.load(1)
if(screen_width.matches){
var vditor_mode = 'ir'
var vditor_height = window.innerHeight / 2
var vditor_toolbar = [
"emoji","headings","bold","strike","link","|",
"list","ordered-list","check","|",
"quote","line","code","inline-code","|",
{
name: 'insert-img',
tipPosition: 's',
tip: '图片',
className: 'right',
tipPosition:'nw',
icon:'<svg t="1599747832593" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4027" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><defs><style type="text/css"></style></defs><path d="M864.05 128.46H129.97c-17.68 0-32 14.33-32 32v639.61c0 17.67 14.32 32 32 32h734.08c17.68 0 32-14.33 32-32V160.46c0-17.67-14.32-32-32-32z m-32 639.61H161.97V192.46h670.08v575.61z" p-id="4028"></path><path d="M795.58 691.57a32.007 32.007 0 0 1-27.33 15.34H225.77c-12.01 0-23-6.72-28.48-17.4a31.988 31.988 0 0 1 2.5-33.28l125.3-174.17c10.17-14.13 29.78-17.54 44.12-7.67l101.77 70.03 129.73-165.51a31.995 31.995 0 0 1 28.21-12.11 31.99 31.99 0 0 1 25.42 17.2L796.7 660.26a32.018 32.018 0 0 1-1.12 31.31z" p-id="4029"></path><path d="M320.03 321.34a64.03 64.83 0 1 0 128.06 0 64.03 64.83 0 1 0-128.06 0Z" p-id="4030"></path></svg>',
click () {
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加图片',
// area:['800px','600px'],
id:'uploadImg',//配置ID,
content:$('#upload-img'),
})
},
},
{
name: 'insert-attachment',
tipPosition: 's',
tip: '附件',
className: 'right',
tipPosition:'nw',
icon:'<svg t="1599964518089" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4929" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><defs><style type="text/css"></style></defs><path d="M633.553 251.102c15.993-12.795 38.385-12.795 55.978 1.6 15.993 15.993 15.993 38.384 0 54.378L347.264 647.747c-22.39 20.792-22.39 57.577 0 81.568 20.792 22.391 57.578 22.391 81.568 0l401.444-403.042c55.978-55.979 55.978-148.742 0-204.72s-148.742-55.979-204.72 0l-47.982 47.98-12.795 12.796-369.455 369.455c-91.165 91.165-91.165 236.708 0 327.872 91.164 91.165 236.707 91.165 327.872 0L894.25 511.8c6.397-3.199 9.596-7.997 12.795-12.795 15.993-15.994 38.385-15.994 54.378 0s15.994 38.385 0 54.379l-3.198 3.199c-3.2 1.599-6.398 6.397-9.597 9.596L577.574 934.035c-119.953 119.953-316.676 119.953-436.63 0s-119.952-316.676 0-436.63l430.233-431.83c86.366-86.367 227.111-86.367 315.077 0 86.366 86.366 86.366 227.11 0 315.076L483.21 783.694c-52.78 52.78-139.145 52.78-190.325 0-52.78-52.78-52.78-139.146 0-190.326l340.667-342.266z m0 0" fill="#333333" p-id="4930"></path></svg>',
click () {
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加附件',
// area:['800px','600px'],
id:'uploadAttach',//配置ID,
content:$('#upload-attach'),
success: function(layero, index){
layer.load(1);
$.post('{% url "manage_attachment" %}',{types:2},function(r){
$("#attach_table tbody").empty()
if(r.status){
//调用分页显示
laypage.render({
elem: 'select-attach-page',//分页的div
count: r.data.length, //数据总数
limit:10, //单页数
jump: function(obj){
//渲染HTML
$("#attach_table tbody").empty();
var thisData = r.data.concat().splice(obj.curr*obj.limit - obj.limit, obj.limit);
layui.each(thisData, function(k, v){
var row = "<tr><td>" + v.filename + "</td><td>"+ v.filesize +"</td><td>"+ v.filetime +"</td><td><button class='layui-btn layui-btn-normal layui-btn-sm' data-name='"+ v.filename +"' data-path='"+ v.filepath +"' onclick='insertAttach(this)'>选择</button></td></tr>"
// arr.push(row);
$("#attach_table tbody").append(row)
});
}
});
layer.closeAll("loading");//关闭加载提示
}else{
layer.closeAll("loading");//关闭加载提示
layer.msg("获取附件失败,请稍后重试!")
}
})
}
})
},
},
"table",
"|","undo","redo","|","fullscreen","edit-mode",
{
name: "more",
toolbar: [
"both",
"code-theme",
"content-theme",
"export",
"outline",
"preview",
"devtools",
"info",
"help",
],
}
]
}else{
var vditor_mode = 'sv'
var vditor_height = window.innerHeight - 200
var vditor_toolbar = [
"emoji","headings","bold","italic","strike","link","|",
"list","ordered-list","check","outdent","indent","|",
"quote","line","code","inline-code","insert-before","insert-after","|",
{
name: 'insert-img',
tipPosition: 's',
tip: '图片',
className: 'right',
tipPosition:'nw',
icon:'<svg t="1599747832593" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4027" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><defs><style type="text/css"></style></defs><path d="M864.05 128.46H129.97c-17.68 0-32 14.33-32 32v639.61c0 17.67 14.32 32 32 32h734.08c17.68 0 32-14.33 32-32V160.46c0-17.67-14.32-32-32-32z m-32 639.61H161.97V192.46h670.08v575.61z" p-id="4028"></path><path d="M795.58 691.57a32.007 32.007 0 0 1-27.33 15.34H225.77c-12.01 0-23-6.72-28.48-17.4a31.988 31.988 0 0 1 2.5-33.28l125.3-174.17c10.17-14.13 29.78-17.54 44.12-7.67l101.77 70.03 129.73-165.51a31.995 31.995 0 0 1 28.21-12.11 31.99 31.99 0 0 1 25.42 17.2L796.7 660.26a32.018 32.018 0 0 1-1.12 31.31z" p-id="4029"></path><path d="M320.03 321.34a64.03 64.83 0 1 0 128.06 0 64.03 64.83 0 1 0-128.06 0Z" p-id="4030"></path></svg>',
click () {
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加图片',
area:['800px','600px'],
id:'uploadImg',//配置ID,
content:$('#upload-img'),
})
},
},
{
name: 'insert-attachment',
tipPosition: 's',
tip: '附件',
className: 'right',
tipPosition:'nw',
icon:'<svg t="1599964518089" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4929" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><defs><style type="text/css"></style></defs><path d="M633.553 251.102c15.993-12.795 38.385-12.795 55.978 1.6 15.993 15.993 15.993 38.384 0 54.378L347.264 647.747c-22.39 20.792-22.39 57.577 0 81.568 20.792 22.391 57.578 22.391 81.568 0l401.444-403.042c55.978-55.979 55.978-148.742 0-204.72s-148.742-55.979-204.72 0l-47.982 47.98-12.795 12.796-369.455 369.455c-91.165 91.165-91.165 236.708 0 327.872 91.164 91.165 236.707 91.165 327.872 0L894.25 511.8c6.397-3.199 9.596-7.997 12.795-12.795 15.993-15.994 38.385-15.994 54.378 0s15.994 38.385 0 54.379l-3.198 3.199c-3.2 1.599-6.398 6.397-9.597 9.596L577.574 934.035c-119.953 119.953-316.676 119.953-436.63 0s-119.952-316.676 0-436.63l430.233-431.83c86.366-86.367 227.111-86.367 315.077 0 86.366 86.366 86.366 227.11 0 315.076L483.21 783.694c-52.78 52.78-139.145 52.78-190.325 0-52.78-52.78-52.78-139.146 0-190.326l340.667-342.266z m0 0" fill="#333333" p-id="4930"></path></svg>',
click () {
layer.ready(function(){
element.init();
});
layer.open({
type:'1',
title:'添加附件',
area:['800px','600px'],
id:'uploadAttach',//配置ID,
content:$('#upload-attach'),
success: function(layero, index){
layer.load(1);
$.post('{% url "manage_attachment" %}',{types:2},function(r){
$("#attach_table tbody").empty()
if(r.status){
//调用分页显示
laypage.render({
elem: 'select-attach-page',//分页的div
count: r.data.length, //数据总数
limit:10, //单页数
jump: function(obj){
//渲染HTML
$("#attach_table tbody").empty();
var thisData = r.data.concat().splice(obj.curr*obj.limit - obj.limit, obj.limit);
layui.each(thisData, function(k, v){
var row = "<tr><td>" + v.filename + "</td><td>"+ v.filesize +"</td><td>"+ v.filetime +"</td><td><button class='layui-btn layui-btn-normal layui-btn-sm' data-name='"+ v.filename +"' data-path='"+ v.filepath +"' onclick='insertAttach(this)'>选择</button></td></tr>"
// arr.push(row);
$("#attach_table tbody").append(row)
});
}
});
layer.closeAll("loading");//关闭加载提示
}else{
layer.closeAll("loading");//关闭加载提示
layer.msg("获取附件失败,请稍后重试!")
}
})
}
})
},
},
"table",
"|","undo","redo","|","fullscreen","edit-mode",
{
name: "more",
toolbar: [
"both",
"code-theme",
"content-theme",
"export",
"outline",
"preview",
"devtools",
"info",
"help",
],
}
]
}
var editor = new Vditor('editor-md',{
"cdn":"{% static 'vditor' %}",
"toolbar": vditor_toolbar,
"height":vditor_height,
"width":'100%',
"mode":vditor_mode, // 编辑器模式
"placeholder":"道友,开始吧……",
"counter":{
enable:true, // 启用计数
},
"cache": {
"enable": false, // 禁用缓存
},
"preview": {
"markdown": {
"autoSpace": true,// 自动空格
"chinesePunct": true,// 矫正标点
"mark": true,//Mark标记
},
"hljs":{
"lineNumber":true,//代码行号
}
},
"after":function(){
layer.closeAll('loading');
},
"input":function(){
autoCacheDoc();
},
"upload":{
fieldName:"editormd-image-file[]",
url:"{% url 'upload_doc_img' %}",
linkToImgUrl:"{% url 'upload_doc_img' %}",
linkToImgCallback:function(e){
console.log(e)
},
linkToImgFormat:function(e){
console.log(JSON.parse(e))
return e
},
handler(files){//自定义粘贴上传图片
console.log(files)
var reader = new FileReader();
reader.onload = function (event) {
var base64 = event.target.result;
//ajax上传图片
layer.load(1);
$.post("{% url 'upload_doc_img' %}",{base:base64}, function (ret) {
layer.msg(ret.message);
if (ret.success === 1) {
//新一行的图片显示
layer.closeAll("loading");
editor.insertValue("\n![](" + ret.url + ")");
editor.focus()
}else{
layer.closeAll("loading");
layer.msg("粘贴图片失败!")
}
});
}; // data url!
var url = reader.readAsDataURL(files[0]);
}
}
});
</script>

View File

@ -1,102 +0,0 @@
{% load i18n %}
<!-- 选择文集 -->
<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">
<option value="">请选择一个文集(必选)</option>
<option value="-1">新建文集</option>
<!-- 自己的文集 -->
<optgroup label="自有文集" id="self-project">
{% for p in project_list %}
{% if p.role == 1 %}
<option value="{{ p.id }}">[私密]《{{ p.name }}》</option>
{% elif p.role == 2 %}
<option value="{{ p.id }}" >[指定用户]《{{ p.name }}》</option>
{% elif p.role == 3 %}
<option value="{{ p.id }}" >[访问码]《{{ p.name }}》</option>
{% else %}
<option value="{{ p.id }}" >[公开]《{{ p.name }}》</option>
{% endif %}
{% endfor %}
</optgroup>
<!-- 协作的文集 -->
{% if colla_project_list.count > 0 %}
<optgroup label="协作文集">
{% for p in colla_project_list %}
<option value="{{ p.project.id }}">[协作]《{{ p.project.name }}》</option>
{% endfor %}
</optgroup>
{% endif %}
</select>
</div>
</div>
<!-- 设置文档排序 -->
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<span>点击文档树选择上级(可选)或</span>
<button class="layui-btn layui-btn-xs layui-btn-primary" id="clearParentDoc">取消上级</button>
<input type="text" id="parent-doc" hidden>
</div>
<div class="layui-col-md12">
<input type="number" class="layui-input" placeholder="输入文档排序值默认99" id="sort">
</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" style="max-height: 400px;overflow: hidden;overflow-y: scroll;overflow-x: scroll;">
<div id="doc-tree"></div>
</div>
</div>
</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;">
<button class="layui-btn layui-btn-primary mrdoc-btn-default" id="save_doc" title="保存当前内容为草稿文档">
<i class="fa fa-save"></i> 保存
</button>
<button class="layui-btn layui-btn-normal" id="pub_doc" title="发布当前内容">
<i class="fa fa-save"></i> 发布
</button>
</div>
</div>
</div>
</div>

View File

@ -1,30 +0,0 @@
{% load i18n %}
<div class="layui-form" style="padding: 10px;">
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-fluid" onclick="createDocTemp()">
<i class="fa fa-save"></i> 保存模板
</button>
</label>
</div>
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-primary layui-btn-fluid" id="doc-cache-btn">
<i class="fa fa-save"></i> 本地缓存
</button>
</label>
</div>
</div>
<!-- 已有模板 -->
<div class="layui-row">
<div class="layui-card">
<div class="layui-card-header">现有模板</div>
<div class="layui-card-body">
{% for temp in doctemps %}
<li><a href="{% url 'modify_doctemp' temp.id %}" target="_blank" title="点击查看修改《{{temp.name}}》的内容"><i class="fa fa-file"></i> {{temp.name}}</a></li>
{% endfor %}
</div>
</div>
</div>
</div>

View File

@ -1,89 +0,0 @@
{% load i18n %}
<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">
<option value="{{ project.id }}">{{ project.name }}</option>
</select>
</div>
</div>
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<span>点击文档树选择上级(可选)或</span>
<button class="layui-btn layui-btn-xs layui-btn-primary" id="clearParentDoc">取消上级</button>
<input type="text" id="parent-doc" hidden>
</div>
<div class="layui-col-md12">
<input type="number" class="layui-input" placeholder="输入文档排序值默认99" id="sort" value="{{doc.sort}}">
</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" style="max-height: 400px;overflow: hidden;overflow-y: scroll;overflow-x: scroll;">
<div id="doc-tree"></div>
</div>
</div>
</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;">
<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> 保存为草稿
</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> 发布文档
</button>
</div>
<div class="layui-row" style="margin-top: 5px;">
<button class="layui-btn layui-btn-warm layui-btn-fluid" onclick="moveDoc()" title="复制或移动此文档到其他文集"><i class="fa fa-copy"></i> 复制/移动文档</button>
</div>
<div class="layui-row" style="margin-top: 5px;">
<button class="layui-btn layui-btn-danger layui-btn-fluid" onclick="delDoc()" title="删除此文档"><i class="fa fa-trash"></i> 删除文档</button>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,30 +0,0 @@
{% load i18n %}
<div class="layui-form" style="padding: 10px;">
<div class="layui-row">
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-normal layui-btn-fluid" onclick="modifyDocTemp()">
<i class="fa fa-save"></i> 保存模板
</button>
</label>
</div>
</div>
<div class="layui-col-md12" style="margin-bottom: 10px;">
<label class="doc-form-label">
<button class="layui-btn layui-btn-primary layui-btn-fluid" id="doc-cache-btn">
<i class="fa fa-save"></i> 本地缓存
</button>
</label>
</div>
<!-- 已有模板 -->
<div class="layui-row">
<div class="layui-card">
<div class="layui-card-header">现有模板</div>
<div class="layui-card-body">
{% for temp in doctemps %}
<li><a href="{% url 'modify_doctemp' temp.id %}" target="_blank" title="点击查看修改《{{temp.name}}》的内容"><i class="fa fa-file"></i> {{temp.name}}</a></li>
{% endfor %}
</div>
</div>
</div>
</div>

View File

@ -1,5 +0,0 @@
{% load i18n %}
<div class="project-title"><i class="fa fa-edit"></i> {% trans "MrDoc文档编辑器" %}<br>
<span style="font-size: 14px;">你正在:{{editor_type }}</span>
</div>
<hr>

View File

@ -33,11 +33,11 @@
{{d.name}}
{{#if (d.role == 0) { }}
{{# }else if(d.role == 1){ }}
<span tooltip="{% trans '私密' %}" placement="right"><i class="layui-icon layui-icon-password"></i></span>
<span tooltip="私密" placement="right"><i class="layui-icon layui-icon-password"></i></span>
{{# }else if(d.role == 2){ }}
<span tooltip="{% trans '指定用户' %}" placement="right"><i class="layui-icon layui-icon-user"></i></span>
<span tooltip="指定用户" placement="right"><i class="layui-icon layui-icon-user"></i></span>
{{# }else if(d.role == 3){ }}
<span tooltip="{% trans '访问码' %}" placement="right"><i class="layui-icon layui-icon-key"></i></span>
<span tooltip="访问码" placement="right"><i class="layui-icon layui-icon-key"></i></span>
{{# } }}
</a>
{% endverbatim %}
@ -46,9 +46,9 @@
<!-- 单个文集操作 -->
<script type="text/html" id="project-bar">
{% verbatim %}
<a href="/manage_pro_doc_sort/{{d.id}}/" class="layui-btn layui-btn-primary pear-btn-sm" lay-event="sort"><i class="layui-icon layui-icon-cols"></i></a>
<a href="/modify_pro/?pro_id={{d.id}}" title="{% trans '修改文集配置' %}" class="layui-btn layui-btn-primary pear-btn-sm"><i class="layui-icon layui-icon-set"></i></a>
<button class="layui-btn layui-btn-warm pear-btn-sm" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
<a href="/manage_pro_doc_sort/{{d.id}}/" title="排序文档" class="layui-btn layui-btn-primary pear-btn-sm" lay-event="sort"><i class="layui-icon layui-icon-cols"></i></a>
<a href="/modify_pro/?pro_id={{d.id}}" title="修改文集配置" class="layui-btn layui-btn-primary pear-btn-sm"><i class="layui-icon layui-icon-set"></i></a>
<button class="layui-btn layui-btn-warm pear-btn-sm" title="删除文集" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
{% endverbatim %}
</script>

View File

@ -33,13 +33,9 @@
<div class="layui-form-item">
<label class="layui-form-label">{% trans "编辑器" %}</label>
<div class="layui-input-block">
{% if user_opt.editor_mode == 2 %}
<input type="radio" name="editor_mode" value="1" title="EditorMD" >
<input type="radio" name="editor_mode" value="2" title="Vditor" checked>
{% else %}
<input type="radio" name="editor_mode" value="1" title="EditorMD" checked>
<input type="radio" name="editor_mode" value="2" title="Vditor" >
{% endif %}
<input type="radio" name="editor_mode" value="1" title="EditorMD(Markdown)" {% if user_opt.editor_mode == 1 %}checked{% endif %}>
<input type="radio" name="editor_mode" value="2" title="Vditor(Markdown)" {% if user_opt.editor_mode == 2 %}checked{% endif %}>
<input type="radio" name="editor_mode" value="3" title="iceEditor(富文本)" {% if user_opt.editor_mode == 3 %}checked{% endif %}>
</div>
</div>