pansou / api /handler.go
Antigravity
Initial commit for HF Spaces
19a9e14
Raw
History Blame Contribute Delete
6.59 kB
package api
import (
// "fmt"
"net/http"
// "os"
"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 = "merge" // 直接设置为默认值merge
}
sourceType := c.Query("src")
if sourceType == "" || sourceType == " " {
sourceType = "all" // 直接设置为默认值all
}
// 处理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
}
// 处理cloud_types参数,支持逗号分隔
var cloudTypes []string
// 检查请求中是否存在cloud_types参数
if c.Request.URL.Query().Has("cloud_types") {
cloudTypesStr := c.Query("cloud_types")
// 判断参数是否非空
if cloudTypesStr != "" && cloudTypesStr != " " {
parts := strings.Split(cloudTypesStr, ",")
for _, part := range parts {
trimmed := strings.TrimSpace(part)
if trimmed != "" {
cloudTypes = append(cloudTypes, trimmed)
}
}
}
} else {
// 如果请求中不存在cloud_types参数,设置为nil
cloudTypes = nil
}
// 处理ext参数,JSON格式
var ext map[string]interface{}
extStr := c.Query("ext")
if extStr != "" && extStr != " " {
// 处理特殊情况:ext={}
if extStr == "{}" {
ext = make(map[string]interface{})
} else {
if err := jsonutil.Unmarshal([]byte(extStr), &ext); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(400, "无效的ext参数格式: "+err.Error()))
return
}
}
}
// 确保ext不为nil
if ext == nil {
ext = make(map[string]interface{})
}
// 处理filter参数,JSON格式
var filter *model.FilterConfig
filterStr := c.Query("filter")
if filterStr != "" && filterStr != " " {
filter = &model.FilterConfig{}
if err := jsonutil.Unmarshal([]byte(filterStr), filter); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(400, "无效的filter参数格式: "+err.Error()))
return
}
}
req = model.SearchRequest{
Keyword: keyword,
Channels: channels,
Concurrency: concurrency,
ForceRefresh: forceRefresh,
ResultType: resultType,
SourceType: sourceType,
Plugins: plugins,
CloudTypes: cloudTypes, // 添加cloud_types到请求中
Ext: ext,
Filter: filter,
}
} 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并转换为merged_by_type
if req.ResultType == "" {
req.ResultType = "merged_by_type"
} 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
}
}
// 可选:启用调试输出(生产环境建议注释掉)
// fmt.Printf("🔧 [调试] 搜索参数: keyword=%s, channels=%v, concurrency=%d, refresh=%v, resultType=%s, sourceType=%s, plugins=%v, cloudTypes=%v, ext=%v\n",
// req.Keyword, req.Channels, req.Concurrency, req.ForceRefresh, req.ResultType, req.SourceType, req.Plugins, req.CloudTypes, req.Ext)
// 执行搜索
result, err := searchService.Search(req.Keyword, req.Channels, req.Concurrency, req.ForceRefresh, req.ResultType, req.SourceType, req.Plugins, req.CloudTypes, req.Ext)
if err != nil {
response := model.NewErrorResponse(500, "搜索失败: "+err.Error())
jsonData, _ := jsonutil.Marshal(response)
c.Data(http.StatusInternalServerError, "application/json", jsonData)
return
}
// 应用过滤器
if req.Filter != nil {
result = applyResultFilter(result, req.Filter, req.ResultType)
}
// 包装SearchResponse到标准响应格式中
response := model.NewSuccessResponse(result)
jsonData, _ := jsonutil.Marshal(response)
c.Data(http.StatusOK, "application/json", jsonData)
}