feat: search file under current folder
This commit is contained in:
parent
d51351eebd
commit
8ab0fe0e2f
8 changed files with 114 additions and 7 deletions
|
@ -117,8 +117,8 @@ func GetFilesByIDsFromTX(tx *gorm.DB, ids []uint, uid uint) ([]File, error) {
|
|||
}
|
||||
|
||||
// GetFilesByKeywords 根据关键字搜索文件,
|
||||
// UID为0表示忽略用户,只根据文件ID检索
|
||||
func GetFilesByKeywords(uid uint, keywords ...interface{}) ([]File, error) {
|
||||
// UID为0表示忽略用户,只根据文件ID检索. 如果 parents 非空, 则只限制在 parent 包含的目录下搜索
|
||||
func GetFilesByKeywords(uid uint, parents []uint, keywords ...interface{}) ([]File, error) {
|
||||
var (
|
||||
files []File
|
||||
result = DB
|
||||
|
@ -136,6 +136,11 @@ func GetFilesByKeywords(uid uint, keywords ...interface{}) ([]File, error) {
|
|||
if uid != 0 {
|
||||
result = result.Where("user_id = ?", uid)
|
||||
}
|
||||
|
||||
if len(parents) > 0 {
|
||||
result = result.Where("folder_id in (?)", parents)
|
||||
}
|
||||
|
||||
result = result.Where("("+conditions+")", keywords...).Find(&files)
|
||||
|
||||
return files, result.Error
|
||||
|
|
|
@ -2,6 +2,7 @@ package filesystem
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||
|
@ -361,7 +362,21 @@ func (fs *FileSystem) resetPolicyToFirstFile(ctx context.Context) error {
|
|||
|
||||
// Search 搜索文件
|
||||
func (fs *FileSystem) Search(ctx context.Context, keywords ...interface{}) ([]serializer.Object, error) {
|
||||
files, _ := model.GetFilesByKeywords(fs.User.ID, keywords...)
|
||||
parents := make([]uint, 0)
|
||||
|
||||
// 如果限定了根目录,则只在这个根目录下搜索。
|
||||
if fs.Root != nil {
|
||||
allFolders, err := model.GetRecursiveChildFolder([]uint{fs.Root.ID}, fs.User.ID, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list all folders: %w", err)
|
||||
}
|
||||
|
||||
for _, folder := range allFolders {
|
||||
parents = append(parents, folder.ID)
|
||||
}
|
||||
}
|
||||
|
||||
files, _ := model.GetFilesByKeywords(fs.User.ID, parents, keywords...)
|
||||
fs.SetTargetFile(&files)
|
||||
|
||||
return fs.listObjects(ctx, "/", files, nil, nil), nil
|
||||
|
|
|
@ -84,6 +84,8 @@ const (
|
|||
CodeBatchSourceSize = 40014
|
||||
// CodeBatchAria2Size 超出最大 Aria2 任务数量限制
|
||||
CodeBatchAria2Size = 40012
|
||||
// CodeParentNotExist 父目录不存在
|
||||
CodeParentNotExist = 40013
|
||||
// CodeDBError 数据库操作失败
|
||||
CodeDBError = 50001
|
||||
// CodeEncryptError 加密失败
|
||||
|
|
|
@ -363,12 +363,18 @@ func GetUploadSession(c *gin.Context) {
|
|||
// SearchFile 搜索文件
|
||||
func SearchFile(c *gin.Context) {
|
||||
var service explorer.ItemSearchService
|
||||
if err := c.ShouldBindUri(&service); err == nil {
|
||||
res := service.Search(c)
|
||||
c.JSON(200, res)
|
||||
} else {
|
||||
if err := c.ShouldBindUri(&service); err != nil {
|
||||
c.JSON(200, ErrorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.ShouldBindQuery(&service); err != nil {
|
||||
c.JSON(200, ErrorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
res := service.Search(c)
|
||||
c.JSON(200, res)
|
||||
}
|
||||
|
||||
// CreateFile 创建空白文件
|
||||
|
|
|
@ -184,6 +184,23 @@ func ListSharedFolder(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// SearchSharedFolder 搜索分享的目录下的对象
|
||||
func SearchSharedFolder(c *gin.Context) {
|
||||
var service share.SearchService
|
||||
if err := c.ShouldBindUri(&service); err != nil {
|
||||
c.JSON(200, ErrorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.ShouldBindQuery(&service); err != nil {
|
||||
c.JSON(200, ErrorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
res := service.Search(c)
|
||||
c.JSON(200, res)
|
||||
}
|
||||
|
||||
// ArchiveShare 打包要下载的分享
|
||||
func ArchiveShare(c *gin.Context) {
|
||||
var service share.ArchiveService
|
||||
|
|
|
@ -335,6 +335,11 @@ func InitMasterRouter() *gin.Engine {
|
|||
middleware.CheckShareUnlocked(),
|
||||
controllers.ListSharedFolder,
|
||||
)
|
||||
// 分享目录搜索
|
||||
share.GET("search/:id/:type/:keywords",
|
||||
middleware.CheckShareUnlocked(),
|
||||
controllers.SearchSharedFolder,
|
||||
)
|
||||
// 归档打包下载
|
||||
share.POST("archive/:id",
|
||||
middleware.CheckShareUnlocked(),
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
type ItemSearchService struct {
|
||||
Type string `uri:"type" binding:"required"`
|
||||
Keywords string `uri:"keywords" binding:"required"`
|
||||
Path string `form:"path"`
|
||||
}
|
||||
|
||||
// Search 执行搜索
|
||||
|
@ -26,6 +27,15 @@ func (service *ItemSearchService) Search(c *gin.Context) serializer.Response {
|
|||
}
|
||||
defer fs.Recycle()
|
||||
|
||||
if service.Path != "" {
|
||||
ok, parent := fs.IsPathExist(service.Path)
|
||||
if !ok {
|
||||
return serializer.Err(serializer.CodeParentNotExist, "Cannot find parent folder", nil)
|
||||
}
|
||||
|
||||
fs.Root = parent
|
||||
}
|
||||
|
||||
switch service.Type {
|
||||
case "keywords":
|
||||
return service.SearchKeywords(c, fs, "%"+service.Keywords+"%")
|
||||
|
|
|
@ -366,3 +366,50 @@ func (service *ArchiveService) Archive(c *gin.Context) serializer.Response {
|
|||
|
||||
return subService.Archive(ctx, c)
|
||||
}
|
||||
|
||||
// SearchService 对分享的目录进行搜索
|
||||
type SearchService struct {
|
||||
explorer.ItemSearchService
|
||||
}
|
||||
|
||||
// Search 执行搜索
|
||||
func (service *SearchService) Search(c *gin.Context) serializer.Response {
|
||||
shareCtx, _ := c.Get("share")
|
||||
share := shareCtx.(*model.Share)
|
||||
|
||||
if !share.IsDir {
|
||||
return serializer.ParamErr("此分享无法列目录", nil)
|
||||
}
|
||||
|
||||
if service.Path != "" && !path.IsAbs(service.Path) {
|
||||
return serializer.ParamErr("路径无效", nil)
|
||||
}
|
||||
|
||||
// 创建文件系统
|
||||
fs, err := filesystem.NewFileSystem(share.Creator())
|
||||
if err != nil {
|
||||
return serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err)
|
||||
}
|
||||
defer fs.Recycle()
|
||||
|
||||
// 上下文
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// 重设根目录
|
||||
fs.Root = share.Source().(*model.Folder)
|
||||
fs.Root.Name = "/"
|
||||
if service.Path != "" {
|
||||
ok, parent := fs.IsPathExist(service.Path)
|
||||
if !ok {
|
||||
return serializer.Err(serializer.CodeParentNotExist, "Cannot find parent folder", nil)
|
||||
}
|
||||
|
||||
fs.Root = parent
|
||||
}
|
||||
|
||||
// 分享Key上下文
|
||||
ctx = context.WithValue(ctx, fsctx.ShareKeyCtx, hashid.HashID(share.ID, hashid.ShareID))
|
||||
|
||||
return service.SearchKeywords(c, fs, "%"+service.Keywords+"%")
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue