parent
7525e6cf2c
commit
e900deb2b4
|
@ -20,6 +20,7 @@ class CustomModelSerializer(ModelSerializer):
|
|||
# 添加默认时间返回格式
|
||||
create_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
|
||||
update_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
|
||||
creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True)
|
||||
|
||||
def __init__(self, instance=None, data=empty, request=None, **kwargs):
|
||||
super().__init__(instance, data, **kwargs)
|
||||
|
|
|
@ -43,6 +43,7 @@ class SaveFileFilter(django_filters.rest_framework.FilterSet):
|
|||
文件管理 简单过滤器
|
||||
"""
|
||||
name = django_filters.CharFilter(lookup_expr='icontains')
|
||||
type = django_filters.CharFilter(lookup_expr='icontains')
|
||||
|
||||
class Meta:
|
||||
model = SaveFile
|
||||
|
|
|
@ -16,6 +16,7 @@ class SaveFile(CoreModel):
|
|||
type = CharField(max_length=32, verbose_name="文件类型", null=True, blank=True)
|
||||
size = CharField(max_length=64, verbose_name="文件大小", null=True, blank=True)
|
||||
address = CharField(max_length=16, verbose_name="存储位置", null=True, blank=True) # 本地、阿里云、腾讯云..
|
||||
source = CharField(max_length=16, verbose_name="文件来源", null=True, blank=True) # 导出、用户上传.
|
||||
oss_url = CharField(max_length=200, verbose_name="OSS地址", null=True, blank=True)
|
||||
status = BooleanField(default=True, verbose_name="文件是否存在")
|
||||
file = FileField(verbose_name="文件URL", upload_to=files_path, )
|
||||
|
|
|
@ -120,7 +120,7 @@ class ConfigSettingsCreateUpdateSerializer(CustomModelSerializer):
|
|||
|
||||
|
||||
# ================================================= #
|
||||
# ************** 参数设置 序列化器 ************** #
|
||||
# ************** 文件管理 序列化器 ************** #
|
||||
# ================================================= #
|
||||
|
||||
class SaveFileSerializer(CustomModelSerializer):
|
||||
|
@ -136,7 +136,7 @@ class SaveFileSerializer(CustomModelSerializer):
|
|||
|
||||
class SaveFileCreateUpdateSerializer(CustomModelSerializer):
|
||||
"""
|
||||
字典详情 创建/更新时的列化器
|
||||
文件管理 创建/更新时的列化器
|
||||
"""
|
||||
file_url = serializers.CharField(source='file.url', read_only=True)
|
||||
|
||||
|
@ -146,6 +146,7 @@ class SaveFileCreateUpdateSerializer(CustomModelSerializer):
|
|||
self.validated_data['size'] = files.size
|
||||
self.validated_data['type'] = files.content_type
|
||||
self.validated_data['address'] = '本地存储'
|
||||
self.validated_data['source'] = '用户上传'
|
||||
instance = super().save(**kwargs)
|
||||
# 进行判断是否需要OSS上传
|
||||
return instance
|
||||
|
@ -228,7 +229,6 @@ class LoginInforSerializer(CustomModelSerializer):
|
|||
"""
|
||||
登录日志 简单序列化器
|
||||
"""
|
||||
creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = LoginInfor
|
||||
|
@ -239,7 +239,6 @@ class ExportLoginInforSerializer(CustomModelSerializer):
|
|||
"""
|
||||
导出 登录日志 简单序列化器
|
||||
"""
|
||||
creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = LoginInfor
|
||||
|
@ -255,7 +254,6 @@ class OperationLogSerializer(CustomModelSerializer):
|
|||
"""
|
||||
操作日志 简单序列化器
|
||||
"""
|
||||
creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = OperationLog
|
||||
|
@ -266,7 +264,6 @@ class ExportOperationLogSerializer(CustomModelSerializer):
|
|||
"""
|
||||
导出 操作日志 简单序列化器
|
||||
"""
|
||||
creator_name = serializers.SlugRelatedField(slug_field="username", source="creator", read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = OperationLog
|
||||
|
|
|
@ -42,5 +42,7 @@ urlpatterns = [
|
|||
re_path('celery_log/clean/', CeleryLogModelViewSet.as_view({'delete': 'clean_all', })),
|
||||
# 导出定时日志
|
||||
re_path('celery_log/export/', CeleryLogModelViewSet.as_view({'get': 'export', })),
|
||||
# 清除废弃文件
|
||||
re_path('clearsavefile/', SaveFileModelViewSet.as_view({'post': 'clearsavefile', })),
|
||||
]
|
||||
urlpatterns += router.urls
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from rest_framework.request import Request
|
||||
|
||||
|
@ -16,6 +19,7 @@ from ..system.serializers import DictDataSerializer, DictDataCreateUpdateSeriali
|
|||
OperationLogSerializer, ExportOperationLogSerializer, ExportLoginInforSerializer, CeleryLogSerializer, \
|
||||
ExportCeleryLogSerializer
|
||||
from ..utils.export_excel import export_excel_save_model
|
||||
from ..utils.file_util import get_all_files, remove_empty_dir, delete_files
|
||||
from ..utils.response import SuccessResponse
|
||||
|
||||
|
||||
|
@ -149,6 +153,26 @@ class SaveFileModelViewSet(CustomModelViewSet):
|
|||
search_fields = ('configName',)
|
||||
ordering = '-create_datetime' # 默认排序
|
||||
|
||||
def clearsavefile(self, request: Request, *args, **kwargs):
|
||||
"""
|
||||
清理废弃文件
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
# 获取废弃文件列表
|
||||
file_list = get_all_files(os.path.join(settings.MEDIA_ROOT, 'system'))
|
||||
queryset_files = [os.path.join(os.path.join(settings.MEDIA_ROOT) + os.sep, ele) for ele in
|
||||
list(self.get_queryset().values_list('file', flat=True))]
|
||||
|
||||
delete_list = list(set(file_list) - set(queryset_files))
|
||||
# 进行文件删除操作
|
||||
delete_files(delete_list)
|
||||
# 递归删除空文件
|
||||
remove_empty_dir(os.path.join(settings.MEDIA_ROOT, 'system'))
|
||||
return SuccessResponse(msg=f"成功清理废弃文件{len(delete_list)}个")
|
||||
|
||||
|
||||
class MessagePushModelViewSet(CustomModelViewSet):
|
||||
"""
|
||||
|
|
|
@ -134,7 +134,9 @@ def export_excel_save_model(request, field_data, data, FilName):
|
|||
savefile.type = 'application/vnd.ms-excel'
|
||||
savefile.size = os.path.getsize(os.path.join(settings.MEDIA_ROOT, file_rul))
|
||||
savefile.address = '本地存储'
|
||||
savefile.source = '导出'
|
||||
savefile.creator = request.user
|
||||
savefile.dept_belong_id = getattr(request.user, 'dept_id', None)
|
||||
savefile.modifier = request.user.username
|
||||
savefile.save()
|
||||
return SaveFileSerializer(savefile).data
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
"""
|
||||
封装文件操作:
|
||||
● 递归读取所有文件目录形成列表
|
||||
● 递归删除空目录
|
||||
● 批量删除文件
|
||||
"""
|
||||
import os
|
||||
|
||||
|
||||
def get_all_files(targetDir):
|
||||
"""
|
||||
递归读取所有文件目录形成列表
|
||||
:param targetDir:
|
||||
:return:
|
||||
"""
|
||||
files = []
|
||||
listFiles = os.listdir(targetDir)
|
||||
for i in range(0, len(listFiles)):
|
||||
path = os.path.join(targetDir, listFiles[i])
|
||||
if os.path.isdir(path):
|
||||
files.extend(get_all_files(path))
|
||||
elif os.path.isfile(path):
|
||||
files.append(path)
|
||||
return files
|
||||
|
||||
|
||||
def remove_empty_dir(path):
|
||||
"""
|
||||
递归删除空目录
|
||||
:param path:
|
||||
:return:
|
||||
"""
|
||||
for root, dirs, files in os.walk(path, topdown=False):
|
||||
if not files and not dirs:
|
||||
os.rmdir(root)
|
||||
|
||||
|
||||
def delete_files(delete_list: list):
|
||||
"""
|
||||
批量删除文件
|
||||
:param delete_list:
|
||||
:return:
|
||||
"""
|
||||
for file_path in delete_list:
|
||||
try:
|
||||
os.remove(file_path)
|
||||
except(FileNotFoundError):
|
||||
pass
|
|
@ -1,4 +1,5 @@
|
|||
asgiref==3.3.1
|
||||
celery==5.0.5
|
||||
Django==2.2.16
|
||||
django-cors-headers==3.7.0
|
||||
django_celery_beat==2.2.0
|
||||
|
|
|
@ -79,8 +79,8 @@
|
|||
"vue-template-compiler": "2.6.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9",
|
||||
"npm": ">= 3.0.0"
|
||||
"node": ">=12.0",
|
||||
"npm": ">= 6.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<el-form-item label="文件类型" prop="type">
|
||||
<el-input
|
||||
v-model="queryParams.type"
|
||||
placeholder="请输入文件类型(待完善)"
|
||||
placeholder="请输入文件类型"
|
||||
clearable
|
||||
size="small"
|
||||
style="width: 240px"
|
||||
|
@ -72,8 +72,33 @@
|
|||
<el-table-column label="文件类型" width="150" align="center" prop="type"/>
|
||||
<el-table-column label="文件大小" width="90" align="center" prop="size"/>
|
||||
<el-table-column label="存储位置" align="center" prop="address"/>
|
||||
<el-table-column label="文件本地地址" align="center" prop="file" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="OSS地址" align="center" prop="oss_url" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="文件来源" align="center" prop="source"/>
|
||||
<el-table-column label="文件本地地址" align="center" prop="file" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-document-copy"
|
||||
@click="CopyFileUrl(scope.row.file)"
|
||||
v-if="scope.row.file"
|
||||
></el-button>
|
||||
|
||||
<span>{{ scope.row.file }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="OSS地址" align="center" prop="oss_url" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-document-copy"
|
||||
@click="CopyFileUrl(scope.row.oss_url)"
|
||||
v-if="scope.row.oss_url"
|
||||
></el-button>
|
||||
|
||||
<span>{{ scope.row.oss_url }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="create_datetime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.create_datetime) }}</span>
|
||||
|
@ -218,9 +243,9 @@
|
|||
type: "warning"
|
||||
}).then(function () {
|
||||
return clearSaveFile();
|
||||
}).then(() => {
|
||||
}).then((values) => {
|
||||
this.getList();
|
||||
this.msgSuccess("删除成功");
|
||||
this.msgSuccess(values.msg);
|
||||
})
|
||||
},
|
||||
/** 完成按钮 */
|
||||
|
@ -229,6 +254,17 @@
|
|||
this.open = false;
|
||||
this.$refs.saveFile.fileList = []
|
||||
},
|
||||
CopyFileUrl(values){
|
||||
const input = document.createElement('input');
|
||||
document.body.appendChild(input);
|
||||
input.setAttribute('value', values);
|
||||
input.select();
|
||||
if (document.execCommand('copy')) {
|
||||
document.execCommand('copy');
|
||||
this.msgSuccess("复制成功");
|
||||
}
|
||||
document.body.removeChild(input);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue