123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- package service
- import (
- "context"
- "encoding/json"
- "go-common/app/job/live/xroom-feed/internal/model"
- daoAnchorV1 "go-common/app/service/live/dao-anchor/api/grpc/v1"
- "go-common/library/log"
- )
- const (
- _isAll = -1
- _roomStatusTagId = 3
- _onlineCurrent = 3
- )
- type attrFilter struct {
- attrId int64
- attrSubId int64
- max int64
- min int64
- top int64
- }
- var attrType = map[string]int64{
- _onlineType: 1,
- _incomeType: 2,
- _dmsType: 3,
- _hourRankType: 4,
- _liveDaysType: 5,
- }
- var tagType = map[string]bool{
- _areaType: true,
- _roomStatusType: true,
- _anchorCateType: true,
- }
- type filterItem struct {
- isTagHit bool
- item *daoAnchorV1.AttrResp
- }
- // ParentAreaIds ...
- var ParentAreaIds []int64
- // AreaIds ...
- var AreaIds [][]int64
- // getConditionTypeIndex ...
- func (s *Service) getConditionTypeIndex(conds []*model.RuleProtocol, sType string) (i int64) {
- i = -1
- for index, cond := range conds {
- if cond == nil {
- continue
- }
- if cond.ConfType == sType {
- i = int64(index)
- break
- }
- }
- return
- }
- // genCondConfRoomList ... recId for log
- func (s *Service) genCondConfRoomList(ctx context.Context, Condition []*model.RuleProtocol, Cond string, recId int) (roomIds []int64) {
- ParentAreaIds := make([]int64, 0)
- AreaIds := make([][]int64, 0)
- areaFilter := make(map[int64]map[int64]bool)
- roomStatus := make(map[int64]bool)
- anchorCate := make(map[int64]bool)
- attrs := make([]*daoAnchorV1.AttrReq, 0)
- attrsFilter := make(map[int64]map[int64]*attrFilter)
- for _, cond := range Condition {
- // 统计型标签
- if attrTypeV, ok := attrType[cond.Key]; ok {
- isAppend := true
- param := &daoAnchorV1.AttrReq{
- AttrId: attrTypeV,
- }
- if len(cond.Condition) <= 0 || cond.Condition[0] == nil {
- continue
- }
- if cond.Key == _onlineType {
- switch cond.Condition[0].StringV {
- case "current":
- param.AttrSubId = 1
- case "last7day":
- param.AttrSubId = 2
- case "last30day":
- param.AttrSubId = 3
- }
- }
- if cond.Key == _incomeType || cond.Key == _dmsType {
- switch cond.Condition[0].StringV {
- case "range15min":
- param.AttrSubId = 1
- case "range30min":
- param.AttrSubId = 2
- case "range45min":
- param.AttrSubId = 3
- case "range60min":
- param.AttrSubId = 4
- }
- }
- if cond.Key == _liveDaysType {
- switch cond.Condition[0].StringV {
- case "last7day":
- param.AttrSubId = 3
- case "last30day":
- param.AttrSubId = 4
- }
- }
- if cond.Key == _hourRankType {
- if cond.Condition[0].TopV <= 0 {
- isAppend = false
- }
- param.AttrSubId = 1 // 目前小时榜固定是1 @orca
- }
- // 排除后台选择了小时榜,但是top写了0,导致dao anchor不返回这个attr,导致下面and or 过滤出错
- if isAppend {
- attrsFilter[attrTypeV] = make(map[int64]*attrFilter)
- attrsFilter[attrTypeV][param.AttrSubId] = &attrFilter{}
- if i := s.getConditionTypeIndex(cond.Condition, _confTypeRange); i >= 0 && cond.Condition[i] != nil {
- attrsFilter[attrTypeV][param.AttrSubId].max = cond.Condition[i].Max
- attrsFilter[attrTypeV][param.AttrSubId].min = cond.Condition[i].Min
- }
- if i := s.getConditionTypeIndex(cond.Condition, _confTypeTop); i >= 0 && cond.Condition[i] != nil {
- attrsFilter[attrTypeV][param.AttrSubId].top = cond.Condition[i].TopV
- }
- attrs = append(attrs, param)
- }
- }
- // 展示型标签
- if _, ok := tagType[cond.Key]; ok {
- if cond.Key == _areaType {
- for index, areaCond := range cond.Condition {
- // parent area id dimension
- if index == 0 {
- err := json.Unmarshal([]byte(areaCond.StringV), &ParentAreaIds)
- if err != nil {
- log.Error("[genCondConfRoomList]recId:%d, unmarshalParentAreaIdErr:%+v", recId, err)
- continue
- }
- if len(ParentAreaIds) == 1 && ParentAreaIds[0] == _isAll {
- areaFilter[_isAll] = make(map[int64]bool)
- break
- }
- for _, pId := range ParentAreaIds {
- if _, ok := areaFilter[pId]; !ok {
- areaFilter[pId] = make(map[int64]bool)
- }
- }
- }
- // area id dimension
- if index == 1 {
- err := json.Unmarshal([]byte(areaCond.StringV), &AreaIds)
- if err != nil {
- log.Error("[genCondConfRoomList]recId:%d, unmarshalAreaIdErr:%+v", recId, err)
- continue
- }
- for pIdIndex, ids := range AreaIds {
- // 后台保证长度对应 ParentAreaId[pIdIndex]
- if len(ParentAreaIds) <= pIdIndex {
- continue
- }
- if _, ok := areaFilter[ParentAreaIds[pIdIndex]]; !ok {
- continue
- }
- for _, id := range ids {
- if _, ok := areaFilter[ParentAreaIds[pIdIndex]][id]; !ok {
- areaFilter[ParentAreaIds[pIdIndex]][id] = true
- }
- }
- }
- }
- }
- }
- if cond.Key == _roomStatusType && len(cond.Condition) >= 0 && cond.Condition[0] != nil {
- switch cond.Condition[0].StringV {
- case "lottery":
- roomStatus[2] = true
- case "pk":
- roomStatus[1] = true
- }
- }
- if cond.Key == _anchorCateType && len(cond.Condition) >= 0 && cond.Condition[0] != nil {
- switch cond.Condition[0].StringV {
- case "normal":
- anchorCate[0] = true
- case "sign":
- anchorCate[1] = true
- case "union":
- anchorCate[2] = true
- }
- }
- }
- }
- log.Info("[genCondConfRoomList]recId:%d, attrs: %+v", recId, attrs)
- roomList, err := s.getOnlineListByAttrs(ctx, attrs)
- if err != nil {
- log.Error("[getOnlineListByAttrs]recId:%d, getOnlineListByAttrsErr:%+v, resp:%+v", recId, err, roomList)
- return
- }
- filterRoomData := make([]*filterItem, 0)
- for _, roomData := range roomList {
- isHit := false
- isTagHit := false
- if Cond == _condAnd {
- isHit = s.andFilter(attrsFilter, areaFilter, roomStatus, anchorCate, roomData, recId)
- }
- if Cond == _condOr {
- isHit, isTagHit = s.orFilter(attrsFilter, areaFilter, roomStatus, anchorCate, roomData, recId)
- }
- if !isHit {
- continue
- }
- // 命中逻辑
- filterRoomData = append(filterRoomData, &filterItem{
- isTagHit: isTagHit,
- item: roomData,
- })
- }
- return s.sort(attrsFilter, filterRoomData, Cond, recId)
- }
- func (s *Service) andFilter(attrsFilters map[int64]map[int64]*attrFilter, areaFilter map[int64]map[int64]bool, roomStatus, anchorCate map[int64]bool, roomData *daoAnchorV1.AttrResp, recId int) (isHit bool) {
- // area filter
- if len(areaFilter) > 0 {
- _, isParentAll := areaFilter[_isAll]
- // 不是全选继续判断
- if !isParentAll {
- if _, ok := areaFilter[roomData.ParentAreaId]; !ok {
- log.Info("[andFilter]recId:%d, ParentAreaIdNotMatch:areaFilter:%+v, parentId:%d, roomId:%d", recId, areaFilter, roomData.ParentAreaId, roomData.RoomId)
- return false
- }
- _, isAreaAll := areaFilter[roomData.ParentAreaId][_isAll]
- _, isAreaIdExist := areaFilter[roomData.ParentAreaId][roomData.AreaId]
- if !isAreaAll && !isAreaIdExist {
- log.Info("[andFilter]recId:%d, AreaIdNotMatch:areaFilter:%+v, Id:%d, roomId:%d", recId, areaFilter, roomData.AreaId, roomData.RoomId)
- return false
- }
- }
- }
- //如果配置了房间状态筛选
- if len(roomStatus) > 0 {
- roomStatusTag := &daoAnchorV1.TagData{}
- for _, tag := range roomData.TagList {
- if tag.TagId == _roomStatusTagId {
- roomStatusTag = tag
- break
- }
- }
- if _, ok := roomStatus[roomStatusTag.TagSubId]; !ok {
- log.Info("[andFilter]recId:%d, roomStatusNotMatch:roomStatus:%+v, tagSubId:%d, roomId:%d", recId, roomStatus, roomStatusTag.TagSubId, roomData.RoomId)
- return false
- }
- }
- //如果配置了主播类型筛选
- if len(anchorCate) > 0 {
- if _, ok := anchorCate[roomData.AnchorProfileType]; !ok {
- log.Info("[andFilter]recId:%d, anchorCateNotMatch:anchorCate:%+v, anchorProfileType:%d, roomId:%d", recId, anchorCate, roomData.AnchorProfileType, roomData.RoomId)
- return false
- }
- }
- // attr(统计类) filter
- attrsMap := make(map[int64]*daoAnchorV1.AttrData)
- for _, attr := range roomData.AttrList {
- attrsMap[attr.AttrId] = attr
- }
- for attrId, attrFilter := range attrsFilters {
- if _, ok := attrsMap[attrId]; !ok {
- log.Info("[andFilter]recId:%d, attrNotExist:attrId:%d, attrFilter:%d, roomID:%d", recId, attrId, attrsMap, roomData.RoomId)
- return false
- }
- for attrSubId, attrInfo := range attrFilter {
- if attrInfo == nil {
- continue
- }
- if attrsMap[attrId].AttrSubId == attrSubId {
- if attrInfo.min > 0 && attrsMap[attrId].AttrValue < attrInfo.min {
- log.Info("[andFilter]recId:%d, attrMinNotMatch:attrId:%d, value:%d, max:%d, min:%d, roomID:%d", recId, attrId, attrsMap[attrId].AttrValue, attrInfo.max, attrInfo.min, roomData.RoomId)
- return false
- }
- if attrInfo.max > 0 && attrsMap[attrId].AttrValue > attrInfo.max {
- log.Info("[andFilter]recId:%d, attrMaxNotMatch:attrId:%d, value:%d, max:%d, min:%d, roomID:%d", recId, attrId, attrsMap[attrId].AttrValue, attrInfo.max, attrInfo.min, roomData.RoomId)
- return false
- }
- }
- }
- }
- log.Info("[andFilter]recId:%d, successMatch:roomData:%+v,attrs:%+v, areaFilter:%+v, roomStatus:%+v, anchorState:%+v, roomID:%d", recId, roomData, attrsFilters, areaFilter, roomStatus, anchorCate, roomData.RoomId)
- return true
- }
- func (s *Service) orFilter(attrsFilters map[int64]map[int64]*attrFilter, areaFilter map[int64]map[int64]bool, roomStatus, anchorCate map[int64]bool, roomData *daoAnchorV1.AttrResp, recId int) (isHit bool, isTagHit bool) {
- // area filter
- isTagHit = false
- if len(areaFilter) > 0 {
- if _, ok := areaFilter[_isAll]; ok {
- log.Info("[orFilter]recId:%d, ParentAreaIdAllMatch:areaFilter:%+v, parentId:%d, roomID:%d", recId, areaFilter, roomData.ParentAreaId, roomData.RoomId)
- isTagHit = true
- return true, isTagHit
- }
- if _, ok := areaFilter[roomData.ParentAreaId]; ok {
- log.Info("[orFilter]recId:%d, ParentAreaIdMatch:areaFilter:%+v, parentId:%d, roomID:%d", recId, areaFilter, roomData.ParentAreaId, roomData.RoomId)
- isTagHit = true
- return true, isTagHit
- }
- _, isAll := areaFilter[roomData.ParentAreaId][_isAll]
- _, isAreaIdExist := areaFilter[roomData.ParentAreaId][roomData.AreaId]
- if isAll || isAreaIdExist {
- log.Info("[orFilter]recId:%d, AreaIdMatch:areaFilter:%+v, Id:%d, roomID:%d", recId, areaFilter, roomData.AreaId, roomData.RoomId)
- isTagHit = true
- return true, isTagHit
- }
- }
- //如果配置了房间状态筛选
- if len(roomStatus) > 0 {
- roomStatusTag := &daoAnchorV1.TagData{}
- for _, tag := range roomData.TagList {
- if tag.TagId == _roomStatusTagId {
- roomStatusTag = tag
- break
- }
- }
- if _, ok := roomStatus[roomStatusTag.TagSubId]; ok {
- log.Info("[orFilter]recId:%d, roomStatusMatch:roomStatus:%+v, tagSubId:%d, roomID:%d", recId, roomStatus, roomStatusTag.TagSubId, roomData.RoomId)
- isTagHit = true
- return true, isTagHit
- }
- }
- //如果配置了主播类型筛选
- if len(anchorCate) > 0 {
- if _, ok := anchorCate[roomData.AnchorProfileType]; ok {
- log.Info("[orFilter]recId:%d, anchorCateMatch:anchorCate:%+v, anchorProfileType:%d, roomID:%d", recId, anchorCate, roomData.AnchorProfileType, roomData.RoomId)
- isTagHit = true
- return true, isTagHit
- }
- }
- // attr filter
- attrDataMap := make(map[int64]*daoAnchorV1.AttrData)
- for _, attr := range roomData.AttrList {
- attrDataMap[attr.AttrId] = attr
- }
- for attrId, attrFilter := range attrsFilters {
- if _, ok := attrDataMap[attrId]; !ok {
- continue
- }
- //小时榜不需要判断max min
- if attrId == attrType[_hourRankType] {
- return true, isTagHit
- }
- for attrSubId, attrFilterInfo := range attrFilter {
- attrData, ok := attrDataMap[attrId]
- if !ok {
- continue
- }
- if attrData.AttrSubId == attrSubId {
- if attrFilterInfo.min > 0 && attrData.AttrValue < attrFilterInfo.min {
- continue
- }
- if attrFilterInfo.max > 0 && attrData.AttrValue > attrFilterInfo.max {
- continue
- }
- log.Info("[orFilter]recId:%d, attrMaxMinMatch:attrId:%d, value:%d, max:%d, min:%d, roomID:%d", recId, attrId, attrDataMap[attrId].AttrValue, attrFilterInfo.max, attrFilterInfo.min, roomData.RoomId)
- return true, isTagHit
- }
- }
- }
- log.Info("[orFilter]recId:%d, failMatch:roomData:%+v,attrs:%+v, areaFilter:%+v, roomStatus:%+v, anchorState:%+v, roomId:%d", recId, roomData, attrsFilters, areaFilter, roomStatus, anchorCate, roomData.RoomId)
- return false, isTagHit
- }
|