137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
|
package admin_promotion
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"crypto/rand"
|
|||
|
"fmt"
|
|||
|
"math/big"
|
|||
|
"time"
|
|||
|
|
|||
|
"tyc-server/app/main/api/internal/svc"
|
|||
|
"tyc-server/app/main/api/internal/types"
|
|||
|
"tyc-server/app/main/model"
|
|||
|
"tyc-server/common/ctxdata"
|
|||
|
"tyc-server/common/xerr"
|
|||
|
|
|||
|
"github.com/pkg/errors"
|
|||
|
"github.com/zeromicro/go-zero/core/logx"
|
|||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|||
|
)
|
|||
|
|
|||
|
type CreatePromotionLinkLogic struct {
|
|||
|
logx.Logger
|
|||
|
ctx context.Context
|
|||
|
svcCtx *svc.ServiceContext
|
|||
|
}
|
|||
|
|
|||
|
func NewCreatePromotionLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePromotionLinkLogic {
|
|||
|
return &CreatePromotionLinkLogic{
|
|||
|
Logger: logx.WithContext(ctx),
|
|||
|
ctx: ctx,
|
|||
|
svcCtx: svcCtx,
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 生成6位随机字符串(大小写字母和数字)
|
|||
|
func generateRandomString() (string, error) {
|
|||
|
const (
|
|||
|
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|||
|
length = 6
|
|||
|
)
|
|||
|
|
|||
|
result := make([]byte, length)
|
|||
|
for i := 0; i < length; i++ {
|
|||
|
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
result[i] = chars[num.Int64()]
|
|||
|
}
|
|||
|
return string(result), nil
|
|||
|
}
|
|||
|
|
|||
|
func (l *CreatePromotionLinkLogic) CreatePromotionLink(req *types.CreatePromotionLinkReq) (resp *types.CreatePromotionLinkResp, err error) {
|
|||
|
// 获取当前用户ID
|
|||
|
adminUserId, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
|||
|
if getUidErr != nil {
|
|||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建推广链接, 获取用户信息失败, %+v", getUidErr)
|
|||
|
}
|
|||
|
|
|||
|
// 生成唯一URL
|
|||
|
var url string
|
|||
|
maxRetries := 5 // 最大重试次数
|
|||
|
for i := 0; i < maxRetries; i++ {
|
|||
|
// 生成6位随机字符串
|
|||
|
randomStr, err := generateRandomString()
|
|||
|
if err != nil {
|
|||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建推广链接, 生成随机字符串失败, %+v", err)
|
|||
|
}
|
|||
|
|
|||
|
// 检查URL是否已存在
|
|||
|
existLink, err := l.svcCtx.AdminPromotionLinkModel.FindOneByUrl(l.ctx, randomStr)
|
|||
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
|||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建推广链接, 检查URL是否存在失败, %+v", err)
|
|||
|
}
|
|||
|
|
|||
|
if existLink != nil {
|
|||
|
continue // URL已存在,继续尝试
|
|||
|
}
|
|||
|
|
|||
|
// URL可用
|
|||
|
url = randomStr
|
|||
|
break
|
|||
|
}
|
|||
|
|
|||
|
if url == "" {
|
|||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建推广链接失败, 多次尝试生成唯一URL均失败")
|
|||
|
}
|
|||
|
url = fmt.Sprintf("%s/%s", l.svcCtx.Config.AdminPromotion.URLDomain, url)
|
|||
|
// 创建推广链接
|
|||
|
link := &model.AdminPromotionLink{
|
|||
|
Name: req.Name,
|
|||
|
Url: url,
|
|||
|
AdminUserId: adminUserId,
|
|||
|
}
|
|||
|
|
|||
|
var linkId int64
|
|||
|
err = l.svcCtx.AdminPromotionLinkModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|||
|
result, err := l.svcCtx.AdminPromotionLinkModel.Insert(l.ctx, session, link)
|
|||
|
if err != nil {
|
|||
|
return fmt.Errorf("创建推广链接失败, %+v", err)
|
|||
|
}
|
|||
|
|
|||
|
linkId, err = result.LastInsertId()
|
|||
|
if err != nil {
|
|||
|
return fmt.Errorf("获取推广链接ID失败, %+v", err)
|
|||
|
}
|
|||
|
|
|||
|
// 创建总统计记录
|
|||
|
totalStats := &model.AdminPromotionLinkStatsTotal{
|
|||
|
LinkId: linkId,
|
|||
|
}
|
|||
|
_, err = l.svcCtx.AdminPromotionLinkStatsTotalModel.Insert(l.ctx, session, totalStats)
|
|||
|
if err != nil {
|
|||
|
return fmt.Errorf("创建推广链接总统计记录失败, %+v", err)
|
|||
|
}
|
|||
|
|
|||
|
// 创建统计历史记录
|
|||
|
historyStats := &model.AdminPromotionLinkStatsHistory{
|
|||
|
LinkId: linkId,
|
|||
|
StatsDate: time.Now().Truncate(24 * time.Hour),
|
|||
|
}
|
|||
|
_, err = l.svcCtx.AdminPromotionLinkStatsHistoryModel.Insert(l.ctx, session, historyStats)
|
|||
|
if err != nil {
|
|||
|
return fmt.Errorf("创建推广链接统计历史记录失败, %+v", err)
|
|||
|
}
|
|||
|
return nil
|
|||
|
})
|
|||
|
if err != nil {
|
|||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建推广链接失败, %+v", err)
|
|||
|
}
|
|||
|
|
|||
|
return &types.CreatePromotionLinkResp{
|
|||
|
Id: linkId,
|
|||
|
Url: url,
|
|||
|
}, nil
|
|||
|
}
|