110 lines
3.4 KiB
Go
110 lines
3.4 KiB
Go
package agent
|
||
|
||
import (
|
||
"context"
|
||
"database/sql"
|
||
"fmt"
|
||
"ycc-server/app/main/model"
|
||
"ycc-server/common/ctxdata"
|
||
"ycc-server/common/tool"
|
||
"ycc-server/common/xerr"
|
||
|
||
"github.com/pkg/errors"
|
||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||
|
||
"ycc-server/app/main/api/internal/svc"
|
||
"ycc-server/app/main/api/internal/types"
|
||
|
||
"github.com/zeromicro/go-zero/core/logx"
|
||
)
|
||
|
||
type GetInviteLinkLogic struct {
|
||
logx.Logger
|
||
ctx context.Context
|
||
svcCtx *svc.ServiceContext
|
||
}
|
||
|
||
func NewGetInviteLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetInviteLinkLogic {
|
||
return &GetInviteLinkLogic{
|
||
Logger: logx.WithContext(ctx),
|
||
ctx: ctx,
|
||
svcCtx: svcCtx,
|
||
}
|
||
}
|
||
|
||
func (l *GetInviteLinkLogic) GetInviteLink() (resp *types.GetInviteLinkResp, err error) {
|
||
// 1. 获取当前代理信息
|
||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
|
||
}
|
||
|
||
agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||
if err != nil {
|
||
if errors.Is(err, model.ErrNotFound) {
|
||
return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
|
||
}
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err)
|
||
}
|
||
|
||
// 2. 为邀请链接生成一个邀请码(每次调用都生成新的,不过期)
|
||
// 这样代理可以分享这个链接,用户通过链接注册时会使用这个邀请码
|
||
var inviteCode string
|
||
err = l.svcCtx.AgentInviteCodeModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
|
||
// 生成8位随机邀请码
|
||
code := tool.Krand(8, tool.KC_RAND_KIND_ALL)
|
||
maxRetries := 10
|
||
for retry := 0; retry < maxRetries; retry++ {
|
||
_, err := l.svcCtx.AgentInviteCodeModel.FindOneByCode(transCtx, code)
|
||
if err != nil {
|
||
if errors.Is(err, model.ErrNotFound) {
|
||
break
|
||
}
|
||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "检查邀请码失败, %v", err)
|
||
}
|
||
code = tool.Krand(8, tool.KC_RAND_KIND_ALL)
|
||
if retry == maxRetries-1 {
|
||
return errors.Wrapf(xerr.NewErrMsg("生成邀请码失败,请重试"), "")
|
||
}
|
||
}
|
||
|
||
// 创建邀请码记录(用于链接,不过期)
|
||
inviteCodeRecord := &model.AgentInviteCode{
|
||
Code: code,
|
||
AgentId: sql.NullInt64{Int64: agent.Id, Valid: true},
|
||
TargetLevel: 1, // 代理发放的邀请码,目标等级为普通代理
|
||
Status: 0, // 未使用
|
||
ExpireTime: sql.NullTime{Valid: false}, // 不过期
|
||
Remark: sql.NullString{String: "邀请链接生成", Valid: true},
|
||
}
|
||
|
||
_, err := l.svcCtx.AgentInviteCodeModel.Insert(transCtx, session, inviteCodeRecord)
|
||
if err != nil {
|
||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建邀请码失败, %v", err)
|
||
}
|
||
|
||
inviteCode = code
|
||
return nil
|
||
})
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 3. 生成邀请链接
|
||
// 使用配置中的前端域名,如果没有则使用默认值
|
||
frontendDomain := l.svcCtx.Config.AdminPromotion.URLDomain
|
||
if frontendDomain == "" {
|
||
frontendDomain = "https://example.com" // 默认值,需要配置
|
||
}
|
||
inviteLink := fmt.Sprintf("%s/register?invite_code=%s", frontendDomain, inviteCode)
|
||
|
||
// 4. 生成二维码URL(使用ImageService)
|
||
qrCodeUrl := fmt.Sprintf("%s/api/v1/image/qrcode?type=invitation&content=%s", frontendDomain, inviteLink)
|
||
|
||
return &types.GetInviteLinkResp{
|
||
InviteLink: inviteLink,
|
||
QrCodeUrl: qrCodeUrl,
|
||
}, nil
|
||
}
|