From 7a453da303928dd86b923480d48e6d0389520845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=BE=89?= Date: Thu, 7 Nov 2024 20:23:41 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=B4=E5=83=8F?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=99=A8=E7=BB=84=E4=BB=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=97=B6url=E4=BC=A0=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/views/system/personal/index.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/views/system/personal/index.vue b/web/src/views/system/personal/index.vue index 6c7d6b4..79f29d3 100644 --- a/web/src/views/system/personal/index.vue +++ b/web/src/views/system/personal/index.vue @@ -354,7 +354,8 @@ const uploadImg = (data: any) => { api.uploadAvatar(formdata).then((res: any) => { if (res.code === 2000) { selectImgVisible.value = false; - state.personalForm.avatar = getBaseURL() + res.data.url; + // state.personalForm.avatar = getBaseURL() + res.data.url; + state.personalForm.avatar = res.data.url; api.updateUserInfo(state.personalForm).then((res: any) => { successMessage('更新成功'); getUserInfo(); From b9976cc2dda79e5a409e0542e8bd10715bc9400c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=BE=89?= Date: Thu, 7 Nov 2024 23:08:11 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E9=99=84=E4=BB=B6=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=9A=84=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/dvadmin/system/views/file_list.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/dvadmin/system/views/file_list.py b/backend/dvadmin/system/views/file_list.py index c595699..3d4b515 100644 --- a/backend/dvadmin/system/views/file_list.py +++ b/backend/dvadmin/system/views/file_list.py @@ -1,6 +1,7 @@ import hashlib import mimetypes +import django_filters from rest_framework import serializers from rest_framework.decorators import action @@ -64,6 +65,15 @@ class FileSerializer(CustomModelSerializer): return super().create(validated_data) +class FileFilter(django_filters.FilterSet): + name = django_filters.CharFilter(field_name="name", lookup_expr="icontains", help_text="文件名") + mime_type = django_filters.CharFilter(field_name="mime_type", lookup_expr="icontains", help_text="文件类型") + + class Meta: + model = FileList + fields = ['name', 'mime_type', 'upload_method'] + + class FileViewSet(CustomModelViewSet): """ 文件管理接口 @@ -75,5 +85,5 @@ class FileViewSet(CustomModelViewSet): """ queryset = FileList.objects.all() serializer_class = FileSerializer - filter_fields = ['name', ] + filter_class = FileFilter permission_classes = [] \ No newline at end of file From 6ad048b86a7576b64c083de6e89f4dc002b2aed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=BE=89?= Date: Thu, 7 Nov 2024 23:08:25 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E9=99=84=E4=BB=B6model=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/dvadmin/system/models.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py index f9d2287..517792c 100644 --- a/backend/dvadmin/system/models.py +++ b/backend/dvadmin/system/models.py @@ -408,6 +408,11 @@ class FileList(CoreModel): mime_type = models.CharField(max_length=100, blank=True, verbose_name="Mime类型", help_text="Mime类型") size = models.CharField(max_length=36, blank=True, verbose_name="文件大小", help_text="文件大小") md5sum = models.CharField(max_length=36, blank=True, verbose_name="文件md5", help_text="文件md5") + UPLOAD_METHOD_CHOIDES = ( + (0, '默认上传'), + (1, '文件选择器上传'), + ) + upload_method = models.SmallIntegerField(default=0, blank=True, null=True, choices=UPLOAD_METHOD_CHOIDES, verbose_name='上传方式', help_text='上传方式') def save(self, *args, **kwargs): if not self.md5sum: # file is new From 4f85de32474bc002caaa401a93531729742c006d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=BE=89?= Date: Fri, 8 Nov 2024 23:20:17 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/dvadmin/system/models.py | 7 + backend/dvadmin/system/views/file_list.py | 17 +- web/src/components/fileSelector/fileItem.vue | 67 ++++++ web/src/components/fileSelector/index.vue | 222 +++++++++++++++++++ web/src/components/fileSelector/types.ts | 7 + web/src/views/system/fileList/crud.tsx | 97 +++++++- web/src/views/system/fileList/index.vue | 35 ++- web/vite.config.ts | 2 +- 8 files changed, 436 insertions(+), 18 deletions(-) create mode 100644 web/src/components/fileSelector/fileItem.vue create mode 100644 web/src/components/fileSelector/index.vue create mode 100644 web/src/components/fileSelector/types.ts diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py index 517792c..5d500b7 100644 --- a/backend/dvadmin/system/models.py +++ b/backend/dvadmin/system/models.py @@ -413,6 +413,13 @@ class FileList(CoreModel): (1, '文件选择器上传'), ) upload_method = models.SmallIntegerField(default=0, blank=True, null=True, choices=UPLOAD_METHOD_CHOIDES, verbose_name='上传方式', help_text='上传方式') + FILE_TYPE_CHOIDES = ( + (0, '图片'), + (1, '视频'), + (2, '音频'), + (3, '其他'), + ) + file_type = models.SmallIntegerField(default=3, choices=FILE_TYPE_CHOIDES, blank=True, null=True, verbose_name='文件类型', help_text='文件类型') def save(self, *args, **kwargs): if not self.md5sum: # file is new diff --git a/backend/dvadmin/system/views/file_list.py b/backend/dvadmin/system/views/file_list.py index 3d4b515..9841dab 100644 --- a/backend/dvadmin/system/views/file_list.py +++ b/backend/dvadmin/system/views/file_list.py @@ -36,6 +36,8 @@ class FileSerializer(CustomModelSerializer): validated_data['md5sum'] = md5.hexdigest() validated_data['engine'] = file_engine validated_data['mime_type'] = file.content_type + ft = {'image':0,'video':1,'audio':2}.get(file.content_type.split('/')[0], None) + validated_data['file_type'] = 3 if ft is None else ft if file_backup: validated_data['url'] = file if file_engine == 'oss': @@ -65,13 +67,20 @@ class FileSerializer(CustomModelSerializer): return super().create(validated_data) +class FileAllSerializer(CustomModelSerializer): + + class Meta: + model = FileList + fields = ['id', 'name'] + + class FileFilter(django_filters.FilterSet): name = django_filters.CharFilter(field_name="name", lookup_expr="icontains", help_text="文件名") mime_type = django_filters.CharFilter(field_name="mime_type", lookup_expr="icontains", help_text="文件类型") class Meta: model = FileList - fields = ['name', 'mime_type', 'upload_method'] + fields = ['name', 'mime_type', 'upload_method', 'file_type'] class FileViewSet(CustomModelViewSet): @@ -86,4 +95,8 @@ class FileViewSet(CustomModelViewSet): queryset = FileList.objects.all() serializer_class = FileSerializer filter_class = FileFilter - permission_classes = [] \ No newline at end of file + permission_classes = [] + + @action(methods=['GET'], detail=False) + def get_all(self, request): + return DetailResponse(data=self.get_serializer(self.get_queryset(), many=True).data) diff --git a/web/src/components/fileSelector/fileItem.vue b/web/src/components/fileSelector/fileItem.vue new file mode 100644 index 0000000..fc75d89 --- /dev/null +++ b/web/src/components/fileSelector/fileItem.vue @@ -0,0 +1,67 @@ + + + \ No newline at end of file diff --git a/web/src/components/fileSelector/index.vue b/web/src/components/fileSelector/index.vue new file mode 100644 index 0000000..e826b4e --- /dev/null +++ b/web/src/components/fileSelector/index.vue @@ -0,0 +1,222 @@ + + + + + \ No newline at end of file diff --git a/web/src/components/fileSelector/types.ts b/web/src/components/fileSelector/types.ts new file mode 100644 index 0000000..76d135b --- /dev/null +++ b/web/src/components/fileSelector/types.ts @@ -0,0 +1,7 @@ +export const SHOW = { + IMAGE: 0b1000, // 图片 + VIDEO: 0b0100, // 视频 + AUDIO: 0b0010, // 音频 + OTHER: 0b0001, // 其他 + ALL: 0b1111, // 全部 +}; \ No newline at end of file diff --git a/web/src/views/system/fileList/crud.tsx b/web/src/views/system/fileList/crud.tsx index 5c6a0d5..4a77c35 100644 --- a/web/src/views/system/fileList/crud.tsx +++ b/web/src/views/system/fileList/crud.tsx @@ -1,7 +1,17 @@ import * as api from './api'; -import { UserPageQuery, AddReq, DelReq, EditReq, CrudExpose, CrudOptions, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'; +import { + UserPageQuery, + AddReq, + DelReq, + EditReq, + CrudExpose, + CrudOptions, + CreateCrudOptionsProps, + CreateCrudOptionsRet, + dict +} from '@fast-crud/fast-crud'; -export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { +export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { const pageRequest = async (query: UserPageQuery) => { return await api.GetList(query); }; @@ -20,7 +30,8 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp actionbar: { buttons: { add: { - show: false, + show: true, + click: () => context.openAddHandle?.() }, }, }, @@ -34,7 +45,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp //固定右侧 fixed: 'right', width: 200, - show:false, + show: false, buttons: { view: { show: false, @@ -95,12 +106,13 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp show: true, }, type: 'input', - column:{ - minWidth: 120, + column: { + minWidth: 200, }, form: { component: { placeholder: '请输入文件名称', + clearable: true }, }, }, @@ -110,8 +122,8 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp search: { disabled: true, }, - column:{ - minWidth: 200, + column: { + minWidth: 360, }, }, md5sum: { @@ -119,13 +131,76 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp search: { disabled: true, }, - column:{ - minWidth: 120, + column: { + minWidth: 300, }, form: { - disabled: false, + disabled: false }, }, + mime_type: { + title: '文件类型', + type: 'input', + form: { + show: false, + component: { + placeholder: '请输入文件名称', + clearable: true + }, + }, + column: { + minWidth: 160 + } + }, + file_type: { + title: '文件类型', + type: 'dict-select', + dict: dict({ + data: [ + { label: '图片', value: 0, color: 'success' }, + { label: '视频', value: 1, color: 'warning' }, + { label: '音频', value: 2, color: 'danger' }, + { label: '其他', value: 3, color: 'primary' }, + ] + }), + column: { + show: false + }, + search: { + show: true + }, + form: { + show: false, + component: { + placeholder: '请选择文件类型' + } + } + }, + size: { + title: '文件大小', + column: { + minWidth: 120 + }, + form: { + show: false + } + }, + upload_method: { + title: '上传方式', + type: 'dict-select', + dict: dict({ + data: [ + { label: '默认上传', value: 0, color: 'primary' }, + { label: '文件选择器上传', value: 1, color: 'warning' }, + ] + }), + column: { + minWidth: 140 + }, + search: { + show: true + } + } }, }, }; diff --git a/web/src/views/system/fileList/index.vue b/web/src/views/system/fileList/index.vue index 119c73a..294603a 100644 --- a/web/src/views/system/fileList/index.vue +++ b/web/src/views/system/fileList/index.vue @@ -1,13 +1,40 @@ + \ No newline at end of file diff --git a/web/vite.config.ts b/web/vite.config.ts index ed6dec2..51ffc73 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -31,7 +31,7 @@ const viteConfig = defineConfig((mode: ConfigEnv) => { server: { host: '0.0.0.0', port: env.VITE_PORT as unknown as number, - open: true, + open: false, hmr: true, proxy: { '/gitee': { From 72e046fd6defe2f78540e2c768b516bb3f96660a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=BE=89?= Date: Fri, 8 Nov 2024 23:30:25 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/fileSelector/fileItem.vue | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/src/components/fileSelector/fileItem.vue b/web/src/components/fileSelector/fileItem.vue index fc75d89..5493770 100644 --- a/web/src/components/fileSelector/fileItem.vue +++ b/web/src/components/fileSelector/fileItem.vue @@ -10,9 +10,7 @@ import { ref, defineProps, PropType, watch, onMounted, h } from 'vue'; const props = defineProps({ fileData: { type: Object as PropType, required: true }, }); -const _OtherFileComponent = defineComponent({ - template: '' -}) +const _OtherFileComponent = defineComponent({ template: '' }); const FileTypes = [ { tag: 'img', attr: { src: props.fileData.url, draggable: false } }, { tag: 'video', attr: { src: props.fileData.url, controls: false, autoplay: true, muted: true, loop: true } }, From 21d61794bc596df1319ea659b32cb5b0e92bff13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=BE=89?= Date: Sun, 10 Nov 2024 19:06:36 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/fileSelector/index.vue | 17 +++++++++++++---- web/src/views/system/fileList/index.vue | 9 ++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/web/src/components/fileSelector/index.vue b/web/src/components/fileSelector/index.vue index e826b4e..89401a3 100644 --- a/web/src/components/fileSelector/index.vue +++ b/web/src/components/fileSelector/index.vue @@ -1,10 +1,10 @@