Files
pansou/api/handler.go

207 lines
5.9 KiB
Go
Raw Normal View History

2025-07-12 19:53:44 +08:00
package api
import (
// "fmt"
2025-07-12 19:53:44 +08:00
"net/http"
// "os"
2025-07-12 19:53:44 +08:00
"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 == " " {
2025-07-17 17:26:09 +08:00
resultType = "merge" // 直接设置为默认值merge
2025-07-12 19:53:44 +08:00
}
sourceType := c.Query("src")
if sourceType == "" || sourceType == " " {
2025-07-17 17:26:09 +08:00
sourceType = "all" // 直接设置为默认值all
2025-07-12 19:53:44 +08:00
}
// 处理plugins参数支持逗号分隔
var plugins []string
2025-07-15 00:03:02 +08:00
// 检查请求中是否存在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)
}
2025-07-12 19:53:44 +08:00
}
}
2025-07-15 00:03:02 +08:00
} else {
// 如果请求中不存在plugins参数设置为nil
plugins = nil
2025-07-12 19:53:44 +08:00
}
2025-07-22 12:12:21 +08:00
2025-07-29 11:33:01 +08:00
// 处理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
}
2025-07-22 12:12:21 +08:00
// 处理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{})
}
2025-07-12 19:53:44 +08:00
req = model.SearchRequest{
Keyword: keyword,
Channels: channels,
Concurrency: concurrency,
ForceRefresh: forceRefresh,
ResultType: resultType,
SourceType: sourceType,
Plugins: plugins,
2025-07-29 11:33:01 +08:00
CloudTypes: cloudTypes, // 添加cloud_types到请求中
2025-07-22 12:12:21 +08:00
Ext: ext,
2025-07-12 19:53:44 +08:00
}
} 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
2025-07-12 19:53:44 +08:00
if req.ResultType == "" {
req.ResultType = "merged_by_type"
2025-07-12 19:53:44 +08:00
} 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参数
2025-07-15 00:03:02 +08:00
} else if req.SourceType == "all" {
// 对于all类型如果plugins为空或不存在统一设为nil
if req.Plugins == nil || len(req.Plugins) == 0 {
req.Plugins = nil
}
2025-07-12 19:53:44 +08:00
}
// 可选:启用调试输出(生产环境建议注释掉)
// 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)
2025-07-12 19:53:44 +08:00
// 执行搜索
2025-07-29 11:33:01 +08:00
result, err := searchService.Search(req.Keyword, req.Channels, req.Concurrency, req.ForceRefresh, req.ResultType, req.SourceType, req.Plugins, req.CloudTypes, req.Ext)
2025-07-12 19:53:44 +08:00
if err != nil {
response := model.NewErrorResponse(500, "搜索失败: "+err.Error())
jsonData, _ := jsonutil.Marshal(response)
c.Data(http.StatusInternalServerError, "application/json", jsonData)
return
}
2025-10-05 20:17:10 +08:00
// 包装SearchResponse到标准响应格式中
2025-07-12 19:53:44 +08:00
response := model.NewSuccessResponse(result)
jsonData, _ := jsonutil.Marshal(response)
c.Data(http.StatusOK, "application/json", jsonData)
}