feat: 增加文件搜索功能

This commit is contained in:
zhengkunwang223 2023-02-06 16:58:45 +08:00 committed by zhengkunwang223
parent 05f2c4661c
commit 292dbf58c5
5 changed files with 108 additions and 21 deletions

View file

@ -4,9 +4,11 @@ import (
"fmt"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"io/fs"
"os"
"path"
"path/filepath"
"strings"
"syscall"
"time"
@ -39,6 +41,7 @@ type FileInfo struct {
type FileOption struct {
Path string `json:"path"`
Search string `json:"search"`
ContainSub bool `json:"containSub"`
Expand bool `json:"expand"`
Dir bool `json:"dir"`
ShowHidden bool `json:"showHidden"`
@ -46,6 +49,11 @@ type FileOption struct {
PageSize int `json:"pageSize"`
}
type FileSearchInfo struct {
Path string `json:"path"`
fs.FileInfo
}
func NewFileInfo(op FileOption) (*FileInfo, error) {
var appFs = afero.NewOsFs()
@ -75,7 +83,7 @@ func NewFileInfo(op FileOption) (*FileInfo, error) {
}
if op.Expand {
if file.IsDir {
if err := file.listChildren(op.Dir, op.ShowHidden, op.Page, op.PageSize); err != nil {
if err := file.listChildren(op.Dir, op.ShowHidden, op.ContainSub, op.Search, op.Page, op.PageSize); err != nil {
return nil, err
}
return file, nil
@ -88,12 +96,59 @@ func NewFileInfo(op FileOption) (*FileInfo, error) {
return file, nil
}
func (f *FileInfo) listChildren(dir, showHidden bool, page, pageSize int) error {
afs := &afero.Afero{Fs: f.Fs}
files, err := afs.ReadDir(f.Path)
if err != nil {
return err
func (f *FileInfo) search(dir, showHidden bool, af afero.Afero, search string, count int) ([]FileSearchInfo, error) {
var files []FileSearchInfo
if err := afero.Walk(af, f.Path, func(path string, info fs.FileInfo, err error) error {
if info != nil {
if dir && !info.IsDir() {
return nil
}
if !showHidden && IsHidden(info.Name()) {
return nil
}
lowerName := strings.ToLower(info.Name())
lowerSearch := strings.ToLower(search)
if strings.Contains(lowerName, lowerSearch) {
files = append(files, FileSearchInfo{
Path: path,
FileInfo: info,
})
}
}
return nil
}); err != nil {
return nil, err
}
return files, nil
}
func (f *FileInfo) listChildren(dir, showHidden, containSub bool, search string, page, pageSize int) error {
afs := &afero.Afero{Fs: f.Fs}
var (
files []FileSearchInfo
err error
)
if search != "" && containSub {
files, err = f.search(dir, showHidden, *afs, search, page*pageSize)
if err != nil {
return err
}
} else {
dirFiles, err := afs.ReadDir(f.Path)
if err != nil {
return err
}
for _, file := range dirFiles {
files = append(files, FileSearchInfo{
Path: f.Path,
FileInfo: file,
})
}
}
f.ItemTotal = 0
var items []*FileInfo
@ -103,7 +158,20 @@ func (f *FileInfo) listChildren(dir, showHidden bool, page, pageSize int) error
}
name := df.Name()
fPath := path.Join(f.Path, df.Name())
fPath := path.Join(df.Path, df.Name())
if search != "" {
if containSub {
fPath = df.Path
name = strings.TrimPrefix(strings.TrimPrefix(fPath, f.Path), "/")
} else {
lowerName := strings.ToLower(name)
lowerSearch := strings.ToLower(search)
if !strings.Contains(lowerName, lowerSearch) {
continue
}
}
}
if !showHidden && IsHidden(name) {
continue
@ -115,7 +183,7 @@ func (f *FileInfo) listChildren(dir, showHidden bool, page, pageSize int) error
isSymlink = true
info, err := f.Fs.Stat(fPath)
if err == nil {
df = info
df.FileInfo = info
} else {
isInvalidLink = true
}
@ -137,6 +205,7 @@ func (f *FileInfo) listChildren(dir, showHidden bool, page, pageSize int) error
Group: GetGroup(df.Sys().(*syscall.Stat_t).Gid),
MimeType: GetMimeType(fPath),
}
if isSymlink {
file.LinkPath = GetSymlink(fPath)
}

View file

@ -27,6 +27,7 @@ export namespace File {
expand: boolean;
dir?: boolean;
showHidden?: boolean;
containSub?: boolean;
}
export interface FileTree {

View file

@ -652,7 +652,7 @@ export default {
upload: '上传',
download: '下载',
fileName: '文件名',
search: '查找',
search: '在当前目录下查找',
mode: '权限',
owner: '所有者',
file: '文件',

View file

@ -231,6 +231,10 @@
.el-input__wrapper {
border-radius: 50px;
}
.el-input-group__prepend {
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
}
}
// drawer头部增加按钮

View file

@ -60,16 +60,18 @@
<el-button plain @click="openDownload" :disabled="selects.length === 0">
{{ $t('file.download') }}
</el-button>
<!-- <div class="search-button">
<el-input
clearable
@clear="search()"
suffix-icon="Search"
@keyup.enter="search()"
@blur="search()"
:placeholder="$t('commons.button.search')"
></el-input>
</div> -->
<div class="search search-button">
<el-input
v-model="req.search"
clearable
@clear="search()"
suffix-icon="Search"
@blur="search()"
:placeholder="$t('file.search')"
>
<template #prepend><el-checkbox v-model="req.containSub">包含子目录</el-checkbox></template>
</el-input>
</div>
</template>
<template #main>
<ComplexTable
@ -175,7 +177,15 @@ interface FilePaths {
const router = useRouter();
const data = ref();
let selects = ref<any>([]);
let req = reactive({ path: '/', expand: true, showHidden: false, page: 1, pageSize: 100 });
let req = reactive({
path: '/',
expand: true,
showHidden: false,
page: 1,
pageSize: 100,
search: '',
containSub: false,
});
let loading = ref(false);
const paths = ref<FilePaths[]>([]);
let pathWidth = ref(0);
@ -258,6 +268,8 @@ const handlePath = () => {
const jump = async (url: string) => {
req.path = url;
req.containSub = false;
req.search = '';
await search();
getPaths(req.path);
nextTick(function () {
@ -482,8 +494,9 @@ onMounted(() => {
}
}
.search-button {
.search {
float: right;
display: inline;
width: 20%;
}
</style>