diff --git a/docs/docs.go b/docs/docs.go index a087c402..23093265 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -8054,7 +8054,7 @@ const docTemplate = `{ "description": "search response", "type": "array", "items": { - "$ref": "#/definitions/schema.SearchResp" + "$ref": "#/definitions/schema.SearchResults" } } } @@ -8107,7 +8107,7 @@ const docTemplate = `{ } } }, - "schema.SearchResp": { + "schema.SearchResults": { "type": "object", "properties": { "object": { diff --git a/internal/controller/search_controller.go b/internal/controller/search_controller.go index 1d135451..be47d1af 100644 --- a/internal/controller/search_controller.go +++ b/internal/controller/search_controller.go @@ -39,7 +39,7 @@ func NewSearchController( // @Security ApiKeyAuth // @Param q query string true "query string" // @Param order query string true "order" Enums(newest,active,score,relevance) -// @Success 200 {object} handler.RespBody{data=schema.SearchListResp} +// @Success 200 {object} handler.RespBody{data=schema.SearchResp} // @Router /answer/api/v1/search [get] func (sc *SearchController) Search(ctx *gin.Context) { dto := schema.SearchDTO{} @@ -65,12 +65,9 @@ func (sc *SearchController) Search(ctx *gin.Context) { } } - resp, total, err := sc.searchService.Search(ctx, &dto) if !isAdmin { sc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionSearch, unit) } - handler.HandleResponse(ctx, err, schema.SearchListResp{ - Total: total, - SearchResp: resp, - }) + resp, err := sc.searchService.Search(ctx, &dto) + handler.HandleResponse(ctx, err, resp) } diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go index ca659991..fcc0d74c 100644 --- a/internal/repo/search_common/search_repo.go +++ b/internal/repo/search_common/search_repo.go @@ -70,7 +70,7 @@ func NewSearchRepo(data *data.Data, uniqueIDRepo unique.UniqueIDRepo, userCommon } // SearchContents search question and answer data -func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes int, page, size int, order string) (resp []schema.SearchResp, total int64, err error) { +func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes int, page, size int, order string) (resp []schema.SearchResult, total int64, err error) { words = filterWords(words) var ( @@ -210,7 +210,7 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs } // SearchQuestions search question data -func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []schema.SearchResp, total int64, err error) { +func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []schema.SearchResult, total int64, err error) { words = filterWords(words) var ( qfs = qFields @@ -319,7 +319,7 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID } // SearchAnswers search answer data -func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []schema.SearchResp, total int64, err error) { +func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []schema.SearchResult, total int64, err error) { words = filterWords(words) var ( @@ -428,7 +428,7 @@ func (sr *searchRepo) parseOrder(ctx context.Context, order string) (res string) } // ParseSearchPluginResult parse search plugin result -func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResp, err error) { +func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResult, err error) { var ( qres []map[string][]byte res = make([]map[string][]byte, 0) @@ -455,7 +455,7 @@ func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin } // parseResult parse search result, return the data structure -func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte) (resp []schema.SearchResp, err error) { +func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte) (resp []schema.SearchResult, err error) { for _, r := range res { var ( objectKey, @@ -525,7 +525,7 @@ func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte) AnswerCount: converter.StringToInt(string(r["answer_count"])), StatusStr: status, } - resp = append(resp, schema.SearchResp{ + resp = append(resp, schema.SearchResult{ ObjectType: objectKey, Object: object, }) diff --git a/internal/schema/search_schema.go b/internal/schema/search_schema.go index 94b237a0..97728402 100644 --- a/internal/schema/search_schema.go +++ b/internal/schema/search_schema.go @@ -107,17 +107,17 @@ type TagResp struct { Reserved bool `json:"reserved"` } -type SearchResp struct { +type SearchResult struct { // object_type ObjectType string `json:"object_type"` // this object Object SearchObject `json:"object"` } -type SearchListResp struct { +type SearchResp struct { Total int64 `json:"count"` // search response - SearchResp []SearchResp `json:"list"` - // extra fields - Extra interface{} `json:"extra"` + SearchResults []SearchResult `json:"list"` + // search plugin desc + SearchPluginIcon string `json:"search_icon,omitempty"` } diff --git a/internal/service/search_common/search.go b/internal/service/search_common/search.go index ef7fe305..8d35ee1b 100644 --- a/internal/service/search_common/search.go +++ b/internal/service/search_common/search.go @@ -7,8 +7,8 @@ import ( ) type SearchRepo interface { - SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes, page, size int, order string) (resp []schema.SearchResp, total int64, err error) - SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []schema.SearchResp, total int64, err error) - SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []schema.SearchResp, total int64, err error) - ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResp, err error) + SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes, page, size int, order string) (resp []schema.SearchResult, total int64, err error) + SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []schema.SearchResult, total int64, err error) + SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []schema.SearchResult, total int64, err error) + ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResult, err error) } diff --git a/internal/service/search_service.go b/internal/service/search_service.go index 995fe039..be5bada4 100644 --- a/internal/service/search_service.go +++ b/internal/service/search_service.go @@ -24,7 +24,7 @@ func NewSearchService( } // Search search contents -func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (resp []schema.SearchResp, total int64, err error) { +func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (resp *schema.SearchResp, err error) { if dto.Page < 1 { dto.Page = 1 } @@ -33,39 +33,43 @@ func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (res cond := ss.searchParser.ParseStructure(ctx, dto) // check search plugin - var s plugin.Search + var finder plugin.Search _ = plugin.CallSearch(func(search plugin.Search) error { - s = search + finder = search return nil }) + resp = &schema.SearchResp{} // search plugin is not found, call system search - if s == nil { + if finder == nil { if cond.SearchAll() { - resp, total, err = ss.searchRepo.SearchContents(ctx, cond.Words, cond.Tags, cond.UserID, cond.VoteAmount, dto.Page, dto.Size, dto.Order) + resp.SearchResults, resp.Total, err = + ss.searchRepo.SearchContents(ctx, cond.Words, cond.Tags, cond.UserID, cond.VoteAmount, dto.Page, dto.Size, dto.Order) } else if cond.SearchQuestion() { - resp, total, err = ss.searchRepo.SearchQuestions(ctx, cond.Words, cond.Tags, cond.NotAccepted, cond.Views, cond.AnswerAmount, dto.Page, dto.Size, dto.Order) + resp.SearchResults, resp.Total, err = + ss.searchRepo.SearchQuestions(ctx, cond.Words, cond.Tags, cond.NotAccepted, cond.Views, cond.AnswerAmount, dto.Page, dto.Size, dto.Order) } else if cond.SearchAnswer() { - resp, total, err = ss.searchRepo.SearchAnswers(ctx, cond.Words, cond.Tags, cond.Accepted, cond.QuestionID, dto.Page, dto.Size, dto.Order) + resp.SearchResults, resp.Total, err = + ss.searchRepo.SearchAnswers(ctx, cond.Words, cond.Tags, cond.Accepted, cond.QuestionID, dto.Page, dto.Size, dto.Order) } return } - return ss.searchByPlugin(ctx, s, cond, dto) + return ss.searchByPlugin(ctx, finder, cond, dto) } -func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Search, cond *schema.SearchCondition, dto *schema.SearchDTO) (resp []schema.SearchResp, total int64, err error) { +func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Search, cond *schema.SearchCondition, dto *schema.SearchDTO) (resp *schema.SearchResp, err error) { var res []plugin.SearchResult + resp = &schema.SearchResp{ + SearchPluginIcon: finder.Description().Icon, + } if cond.SearchAll() { - res, total, err = finder.SearchContents(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) + res, resp.Total, err = finder.SearchContents(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) } else if cond.SearchQuestion() { - res, total, err = finder.SearchQuestions(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) + res, resp.Total, err = finder.SearchQuestions(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) } else if cond.SearchAnswer() { - res, total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) + res, resp.Total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) } - resp, err = ss.searchRepo.ParseSearchPluginResult(ctx, res) - if err != nil { - return nil, 0, err - } - return + resp.SearchResults, err = ss.searchRepo.ParseSearchPluginResult(ctx, res) + return resp, err } diff --git a/plugin/search.go b/plugin/search.go index 4d9d1921..64a4b9e0 100644 --- a/plugin/search.go +++ b/plugin/search.go @@ -83,6 +83,7 @@ const ( type Search interface { Base + Description() SearchDesc SearchContents(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error) SearchQuestions(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error) SearchAnswers(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error) @@ -90,6 +91,11 @@ type Search interface { DeleteContent(ctx context.Context, contentID string) error } +type SearchDesc struct { + // A svg icon it wil be display in search result page + Icon string `json:"icon"` +} + var ( // CallUserCenter is a function that calls all registered parsers CallSearch,