mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
style: 增加计算文件夹大小接口
This commit is contained in:
parent
450114f049
commit
d333fae2fe
@ -207,3 +207,17 @@ func (b *BaseApi) Download(c *gin.Context) {
|
||||
}
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
func (b *BaseApi) Size(c *gin.Context) {
|
||||
var req dto.DirSizeReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := fileService.DirSize(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
@ -75,3 +75,11 @@ type FileDownload struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type DirSizeReq struct {
|
||||
Path string `json:"path" validate:"required"`
|
||||
}
|
||||
|
||||
type DirSizeRes struct {
|
||||
Size float64 `json:"size" validate:"required"`
|
||||
}
|
||||
|
@ -167,6 +167,15 @@ func (f FileService) FileDownload(d dto.FileDownload) (string, error) {
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
func (f FileService) DirSize(req dto.DirSizeReq) (dto.DirSizeRes, error) {
|
||||
fo := files.NewFileOp()
|
||||
size, err := fo.GetDirSize(req.Path)
|
||||
if err != nil {
|
||||
return dto.DirSizeRes{}, err
|
||||
}
|
||||
return dto.DirSizeRes{Size: size}, nil
|
||||
}
|
||||
|
||||
func getUuid() string {
|
||||
b := make([]byte, 16)
|
||||
_, _ = io.ReadFull(rand.Reader, b)
|
||||
|
@ -29,6 +29,7 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) {
|
||||
fileRouter.POST("/wget", baseApi.WgetFile)
|
||||
fileRouter.POST("/move", baseApi.MoveFile)
|
||||
fileRouter.POST("/download", baseApi.Download)
|
||||
fileRouter.POST("/size", baseApi.Size)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type FileOp struct {
|
||||
@ -221,6 +222,23 @@ func (f FileOp) CopyFile(src, dst string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f FileOp) GetDirSize(path string) (float64, error) {
|
||||
var m sync.Map
|
||||
var wg sync.WaitGroup
|
||||
|
||||
wg.Add(1)
|
||||
go ScanDir(f.Fs, path, &m, &wg)
|
||||
wg.Wait()
|
||||
|
||||
var dirSize float64
|
||||
m.Range(func(k, v interface{}) bool {
|
||||
dirSize = dirSize + v.(float64)
|
||||
return true
|
||||
})
|
||||
|
||||
return dirSize, nil
|
||||
}
|
||||
|
||||
type CompressType string
|
||||
|
||||
const (
|
||||
|
@ -2,9 +2,12 @@ package files
|
||||
|
||||
import (
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
"github.com/spf13/afero"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func IsSymlink(mode os.FileMode) bool {
|
||||
@ -43,6 +46,22 @@ func GetSymlink(path string) string {
|
||||
return linkPath
|
||||
}
|
||||
|
||||
func ScanDir(fs afero.Fs, path string, dirMap *sync.Map, wg *sync.WaitGroup) {
|
||||
afs := &afero.Afero{Fs: fs}
|
||||
files, _ := afs.ReadDir(path)
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
wg.Add(1)
|
||||
go ScanDir(fs, filepath.Join(path, f.Name()), dirMap, wg)
|
||||
} else {
|
||||
if f.Size() > 0 {
|
||||
dirMap.Store(filepath.Join(path, f.Name()), float64(f.Size()))
|
||||
}
|
||||
}
|
||||
}
|
||||
defer wg.Done()
|
||||
}
|
||||
|
||||
const dotCharacter = 46
|
||||
|
||||
func IsHidden(path string) bool {
|
||||
|
@ -15,6 +15,7 @@ export namespace File {
|
||||
modTime: string;
|
||||
mode: number;
|
||||
mimeType: string;
|
||||
dirSize: number;
|
||||
items: File[];
|
||||
}
|
||||
|
||||
@ -89,4 +90,12 @@ export namespace File {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface DirSizeReq {
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface DirSizeRes {
|
||||
size: number;
|
||||
}
|
||||
}
|
||||
|
@ -56,3 +56,7 @@ export const MoveFile = (params: File.FileMove) => {
|
||||
export const DownloadFile = (params: File.FileDownload) => {
|
||||
return http.download<BlobPart>('files/download', params, { responseType: 'blob' });
|
||||
};
|
||||
|
||||
export const ComputeDirSize = (params: File.DirSizeReq) => {
|
||||
return http.post<File.DirSizeRes>('files/size', params);
|
||||
};
|
||||
|
@ -3,9 +3,9 @@
|
||||
<template #menu>
|
||||
<Menu></Menu>
|
||||
</template>
|
||||
<!-- <template #header>
|
||||
<template #header>
|
||||
<Header></Header>
|
||||
</template> -->
|
||||
</template>
|
||||
<template #footer>
|
||||
<Footer></Footer>
|
||||
</template>
|
||||
@ -13,7 +13,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Layout from '@/layout/index.vue';
|
||||
// import Header from './header/index.vue';
|
||||
import Header from './header/index.vue';
|
||||
import Footer from './footer/index.vue';
|
||||
import Menu from './menu/index.vue';
|
||||
</script>
|
||||
|
@ -242,5 +242,6 @@ export default {
|
||||
moveStart: 'Move start',
|
||||
move: 'Move',
|
||||
copy: 'Cpoy',
|
||||
calculate: 'Calculate',
|
||||
},
|
||||
};
|
||||
|
@ -242,5 +242,6 @@ export default {
|
||||
moveStart: '移动成功',
|
||||
move: '移动',
|
||||
copy: '复制',
|
||||
calculate: '计算',
|
||||
},
|
||||
};
|
||||
|
@ -72,3 +72,13 @@ export function getRandomStr(e: number): string {
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
export function computeSize(size: number): string {
|
||||
const num = 1024.0;
|
||||
|
||||
if (size < num) return size + ' B';
|
||||
if (size < Math.pow(num, 2)) return (size / num).toFixed(2) + ' K';
|
||||
if (size < Math.pow(num, 3)) return (size / Math.pow(num, 2)).toFixed(2) + ' MB';
|
||||
if (size < Math.pow(num, 4)) return (size / Math.pow(num, 3)).toFixed(2) + ' GB';
|
||||
return (size / Math.pow(num, 4)).toFixed(2) + ' TB';
|
||||
}
|
||||
|
@ -105,7 +105,19 @@
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('file.user')" prop="user"></el-table-column>
|
||||
<el-table-column :label="$t('file.group')" prop="group"></el-table-column>
|
||||
<el-table-column :label="$t('file.size')" prop="size"></el-table-column>
|
||||
<el-table-column :label="$t('file.size')" prop="size">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.isDir">
|
||||
<el-button type="primary" link small @click="getDirSize(row)">
|
||||
<span v-if="row.dirSize == undefined">
|
||||
{{ $t('file.calculate') }}
|
||||
</span>
|
||||
<span v-else>{{ getFileSize(row.dirSize) }}</span>
|
||||
</el-button>
|
||||
</span>
|
||||
<span v-else>{{ getFileSize(row.size) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('file.updateTime')"
|
||||
prop="modTime"
|
||||
@ -170,8 +182,15 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
||||
import { GetFilesList, GetFilesTree, DeleteFile, GetFileContent, SaveFileContent } from '@/api/modules/files';
|
||||
import { dateFromat, getRandomStr } from '@/utils/util';
|
||||
import {
|
||||
GetFilesList,
|
||||
GetFilesTree,
|
||||
DeleteFile,
|
||||
GetFileContent,
|
||||
SaveFileContent,
|
||||
ComputeDirSize,
|
||||
} from '@/api/modules/files';
|
||||
import { computeSize, dateFromat, getRandomStr } from '@/utils/util';
|
||||
import { File } from '@/api/interface/file';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import { ElMessage } from 'element-plus';
|
||||
@ -192,10 +211,10 @@ import Move from './move/index.vue';
|
||||
import Download from './download/index.vue';
|
||||
|
||||
const data = ref();
|
||||
const selects = ref<any>([]);
|
||||
const req = reactive({ path: '/', expand: true, showHidden: false });
|
||||
const loading = ref(false);
|
||||
const treeLoading = ref(false);
|
||||
let selects = ref<any>([]);
|
||||
let req = reactive({ path: '/', expand: true, showHidden: false });
|
||||
let loading = ref(false);
|
||||
let treeLoading = ref(false);
|
||||
const paths = ref<string[]>([]);
|
||||
const fileTree = ref<File.FileTree[]>([]);
|
||||
const expandKeys = ref<string[]>([]);
|
||||
@ -326,6 +345,24 @@ const delFile = async (row: File.File | null) => {
|
||||
search(req);
|
||||
};
|
||||
|
||||
const getFileSize = (size: number) => {
|
||||
return computeSize(size);
|
||||
};
|
||||
|
||||
const getDirSize = async (row: any) => {
|
||||
const req = {
|
||||
path: row.path,
|
||||
};
|
||||
loading.value = true;
|
||||
await ComputeDirSize(req)
|
||||
.then(async (res) => {
|
||||
row.dirSize = res.data.size;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const closeCreate = () => {
|
||||
filePage.open = false;
|
||||
search(req);
|
||||
|
Loading…
x
Reference in New Issue
Block a user