hi-server/internal/logic/public/user/getInviteSalesLogic.go
2026-02-01 19:07:50 -08:00

126 lines
3.4 KiB
Go

package user
import (
"context"
"github.com/perfect-panel/server/internal/model/user"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/constant"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/xerr"
"github.com/pkg/errors"
)
type GetInviteSalesLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetInviteSalesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetInviteSalesLogic {
return &GetInviteSalesLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetInviteSalesLogic) GetInviteSales(req *types.GetInviteSalesRequest) (resp *types.GetInviteSalesResponse, err error) {
// 1. Get current user
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
if !ok {
l.Errorw("[GetInviteSales] user not found in context")
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
}
userId := u.Id
// 2. Count total sales
var totalSales int64
err = l.svcCtx.DB.WithContext(l.ctx).
Table("`order` o").
Joins("JOIN user u ON o.user_id = u.id").
Where("u.referer_id = ? AND o.status IN (?, ?)", userId, 2, 5).
Count(&totalSales).Error
if err != nil {
l.Errorw("[GetInviteSales] count sales failed",
logger.Field("error", err.Error()),
logger.Field("user_id", userId))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError),
"count sales failed: %v", err.Error())
}
// 3. Pagination
if req.Page < 1 {
req.Page = 1
}
if req.Size < 1 {
req.Size = 10
}
if req.Size > 100 {
req.Size = 100
}
offset := (req.Page - 1) * req.Size
// 4. Get sales data
type OrderWithUser struct {
Amount int64 `gorm:"column:amount"`
CreatedAt int64 `gorm:"column:created_at"`
UserId int64 `gorm:"column:user_id"`
}
var orderData []OrderWithUser
err = l.svcCtx.DB.WithContext(l.ctx).
Table("`order` o").
Select("o.amount, CAST(UNIX_TIMESTAMP(o.created_at) * 1000 AS SIGNED) as created_at, u.id as user_id").
Joins("JOIN user u ON o.user_id = u.id").
Where("u.referer_id = ? AND o.status IN (?, ?)", userId, 2, 5). // status 2: Paid, 5: Finished
Order("o.created_at DESC").
Limit(req.Size).
Offset(offset).
Scan(&orderData).Error
if err != nil {
l.Errorw("[GetInviteSales] query sales failed",
logger.Field("error", err.Error()),
logger.Field("user_id", userId))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError),
"query sales failed: %v", err.Error())
}
// 5. Get user emails
var list []types.InvitedUserSale
for _, order := range orderData {
var email string
// Try email auth first
err = l.svcCtx.DB.WithContext(l.ctx).
Table("user_auth_methods").
Select("auth_identifier").
Where("user_id = ? AND auth_type = ?", order.UserId, "email").
Limit(1).
Scan(&email).Error
// Fallback to any auth method
if err != nil || email == "" {
err = l.svcCtx.DB.WithContext(l.ctx).
Table("user_auth_methods").
Select("auth_identifier").
Where("user_id = ?", order.UserId).
Order("created_at ASC").
Limit(1).
Scan(&email).Error
}
list = append(list, types.InvitedUserSale{
Amount: float64(order.Amount) / 100.0, // Convert cents to dollars
CreatedAt: order.CreatedAt,
UserEmail: email,
UserId: order.UserId,
})
}
return &types.GetInviteSalesResponse{
Total: totalSales,
List: list,
}, nil
}