fix: 查看文件/文件夹属性详情 (#5844)

Refs #5842

查看文件/文件夹属性详情,不再获取文件内容。
pull/5846/head
2024-07-17 14:43:27 +08:00 committed by GitHub
parent 864bff574a
commit ed599265e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 123 additions and 72 deletions

View File

@ -104,20 +104,25 @@ func NewFileInfo(op FileOption) (*FileInfo, error) {
file.LinkPath = GetSymlink(op.Path) file.LinkPath = GetSymlink(op.Path)
} }
if op.Expand { if op.Expand {
if file.IsDir { if err := handleExpansion(file, op); err != nil {
if err := file.listChildren(op); err != nil { return nil, err
return nil, err
}
return file, nil
} else {
if err := file.getContent(); err != nil {
return nil, err
}
} }
} }
return file, nil return file, nil
} }
func handleExpansion(file *FileInfo, op FileOption) error {
if file.IsDir {
return file.listChildren(op)
}
if !file.IsDetail {
return file.getContent()
}
return nil
}
func (f *FileInfo) search(search string, count int) (files []FileSearchInfo, total int, err error) { func (f *FileInfo) search(search string, count int) (files []FileSearchInfo, total int, err error) {
cmd := exec.Command("find", f.Path, "-name", fmt.Sprintf("*%s*", search)) cmd := exec.Command("find", f.Path, "-name", fmt.Sprintf("*%s*", search))
output, err := cmd.StdoutPipe() output, err := cmd.StdoutPipe()
@ -203,63 +208,82 @@ func (f *FileInfo) listChildren(option FileOption) error {
return err return err
} }
} else { } else {
dirFiles, err := afs.ReadDir(f.Path) files, err = f.getFiles(afs, option)
if err != nil { if err != nil {
return err return err
} }
var (
dirs []FileSearchInfo
fileList []FileSearchInfo
)
for _, file := range dirFiles {
info := FileSearchInfo{
Path: f.Path,
FileInfo: file,
}
if file.IsDir() {
dirs = append(dirs, info)
} else {
fileList = append(fileList, info)
}
}
sortFileList(dirs, option.SortBy, option.SortOrder)
sortFileList(fileList, option.SortBy, option.SortOrder)
files = append(dirs, fileList...)
} }
items, err := f.processFiles(files, option)
if err != nil {
return err
}
if option.ContainSub {
f.ItemTotal = total
}
start := (option.Page - 1) * option.PageSize
end := option.PageSize + start
var result []*FileInfo
if start < 0 || start > f.ItemTotal || end < 0 || start > end {
result = items
} else {
if end > f.ItemTotal {
result = items[start:]
} else {
result = items[start:end]
}
}
f.Items = result
return nil
}
func (f *FileInfo) getFiles(afs *afero.Afero, option FileOption) ([]FileSearchInfo, error) {
dirFiles, err := afs.ReadDir(f.Path)
if err != nil {
return nil, err
}
var (
dirs []FileSearchInfo
fileList []FileSearchInfo
)
for _, file := range dirFiles {
info := FileSearchInfo{
Path: f.Path,
FileInfo: file,
}
if file.IsDir() {
dirs = append(dirs, info)
} else {
fileList = append(fileList, info)
}
}
sortFileList(dirs, option.SortBy, option.SortOrder)
sortFileList(fileList, option.SortBy, option.SortOrder)
return append(dirs, fileList...), nil
}
func (f *FileInfo) processFiles(files []FileSearchInfo, option FileOption) ([]*FileInfo, error) {
var items []*FileInfo var items []*FileInfo
for _, df := range files { for _, df := range files {
if option.Dir && !df.IsDir() { if shouldSkipFile(df, option) {
continue continue
} }
name := df.Name()
fPath := path.Join(df.Path, df.Name()) name, fPath := f.getFilePathAndName(option, df)
if option.Search != "" {
if option.ContainSub {
fPath = df.Path
name = strings.TrimPrefix(strings.TrimPrefix(fPath, f.Path), "/")
} else {
lowerName := strings.ToLower(name)
lowerSearch := strings.ToLower(option.Search)
if !strings.Contains(lowerName, lowerSearch) {
continue
}
}
}
if !option.ShowHidden && IsHidden(name) { if !option.ShowHidden && IsHidden(name) {
continue continue
} }
f.ItemTotal++ f.ItemTotal++
isSymlink, isInvalidLink := false, false
if IsSymlink(df.Mode()) { isSymlink, isInvalidLink := f.checkSymlink(df)
isSymlink = true
info, err := f.Fs.Stat(fPath)
if err == nil {
df.FileInfo = info
} else {
isInvalidLink = true
}
}
file := &FileInfo{ file := &FileInfo{
Fs: f.Fs, Fs: f.Fs,
@ -294,24 +318,53 @@ func (f *FileInfo) listChildren(option FileOption) error {
} }
items = append(items, file) items = append(items, file)
} }
if option.ContainSub {
f.ItemTotal = total return items, nil
}
func shouldSkipFile(df FileSearchInfo, option FileOption) bool {
if option.Dir && !df.IsDir() {
return true
} }
start := (option.Page - 1) * option.PageSize
end := option.PageSize + start if option.Search != "" && !option.ContainSub {
var result []*FileInfo lowerName := strings.ToLower(df.Name())
if start < 0 || start > f.ItemTotal || end < 0 || start > end { lowerSearch := strings.ToLower(option.Search)
result = items if !strings.Contains(lowerName, lowerSearch) {
} else { return true
if end > f.ItemTotal {
result = items[start:]
} else {
result = items[start:end]
} }
} }
f.Items = result return false
return nil }
func (f *FileInfo) getFilePathAndName(option FileOption, df FileSearchInfo) (string, string) {
name := df.Name()
fPath := path.Join(df.Path, df.Name())
if option.Search != "" && option.ContainSub {
fPath = df.Path
name = strings.TrimPrefix(strings.TrimPrefix(fPath, f.Path), "/")
}
return name, fPath
}
func (f *FileInfo) checkSymlink(df FileSearchInfo) (bool, bool) {
isSymlink := false
isInvalidLink := false
if IsSymlink(df.Mode()) {
isSymlink = true
info, err := f.Fs.Stat(path.Join(df.Path, df.Name()))
if err == nil {
df.FileInfo = info
} else {
isInvalidLink = true
}
}
return isSymlink, isInvalidLink
} }
func (f *FileInfo) getContent() error { func (f *FileInfo) getContent() error {
@ -326,10 +379,8 @@ func (f *FileInfo) getContent() error {
if err != nil { if err != nil {
return nil return nil
} }
if !f.IsDetail { if len(cByte) > 0 && DetectBinary(cByte) {
if len(cByte) > 0 && DetectBinary(cByte) { return buserr.New(constant.ErrFileCanNotRead)
return buserr.New(constant.ErrFileCanNotRead)
}
} }
f.Content = string(cByte) f.Content = string(cByte)
return nil return nil

View File

@ -11,7 +11,7 @@
<el-descriptions-item :label="$t('file.path')">{{ data.path }}</el-descriptions-item> <el-descriptions-item :label="$t('file.path')">{{ data.path }}</el-descriptions-item>
<el-descriptions-item :label="$t('file.size')"> <el-descriptions-item :label="$t('file.size')">
<span v-if="data.isDir"> <span v-if="data.isDir">
<el-button type="primary" link small @click="getDirSize(data)"> <el-button type="primary" link small @click="getDirSize(data)" :loading="loading">
<span v-if="data.dirSize == undefined"> <span v-if="data.dirSize == undefined">
{{ $t('file.calculate') }} {{ $t('file.calculate') }}
</span> </span>