优化后台文档管理文档历史记录页面和接口

This commit is contained in:
zmister 2021-07-23 14:32:58 +08:00
parent cd163011a0
commit ed2b9adbe8
7 changed files with 203 additions and 5 deletions

View File

@ -4,6 +4,7 @@
- [新增]后台管理中心的图片管理和附件管理功能;
- [新增]站点搜索中文档搜索支持「全文搜索」和「匹配搜索」功能和切换开关;
- [新增]后台文档管理文档历史记录页面和接口;
- [修复]vditor编辑器粘贴多图片文本时图片只有一张图的问题;
- [修复]找回密码邮件发送失败的问题;
- [修复]后台管理用户管理用户无法搜索的问题;
@ -16,6 +17,7 @@
- [优化]文集内搜索文档;
- [优化]后台文档管理文档编辑模式显示;
- [优化]后台图片管理图片预览功能;
- [优化]文档历史记录对比接口;
### v0.6.8 2021-06-27

View File

@ -15,6 +15,10 @@ urlpatterns = [
path('project_del/',views.admin_project_delete,name="admin_project_del"), # 删除文集
path('doc_manage/',views.admin_doc,name='doc_manage'), # 文档管理
# 文档历史记录管理及接口
path('doc_history_manage/<int:id>/', views.admin_doc_history, name='doc_history_manage'), # 文档历史记录管理
path('api/doc_history/<int:id>/', views.AdminDocHistory.as_view(), name="api_doc_history"), # 文档历史记录接口
path('api/doc_history_detail/', views.AdminDocHistoryDetail.as_view(), name="api_doc_history_detail"), # 文档历史记录详情接口
path('doctemp_manage/',views.admin_doctemp,name='doctemp_manage'), # 文档模板管理
path('setting/',views.admin_setting,name="sys_setting"), # 应用设置
path('forget_pwd/',views.forget_pwd,name='forget_pwd'), # 忘记密码

View File

@ -689,6 +689,63 @@ def admin_doc(request):
}
return JsonResponse(resp_data)
# 后台管理 - 文档管理 - 文档历史管理
@superuser_only
def admin_doc_history(request,id):
doc = Doc.objects.get(id=id)
return render(request,'app_admin/admin_doc_history.html',locals())
# 文档历史接口 - 通过文档id
class AdminDocHistory(APIView):
authentication_classes = [SessionAuthentication, AppMustAuth]
permission_classes = [SuperUserPermission]
def get_object(self, id):
try:
return Doc.objects.get(id=id)
except ObjectDoesNotExist:
raise Http404
# 获取文档的历史记录
def get(self,request, id):
doc = self.get_object(id=id)
page_num = request.query_params.get('page', 1)
limit = request.query_params.get('limit', 10)
history_data = DocHistory.objects.filter(doc=doc).order_by('-create_time')
page = PageNumberPagination() # 实例化一个分页器
page.page_size = limit
page_historys = page.paginate_queryset(history_data, request, view=self) # 进行分页查询
serializer = DocHistorySerializer(page_historys, many=True) # 对分页后的结果进行序列化处理
resp = {
'code': 0,
'data': serializer.data,
'count': history_data.count()
}
return Response(resp)
# 删除文档的历史记录
def delete(self,request,id):
pass
# 文档历史详情接口 - 通过文档历史id
class AdminDocHistoryDetail(APIView):
authentication_classes = [SessionAuthentication, AppMustAuth]
permission_classes = [SuperUserPermission]
def delete(self,request):
try:
id = request.data.get('id','')
his = DocHistory.objects.filter(id=id).delete()
return Response({'code':0})
except:
return Response({'code':5,'data':_("系统异常")})
# 后台管理 - 文档模板管理
@superuser_only

View File

@ -65,6 +65,18 @@ class DocSerializer(ModelSerializer):
pro_name = Project.objects.get(id=obj.top_doc).name
return pro_name
# 文档历史序列化器
class DocHistorySerializer(ModelSerializer):
username = serializers.SerializerMethodField(label="用户名")
class Meta:
model = DocHistory
fields = ('__all__')
def get_username(self,obj):
return obj.create_user.username
# 文档模板序列化器
class DocTempSerializer(ModelSerializer):
class Meta:

View File

@ -1492,7 +1492,7 @@ def diff_doc(request,doc_id,his_id):
doc = Doc.objects.get(id=doc_id) # 查询文档信息
project = Project.objects.get(id=doc.top_doc) # 查询文档所属的文集信息
pro_colla = ProjectCollaborator.objects.filter(project=project, user=request.user) # 查询用户的协作文集信息
if (request.user == doc.create_user) or (pro_colla[0].role == 1):
if (request.user == doc.create_user) or (pro_colla[0].role == 1) or (request.user.is_superuser):
history = DocHistory.objects.get(id=his_id)
history_list = DocHistory.objects.filter(doc=doc).order_by('-create_time')
if history.doc == doc:
@ -1510,7 +1510,7 @@ def diff_doc(request,doc_id,his_id):
doc = Doc.objects.get(id=doc_id) # 查询文档信息
project = Project.objects.get(id=doc.top_doc) # 查询文档所属的文集信息
pro_colla = ProjectCollaborator.objects.filter(project=project, user=request.user) # 查询用户的协作文集信息
if (request.user == doc.create_user) or (pro_colla[0].role == 1):
if (request.user == doc.create_user) or (pro_colla[0].role == 1) or (request.user.is_superuser):
history = DocHistory.objects.get(id=his_id)
if history.doc == doc:
return JsonResponse({'status':True,'data':history.pre_content})

View File

@ -128,7 +128,7 @@
<!-- 单个文档操作 -->
<script type="text/html" id="doc-bar">
{% verbatim %}
<a href="/manage_doc_history/{{d.id}}/" class="pear-btn pear-btn-sm"><i class="layui-icon layui-icon-log"></i></a>
<a href="/admin/doc_history_manage/{{d.id}}/" class="pear-btn pear-btn-sm"><i class="layui-icon layui-icon-log"></i></a>
<!-- <a href="/modify_doc/{{d.id}}/" title="修改文档" class="layui-btn layui-btn-primary pear-btn-sm" target="_blank"><i class="layui-icon layui-icon-edit"></i></a> -->
<button class="pear-btn pear-btn-danger pear-btn-sm" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
{% endverbatim %}
@ -148,7 +148,7 @@
});
let cols = [
[
{type: 'checkbox',width:20},
{type: 'checkbox',width:20},
{title: '文档名称',field: 'name',align: 'left',templet:"#doc-name",minWidth:280},
{title: '状态',field: 'status',align: 'left',templet:"#doc-status",width:90},
{title: '上级',field: 'parent',align: 'left',},
@ -157,7 +157,8 @@
{title: '展开下级',field: 'open_children',align: 'left',width:90, templet:"#open_children"},
{title: '文档作者',field: 'create_user',align: 'left',},
{title: '最后编辑',field: 'modify_time',align: 'left',templet:"#doc-modify-time"},
{title: '操作',toolbar: '#doc-bar',align: 'left',} ]
{title: '操作',toolbar: '#doc-bar',align: 'left',}
]
]
// 渲染表格
table.render({

View File

@ -0,0 +1,122 @@
{% extends 'app_admin/admin_base.html' %}
{% load static %}
{% load i18n %}
{% block title %}{% trans "文档历史版本管理" %}{% endblock %}
{% block content %}
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-row" style="padding-left:15px;">
<span class="layui-breadcrumb" lay-separator=">">
<a href="{% url 'doc_manage' %}">{% trans "文档管理" %}</a>
<a><cite>{% trans "历史版本管理" %}</cite></a>
</span>
</div>
</div>
</div>
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-card-header">
<div class="layui-row">
<span style="font-size:18px;">{% trans "文档:" %}{{doc.name}} {% trans "的历史版本管理" %}</span>
</div>
</div>
<div class="layui-row" >
<table class="layui-table" id="history-table" lay-filter="history-table"></table>
</div>
</div>
</div>
<!-- 创建时间 -->
<script type="text/html" id="create-time">
{% verbatim %}
{{layui.util.toDateString(d.create_time, "yyyy-MM-dd HH:mm:ss")}}
{% endverbatim %}
</script>
<!-- 单个历史记录操作 -->
<script type="text/html" id="history-bar">
{% verbatim %}
<a href="/diff_doc/{{d.doc}}-{{d.id}}/" title="对比查看" class="pear-btn pear-btn-normal pear-btn-sm" target="_blank"><i class="pear-icon pear-icon-browse"></i></a>
<button class="pear-btn pear-btn-danger pear-btn-sm" title="删除记录" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
{% endverbatim %}
</script>
{% endblock %}
{% block custom_script %}
<script>
layui.use(['table', 'form', 'jquery','layer','element'], function() {
let table = layui.table;
let form = layui.form;
let $ = layui.jquery;
var layer = layui.layer;
let element = layui.element;
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
headers: {"X-CSRFToken":'{{ csrf_token }}'},
});
// 表格列名
let cols = [
[
{type: 'checkbox',width:20},
{title: '创建时间',field: 'create_time',align: 'left',templet:"#create-time",minWidth:280},
{title: '创建人',field: 'username',align: 'left',width:90},
{title: '操作',toolbar: '#history-bar',align: 'left',}
]
]
// 渲染表格
table.render({
elem: '#history-table',
method:'get',
url: "/admin/api/doc_history/" + '{{doc.id}}' + '/',
page: true,
cols: cols,
skin: 'line',
});
// 侦听历史记录操作
table.on("tool(history-table)",function(obj){
if (obj.event === 'remove') {
// console.log(obj)
delDocHis(obj.data.id)
}
});
delDocHis = function(history_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 = {
'history_id':history_id,
}
$.ajax({
url:'/admin/api/doc_history_detail/',
type:'delete',
data:{'id':history_id},
success:function(r){
layer.closeAll()
if(r.code == 0){
layer.msg("删除成功",function(){
table.reload("history-table")
})
}else{
layer.msg("删除失败")
}
},
error:function(){
layer.closeAll()
layer.msg("删除异常")
}
})
},
});
};
})
</script>
{% endblock %}