table_object_search.go 4.6 KB
package service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/query"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
	"sort"
)

func (tableService *TableService) TableObjectSearch(searchQuery *query.SearchTableQuery) (interface{}, error) {
	if err := searchQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}

	tableRepository, _, _ := factory.FastPgTable(transactionContext, 0)
	_, tables, err := tableRepository.Find(utils.ObjectToMap(searchQuery))
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	var result = make([]*dto.TableObjectDto, 0)
	for _, table := range tables {
		var item = &dto.TableObjectDto{}
		item.Load(table)
		if searchQuery.ReturnDetailStructInfo {
			item.SetDetailStructInfo(table)
		}
		item.Flag = domain.FlagSet
		if item.TableType == domain.MainTable.ToString() ||
			item.TableType == domain.SubTable.ToString() ||
			item.TableType == domain.SideTable.ToString() {
			item.ParentId = 0
			item.Status = domain.StatusOn
		}
		result = append(result, item)
	}
	if searchQuery.TableId > 0 {
		return map[string]interface{}{
			"count":        len(result),
			"tableObjects": result,
		}, nil
	}

	querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0)
	_, querySets, _ := querySetRepository.Find(map[string]interface{}{"context": searchQuery.Context})

	var (
		querySetMapById      = make(map[int]*domain.QuerySet)
		querySetMapByTableId = make(map[int]*domain.QuerySet)
	)
	if searchQuery.ReturnGroupItem != nil && *searchQuery.ReturnGroupItem {
		for _, qs := range querySets {
			querySetMapById[qs.QuerySetId] = qs
		}
	}

	for _, qs := range querySets {
		if qs.QuerySetInfo.BindTableId == 0 {
			continue
		}
		querySetMapByTableId[qs.QuerySetInfo.BindTableId] = qs
	}

	var response = make([]*dto.TableObjectDto, 0)
	for index, t := range result {
		v, ok := querySetMapByTableId[t.TableId]
		if !ok {
			continue
		}
		result[index].Update(v)
	}
	// 分组
	querySetMapGroup := make(map[int]bool)
	querySetGroups := make([]*domain.QuerySet, 0)
	for _, t := range result {
		if filterTableByFilterRule(t, searchQuery) {
			continue
		}
		if !domain.TableType(t.TableType).TableIsSplitByGroup() {
			response = append(response, t)
			continue
		}
		v, ok := querySetMapByTableId[t.TableId]
		if !ok {
			response = append(response, t)
			continue
		}
		t.Update(v)
		parentGroupId := v.ParentId

		response = append(response, t)
		for {
			if parentGroupId == 0 {
				break
			}
			if _, ok := querySetMapGroup[parentGroupId]; ok {
				break
			}
			querySetMapGroup[parentGroupId] = true
			if v, ok := querySetMapById[parentGroupId]; ok {
				querySetGroups = append(querySetGroups, v)
				parentGroupId = v.ParentId
			}
		}
	}

	for _, querySetGroup := range querySetGroups {
		var groupItem = &dto.TableObjectDto{}
		groupItem.LoadGroup(querySetGroup)
		response = append(response, groupItem)
	}

	sort.Slice(response, func(i, j int) bool {
		item1 := response[i]
		item2 := response[j]
		k1 := fmt.Sprintf("%v-%v-%v", item1.TableType, item1.ParentId, item1.Id)
		k2 := fmt.Sprintf("%v-%v-%v", item2.TableType, item2.ParentId, item2.Id)
		return k1 < k2
	})
	return map[string]interface{}{
		"count":        len(response),
		"tableObjects": response,
	}, nil
}

// true:代表需要过滤  false:不需要过滤
func filterTableByFilterRule(item *dto.TableObjectDto, searchQuery *query.SearchTableQuery) bool {
	filterRules := searchQuery.FilterRules
	if len(searchQuery.ExcludeTables) > 0 {
		for _, t := range searchQuery.ExcludeTables {
			if t == item.TableId {
				return true
			}
		}
	}
	for _, rule := range filterRules {
		if rule.TableType == item.TableType && rule.Status > 0 && rule.Status != item.Status {
			return true
		}
		if rule.TableType == item.TableType && rule.Status == 0 {
			return true
		}
	}
	for _, rule := range filterRules {
		if rule.TableType == "*" && rule.Status > 0 && rule.Status != item.Status {
			return true
		}
	}
	return false
}