feat: 迁移商务与游戏商务画像及交互看板

This commit is contained in:
Yvan
2026-11-03 23:11:46 +08:00
parent 7f8105f6fb
commit 0de822f121
30 changed files with 1959 additions and 26 deletions
@@ -0,0 +1,73 @@
package business
import (
"context"
"kra/internal/biz/business"
"kra/internal/service/dto"
)
type BusinessPortraitUsecase interface {
ForUser(context.Context, uint, []string, string) (*business.BusinessPortrait, error)
ForBinding(context.Context, business.PlatformKey, string) (*business.BusinessPortrait, error)
}
type BusinessPortraitService struct{ uc BusinessPortraitUsecase }
func NewBusinessPortraitService(uc *business.BusinessPortraitUsecase) *BusinessPortraitService {
return &BusinessPortraitService{uc: uc}
}
func portraitMetricResponse(m *business.PortraitMetric) *dto.PortraitMetric {
if m == nil {
return nil
}
return &dto.PortraitMetric{Value: m.Value, CompareValue: m.CompareValue, ChangeRate: m.ChangeRate, ChangeDiff: m.ChangeDiff, CompareLabel: m.CompareLabel}
}
func portraitResponse(p *business.BusinessPortrait) *dto.BusinessPortraitResponse {
b := p.Basic
out := &dto.BusinessPortraitResponse{Basic: &dto.PortraitBasic{UserID: b.UserID, UserName: b.UserName, RealName: b.RealName, Level: b.Level, LevelLabel: business.BusinessLevelLabel(b.Level), ParentUserID: b.ParentUserID, ParentUserName: b.ParentUserName, ParentRealName: b.ParentRealName, CreateTime: localTime(b.CreatedAt), Status: b.Status, StatusLabel: b.StatusLabel, PromoteCount: b.PromoteCount, MonthNewPromote: b.MonthNewPromote}, Period: p.Period, RegisterTrend: []*dto.PortraitTrend{}, PayTrend: []*dto.PortraitTrend{}, RegisterTop5: []*dto.PortraitRank{}, PayTop5: []*dto.PortraitRank{}, Available: p.Available, UnavailableReason: p.UnavailableReason}
if m := p.Metrics; m != nil {
out.Metrics = &dto.PortraitMetrics{Register: portraitMetricResponse(m.Register), PayAmount: portraitMetricResponse(m.PayAmount), PayRate: portraitMetricResponse(m.PayRate), ARPU: portraitMetricResponse(m.ARPU)}
}
for _, point := range p.RegisterTrend {
out.RegisterTrend = append(out.RegisterTrend, &dto.PortraitTrend{Label: point.Label, Value: point.Value})
}
for _, point := range p.PayTrend {
out.PayTrend = append(out.PayTrend, &dto.PortraitTrend{Label: point.Label, Value: point.Value})
}
ranks := func(rows []*business.PortraitRank) []*dto.PortraitRank {
result := make([]*dto.PortraitRank, 0, len(rows))
for _, row := range rows {
result = append(result, &dto.PortraitRank{Rank: row.Rank, SourceDB: row.SourceDB, SourceDBLabel: business.PlatformName(row.SourceDB), PromoteID: row.ID, PromoteName: row.PromoteName, Value: row.Value})
}
return result
}
out.RegisterTop5 = ranks(p.RegisterTop5)
out.PayTop5 = ranks(p.PayTop5)
return out
}
func (s *BusinessPortraitService) ForUser(ctx context.Context, id uint, req *dto.BusinessPortraitQuery) (*dto.BusinessPortraitResponse, error) {
if id == 0 || req == nil {
return nil, business.ErrAccountInput
}
sources, err := normalizePlatforms(req.Sources)
if err != nil {
return nil, err
}
if len(sources) == 0 {
return nil, business.ErrPortraitPlatforms
}
portrait, err := s.uc.ForUser(ctx, id, sources, req.Period)
if err != nil {
return nil, err
}
return portraitResponse(portrait), nil
}
func (s *BusinessPortraitService) ForBinding(ctx context.Context, req *dto.BindingPortraitQuery) (*dto.BusinessPortraitResponse, error) {
if req == nil || req.PlatformBusierID == 0 {
return nil, business.ErrAccountInput
}
portrait, err := s.uc.ForBinding(ctx, business.PlatformKey{SourceDB: req.SourceDB, BusierID: req.PlatformBusierID}, req.Period)
if err != nil {
return nil, err
}
return portraitResponse(portrait), nil
}
+62
View File
@@ -0,0 +1,62 @@
package dto
type BusinessPortraitQuery struct {
Sources []string `form:"sourceDbList"`
Period string `form:"period"`
}
type BindingPortraitQuery struct {
SourceDB string `form:"sourceDb"`
PlatformBusierID uint64 `form:"platformBusierId"`
Period string `form:"period"`
}
type PortraitBasic struct {
UserID uint64 `json:"userId"`
UserName string `json:"userName"`
RealName string `json:"realName"`
Level *int `json:"level"`
LevelLabel string `json:"levelLabel"`
ParentUserID *uint64 `json:"parentUserId"`
ParentUserName string `json:"parentUserName"`
ParentRealName string `json:"parentRealName"`
CreateTime *string `json:"createTime"`
Status *string `json:"status"`
StatusLabel string `json:"statusLabel"`
PromoteCount *int64 `json:"promoteCount"`
MonthNewPromote *int64 `json:"monthNewPromote"`
}
type PortraitMetric struct {
Value string `json:"value"`
CompareValue *string `json:"compareValue"`
ChangeRate *string `json:"changeRate"`
ChangeDiff *string `json:"changeDiff"`
CompareLabel string `json:"compareLabel"`
}
type PortraitMetrics struct {
Register *PortraitMetric `json:"register"`
PayAmount *PortraitMetric `json:"payAmount"`
PayRate *PortraitMetric `json:"payRate"`
ARPU *PortraitMetric `json:"arpu"`
}
type PortraitTrend struct {
Label string `json:"label"`
Value string `json:"value"`
}
type PortraitRank struct {
Rank int `json:"rank"`
SourceDB string `json:"sourceDb"`
SourceDBLabel string `json:"sourceDbLabel"`
PromoteID uint64 `json:"promoteId"`
PromoteName string `json:"promoteName"`
Value string `json:"value"`
}
type BusinessPortraitResponse struct {
Basic *PortraitBasic `json:"basic"`
Period string `json:"period"`
Metrics *PortraitMetrics `json:"metrics"`
RegisterTrend []*PortraitTrend `json:"registerTrend"`
PayTrend []*PortraitTrend `json:"payTrend"`
RegisterTop5 []*PortraitRank `json:"registerTop5"`
PayTop5 []*PortraitRank `json:"payTop5"`
Available bool `json:"available"`
UnavailableReason string `json:"unavailableReason"`
}
+1
View File
@@ -21,6 +21,7 @@ var ProviderSet = wire.NewSet(
businessservice.NewAlertRecordService,
businessservice.NewActivationService,
businessservice.NewChannelService,
businessservice.NewBusinessPortraitService,
systemservice.ProviderSet,
paymentservice.ProviderSet,
integrationservice.ProviderSet,