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 }