diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py
index f9d2287..5d500b7 100644
--- a/backend/dvadmin/system/models.py
+++ b/backend/dvadmin/system/models.py
@@ -408,6 +408,18 @@ 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='上传方式')
+ 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 c595699..9841dab 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
@@ -35,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':
@@ -64,6 +67,22 @@ 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', 'file_type']
+
+
class FileViewSet(CustomModelViewSet):
"""
文件管理接口
@@ -75,5 +94,9 @@ class FileViewSet(CustomModelViewSet):
"""
queryset = FileList.objects.all()
serializer_class = FileSerializer
- filter_fields = ['name', ]
- permission_classes = []
\ No newline at end of file
+ filter_class = FileFilter
+ 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..5493770
--- /dev/null
+++ b/web/src/components/fileSelector/fileItem.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
\ 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..00160be
--- /dev/null
+++ b/web/src/components/fileSelector/index.vue
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+ 文件选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
\ 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..b388ad4 100644
--- a/web/src/views/system/fileList/index.vue
+++ b/web/src/views/system/fileList/index.vue
@@ -1,13 +1,35 @@
-
+
+
+
+ 上传
+
+
+
+ {{ scope.row.size ? getSizeDisplay(scope.row.size) : '0b' }}
+
+
+
+
\ No newline at end of file
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();
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': {