package dashboard import ( "context" "fmt" "strings" "time" "github.com/shopspring/decimal" ) func (m *Mapper) amountContribution( ctx context.Context, schema string, table string, action string, row Row, amount decimal.Decimal, apply func(*Contribution, decimal.Decimal), ) ([]Contribution, error) { sysOrigin := row.String("sys_origin") if !m.allowed(sysOrigin) { return nil, nil } user, ok, err := m.user(ctx, row.Int64("user_id")) if err != nil || !ok || user.IsDeleted { return nil, err } if user.SysOrigin != sysOrigin { return nil, nil } c := m.base(schema, table, action, row, user, m.sourceTime(row, "create_time")) apply(&c, amount) return []Contribution{c}, nil } func (m *Mapper) sourceTime(row Row, field string) time.Time { value := row.Time(field) if value.IsZero() || m.sourceTimeOffset == 0 { return value } return value.Add(m.sourceTimeOffset) } func (m *Mapper) base(schema string, table string, action string, row Row, user UserCountry, eventTime time.Time) Contribution { return Contribution{ SourceSchema: schema, SourceTable: table, SourcePK: rowPK(row), SourceAction: action, DeltaSign: signForAction(action), SysOrigin: user.SysOrigin, UserID: user.UserID, Country: user.Country, EventTime: eventTime, UserCreatedAt: user.CreatedAt, } } func (m *Mapper) user(ctx context.Context, userID int64) (UserCountry, bool, error) { if userID == 0 { return UserCountry{}, false, nil } return m.store.UserCountry(ctx, userID) } func (m *Mapper) allowed(sysOrigin string) bool { if len(m.sysOrigins) == 0 { return true } _, ok := m.sysOrigins[sysOrigin] return ok } func UserCountryFromRow(row Row, unknownCountry string) UserCountry { code := strings.TrimSpace(row.String("country_code")) if code == "" { code = unknownCountry } name := strings.TrimSpace(row.String("country_name")) if name == "" { name = code } return UserCountry{ UserID: row.Int64("id"), SysOrigin: strings.TrimSpace(row.String("origin_sys")), Country: Country{Code: code, Name: name}, IsDeleted: row.Bool("is_del"), CreatedAt: row.Time("create_time"), UpdatedAt: row.Time("update_time"), } } func rowPK(row Row) string { id := strings.TrimSpace(row.String("id")) if id != "" { return id } return strings.TrimSpace(row.String("event_id")) } func WalletMetricEventKey(schema string, table string, id string) string { if strings.TrimSpace(id) == "" { return "" } return fmt.Sprintf("wallet-metric:%s.%s:%s", schema, table, id) } func rechargeDetail(sourceType string, recordID string, sourceChannel string, row Row, user UserCountry, amount decimal.Decimal, coinQuantity decimal.Decimal, remark string) *RechargeDetail { if recordID == "" || user.UserID == 0 { return nil } return &RechargeDetail{ SourceType: sourceType, RecordID: recordID, SourceChannel: strings.TrimSpace(sourceChannel), SysOrigin: user.SysOrigin, UserID: user.UserID, Country: user.Country, Amount: amount, CoinQuantity: coinQuantity, Remark: strings.TrimSpace(remark), EventTime: row.Time("create_time"), } } func detailUser(c Contribution) UserCountry { return UserCountry{ UserID: c.UserID, SysOrigin: c.SysOrigin, Country: c.Country, } } func signForAction(action string) int { if action == "delete" { return -1 } return 1 }