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

View file

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

View file

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

View file

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

View file

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