Add admin endpoints for affiliate overview, invites, rebates, transfers, user overrides, batch rate updates, and global rebate config.
142 lines
4.8 KiB
Go
142 lines
4.8 KiB
Go
package model
|
|
|
|
import "time"
|
|
|
|
type RebateRecord struct {
|
|
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
|
|
InviterId int `json:"inviter_id" gorm:"index;uniqueIndex:idx_rebate_order_invite,priority:3;not null"`
|
|
InviteeId int `json:"invitee_id" gorm:"index;uniqueIndex:idx_rebate_order_invite,priority:4;not null"`
|
|
OrderId int `json:"order_id" gorm:"index;uniqueIndex:idx_rebate_order_invite,priority:2"`
|
|
OrderType string `json:"order_type" gorm:"type:varchar(16);uniqueIndex:idx_rebate_order_invite,priority:1;not null"`
|
|
OrderAmount int `json:"order_amount" gorm:"not null"`
|
|
RebateAmount int `json:"rebate_amount" gorm:"not null"`
|
|
RatePercent int `json:"rate_percent" gorm:"not null"`
|
|
Status string `json:"status" gorm:"type:varchar(16);not null;default:'frozen';index"`
|
|
FrozenUntil *time.Time `json:"frozen_until" gorm:"index"`
|
|
ReleasedAt *time.Time `json:"released_at"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
func (RebateRecord) TableName() string {
|
|
return "rebate_records"
|
|
}
|
|
|
|
func (r *RebateRecord) Insert() error {
|
|
return DB.Create(r).Error
|
|
}
|
|
|
|
func (r *RebateRecord) Update() error {
|
|
return DB.Save(r).Error
|
|
}
|
|
|
|
func GetFrozenRebatesDue() ([]RebateRecord, error) {
|
|
var records []RebateRecord
|
|
err := DB.Where("status = ? AND frozen_until IS NOT NULL AND frozen_until <= ?", "frozen", time.Now()).
|
|
Order("id ASC").
|
|
Find(&records).Error
|
|
return records, err
|
|
}
|
|
|
|
func GetRebateRecords(page int, pageSize int, status string, userId int) ([]RebateRecord, int64, error) {
|
|
var records []RebateRecord
|
|
var total int64
|
|
query := DB.Model(&RebateRecord{})
|
|
if status != "" {
|
|
query = query.Where("status = ?", status)
|
|
}
|
|
if userId > 0 {
|
|
query = query.Where("inviter_id = ? OR invitee_id = ?", userId, userId)
|
|
}
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if pageSize < 1 {
|
|
pageSize = 20
|
|
}
|
|
err := query.Order("id DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&records).Error
|
|
return records, total, err
|
|
}
|
|
|
|
type AffiliateOverview struct {
|
|
TotalInvites int64 `json:"total_invites"`
|
|
TotalRebates int64 `json:"total_rebates"`
|
|
TotalRebateAmount int64 `json:"total_rebate_amount"`
|
|
FrozenRebateAmount int64 `json:"frozen_rebate_amount"`
|
|
ReleasedRebateAmount int64 `json:"released_rebate_amount"`
|
|
}
|
|
|
|
func GetAffiliateOverview() (AffiliateOverview, error) {
|
|
var overview AffiliateOverview
|
|
if err := DB.Model(&User{}).Where("inviter_id > 0").Count(&overview.TotalInvites).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
if err := DB.Model(&RebateRecord{}).Count(&overview.TotalRebates).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
if err := DB.Model(&RebateRecord{}).
|
|
Select("COALESCE(SUM(rebate_amount), 0)").
|
|
Scan(&overview.TotalRebateAmount).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
if err := DB.Model(&RebateRecord{}).
|
|
Where("status = ?", "frozen").
|
|
Select("COALESCE(SUM(rebate_amount), 0)").
|
|
Scan(&overview.FrozenRebateAmount).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
if err := DB.Model(&RebateRecord{}).
|
|
Where("status = ?", "released").
|
|
Select("COALESCE(SUM(rebate_amount), 0)").
|
|
Scan(&overview.ReleasedRebateAmount).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
return overview, nil
|
|
}
|
|
|
|
type AffiliateUserOverview struct {
|
|
User *User `json:"user"`
|
|
InvitedUsers int64 `json:"invited_users"`
|
|
TotalRebates int64 `json:"total_rebates"`
|
|
TotalRebateAmount int64 `json:"total_rebate_amount"`
|
|
FrozenRebateAmount int64 `json:"frozen_rebate_amount"`
|
|
ReleasedRebateAmount int64 `json:"released_rebate_amount"`
|
|
}
|
|
|
|
func GetAffiliateUserOverview(userId int) (AffiliateUserOverview, error) {
|
|
var overview AffiliateUserOverview
|
|
user, err := GetUserById(userId, false)
|
|
if err != nil {
|
|
return overview, err
|
|
}
|
|
overview.User = user
|
|
if err := DB.Model(&User{}).Where("inviter_id = ?", userId).Count(&overview.InvitedUsers).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
baseQuery := DB.Model(&RebateRecord{}).Where("inviter_id = ?", userId)
|
|
if err := baseQuery.Count(&overview.TotalRebates).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
if err := DB.Model(&RebateRecord{}).
|
|
Where("inviter_id = ?", userId).
|
|
Select("COALESCE(SUM(rebate_amount), 0)").
|
|
Scan(&overview.TotalRebateAmount).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
if err := DB.Model(&RebateRecord{}).
|
|
Where("inviter_id = ? AND status = ?", userId, "frozen").
|
|
Select("COALESCE(SUM(rebate_amount), 0)").
|
|
Scan(&overview.FrozenRebateAmount).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
if err := DB.Model(&RebateRecord{}).
|
|
Where("inviter_id = ? AND status = ?", userId, "released").
|
|
Select("COALESCE(SUM(rebate_amount), 0)").
|
|
Scan(&overview.ReleasedRebateAmount).Error; err != nil {
|
|
return overview, err
|
|
}
|
|
return overview, nil
|
|
}
|