v1.1
This commit is contained in:
@@ -5,12 +5,15 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
"ycc-server/app/main/model"
|
||||
"ycc-server/common/ctxdata"
|
||||
"ycc-server/common/globalkey"
|
||||
"ycc-server/common/xerr"
|
||||
"ycc-server/pkg/lzkit/crypto"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
@@ -57,33 +60,26 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 查询邀请码
|
||||
inviteCodeModel, err := l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, req.InviteCode)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码不存在"), "")
|
||||
}
|
||||
var inviteCodeModel *model.AgentInviteCode
|
||||
inviteCodeModel, err = l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, req.Referrer)
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请码失败, %v", err)
|
||||
}
|
||||
|
||||
// 2. 验证邀请码状态
|
||||
// 钻石级别的邀请码只能使用一次,使用后立即失效
|
||||
// 普通级别的邀请码可以无限使用
|
||||
if inviteCodeModel.Status != 0 {
|
||||
if inviteCodeModel.Status == 1 {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
|
||||
if inviteCodeModel != nil {
|
||||
if inviteCodeModel.Status != 0 {
|
||||
if inviteCodeModel.Status == 1 {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
|
||||
}
|
||||
if inviteCodeModel.ExpireTime.Valid && inviteCodeModel.ExpireTime.Time.Before(time.Now()) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
|
||||
}
|
||||
|
||||
// 3. 验证邀请码是否过期
|
||||
if inviteCodeModel.ExpireTime.Valid && inviteCodeModel.ExpireTime.Time.Before(time.Now()) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
|
||||
}
|
||||
|
||||
// 4. 使用事务处理注册
|
||||
var userID int64
|
||||
var agentID int64
|
||||
var userID string
|
||||
var agentID string
|
||||
var agentLevel int64
|
||||
|
||||
err = l.svcCtx.AgentInviteCodeModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
|
||||
@@ -113,15 +109,11 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
// 注意:非微信环境下 claims 为 nil,此逻辑不会执行,直接使用已存在的 user.Id
|
||||
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||||
if err == nil && claims != nil && claims.UserType == model.UserTypeTemp {
|
||||
userTemp, err := l.svcCtx.UserTempModel.FindOne(l.ctx, claims.UserId)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询临时用户失败, %v", err)
|
||||
}
|
||||
userAuth, err := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, user.Id, userTemp.AuthType)
|
||||
userAuth, err := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, user.Id, claims.AuthType)
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户认证失败, %v", err)
|
||||
}
|
||||
if userAuth != nil && userAuth.AuthKey != userTemp.AuthKey {
|
||||
if userAuth != nil && userAuth.AuthKey != claims.AuthKey {
|
||||
return errors.Wrapf(xerr.NewErrMsg("该手机号已绑定其他微信号"), "")
|
||||
}
|
||||
// 绑定临时用户到正式用户
|
||||
@@ -134,19 +126,37 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
userID = user.Id
|
||||
}
|
||||
|
||||
// 4.2 获取邀请码信息
|
||||
targetLevel := inviteCodeModel.TargetLevel
|
||||
var parentAgentId int64 = 0
|
||||
if inviteCodeModel.AgentId.Valid {
|
||||
parentAgentId = inviteCodeModel.AgentId.Int64
|
||||
var targetLevel int64
|
||||
var parentAgentId string
|
||||
if inviteCodeModel != nil {
|
||||
targetLevel = inviteCodeModel.TargetLevel
|
||||
if inviteCodeModel.AgentId.Valid {
|
||||
parentAgentId = inviteCodeModel.AgentId.String
|
||||
}
|
||||
} else {
|
||||
if codeVal, parseErr := strconv.ParseInt(req.Referrer, 10, 64); parseErr == nil && codeVal > 0 {
|
||||
parentAgent, err := l.findAgentByCode(transCtx, codeVal)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "")
|
||||
}
|
||||
parentAgentId = parentAgent.Id
|
||||
targetLevel = 1
|
||||
} else {
|
||||
encRefMobile, _ := crypto.EncryptMobile(req.Referrer, l.svcCtx.Config.Encrypt.SecretKey)
|
||||
agents, findErr := l.svcCtx.AgentModel.FindAll(transCtx, l.svcCtx.AgentModel.SelectBuilder().Where("mobile = ? AND del_state = ?", encRefMobile, globalkey.DelStateNo).Limit(1), "")
|
||||
if findErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询上级代理失败, %v", findErr)
|
||||
}
|
||||
if len(agents) == 0 {
|
||||
return errors.Wrapf(xerr.NewErrMsg("邀请信息无效"), "")
|
||||
}
|
||||
parentAgentId = agents[0].Id
|
||||
targetLevel = 1
|
||||
}
|
||||
}
|
||||
|
||||
// 4.3 创建代理记录
|
||||
newAgent := &model.Agent{
|
||||
UserId: userID,
|
||||
Level: targetLevel,
|
||||
Mobile: encryptedMobile,
|
||||
}
|
||||
newAgent := &model.Agent{Id: uuid.NewString(), UserId: userID, Level: targetLevel, Mobile: encryptedMobile}
|
||||
if req.Region != "" {
|
||||
newAgent.Region = sql.NullString{String: req.Region, Valid: true}
|
||||
}
|
||||
@@ -155,7 +165,7 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
}
|
||||
|
||||
// 4.4 处理上级关系
|
||||
if parentAgentId > 0 {
|
||||
if parentAgentId != "" {
|
||||
// 查找上级代理
|
||||
parentAgent, err := l.svcCtx.AgentModel.FindOne(transCtx, parentAgentId)
|
||||
if err != nil {
|
||||
@@ -172,57 +182,50 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "查找团队首领失败")
|
||||
}
|
||||
if teamLeaderId > 0 {
|
||||
newAgent.TeamLeaderId = sql.NullInt64{Int64: teamLeaderId, Valid: true}
|
||||
if teamLeaderId != "" {
|
||||
newAgent.TeamLeaderId = sql.NullString{String: teamLeaderId, Valid: true}
|
||||
}
|
||||
|
||||
// 先插入代理记录
|
||||
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
|
||||
newAgent.AgentCode = 0
|
||||
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "创建代理记录失败")
|
||||
}
|
||||
agentID, _ = agentResult.LastInsertId()
|
||||
newAgent.Id = agentID
|
||||
agentID = newAgent.Id
|
||||
|
||||
// 建立关系
|
||||
relation := &model.AgentRelation{
|
||||
ParentId: parentAgent.Id,
|
||||
ChildId: agentID,
|
||||
RelationType: 1, // 直接关系
|
||||
}
|
||||
relation := &model.AgentRelation{Id: uuid.NewString(), ParentId: parentAgent.Id, ChildId: agentID, RelationType: 1}
|
||||
if _, err := l.svcCtx.AgentRelationModel.Insert(transCtx, session, relation); err != nil {
|
||||
return errors.Wrapf(err, "建立代理关系失败")
|
||||
}
|
||||
} else {
|
||||
// 平台发放的钻石邀请码,独立成团队
|
||||
if targetLevel == 3 {
|
||||
// 先插入代理记录
|
||||
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
|
||||
newAgent.AgentCode = 0
|
||||
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "创建代理记录失败")
|
||||
}
|
||||
agentID, _ = agentResult.LastInsertId()
|
||||
newAgent.Id = agentID
|
||||
agentID = newAgent.Id
|
||||
|
||||
// 设置自己为团队首领
|
||||
newAgent.TeamLeaderId = sql.NullInt64{Int64: agentID, Valid: true}
|
||||
newAgent.TeamLeaderId = sql.NullString{String: agentID, Valid: true}
|
||||
if err := l.svcCtx.AgentModel.UpdateInTransaction(transCtx, session, newAgent); err != nil {
|
||||
return errors.Wrapf(err, "更新团队首领失败")
|
||||
}
|
||||
} else {
|
||||
// 普通/黄金代理,但没有上级(异常情况)
|
||||
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
|
||||
newAgent.AgentCode = 0
|
||||
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "创建代理记录失败")
|
||||
}
|
||||
agentID, _ = agentResult.LastInsertId()
|
||||
agentID = newAgent.Id
|
||||
}
|
||||
}
|
||||
|
||||
// 4.5 初始化钱包
|
||||
wallet := &model.AgentWallet{
|
||||
AgentId: agentID,
|
||||
}
|
||||
wallet := &model.AgentWallet{Id: uuid.NewString(), AgentId: agentID}
|
||||
if _, err := l.svcCtx.AgentWalletModel.Insert(transCtx, session, wallet); err != nil {
|
||||
return errors.Wrapf(err, "初始化钱包失败")
|
||||
}
|
||||
@@ -234,25 +237,21 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
// 钻石邀请码:使用后失效
|
||||
inviteCodeModel.Status = 1 // 已使用(使用后立即失效)
|
||||
}
|
||||
// 记录使用信息(用于统计,普通邀请码可以多次使用)
|
||||
inviteCodeModel.UsedUserId = sql.NullInt64{Int64: userID, Valid: true}
|
||||
inviteCodeModel.UsedAgentId = sql.NullInt64{Int64: agentID, Valid: true}
|
||||
inviteCodeModel.UsedTime = sql.NullTime{Time: time.Now(), Valid: true}
|
||||
if err := l.svcCtx.AgentInviteCodeModel.UpdateWithVersion(transCtx, session, inviteCodeModel); err != nil {
|
||||
return errors.Wrapf(err, "更新邀请码状态失败")
|
||||
if inviteCodeModel != nil {
|
||||
inviteCodeModel.UsedUserId = sql.NullString{String: userID, Valid: true}
|
||||
inviteCodeModel.UsedAgentId = sql.NullString{String: agentID, Valid: true}
|
||||
inviteCodeModel.UsedTime = sql.NullTime{Time: time.Now(), Valid: true}
|
||||
if err := l.svcCtx.AgentInviteCodeModel.UpdateWithVersion(transCtx, session, inviteCodeModel); err != nil {
|
||||
return errors.Wrapf(err, "更新邀请码状态失败")
|
||||
}
|
||||
}
|
||||
|
||||
// 4.7 记录邀请码使用历史(用于统计和查询)
|
||||
usage := &model.AgentInviteCodeUsage{
|
||||
InviteCodeId: inviteCodeModel.Id,
|
||||
Code: inviteCodeModel.Code,
|
||||
UserId: userID,
|
||||
AgentId: agentID,
|
||||
AgentLevel: targetLevel,
|
||||
UsedTime: time.Now(),
|
||||
}
|
||||
if _, err := l.svcCtx.AgentInviteCodeUsageModel.Insert(transCtx, session, usage); err != nil {
|
||||
return errors.Wrapf(err, "记录邀请码使用历史失败")
|
||||
if inviteCodeModel != nil {
|
||||
usage := &model.AgentInviteCodeUsage{Id: uuid.NewString(), InviteCodeId: inviteCodeModel.Id, Code: inviteCodeModel.Code, UserId: userID, AgentId: agentID, AgentLevel: targetLevel, UsedTime: time.Now()}
|
||||
if _, err := l.svcCtx.AgentInviteCodeUsageModel.Insert(transCtx, session, usage); err != nil {
|
||||
return errors.Wrapf(err, "记录邀请码使用历史失败")
|
||||
}
|
||||
}
|
||||
|
||||
agentLevel = targetLevel
|
||||
@@ -280,6 +279,7 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
case 3:
|
||||
levelName = "钻石"
|
||||
}
|
||||
agent, _ := l.svcCtx.AgentModel.FindOne(l.ctx, agentID)
|
||||
return &types.RegisterByInviteCodeResp{
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
@@ -287,11 +287,17 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
|
||||
AgentId: agentID,
|
||||
Level: agentLevel,
|
||||
LevelName: levelName,
|
||||
AgentCode: func() int64 {
|
||||
if agent != nil {
|
||||
return agent.AgentCode
|
||||
}
|
||||
return 0
|
||||
}(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// findTeamLeader 查找团队首领(钻石代理)
|
||||
func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId int64) (int64, error) {
|
||||
func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId string) (string, error) {
|
||||
currentId := agentId
|
||||
maxDepth := 100
|
||||
depth := 0
|
||||
@@ -301,22 +307,22 @@ func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId
|
||||
Where("child_id = ? AND relation_type = ? AND del_state = ?", currentId, 1, 0)
|
||||
relations, err := l.svcCtx.AgentRelationModel.FindAll(ctx, builder, "")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
if len(relations) == 0 {
|
||||
agent, err := l.svcCtx.AgentModel.FindOne(ctx, currentId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
if agent.Level == 3 {
|
||||
return agent.Id, nil
|
||||
}
|
||||
return 0, nil
|
||||
return "", nil
|
||||
}
|
||||
|
||||
parentAgent, err := l.svcCtx.AgentModel.FindOne(ctx, relations[0].ParentId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
if parentAgent.Level == 3 {
|
||||
@@ -327,5 +333,30 @@ func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId
|
||||
depth++
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (l *RegisterByInviteCodeLogic) findAgentByCode(ctx context.Context, code int64) (*model.Agent, error) {
|
||||
builder := l.svcCtx.AgentModel.SelectBuilder().Where("agent_code = ? AND del_state = ?", code, globalkey.DelStateNo).Limit(1)
|
||||
agents, err := l.svcCtx.AgentModel.FindAll(ctx, builder, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询上级代理失败, %v", err)
|
||||
}
|
||||
if len(agents) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("上级邀请码不存在"), "")
|
||||
}
|
||||
return agents[0], nil
|
||||
}
|
||||
|
||||
func (l *RegisterByInviteCodeLogic) allocateAgentCode(ctx context.Context, session sqlx.Session) (int64, error) {
|
||||
builder := l.svcCtx.AgentModel.SelectBuilder().OrderBy("agent_code DESC").Limit(1)
|
||||
rows, err := l.svcCtx.AgentModel.FindAll(ctx, builder, "")
|
||||
if err != nil {
|
||||
return 0, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理编码失败, %v", err)
|
||||
}
|
||||
var next int64 = 16800
|
||||
if len(rows) > 0 && rows[0].AgentCode > 0 {
|
||||
next = rows[0].AgentCode + 1
|
||||
}
|
||||
return next, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user