github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/service/explorer/search.go (about)

     1  package explorer
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	model "github.com/cloudreve/Cloudreve/v3/models"
     8  	"github.com/cloudreve/Cloudreve/v3/pkg/filesystem"
     9  	"github.com/cloudreve/Cloudreve/v3/pkg/hashid"
    10  	"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
    11  	"github.com/gin-gonic/gin"
    12  )
    13  
    14  // ItemSearchService 文件搜索服务
    15  type ItemSearchService struct {
    16  	Type     string `uri:"type" binding:"required"`
    17  	Keywords string `uri:"keywords" binding:"required"`
    18  	Path     string `form:"path"`
    19  }
    20  
    21  // Search 执行搜索
    22  func (service *ItemSearchService) Search(c *gin.Context) serializer.Response {
    23  	// 创建文件系统
    24  	fs, err := filesystem.NewFileSystemFromContext(c)
    25  	if err != nil {
    26  		return serializer.Err(serializer.CodeCreateFSError, "", err)
    27  	}
    28  	defer fs.Recycle()
    29  
    30  	if service.Path != "" {
    31  		ok, parent := fs.IsPathExist(service.Path)
    32  		if !ok {
    33  			return serializer.Err(serializer.CodeParentNotExist, "", nil)
    34  		}
    35  
    36  		fs.Root = parent
    37  	}
    38  
    39  	switch service.Type {
    40  	case "keywords":
    41  		return service.SearchKeywords(c, fs, "%"+service.Keywords+"%")
    42  	case "image":
    43  		return service.SearchKeywords(c, fs, "%.bmp", "%.iff", "%.png", "%.gif", "%.jpg", "%.jpeg", "%.psd", "%.svg", "%.webp")
    44  	case "video":
    45  		return service.SearchKeywords(c, fs, "%.mp4", "%.flv", "%.avi", "%.wmv", "%.mkv", "%.rm", "%.rmvb", "%.mov", "%.ogv")
    46  	case "audio":
    47  		return service.SearchKeywords(c, fs, "%.mp3", "%.flac", "%.ape", "%.wav", "%.acc", "%.ogg", "%.midi", "%.mid")
    48  	case "doc":
    49  		return service.SearchKeywords(c, fs, "%.txt", "%.md", "%.pdf", "%.doc", "%.docx", "%.ppt", "%.pptx", "%.xls", "%.xlsx", "%.pub")
    50  	case "tag":
    51  		if tid, err := hashid.DecodeHashID(service.Keywords, hashid.TagID); err == nil {
    52  			if tag, err := model.GetTagsByID(tid, fs.User.ID); err == nil {
    53  				if tag.Type == model.FileTagType {
    54  					exp := strings.Split(tag.Expression, "\n")
    55  					expInput := make([]interface{}, len(exp))
    56  					for i := 0; i < len(exp); i++ {
    57  						expInput[i] = exp[i]
    58  					}
    59  					return service.SearchKeywords(c, fs, expInput...)
    60  				}
    61  			}
    62  		}
    63  		return serializer.Err(serializer.CodeNotFound, "", nil)
    64  	default:
    65  		return serializer.ParamErr("Unknown search type", nil)
    66  	}
    67  }
    68  
    69  // SearchKeywords 根据关键字搜索文件
    70  func (service *ItemSearchService) SearchKeywords(c *gin.Context, fs *filesystem.FileSystem, keywords ...interface{}) serializer.Response {
    71  	// 上下文
    72  	ctx, cancel := context.WithCancel(context.Background())
    73  	defer cancel()
    74  
    75  	// 获取子项目
    76  	objects, err := fs.Search(ctx, keywords...)
    77  	if err != nil {
    78  		return serializer.Err(serializer.CodeNotSet, err.Error(), err)
    79  	}
    80  
    81  	return serializer.Response{
    82  		Code: 0,
    83  		Data: map[string]interface{}{
    84  			"parent":  0,
    85  			"objects": objects,
    86  		},
    87  	}
    88  }