Files
kra-new/internal/service/business/channel.go
T

123 lines
5.2 KiB
Go

package business
import (
"context"
"math"
"strconv"
"strings"
"time"
"unicode/utf16"
"kra/internal/biz/business"
"kra/internal/service/dto"
)
type ChannelUsecase interface {
List(context.Context, business.ChannelFilter, ...business.ListOption) (*business.ChannelPage, error)
BindOptions(context.Context, string) ([]*business.Binding, error)
Create(context.Context, *business.ChannelCreate) (*business.ChannelCreateResult, error)
Games(context.Context, business.ChannelKey) ([]*business.ChannelGame, error)
}
type ChannelService struct{ uc ChannelUsecase }
func NewChannelService(uc *business.ChannelUsecase) *ChannelService { return &ChannelService{uc: uc} }
func (s *ChannelService) List(ctx context.Context, req *dto.ChannelQuery) (*dto.ChannelPage, error) {
if req == nil {
return nil, business.ErrChannelInput
}
sources, err := normalizePlatforms(req.Sources)
if err != nil {
return nil, err
}
page, size := req.Page, req.PageSize
if page < 1 {
page = 1
}
if size < 1 {
size = 10
}
if size > 500 {
size = 500
}
if page > int(^uint(0)>>1)/size {
return nil, business.ErrChannelInput
}
filter := business.ChannelFilter{Sources: sources, BusierUserID: req.BusierUserID, BusierAccount: strings.TrimSpace(req.BusierAccount), Keyword: strings.TrimSpace(req.Keyword), Level: req.Level, RegisterType: req.RegisterType, Status: req.Status, LockStatus: req.LockStatus, Effective: req.Effective}
filter.Phone, filter.SettlementDays = strings.TrimSpace(req.Phone), req.SettlementDays
filter.SortField, filter.Ascending = req.SortField, req.SortOrder == "asc"
if filter.SortField != "" && filter.SortField != "createdAt" || filter.SettlementDays != nil && *filter.SettlementDays < 1 {
return nil, business.ErrChannelInput
}
for _, pair := range []struct {
begin, end string
outBegin, outEnd **time.Time
}{
{req.CreatedBegin, req.CreatedEnd, &filter.CreatedBegin, &filter.CreatedEnd},
{req.LoginBegin, req.LoginEnd, &filter.LoginBegin, &filter.LoginEnd},
} {
parsed, err := analyticsRequest(&dto.AnalyticsQuery{BeginTime: pair.begin, EndTime: pair.end})
if err != nil {
return nil, business.ErrChannelInput
}
*pair.outBegin, *pair.outEnd = parsed.StartDate, parsed.EndDate
}
result, err := s.uc.List(ctx, filter, business.ListOffset((page-1)*size), business.ListLimit(size))
if err != nil {
return nil, err
}
out := &dto.ChannelPage{Rows: []*dto.ChannelResponse{}, Total: result.Total, Available: result.Available}
if result.StatusCounts != nil {
out.StatusCounts = &dto.ChannelStatusCounts{Normal: result.StatusCounts.Normal, Locked: result.StatusCounts.Locked, Terminated: result.StatusCounts.Terminated}
}
for _, c := range result.Rows {
out.Rows = append(out.Rows, &dto.ChannelResponse{ID: c.ID, SourceDB: c.SourceDB, PlatformName: business.PlatformName(c.SourceDB), Account: c.Account, Nickname: c.Nickname, Level: c.Level, ParentID: c.ParentID, ParentName: c.ParentName, RealName: c.RealName, RegisterType: c.RegisterType, BusierID: c.BusierID, BusierUserID: c.BusierUserID, BusierDisplayName: c.BusinessDisplayName(), Status: c.Status, LockStatus: c.LockStatus, GameCount: c.GameCount, PlayerCount: c.PlayerCount, TotalPayAmount: c.TotalPayAmount, Effective: c.QualifiedAt != nil, QualifiedAt: c.QualifiedAt, CreatedAt: c.CreatedUnix, LastLoginAt: c.LastLoginUnix, Phone: c.Phone, SettlementDays: c.SettlementDays})
}
return out, nil
}
func (s *ChannelService) BindOptions(ctx context.Context, source string) ([]*dto.ChannelBindOption, error) {
rows, err := s.uc.BindOptions(ctx, source)
if err != nil {
return nil, err
}
out := make([]*dto.ChannelBindOption, 0, len(rows))
for _, b := range rows {
out = append(out, &dto.ChannelBindOption{SourceDB: b.SourceDB, PlatformBusierID: b.BusierID, Account: b.Account, UserID: b.UserID})
}
return out, nil
}
func (s *ChannelService) Create(ctx context.Context, req *dto.ChannelCreateRequest) (*dto.ChannelCreateResult, error) {
if req == nil || len(utf16.Encode([]rune(req.SourceDB))) > 10 || len(utf16.Encode([]rune(req.Account))) > 30 {
return nil, business.ErrChannelInput
}
id, err := strconv.ParseUint(req.PlatformBusierID.String(), 10, 32)
if err != nil || id == 0 || id > math.MaxInt32 {
return nil, business.ErrChannelBinding
}
registerType := 0
if req.RegisterType != nil {
registerType = *req.RegisterType
}
if registerType > math.MaxInt32 || registerType < math.MinInt32 {
return nil, business.ErrChannelInput
}
result, err := s.uc.Create(ctx, &business.ChannelCreate{SourceDB: req.SourceDB, Account: req.Account, Password: req.Password, BusierID: id, RegisterType: registerType})
if err != nil {
return nil, err
}
return &dto.ChannelCreateResult{ID: result.ID, SourceDB: result.SourceDB}, nil
}
func (s *ChannelService) Games(ctx context.Context, req *dto.ChannelGameQuery) ([]*dto.ChannelGameResponse, error) {
if req == nil || req.PromoteID == 0 {
return nil, business.ErrChannelInput
}
games, err := s.uc.Games(ctx, business.ChannelKey{SourceDB: req.SourceDB, ID: req.PromoteID})
if err != nil {
return nil, err
}
out := make([]*dto.ChannelGameResponse, 0, len(games))
for _, game := range games {
out = append(out, &dto.ChannelGameResponse{GameID: game.ID, GameName: game.Name, RegisterCount: game.RegisterCount, PayAmount: game.PayAmount})
}
return out, nil
}