123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- package service
- import (
- "context"
- "encoding/json"
- "go-common/app/interface/bbq/app-bbq/api/http/v1"
- "go-common/app/interface/bbq/app-bbq/model"
- "go-common/app/service/bbq/common"
- "go-common/library/ecode"
- "go-common/library/log"
- "github.com/json-iterator/go"
- )
- const (
- searchTypeVideo = "bbq_video"
- searchTypeUser = "bbq_user"
- suggestType = "bbq"
- suggestVer = "v4"
- searchLen = 20
- )
- // SearchCursor .
- type SearchCursor struct {
- Offset int64 `json:"offset"` // 默认为0,数据从1开始
- }
- func parseSearchCursor(c context.Context, cursorPrev, cursorNext string) (cursor *SearchCursor, directionNext bool, err error) {
- cursor = new(SearchCursor)
- // 判断是向前还是向后查询
- directionNext = true
- cursorStr := cursorNext
- if len(cursorNext) == 0 && len(cursorPrev) > 0 {
- directionNext = false
- cursorStr = cursorPrev
- }
- // 解析
- if len(cursorStr) != 0 {
- var cursorData = []byte(cursorStr)
- err = json.Unmarshal(cursorData, &cursor)
- if err != nil {
- err = ecode.ReqParamErr
- return
- }
- }
- return
- }
- //HotWord .
- func (s *Service) HotWord(c context.Context, req *v1.HotWordRequest) (res *v1.HotWordResponse, err error) {
- res = new(v1.HotWordResponse)
- res.List = append(res.List, "小姐姐")
- res.List = append(res.List, "舞蹈")
- res.List = append(res.List, "MMD")
- return
- }
- // VideoSearch 视频搜索
- func (s *Service) VideoSearch(c context.Context, arg *v1.BaseSearchReq) (res *v1.VideoSearchRes, err error) {
- res = new(v1.VideoSearchRes)
- var (
- sres []*model.VideoSearchResult
- searchRes *model.RawSearchRes
- relids []int32
- svids []int64
- svidMap map[int64]int64
- )
- // 0. check
- // 1. 生成请求,会根据请求参数
- // v2接口
- reqPage := int64(1)
- firstItemOffset := int64(0)
- var cursor *SearchCursor
- var directionNext bool
- if arg.Page == 0 {
- cursor, directionNext, err = parseSearchCursor(c, arg.CursorPrev, arg.CursorNext)
- if err != nil {
- log.Warnw(c, "log", "parse search cursor fail", "prev", arg.CursorPrev, "next", arg.CursorNext)
- return
- }
- firstItemOffset = cursor.Offset - 1
- if directionNext {
- firstItemOffset = cursor.Offset + 1
- }
- reqPage = (firstItemOffset-1)/searchLen + 1
- log.V(1).Infow(c, "log", "v2 request", "next", arg.CursorNext, "prev", arg.CursorPrev)
- } else {
- reqPage = arg.Page
- }
- var json = jsoniter.ConfigCompatibleWithStandardLibrary
- sp := &model.SearchBaseReq{
- KeyWord: arg.Key,
- Type: searchTypeVideo,
- Page: reqPage,
- PageSize: searchLen,
- Highlight: int64(arg.Highlight),
- }
- // 相信搜索结果返回的就是searchLen
- searchRes, err = s.dao.SearchBBQ(c, sp)
- if searchRes.Res == nil {
- return
- }
- if err = json.Unmarshal(searchRes.Res, &sres); err != nil {
- return
- }
- for _, v := range sres {
- relids = append(relids, v.ID)
- }
- if len(relids) == 0 {
- log.Infov(c, log.KV("log", "search ret empty"))
- return
- }
- ids := s.dao.ParseRel2ID(relids)
- svidMap, err = s.dao.ConvID2SVID(c, ids)
- if err != nil {
- log.Error("ConvID2SVID err [%v]", err)
- err = nil
- return
- }
- for _, svid := range svidMap {
- svids = append(svids, svid)
- }
- svMap, _ := s.svInfos(c, svids, 0, false)
- for index, sinfo := range sres {
- id := s.dao.ParseRel2ID([]int32{sinfo.ID})
- if id[0] == 0 {
- continue
- }
- if svid, ok := svidMap[id[0]]; ok {
- if sv, ok := svMap[svid]; ok {
- if common.IsSearchSvStateAvailable(int64(sv.State)) {
- r := new(v1.VideoSearchList)
- r.VideoResponse = *sv
- r.SVID = svid
- r.HitColumns = sinfo.HitColumns
- r.TitleHighlight = sinfo.Title
- r.Offset = (reqPage-1)*int64(searchLen) + int64(index) + 1
- res.List = append(res.List, r)
- } else {
- log.Warnw(c, "log", "get error svid in search list", "svid", svid, "sv", sv)
- }
- }
- }
- }
- res.NumPage = searchRes.PageNum
- res.Page = searchRes.Page
- res.HasMore = false
- if arg.Page == 0 {
- if (directionNext && searchRes.PageNum > searchRes.Page) || (!directionNext && searchRes.Page > 1) {
- res.HasMore = true
- }
- var list []*v1.VideoSearchList
- if directionNext {
- for _, item := range res.List {
- if item.Offset < firstItemOffset {
- continue
- }
- list = append(list, item)
- }
- } else {
- if firstItemOffset >= int64(len(res.List)) {
- firstItemOffset = int64(len(res.List)) - 1
- }
- for i := firstItemOffset - 1; i >= 0; i-- {
- list = append(list, res.List[i])
- }
- }
- res.List = list
- }
- var cursorValue SearchCursor
- for _, item := range res.List {
- cursorValue.Offset = item.Offset
- data, _ := json.Marshal(cursorValue)
- item.CursorValue = string(data)
- }
- return
- }
- // UserSearch 用户搜索
- func (s *Service) UserSearch(c context.Context, mid int64, arg *v1.BaseSearchReq) (res *v1.UserSearchRes, err error) {
- res = new(v1.UserSearchRes)
- var (
- sres []*model.UserSearchResult
- searchRes *model.RawSearchRes
- mids []int64
- )
- // 1. 生成请求,会根据请求参数
- // v2接口
- reqPage := int64(1)
- firstItemOffset := int64(0)
- var cursor *SearchCursor
- var directionNext bool
- if arg.Page == 0 {
- cursor, directionNext, err = parseSearchCursor(c, arg.CursorPrev, arg.CursorNext)
- if err != nil {
- log.Warnw(c, "log", "parse search cursor fail", "prev", arg.CursorPrev, "next", arg.CursorNext)
- return
- }
- firstItemOffset = cursor.Offset - 1
- if directionNext {
- firstItemOffset = cursor.Offset + 1
- }
- reqPage = (firstItemOffset-1)/searchLen + 1
- log.V(1).Infow(c, "log", "v2 request", "next", arg.CursorNext, "prev", arg.CursorPrev)
- } else {
- reqPage = arg.Page
- }
- sp := &model.SearchBaseReq{
- KeyWord: arg.Key,
- Type: searchTypeUser,
- Page: reqPage,
- PageSize: searchLen,
- Highlight: int64(arg.Highlight),
- }
- searchRes, err = s.dao.SearchBBQ(c, sp)
- if searchRes.Res == nil {
- return
- }
- if err = json.Unmarshal(searchRes.Res, &sres); err != nil {
- return
- }
- for _, v := range sres {
- mids = append(mids, v.ID)
- }
- if len(mids) == 0 {
- log.Infov(c, log.KV("log", "search ret empty"))
- return
- }
- uMap, _ := s.dao.BatchUserInfo(c, mid, mids, false, true, true)
- for index, sinfo := range sres {
- if u, ok := uMap[sinfo.ID]; ok {
- r := &v1.UserSearchList{
- UserInfo: *u,
- }
- st := new(v1.UserStatic)
- st.Fan = u.Fan
- st.Follow = u.Follow
- st.Like = u.Like
- st.Liked = u.Liked
- st.FollowState = u.FollowState
- r.UserStatic = st
- r.HitColumns = sinfo.HitColumns
- r.UnameHighlight = sinfo.Uname
- r.Offset = (reqPage-1)*int64(searchLen) + int64(index) + 1
- res.List = append(res.List, r)
- }
- }
- res.NumPage = searchRes.PageNum
- res.Page = searchRes.Page
- res.HasMore = false
- if arg.Page == 0 {
- if (directionNext && searchRes.PageNum > searchRes.Page) || (!directionNext && searchRes.Page > 1) {
- res.HasMore = true
- }
- var list []*v1.UserSearchList
- if directionNext {
- for _, item := range res.List {
- if item.Offset < firstItemOffset {
- continue
- }
- list = append(list, item)
- }
- } else {
- if firstItemOffset >= int64(len(res.List)) {
- firstItemOffset = int64(len(res.List)) - 1
- }
- for i := firstItemOffset - 1; i >= 0; i-- {
- list = append(list, res.List[i])
- }
- }
- res.List = list
- }
- var cursorValue SearchCursor
- for _, item := range res.List {
- cursorValue.Offset = item.Offset
- data, _ := json.Marshal(cursorValue)
- item.CursorValue = string(data)
- }
- return
- }
- // BBQSug BBQSUG服务
- func (s *Service) BBQSug(c context.Context, arg *v1.SugReq) (res []*v1.SugTag, err error) {
- var (
- sres []*model.RawSugTag
- data json.RawMessage
- )
- sp := &model.SugBaseReq{
- Term: arg.KeyWord,
- SuggestType: suggestType,
- MainVer: suggestVer,
- SugNum: arg.PageSize,
- Highlight: int64(arg.Highlight),
- }
- data, err = s.dao.SugBBQ(c, sp)
- if err != nil {
- log.Error("s.dao.SugBBQ err[%v] data [%s]", err, string(data))
- return
- }
- var json = jsoniter.ConfigCompatibleWithStandardLibrary
- if err = json.Unmarshal(data, &sres); err != nil {
- log.Error("json.Unmarshal err[%v] data [%s]", err, string(data))
- return
- }
- for _, sinfo := range sres {
- r := new(v1.SugTag)
- name := sinfo.Name
- r.Name = name
- r.Value = sinfo.Value
- r.Type = sinfo.Type
- r.Ref = sinfo.Ref
- res = append(res, r)
- }
- return
- }
|