232 lines
7.3 KiB
Go
232 lines
7.3 KiB
Go
package transfer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"gitea.pena/PenaSide/hlog"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"time"
|
|
"transfer_to_clickhouse/models"
|
|
)
|
|
|
|
const promoCodesColl = "promoCodes"
|
|
const promoStatsColl = "promoStats"
|
|
|
|
type Codeword struct {
|
|
logger hlog.Logger
|
|
collectionPromoCodes *mongo.Collection
|
|
collectionPromoStats *mongo.Collection
|
|
}
|
|
|
|
func NewCodeword(logger hlog.Logger, db *mongo.Database) *Codeword {
|
|
return &Codeword{
|
|
logger: logger,
|
|
collectionPromoCodes: db.Collection(promoCodesColl),
|
|
collectionPromoStats: db.Collection(promoStatsColl),
|
|
}
|
|
}
|
|
|
|
type PromoCodeStats struct {
|
|
ID primitive.ObjectID `bson:"_id" json:"id,omitempty"`
|
|
UsageMap map[string][]struct {
|
|
UserID string `bson:"userID" json:"userID"`
|
|
Time uint64 `bson:"time" json:"time"`
|
|
} `bson:"usageMap" json:"usageMap"`
|
|
}
|
|
|
|
type PromoCode struct {
|
|
ID primitive.ObjectID `json:"id" bson:"_id"`
|
|
Codeword string `json:"codeword" bson:"codeword"` // то, что будет вводить пользователь, чтобы получить плюшки
|
|
Description string `json:"description" bson:"description"` // описание, необходимое менеджеру в админке
|
|
Greetings string `json:"greetings" bson:"greetings"` // текст, выдаваемый пользователю в ответ на активацию промокода
|
|
DueTo int64 `json:"dueTo" bson:"dueTo"` // таймштамп времени окончания работы активации промокода
|
|
ActivationCount int64 `json:"activationCount" bson:"activationCount"` // предел количества активаций промокода
|
|
ActivationLimit int64 `json:"activationLimit" bson:"activationLimit"` // лимит если 0 то без лимита
|
|
Bonus struct {
|
|
Privilege struct {
|
|
PrivilegeID string `json:"privilegeID" bson:"privilegeID"` // айдишник привилегии, которая будет выдаваться
|
|
Amount uint64 `json:"amount" bson:"amount"` // количество
|
|
ServiceKey string `json:"serviceKey" bson:"serviceKey"` // тип сервиса
|
|
} `json:"privilege" bson:"privilege"`
|
|
Discount struct {
|
|
Layer uint32 `json:"layer" bson:"layer"` // 1|2
|
|
Factor float64 `json:"factor" bson:"factor"` // процент скидки, вернее множитель, при котором достигается этот процент скидки
|
|
Target string `json:"target" bson:"target"` // PrivilegeID или ServiceKey в зависимости от слоя
|
|
Threshold int64 `json:"threshold" bson:"threshold"` // граничное значение, при пересечении которого применяется эта скидка
|
|
} `json:"discount" bson:"discount"`
|
|
} `json:"bonus" bson:"bonus"`
|
|
Outdated bool `json:"outdated" bson:"outdated"`
|
|
OffLimit bool `json:"offLimit" bson:"offLimit"`
|
|
Delete bool `json:"delete" bson:"delete"`
|
|
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
|
FastLinks []string `json:"fastLinks" bson:"fastLinks"`
|
|
}
|
|
|
|
func (r *Codeword) ActivatedEvents(ctx context.Context) error {
|
|
var promoCodeStatsList []PromoCodeStats
|
|
|
|
filter := bson.M{}
|
|
|
|
cursor, err := r.collectionPromoStats.Find(ctx, filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
for cursor.Next(ctx) {
|
|
var promoCodeStats PromoCodeStats
|
|
if err := cursor.Decode(&promoCodeStats); err != nil {
|
|
continue
|
|
}
|
|
promoCodeStatsList = append(promoCodeStatsList, promoCodeStats)
|
|
}
|
|
|
|
if err := cursor.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, i := range promoCodeStatsList {
|
|
promoCode, err := r.GetPromoCode(ctx, i.ID)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
continue
|
|
}
|
|
for key, u := range i.UsageMap {
|
|
if key == promoCode.Codeword {
|
|
for _, j := range u {
|
|
r.logger.Emit(models.InfoPromocodeActivated{
|
|
CtxID: i.ID.String(),
|
|
CtxUserID: j.UserID,
|
|
CtxCode: key,
|
|
})
|
|
}
|
|
} else {
|
|
for _, j := range u {
|
|
r.logger.Emit(models.InfoFastlinkActivated{
|
|
CtxID: i.ID.String(),
|
|
CtxUserID: j.UserID,
|
|
CtxPromocodeID: key,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *Codeword) GetPromoCode(ctx context.Context, promoCodeID primitive.ObjectID) (*PromoCode, error) {
|
|
filter := bson.M{"_id": promoCodeID}
|
|
|
|
var promoCode PromoCode
|
|
err := r.collectionPromoCodes.FindOne(ctx, filter).Decode(&promoCode)
|
|
if err != nil {
|
|
if errors.Is(err, mongo.ErrNoDocuments) {
|
|
return nil, err
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &promoCode, nil
|
|
}
|
|
|
|
func (r *Codeword) DeletedEvents(ctx context.Context) error {
|
|
filter := bson.M{"delete": true}
|
|
|
|
var deletedPromoCodes []PromoCode
|
|
|
|
cursor, err := r.collectionPromoCodes.Find(ctx, filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
for cursor.Next(ctx) {
|
|
var promoCode PromoCode
|
|
if err := cursor.Decode(&promoCode); err != nil {
|
|
return err
|
|
}
|
|
deletedPromoCodes = append(deletedPromoCodes, promoCode)
|
|
}
|
|
|
|
if err := cursor.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, i := range deletedPromoCodes {
|
|
r.logger.Emit(models.InfoPromocodeDeleted{
|
|
CtxID: i.ID.String(),
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *Codeword) EventCreate(ctx context.Context) error {
|
|
filter := bson.M{}
|
|
var promoCodes []PromoCode
|
|
|
|
cursor, err := r.collectionPromoCodes.Find(ctx, filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
for cursor.Next(ctx) {
|
|
var promoCode PromoCode
|
|
if err := cursor.Decode(&promoCode); err != nil {
|
|
return err
|
|
}
|
|
promoCodes = append(promoCodes, promoCode)
|
|
}
|
|
|
|
if err := cursor.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, createdPromoCode := range promoCodes {
|
|
var keyType string
|
|
var keyTargetType string
|
|
var ctxTarget string
|
|
var ctxAmount int64
|
|
|
|
if createdPromoCode.Bonus.Privilege.PrivilegeID != "" && createdPromoCode.Bonus.Discount.Factor != 0 && createdPromoCode.Bonus.Discount.Factor != 1 {
|
|
keyType = "privilege,discount"
|
|
keyTargetType = "privilege,service"
|
|
ctxTarget = fmt.Sprintf("%s,%s", createdPromoCode.Bonus.Privilege.PrivilegeID, createdPromoCode.Bonus.Discount.Target)
|
|
ctxAmount = int64(createdPromoCode.Bonus.Privilege.Amount)
|
|
} else if createdPromoCode.Bonus.Privilege.PrivilegeID != "" {
|
|
keyType = "privilege"
|
|
keyTargetType = "privilege"
|
|
ctxTarget = createdPromoCode.Bonus.Privilege.PrivilegeID
|
|
ctxAmount = int64(createdPromoCode.Bonus.Privilege.Amount)
|
|
} else if createdPromoCode.Bonus.Discount.Factor != 0 && createdPromoCode.Bonus.Discount.Factor != 1 {
|
|
keyType = "discount"
|
|
keyTargetType = "service"
|
|
ctxTarget = createdPromoCode.Bonus.Discount.Target
|
|
}
|
|
r.logger.Emit(models.InfoPromocodeCreated{
|
|
CtxID: createdPromoCode.ID.String(),
|
|
KeyType: keyType,
|
|
KeyTargetType: keyTargetType,
|
|
CtxTarget: ctxTarget,
|
|
CtxAmount: ctxAmount,
|
|
CtxCode: createdPromoCode.Codeword,
|
|
})
|
|
|
|
if len(createdPromoCode.FastLinks) > 0 {
|
|
for _, link := range createdPromoCode.FastLinks {
|
|
r.logger.Emit(models.InfoFastlinkCreated{
|
|
CtxID: link,
|
|
CtxPromocodeID: createdPromoCode.ID.String(),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|