mirror of
https://github.com/fish2018/pansou.git
synced 2025-11-25 03:14:59 +08:00
160 lines
4.2 KiB
Go
160 lines
4.2 KiB
Go
package api
|
||
|
||
import (
|
||
"net/http"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"pansou/config"
|
||
"pansou/model"
|
||
"pansou/service"
|
||
jsonutil "pansou/util/json"
|
||
"pansou/util"
|
||
"strings"
|
||
)
|
||
|
||
// 保存搜索服务的实例
|
||
var searchService *service.SearchService
|
||
|
||
// SetSearchService 设置搜索服务实例
|
||
func SetSearchService(service *service.SearchService) {
|
||
searchService = service
|
||
}
|
||
|
||
// SearchHandler 搜索处理函数
|
||
func SearchHandler(c *gin.Context) {
|
||
var req model.SearchRequest
|
||
var err error
|
||
|
||
// 根据请求方法不同处理参数
|
||
if c.Request.Method == http.MethodGet {
|
||
// GET方式:从URL参数获取
|
||
// 获取keyword,必填参数
|
||
keyword := c.Query("kw")
|
||
|
||
// 处理channels参数,支持逗号分隔
|
||
channelsStr := c.Query("channels")
|
||
var channels []string
|
||
// 只有当参数非空时才处理
|
||
if channelsStr != "" && channelsStr != " " {
|
||
parts := strings.Split(channelsStr, ",")
|
||
for _, part := range parts {
|
||
trimmed := strings.TrimSpace(part)
|
||
if trimmed != "" {
|
||
channels = append(channels, trimmed)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 处理并发数
|
||
concurrency := 0
|
||
concStr := c.Query("conc")
|
||
if concStr != "" && concStr != " " {
|
||
concurrency = util.StringToInt(concStr)
|
||
}
|
||
|
||
// 处理强制刷新
|
||
forceRefresh := false
|
||
refreshStr := c.Query("refresh")
|
||
if refreshStr != "" && refreshStr != " " && refreshStr == "true" {
|
||
forceRefresh = true
|
||
}
|
||
|
||
// 处理结果类型和来源类型
|
||
resultType := c.Query("res")
|
||
if resultType == "" || resultType == " " {
|
||
resultType = "" // 使用默认值
|
||
}
|
||
|
||
sourceType := c.Query("src")
|
||
if sourceType == "" || sourceType == " " {
|
||
sourceType = "" // 使用默认值
|
||
}
|
||
|
||
// 处理plugins参数,支持逗号分隔
|
||
var plugins []string
|
||
// 检查请求中是否存在plugins参数
|
||
if c.Request.URL.Query().Has("plugins") {
|
||
pluginsStr := c.Query("plugins")
|
||
// 判断参数是否非空
|
||
if pluginsStr != "" && pluginsStr != " " {
|
||
parts := strings.Split(pluginsStr, ",")
|
||
for _, part := range parts {
|
||
trimmed := strings.TrimSpace(part)
|
||
if trimmed != "" {
|
||
plugins = append(plugins, trimmed)
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
// 如果请求中不存在plugins参数,设置为nil
|
||
plugins = nil
|
||
}
|
||
|
||
req = model.SearchRequest{
|
||
Keyword: keyword,
|
||
Channels: channels,
|
||
Concurrency: concurrency,
|
||
ForceRefresh: forceRefresh,
|
||
ResultType: resultType,
|
||
SourceType: sourceType,
|
||
Plugins: plugins,
|
||
}
|
||
} else {
|
||
// POST方式:从请求体获取
|
||
data, err := c.GetRawData()
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, model.NewErrorResponse(400, "读取请求数据失败: "+err.Error()))
|
||
return
|
||
}
|
||
|
||
if err := jsonutil.Unmarshal(data, &req); err != nil {
|
||
c.JSON(http.StatusBadRequest, model.NewErrorResponse(400, "无效的请求参数: "+err.Error()))
|
||
return
|
||
}
|
||
}
|
||
|
||
// 检查并设置默认值
|
||
if len(req.Channels) == 0 {
|
||
req.Channels = config.AppConfig.DefaultChannels
|
||
}
|
||
|
||
// 如果未指定结果类型,默认返回merge
|
||
if req.ResultType == "" {
|
||
req.ResultType = "merge"
|
||
} else if req.ResultType == "merge" {
|
||
// 将merge转换为merged_by_type,以兼容内部处理
|
||
req.ResultType = "merged_by_type"
|
||
}
|
||
|
||
// 如果未指定数据来源类型,默认为全部
|
||
if req.SourceType == "" {
|
||
req.SourceType = "all"
|
||
}
|
||
|
||
// 参数互斥逻辑:当src=tg时忽略plugins参数,当src=plugin时忽略channels参数
|
||
if req.SourceType == "tg" {
|
||
req.Plugins = nil // 忽略plugins参数
|
||
} else if req.SourceType == "plugin" {
|
||
req.Channels = nil // 忽略channels参数
|
||
} else if req.SourceType == "all" {
|
||
// 对于all类型,如果plugins为空或不存在,统一设为nil
|
||
if req.Plugins == nil || len(req.Plugins) == 0 {
|
||
req.Plugins = nil
|
||
}
|
||
}
|
||
|
||
// 执行搜索
|
||
result, err := searchService.Search(req.Keyword, req.Channels, req.Concurrency, req.ForceRefresh, req.ResultType, req.SourceType, req.Plugins)
|
||
|
||
if err != nil {
|
||
response := model.NewErrorResponse(500, "搜索失败: "+err.Error())
|
||
jsonData, _ := jsonutil.Marshal(response)
|
||
c.Data(http.StatusInternalServerError, "application/json", jsonData)
|
||
return
|
||
}
|
||
|
||
// 返回结果
|
||
response := model.NewSuccessResponse(result)
|
||
jsonData, _ := jsonutil.Marshal(response)
|
||
c.Data(http.StatusOK, "application/json", jsonData)
|
||
} |