diff --git a/pkg/items/item.go b/pkg/items/item.go index 52cc0e36d4fe38892c7c8bba0f080803236a339a..c0a0ef935f60e14a5c2543e2fac98f1a9a52c41e 100644 --- a/pkg/items/item.go +++ b/pkg/items/item.go @@ -3,14 +3,13 @@ package items import ( "context" "fmt" + "reflect" "time" "git.perx.ru/perxis/perxis-go/pkg/data" "git.perx.ru/perxis/perxis-go/pkg/errors" - "git.perx.ru/perxis/perxis-go/pkg/locales" "git.perx.ru/perxis/perxis-go/pkg/schema" "git.perx.ru/perxis/perxis-go/pkg/schema/field" - "git.perx.ru/perxis/perxis-go/pkg/schema/localizer" pb "git.perx.ru/perxis/perxis-go/proto/items" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" @@ -162,21 +161,23 @@ func (i *Item) ToMap() map[string]interface{} { } } -func (i *Item) SetData(data map[string]interface{}, localizer *localizer.Localizer) (err error) { - if localizer != nil && localizer.LocaleID != locales.DefaultID { - i.Translations[localizer.LocaleID], err = localizer.ExtractTranslation(i.Data, i.Translations) +func (i *Item) SetData(locale string, data map[string]interface{}) { + if locale != "" { + if i.Translations == nil { + i.Translations = make(map[string]map[string]interface{}) + } + i.Translations[locale] = data return } - i.Data = data - return } -func (i *Item) GetData(localizer *localizer.Localizer) (map[string]interface{}, error) { - if localizer != nil { - return localizer.Localize(i.Data, i.Translations) +func (i *Item) GetData(locale string) map[string]interface{} { + if locale != "" && i.Translations != nil { + translation := i.Translations[locale] + return MergeData(i.Data, translation) } - return i.Data, nil + return i.Data } func (i Item) Encode(ctx context.Context, s *schema.Schema) (*Item, error) { @@ -214,9 +215,40 @@ func (i Item) Decode(ctx context.Context, s *schema.Schema) (res *Item, err erro return &i, nil } +// MergeData дополняет отсутствующие данные из оригинальных данных +func MergeData(data ...map[string]interface{}) map[string]interface{} { + merge := make(map[string]interface{}) + for _, d := range data { + for k, v := range d { + merge[k] = v + } + } + return merge +} + +// ClearData убирает данные которые не изменились по сравнению с оригинальными данными +func ClearData(data ...map[string]interface{}) map[string]interface{} { + var clear map[string]interface{} + + for _, d := range data { + if clear == nil { + clear = d + continue + } + + for k, v := range d { + if reflect.DeepEqual(clear[k], v) { + delete(clear, k) + } + } + } + + return clear +} + type ProcessDataFunc func(ctx context.Context, sch *schema.Schema, data map[string]interface{}) (map[string]interface{}, error) -func (i Item) ProcessData(ctx context.Context, sch *schema.Schema, fn ProcessDataFunc, locales ...*locales.Locale) (*Item, error) { +func (i Item) ProcessData(ctx context.Context, sch *schema.Schema, fn ProcessDataFunc, locales ...string) (*Item, error) { if i.Data != nil { dt, err := fn(ctx, sch, i.Data) if err != nil { @@ -227,16 +259,14 @@ func (i Item) ProcessData(ctx context.Context, sch *schema.Schema, fn ProcessDat tr := make(map[string]map[string]interface{}) for _, l := range locales { - data, err := i.GetData(localizer.NewLocalizer(sch, locales, l.ID)) - if err != nil { - return nil, errors.WithField(err, fmt.Sprintf("translations.%s", l.ID)) - } + + data := i.GetData(l) dt, err := fn(ctx, sch, data) if err != nil { - return nil, errors.WithField(err, fmt.Sprintf("translations.%s", l.ID)) + return nil, errors.WithField(err, fmt.Sprintf("translations.%s", l)) } - tr[l.ID] = dt + tr[l] = dt }