Files
pansou/api/handler.go
www.xueximeng.com 5a3917c999 异步插件缓存
2025-07-15 00:03:02 +08:00

160 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}