tokenFactory/model/aff_invite_profit_share_log.go

144 lines
4.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"errors"
"fmt"
"strings"
"github.com/QuantumNous/new-api/common"
"gorm.io/gorm"
)
// AffInviteProfitShareLog 利润分成模式下,单次请求结算产生的分销入账流水。
type AffInviteProfitShareLog struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
InviterId int `json:"inviter_id" gorm:"not null;index:idx_aff_ps_inv_inv,priority:1"`
InviteeUserId int `json:"invitee_user_id" gorm:"not null;index:idx_aff_ps_inv_inv,priority:2;index"`
ChannelId int `json:"channel_id" gorm:"not null;column:channel_id"`
RouteSlug string `json:"route_slug,omitempty" gorm:"-"`
ModelName string `json:"model_name" gorm:"type:varchar(255);not null;default:'';column:model_name"`
UserQuotaCharged int `json:"user_quota_charged" gorm:"not null;column:user_quota_charged"`
MarkupSliceQuota int `json:"markup_slice_quota" gorm:"not null;column:markup_slice_quota"`
RewardQuota int `json:"reward_quota" gorm:"not null;column:reward_quota"`
// CommissionBps 本条结算适用的代理分润比例(万分之一,与 AffiliateDefaultCommissionBps / EffectiveAffiliateCommissionBps 同单位)。
CommissionBps int `json:"commission_bps" gorm:"not null;default:0;column:commission_bps"`
CreatedAt int64 `json:"created_at" gorm:"bigint;index"`
}
func (AffInviteProfitShareLog) TableName() string {
return "aff_invite_profit_share_logs"
}
// CreditDistributorProfitShare 将利润分成「入账额度」记入邀请人 aff_quota并累计关系表 profit_share_earned_quota。
// markupSliceQuota用户扣费中的加价切片分润基数rewardQuota基数 × 生效分润比例后的入账额度rewardQuota <= markupSliceQuota
// commissionBps本条入账采用的万分之一比例记入流水供明细展示
func CreditDistributorProfitShare(inviterId, inviteeUserId, channelId int, modelName string, userQuotaCharged, markupSliceQuota, rewardQuota, commissionBps int) error {
if inviterId <= 0 || inviteeUserId <= 0 || rewardQuota <= 0 {
return nil
}
if markupSliceQuota < 0 {
markupSliceQuota = 0
}
reward := rewardQuota
modelName = strings.TrimSpace(modelName)
ts := common.GetTimestamp()
return DB.Transaction(func(tx *gorm.DB) error {
up := tx.Model(&User{}).Where("id = ?", inviterId).Updates(map[string]interface{}{
"aff_quota": gorm.Expr("aff_quota + ?", reward),
"aff_history": gorm.Expr("aff_history + ?", reward),
})
if up.Error != nil {
return up.Error
}
if up.RowsAffected == 0 {
return fmt.Errorf("inviter user not found: %d", inviterId)
}
res := tx.Model(&AffInviteRelation{}).
Where("inviter_id = ? AND invitee_user_id = ?", inviterId, inviteeUserId).
UpdateColumn("profit_share_earned_quota", gorm.Expr("profit_share_earned_quota + ?", reward))
if res.Error != nil {
return res.Error
}
if commissionBps < 0 {
commissionBps = 0
}
if commissionBps > maxAffiliateCommissionBps {
commissionBps = maxAffiliateCommissionBps
}
row := AffInviteProfitShareLog{
InviterId: inviterId,
InviteeUserId: inviteeUserId,
ChannelId: channelId,
ModelName: modelName,
UserQuotaCharged: userQuotaCharged,
MarkupSliceQuota: markupSliceQuota,
RewardQuota: reward,
CommissionBps: commissionBps,
CreatedAt: ts,
}
return tx.Create(&row).Error
})
}
// ListAffInviteProfitShareLogs 分页返回某邀请人对某一被邀请人的利润分成明细。
func ListAffInviteProfitShareLogs(inviterId, inviteeUserId int, pageInfo *common.PageInfo) ([]AffInviteProfitShareLog, int64, error) {
if inviterId <= 0 || inviteeUserId <= 0 {
return nil, 0, errors.New("invalid id")
}
var total int64
base := DB.Model(&AffInviteProfitShareLog{}).Where("inviter_id = ? AND invitee_user_id = ?", inviterId, inviteeUserId)
if err := base.Count(&total).Error; err != nil {
return nil, 0, err
}
var rows []AffInviteProfitShareLog
err := DB.Where("inviter_id = ? AND invitee_user_id = ?", inviterId, inviteeUserId).
Order("created_at DESC").
Limit(pageInfo.GetPageSize()).
Offset(pageInfo.GetStartIdx()).
Find(&rows).Error
if err != nil {
return nil, 0, err
}
if rows == nil {
rows = []AffInviteProfitShareLog{}
}
attachProfitShareLogRouteSlugs(rows)
return rows, total, nil
}
func attachProfitShareLogRouteSlugs(rows []AffInviteProfitShareLog) {
if len(rows) == 0 {
return
}
ids := make([]int, 0, len(rows))
seen := make(map[int]struct{}, len(rows))
for i := range rows {
cid := rows[i].ChannelId
if cid <= 0 {
continue
}
if _, ok := seen[cid]; ok {
continue
}
seen[cid] = struct{}{}
ids = append(ids, cid)
}
slugMap := GetRouteSlugsByChannelIDs(ids)
for i := range rows {
cid := rows[i].ChannelId
if cid <= 0 {
continue
}
slug := ""
if slugMap != nil {
slug = strings.TrimSpace(slugMap[cid])
}
if slug == "" {
slug = DefaultRouteSlugFromChannelID(int64(cid))
}
rows[i].RouteSlug = slug
}
}