diff --git a/dvadmin-backend/apps/system/models/__init__.py b/dvadmin-backend/apps/system/models/__init__.py index 98f83d0..ee29d6a 100644 --- a/dvadmin-backend/apps/system/models/__init__.py +++ b/dvadmin-backend/apps/system/models/__init__.py @@ -2,3 +2,4 @@ from ..models.config_settings import ConfigSettings from ..models.dict_data import DictData from ..models.dict_details import DictDetails from ..models.web_set import WebSet +from ..models.save_file import SaveFile diff --git a/dvadmin-backend/apps/system/models/save_file.py b/dvadmin-backend/apps/system/models/save_file.py new file mode 100644 index 0000000..48f4695 --- /dev/null +++ b/dvadmin-backend/apps/system/models/save_file.py @@ -0,0 +1,27 @@ +import os +import uuid + +from django.db.models import CharField, FileField +from django.utils import timezone + +from apps.op_drf.models import CoreModel + + +def files_path(instance, filename): + return '/'.join(['system', timezone.now().strftime("%Y-%m-%d"), str(uuid.uuid4()) + os.path.splitext(filename)[-1]]) + + +class SaveFile(CoreModel): + name = CharField(max_length=128, verbose_name="文件名称", null=True, blank=True) + 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) # 本地、阿里云、腾讯云.. + oss_url = CharField(max_length=200, verbose_name="OSS地址", null=True, blank=True) + file = FileField(verbose_name="文件URL", upload_to=files_path, ) + + class Meta: + verbose_name = '文件管理' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.name}" diff --git a/dvadmin-backend/apps/system/serializers.py b/dvadmin-backend/apps/system/serializers.py index a8ed45d..13255d3 100644 --- a/dvadmin-backend/apps/system/serializers.py +++ b/dvadmin-backend/apps/system/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers from apps.op_drf.serializers import CustomModelSerializer -from apps.system.models import DictData, DictDetails, ConfigSettings +from apps.system.models import DictData, DictDetails, ConfigSettings, SaveFile # ================================================= # @@ -89,3 +89,39 @@ class ConfigSettingsCreateUpdateSerializer(CustomModelSerializer): model = ConfigSettings exclude = ('description', 'creator', 'modifier') read_only_fields = ('update_datetime', 'create_datetime', 'creator', 'modifier') + + +# ================================================= # +# ************** 参数设置 序列化器 ************** # +# ================================================= # + +class SaveFileSerializer(CustomModelSerializer): + """ + 文件管理 简单序列化器 + """ + file_url = serializers.CharField(source='file.url', read_only=True) + + class Meta: + model = SaveFile + exclude = ('description',) + + +class SaveFileCreateUpdateSerializer(CustomModelSerializer): + """ + 字典详情 创建/更新时的列化器 + """ + file_url = serializers.CharField(source='file.url', read_only=True) + + def save(self, **kwargs): + files = self.context.get('request').FILES.get('file') + self.validated_data['name'] = files.name + self.validated_data['size'] = files.size + self.validated_data['type'] = files.content_type + self.validated_data['address'] = '本地存储' + instance = super().save(**kwargs) + # 进行判断是否需要OSS上传 + return instance + + class Meta: + model = SaveFile + exclude = ('description', 'creator', 'modifier') diff --git a/dvadmin-backend/apps/system/urls.py b/dvadmin-backend/apps/system/urls.py index 3f7230e..e0319be 100644 --- a/dvadmin-backend/apps/system/urls.py +++ b/dvadmin-backend/apps/system/urls.py @@ -2,14 +2,17 @@ from django.urls import re_path from rest_framework.routers import DefaultRouter from apps.system.views import DictDataModelViewSet, DictDetailsModelViewSet, \ - ConfigSettingsModelViewSet + ConfigSettingsModelViewSet, SaveFileModelViewSet router = DefaultRouter() router.register(r'dict/type', DictDataModelViewSet) router.register(r'dict/data', DictDetailsModelViewSet) router.register(r'config', ConfigSettingsModelViewSet) +router.register(r'savefile', SaveFileModelViewSet) urlpatterns = [ re_path('dict/get/type/(?P.*)/', DictDetailsModelViewSet.as_view({'get': 'dict_details_list'})), re_path('config/configKey/(?P.*)/', ConfigSettingsModelViewSet.as_view({'get': 'get_config_key'})), + # 下载文件 + re_path('savefile/(?P.*)/', SaveFileModelViewSet.as_view({'get': 'download_file'})), ] urlpatterns += router.urls diff --git a/dvadmin-backend/apps/system/views.py b/dvadmin-backend/apps/system/views.py index 6e85ee9..554660e 100644 --- a/dvadmin-backend/apps/system/views.py +++ b/dvadmin-backend/apps/system/views.py @@ -1,11 +1,15 @@ +import os + +from django.conf import settings +from django.http import HttpResponse from rest_framework.request import Request from apps.op_drf.viewsets import CustomModelViewSet from apps.system.filters import DictDetailsFilter, DictDataFilter, ConfigSettingsFilter -from apps.system.models import DictData, DictDetails, ConfigSettings +from apps.system.models import DictData, DictDetails, ConfigSettings, SaveFile from apps.system.serializers import DictDataSerializer, DictDataCreateUpdateSerializer, DictDetailsSerializer, \ DictDetailsCreateUpdateSerializer, DictDetailsListSerializer, ConfigSettingsSerializer, \ - ConfigSettingsCreateUpdateSerializer + ConfigSettingsCreateUpdateSerializer, SaveFileSerializer, SaveFileCreateUpdateSerializer from utils.response import SuccessResponse @@ -84,3 +88,32 @@ class ConfigSettingsModelViewSet(CustomModelViewSet): # if hasattr(self, 'handle_logging'): # self.handle_logging(request, *args, **kwargs) return SuccessResponse(msg=queryset.configValue if queryset else '') + + +class SaveFileModelViewSet(CustomModelViewSet): + """ + 参数设置 模型的CRUD视图 + """ + queryset = SaveFile.objects.all() + serializer_class = SaveFileSerializer + create_serializer_class = SaveFileCreateUpdateSerializer + update_serializer_class = SaveFileCreateUpdateSerializer + # filter_class = ConfigSettingsFilter + search_fields = ('configName',) + ordering = 'id' # 默认排序 + + def download_file(self, request: Request, *args, **kwargs): + """ + 下载文件 + :param request: + :param args: + :param kwargs: + :return: + """ + instance = self.get_object() + file_path = os.path.join(settings.MEDIA_ROOT,str(instance.file)) + with open(file_path, "rb") as f: + res = HttpResponse(f) + res["Content-Type"] = instance.type # 注意格式 + res["Content-Disposition"] = 'filename="{}"'.format(instance.name) + return res diff --git a/dvadmin-backend/scripts/__init__.py b/dvadmin-backend/scripts/__init__.py index a637113..2ba554d 100644 --- a/dvadmin-backend/scripts/__init__.py +++ b/dvadmin-backend/scripts/__init__.py @@ -8,6 +8,6 @@ def getSql(filename): :return: """ pwd = os.path.join(os.getcwd(), 'scripts', filename) - with open(pwd) as fp: - content = fp.read() + with open(pwd,'rb') as fp: + content = fp.read().decode('utf8') return [ele for ele in content.split('\n') if not ele.startswith('--') and ele] diff --git a/dvadmin-ui/src/api/system/savefile.js b/dvadmin-ui/src/api/system/savefile.js new file mode 100644 index 0000000..62e5497 --- /dev/null +++ b/dvadmin-ui/src/api/system/savefile.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + +// 查询文件列表 +export function listSaveFile(query) { + return request({ + url: '/system/savefile/', + method: 'get', + params: query + }) +} + +// 新增文件 +export function addSaveFile(data) { + return request({ + url: '/system/savefile/', + method: 'post', + data: data + }) +} + + +// 删除文件 +export function delSaveFile(menuId) { + return request({ + url: '/system/savefile/' + menuId + '/', + method: 'delete' + }) +} + +// 清理废弃文件 +export function clearSaveFile() { + return request({ + url: '/system/clearsavefile/', + method: 'get' + }) +} diff --git a/dvadmin-ui/src/components/FileUpload/index.vue b/dvadmin-ui/src/components/FileUpload/index.vue index 69942aa..1fe014f 100755 --- a/dvadmin-ui/src/components/FileUpload/index.vue +++ b/dvadmin-ui/src/components/FileUpload/index.vue @@ -61,9 +61,10 @@ export default { default: true } }, + name:'FileUpload', data() { return { - uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 + uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/savefile/", // 上传的图片服务器地址 headers: { Authorization: "Bearer " + getToken(), }, @@ -99,7 +100,7 @@ export default { // 上传前校检格式和大小 handleBeforeUpload(file) { // 校检文件类型 - if (this.fileType) { + if (this.fileType && this.fileType[0] !== 'ALL') { let fileExtension = ""; if (file.name.lastIndexOf(".") > -1) { fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1); @@ -176,4 +177,4 @@ export default { .ele-upload-list__item-content-action .el-link { margin-right: 10px; } - \ No newline at end of file + diff --git a/dvadmin-ui/src/views/permission/menu/index.vue b/dvadmin-ui/src/views/permission/menu/index.vue index ceff220..b9b579c 100755 --- a/dvadmin-ui/src/views/permission/menu/index.vue +++ b/dvadmin-ui/src/views/permission/menu/index.vue @@ -179,8 +179,8 @@ - - + + @@ -325,6 +325,10 @@ let res = this.form.interface_path + ":" + this.form.interface_method this.form.perms = res.toLocaleLowerCase().replace(/(\/)/g,':').replace(/(::)/g,':').replace(/(^:)|(:$)/g, "") }, + /** 组件路径变化,替换斜杠开头 */ + ComponentPathChange(){ + this.form.component_path = this.form.component_path.replace(/(^\/)/g,'') + }, /** 查询菜单列表 */ getList() { this.loading = true; diff --git a/dvadmin-ui/src/views/permission/user/index.vue b/dvadmin-ui/src/views/permission/user/index.vue index 930d068..17b4791 100755 --- a/dvadmin-ui/src/views/permission/user/index.vue +++ b/dvadmin-ui/src/views/permission/user/index.vue @@ -405,7 +405,7 @@ export default { // 设置上传的请求头部 headers: { Authorization: "Bearer " + getToken() }, // 上传的地址 - url: process.env.VUE_APP_BASE_API + "/permission/user/importData" + url: process.env.VUE_APP_BASE_API + "/system/savefile/" }, // 查询参数 queryParams: { diff --git a/dvadmin-ui/src/views/system/savefile/index.vue b/dvadmin-ui/src/views/system/savefile/index.vue new file mode 100755 index 0000000..55fadf0 --- /dev/null +++ b/dvadmin-ui/src/views/system/savefile/index.vue @@ -0,0 +1,277 @@ + + + + +