Files
kra-new/internal/data/business/channel_portrait.go
T

123 lines
4.5 KiB
Go

package business
import (
"context"
"gorm.io/gorm"
"kra/internal/biz/business"
)
type channelPortraitRepo struct{ data Provider }
func NewChannelPortraitRepo(data Provider) business.ChannelPortraitRepo {
return &channelPortraitRepo{data: data}
}
func (r *channelPortraitRepo) GameCount(ctx context.Context, key business.ChannelKey) (*int64, error) {
db := r.data.DB().WithContext(ctx)
available, err := businessTableAvailable(db, "tab_promote_apply")
if err != nil {
return nil, err
}
if !available {
return nil, nil
}
var count int64
if err := db.Table("tab_promote_apply").Where("source_db = ? AND promote_id = ? AND status = 1", key.SourceDB, key.ID).Distinct("game_id").Count(&count).Error; err != nil {
return nil, business.ErrStorage
}
return &count, nil
}
func (r *channelPortraitRepo) EarliestDate(ctx context.Context, scope business.ChannelGameScope) (string, bool, error) {
db := r.data.DB().WithContext(ctx)
available, err := businessTableAvailable(db, "tab_sw_report_day")
if err != nil {
return "", false, err
}
if !available {
return "", false, nil
}
mode := 0
if scope.IDCardDedup {
mode = 1
}
var result struct{ FirstDate *string }
q := db.Table("tab_sw_report_day r").Where("r.source_db = ? AND r.dedup_mode = ? AND r.game_id > 0", scope.Root.SourceDB, mode).Where("(r.source_db,r.promote_id) IN (?)", channelGameTree(db, scope).Select("p.source_db,p.id"))
if err := q.Select("CAST(MIN(r.stat_date) AS CHAR) AS first_date").Scan(&result).Error; err != nil {
return "", false, business.ErrStorage
}
if result.FirstDate == nil {
return "", true, nil
}
return *result.FirstDate, true, nil
}
func channelTierKeys(db *gorm.DB, scope business.ChannelGameScope) *gorm.DB {
mode := 0
if scope.IDCardDedup {
mode = 1
}
return db.Table("tab_sw_report_day_key r").Where("r.source_db = ? AND r.dedup_mode = ? AND r.game_id > 0 AND r.metric = 1 AND r.stat_date >= ? AND r.stat_date <= ? AND r.identity_key IS NOT NULL", scope.Root.SourceDB, mode, scope.BeginDate, scope.EndDate).Where("(r.source_db,r.promote_id) IN (?)", channelGameTree(db, scope).Select("p.source_db,p.id"))
}
func (r *channelPortraitRepo) TierData(ctx context.Context, scope business.ChannelGameScope) (*business.ChannelTierData, error) {
result := &business.ChannelTierData{Available: true, RegisterKeys: []string{}, Payments: []*business.ChannelIdentityPay{}}
db := r.data.DB().WithContext(ctx)
available, err := businessTableAvailable(db, "tab_sw_report_day_key")
if err != nil {
return nil, err
}
if !available {
result.Available = false
return result, nil
}
identity := portraitIdentity(db, scope.IDCardDedup)
if err := channelTierKeys(db, scope).Select("DISTINCT " + identity).Scan(&result.RegisterKeys).Error; err != nil {
return nil, business.ErrStorage
}
if len(result.RegisterKeys) == 0 {
if err := channelTierKeys(db, scope).Select("COUNT(DISTINCT " + identity + ")").Scan(&result.FallbackCount).Error; err != nil {
return nil, business.ErrStorage
}
return result, nil
}
tables := []string{"tab_spend"}
if scope.IDCardDedup {
tables = append(tables, "tab_user")
}
for _, table := range tables {
available, err := businessTableAvailable(db, table)
if err != nil {
return nil, err
}
if !available {
result.Available = false
return result, nil
}
}
// 分层金额按历史成功支付累计,不受画像周期或注册日期范围限制。
q := db.Table("tab_spend s").Where("s.source_db = ? AND s.pay_status = 1", scope.Root.SourceDB).Where("(s.source_db,s.promote_id) IN (?)", channelGameTree(db, scope).Select("p.source_db,p.id"))
if scope.IDCardDedup {
var rows []struct {
IDCard *string `gorm:"column:idcard"`
Amount string
}
if err := q.Joins("JOIN tab_user u ON u.id=s.user_id AND u.source_db=s.source_db").Where("u.idcard IS NOT NULL AND TRIM(u.idcard) <> ''").Select("u.idcard AS idcard,COALESCE(SUM(s.pay_amount),0) AS amount").Group("u.idcard").Scan(&rows).Error; err != nil {
return nil, business.ErrStorage
}
for _, row := range rows {
result.Payments = append(result.Payments, &business.ChannelIdentityPay{IDCard: row.IDCard, Amount: row.Amount})
}
} else {
var rows []struct {
UserID *uint64
Amount string
}
if err := q.Select("s.user_id,COALESCE(SUM(s.pay_amount),0) AS amount").Group("s.user_id").Scan(&rows).Error; err != nil {
return nil, business.ErrStorage
}
for _, row := range rows {
result.Payments = append(result.Payments, &business.ChannelIdentityPay{UserID: row.UserID, Amount: row.Amount})
}
}
return result, nil
}