new-api/model/rebate_record.go
zizi 886d32f255 feat: add affiliate admin API
Add admin endpoints for affiliate overview, invites, rebates, transfers, user overrides, batch rate updates, and global rebate config.
2026-05-20 14:18:06 +08:00

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
}