This commit is contained in:
parent
e85bfe3f08
commit
48900fec5e
|
@ -1,4 +1,5 @@
|
|||
import { getToken } from "@/utils/auth";
|
||||
import { getToken } from "@/utils/auth"
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function uploadUrl() {
|
||||
return process.env.VUE_APP_BASE_API + '/file/'
|
||||
|
@ -6,4 +7,12 @@ export function uploadUrl() {
|
|||
|
||||
export function upHeaders() {
|
||||
return { Authorization: "Bearer " + getToken() }
|
||||
}
|
||||
|
||||
export function getFileList(query) {
|
||||
return request({
|
||||
url: '/file/',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
|
@ -97,6 +97,12 @@ export const asyncRoutes = [
|
|||
name: 'Dict',
|
||||
component: () => import('@/views/system/dict'),
|
||||
meta: { title: '数据字典', icon: 'example', perms: ['dict_manage'] }
|
||||
},
|
||||
{
|
||||
path: 'file',
|
||||
name: 'File',
|
||||
component: () => import('@/views/system/file'),
|
||||
meta: { title: '文件库', icon: 'documentation', perms: ['file_room'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -114,7 +120,17 @@ export const asyncRoutes = [
|
|||
meta: { title: '权限菜单', icon: 'example', perms: ['perm_manage'] }
|
||||
},
|
||||
{
|
||||
path: 'external-link',
|
||||
path: 'form-gen-link',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: 'https://jakhuang.github.io/form-generator/',
|
||||
meta: { title: '表单设计器', icon: 'link', perms: ['dev_form_gen'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'docs-link',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
|
@ -124,7 +140,7 @@ export const asyncRoutes = [
|
|||
]
|
||||
},
|
||||
{
|
||||
path: 'external-link2',
|
||||
path: 'admin-link',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div>
|
||||
<el-select
|
||||
v-model="listQuery.type"
|
||||
placeholder="文件类型"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
class="filter-item"
|
||||
@change="handleFilter"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in enabledOptions"
|
||||
:key="item.key"
|
||||
:label="item.display_name"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-model="listQuery.search"
|
||||
placeholder="文件名"
|
||||
style="width: 300px;"
|
||||
class="filter-item"
|
||||
@keyup.enter.native="handleFilter"
|
||||
/>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
@click="handleFilter"
|
||||
>搜索</el-button>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
style="margin-left: 10px;"
|
||||
type="primary"
|
||||
icon="el-icon-refresh-left"
|
||||
@click="resetFilter"
|
||||
>刷新重置</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="fileList.results"
|
||||
style="width: 100%;margin-top:10px;"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="600"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column align="center" label="名称">
|
||||
<template slot-scope="scope">
|
||||
<el-link type="primary" :href="scope.row.file" target="_blank">{{ scope.row.name }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="header-center" label="类型">
|
||||
<template slot-scope="scope">{{ scope.row.type }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="header-center" label="格式">
|
||||
<template slot-scope="scope">{{ scope.row.mime }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="header-center" label="大小(B)">
|
||||
<template slot-scope="scope">{{ scope.row.size }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="header-center" label="地址">
|
||||
<template slot-scope="scope">{{ scope.row.path }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上传日期">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.create_time }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="fileList.count>0"
|
||||
:total="fileList.count"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.page_size"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getFileList } from "@/api/file"
|
||||
import Pagination from "@/components/Pagination"
|
||||
export default {
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
fileList: {count:0},
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
page_size: 20
|
||||
},
|
||||
enabledOptions: [
|
||||
{ key: "文档", display_name: "文档" },
|
||||
{ key: "图片", display_name: "图片" },
|
||||
{ key: "音频", display_name: "音频" },
|
||||
{ key: "视频", display_name: "视频" },
|
||||
{ key: "其它", display_name: "其它" }
|
||||
],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
getFileList(this.listQuery).then(response => {
|
||||
if (response.data) {
|
||||
this.fileList = response.data
|
||||
}
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
resetFilter() {
|
||||
this.listQuery = {
|
||||
page: 1,
|
||||
page_size: 20
|
||||
};
|
||||
this.getList();
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1;
|
||||
this.getList();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -82,16 +82,6 @@
|
|||
slot-scope="scope"
|
||||
>{{ scope.row.dept_name }}</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column align="header-center" label="状态">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.is_active"
|
||||
:disabled="!checkPermission(['user_update'])"
|
||||
active-color="#409EFF"
|
||||
inactive-color="#F56C6C"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>-->
|
||||
<el-table-column label="创建日期">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.date_joined }}</span>
|
||||
|
|
|
@ -193,6 +193,9 @@ class CommonBModel(SoftModel):
|
|||
|
||||
|
||||
class File(CommonAModel):
|
||||
"""
|
||||
文件存储表,业务表根据具体情况选择是否外键关联
|
||||
"""
|
||||
name = models.CharField('名称', max_length=30, null=True, blank=True)
|
||||
size = models.IntegerField('文件大小', default=1, null=True, blank=True)
|
||||
file = models.FileField('文件', upload_to='%Y/%m/%d/')
|
||||
|
@ -206,3 +209,10 @@ class File(CommonAModel):
|
|||
mime = models.CharField('文件格式', max_length=50, null=True, blank=True)
|
||||
type = models.CharField('文件类型', max_length=50, choices=type_choices, default='文档')
|
||||
path = models.CharField('地址', max_length=1000, null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '文件库'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
|
@ -59,26 +59,27 @@ def rbac_filter_queryset(user, queryset):
|
|||
"""
|
||||
roles = user.roles
|
||||
data_range = roles.values_list('datas', flat=True)
|
||||
if '全部' in data_range:
|
||||
return queryset
|
||||
elif '自定义' in data_range:
|
||||
if roles.depts.exists():
|
||||
queryset = queryset.filter(belong_to__in = roles.depts)
|
||||
if hasattr(queryset.model, 'belong_to'):
|
||||
if '全部' in data_range:
|
||||
return queryset
|
||||
elif '同级及以下' in data_range:
|
||||
if user.dept.pid:
|
||||
belong_tos = get_child_queryset2(user.dept.pid)
|
||||
elif '自定义' in data_range:
|
||||
if roles.depts.exists():
|
||||
queryset = queryset.filter(belong_to__in = roles.depts)
|
||||
return queryset
|
||||
elif '同级及以下' in data_range:
|
||||
if user.dept.pid:
|
||||
belong_tos = get_child_queryset2(user.dept.pid)
|
||||
queryset = queryset.filter(belong_to__in = belong_tos)
|
||||
return queryset
|
||||
elif '本级及以下' in data_range:
|
||||
belong_tos = get_child_queryset2(user.dept)
|
||||
queryset = queryset.filter(belong_to__in = belong_tos)
|
||||
return queryset
|
||||
elif '本级及以下' in data_range:
|
||||
belong_tos = get_child_queryset2(user.dept)
|
||||
queryset = queryset.filter(belong_to__in = belong_tos)
|
||||
return queryset
|
||||
elif '本级' in data_range:
|
||||
queryset = queryset.filter(belong_to = user.dept)
|
||||
return queryset
|
||||
elif '仅本人' in data_range:
|
||||
queryset = queryset.filter(Q(create_by=user)|Q(update_by=user))
|
||||
return queryset
|
||||
elif '本级' in data_range:
|
||||
queryset = queryset.filter(belong_to = user.dept)
|
||||
return queryset
|
||||
elif '仅本人' in data_range:
|
||||
queryset = queryset.filter(Q(create_by=user)|Q(update_by=user))
|
||||
return queryset
|
||||
return queryset
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ class FileViewSet(ModelViewSet):
|
|||
parser_classes = [MultiPartParser, JSONParser]
|
||||
queryset = File.objects.all()
|
||||
serializer_class = FileSerializer
|
||||
filterset_fields = ['type']
|
||||
search_fields = ['name']
|
||||
ordering = '-create_time'
|
||||
|
||||
|
|
|
@ -13,26 +13,21 @@ Including another URLconf
|
|||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
from rest_framework import routers
|
||||
from rest_framework.documentation import include_docs_urls
|
||||
from rest_framework_simplejwt.views import (TokenObtainPairView,
|
||||
TokenRefreshView)
|
||||
|
||||
from django.conf import settings
|
||||
from apps.system.views import LogoutView
|
||||
from utils.view import UploadFileView
|
||||
|
||||
|
||||
from rest_framework import routers
|
||||
from apps.system.views import FileViewSet
|
||||
from apps.system.views import FileViewSet, LogoutView
|
||||
router = routers.DefaultRouter()
|
||||
router.register('file', FileViewSet, basename="file")
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('upload/', UploadFileView.as_view(), name='file_upload'),
|
||||
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||
path('token/black/', LogoutView.as_view(), name='token_black'),
|
||||
|
@ -42,4 +37,3 @@ urlpatterns = [
|
|||
path('', include(router.urls)),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
|
||||
|
|
|
@ -10,21 +10,21 @@ import os
|
|||
import uuid
|
||||
|
||||
|
||||
class UploadFileView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = (MultiPartParser,)
|
||||
# class UploadFileView(APIView):
|
||||
# permission_classes = [IsAuthenticated]
|
||||
# parser_classes = (MultiPartParser,)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
fileobj = request.FILES['file']
|
||||
file_name = fileobj.name.encode('utf-8').decode('utf-8')
|
||||
file_name_new = str(uuid.uuid1()) + '.' + file_name.split('.')[-1]
|
||||
subfolder = os.path.join('media', datetime.now().strftime("%Y%m%d"))
|
||||
if not os.path.exists(subfolder):
|
||||
os.mkdir(subfolder)
|
||||
file_path = os.path.join(subfolder, file_name_new)
|
||||
file_path = file_path.replace('\\', '/')
|
||||
with open(file_path, 'wb') as f:
|
||||
for chunk in fileobj.chunks():
|
||||
f.write(chunk)
|
||||
resdata = {"name": file_name, "path": '/' + file_path}
|
||||
return Response(resdata)
|
||||
# def post(self, request, *args, **kwargs):
|
||||
# fileobj = request.FILES['file']
|
||||
# file_name = fileobj.name.encode('utf-8').decode('utf-8')
|
||||
# file_name_new = str(uuid.uuid1()) + '.' + file_name.split('.')[-1]
|
||||
# subfolder = os.path.join('media', datetime.now().strftime("%Y%m%d"))
|
||||
# if not os.path.exists(subfolder):
|
||||
# os.mkdir(subfolder)
|
||||
# file_path = os.path.join(subfolder, file_name_new)
|
||||
# file_path = file_path.replace('\\', '/')
|
||||
# with open(file_path, 'wb') as f:
|
||||
# for chunk in fileobj.chunks():
|
||||
# f.write(chunk)
|
||||
# resdata = {"name": file_name, "path": '/' + file_path}
|
||||
# return Response(resdata)
|
||||
|
|
Loading…
Reference in New Issue