field_optional_values.go 5.1 KB
package service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	"github.com/zeromicro/go-zero/core/collection"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
	"gorm.io/gorm"
	"sort"
)

func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd *command.FieldOptionalValuesCommand) (interface{}, error) {
	if err := cmd.ValidateCommand(); 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())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var dataTable *domain.DataTable
	var empty = map[string]interface{}{
		"values": []string{},
		"total":  0,
	}
	tableRepository, _, _ := factory.FastPgTable(transactionContext, 0)
	var table *domain.Table
	var db *gorm.DB
	switch cmd.ObjectType {
	case domain.ObjectFile:
		byteCore, _ := factory.CreateByteCoreService(transactionContext)
		response, err := byteCore.FieldOptionalValues(domain.ReqFieldOptionalValues{
			FileId: cmd.ObjectId,
			Field:  &cmd.Field,
			Match:  cmd.Match,
			Where: domain.Where{
				PageNumber: cmd.PageNumber,
				PageSize:   cmd.PageSize,
			},
		})
		if err != nil {
			return nil, factory.FastError(err)
		}
		return map[string]interface{}{
			"values": response.Values,
			"total":  response.Total,
		}, nil
	case domain.ObjectMetaTable:
		table, err = tableRepository.FindOne(map[string]interface{}{"ctx": ctx, "tableId": cmd.ObjectId})
		if err != nil {
			return nil, factory.FastError(err)
		}
		db = starrocks.DB
	case domain.ObjectDBTable:
		table = domain.DBTables[cmd.ObjectId]
		db = pg.GormDB
	}

	field, ok := table.MatchField(&cmd.Field)
	if !ok {
		return nil, factory.FastError(fmt.Errorf("列:%v 不存在", cmd.Field.Name))
	}
	// 字段只传name时,补齐sqlName
	for i, c := range cmd.Where.Conditions {
		if c.Field != nil && c.Field.SQLName == "" {
			if v, ok := table.MatchField(c.Field); ok {
				cmd.Where.Conditions[i].Field.SQLName = v.SQLName
				cmd.Where.Conditions[i].Field.SQLType = v.SQLType
			}
		}
	}
	if table.TableType == domain.SubTable.ToString() && field.Flag == domain.ManualField {
		return empty, nil
	}
	match := cmd.Match
	if !domain.SQLType(field.SQLType).IsString() {
		match = ""
	}

	if table.TableType == domain.CalculateSet.ToString() {
		var querySet *domain.QuerySet
		querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0)
		querySet, err = querySetRepository.FindOne(map[string]interface{}{"BindTableId": cmd.ObjectId})
		if err != nil {
			return nil, factory.FastError(err)
		}
		svr, _ := factory.FastQuerySetServices(transactionContext)
		dataTable, err = svr.LoadCalculateSetData(ctx, querySet, querySet.QueryComponents)
		if err != nil {
			return nil, factory.FastError(err)
		}
		if cmd.Where != nil {
			data, length := dataTable.FilterByWhere(*cmd.Where)
			dataTable.Data = data
			dataTable.Total = length
		}
		values := removeDuplicate(dataTable.Values(field))
		sort.SliceStable(values, func(i, j int) bool {
			return values[i] < values[j]
		})
		return map[string]interface{}{
			"values": values,
			"total":  len(values),
		}, nil
	}
	options := &starrocks.QueryOptions{
		Table:     table,
		TableName: table.SQLName,
		Select:    []*domain.Field{field},
		Where: []starrocks.Condition{
			{
				Condition: domain.Condition{
					Field: field,
					Like:  match,
					Order: "ASC",
				},
				Distinct: true,
			},
		},
	}
	if cmd.Where != nil && len(cmd.Where.Conditions) > 0 {
		for _, c := range cmd.Where.Conditions {
			options.Where = append(options.Where, starrocks.Condition{
				Condition: c,
			})
		}
	}
	options.AdditionOptionsByTable(table)
	options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize)

	dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db))
	if err != nil {
		return nil, factory.FastError(err)
	}
	dataTable.Total, err = starrocks.WrapQueryCountWithDB(*options, db)()
	if err != nil {
		return nil, factory.FastError(err)
	}

	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	values := dataTable.OptionalValue(cmd.Match, field.SQLType)
	return map[string]interface{}{
		"values": values,
		"total":  len(values),
	}, nil
}

func removeDuplicate(inputs []string) []string {
	s := collection.NewSet()
	var result = make([]string, 0)
	for _, input := range inputs {
		if !s.Contains(input) {
			s.Add(input)
			result = append(result, input)
		}
	}
	return result
}