package agent import ( "context" "database/sql" "ycc-server/app/main/model" "ycc-server/common/ctxdata" "ycc-server/common/xerr" "ycc-server/pkg/lzkit/lzUtils" "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 ApplyUpgradeLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewApplyUpgradeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ApplyUpgradeLogic { return &ApplyUpgradeLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *ApplyUpgradeLogic) ApplyUpgrade(req *types.ApplyUpgradeReq) (resp *types.ApplyUpgradeResp, err error) { userID, err := ctxdata.GetUidFromCtx(l.ctx) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err) } // 1. 获取代理信息 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) } fromLevel := agent.Level toLevel := req.ToLevel // 2. 验证升级条件 if !l.canUpgrade(agent.Level, toLevel, 1) { return nil, errors.Wrapf(xerr.NewErrMsg("升级条件不满足"), "") } // 3. 计算升级费用和返佣 upgradeFee := l.svcCtx.AgentService.GetUpgradeFee(fromLevel, toLevel) rebateAmount := l.svcCtx.AgentService.GetUpgradeRebate(fromLevel, toLevel) // 4. 查找原直接上级(用于返佣) var rebateAgentId int64 parent, err := l.svcCtx.AgentService.FindDirectParent(l.ctx, agent.Id) if err != nil && !errors.Is(err, model.ErrNotFound) { return nil, errors.Wrapf(err, "查找直接上级失败") } if parent != nil { rebateAgentId = parent.Id } // 5. 使用事务处理升级 var upgradeId int64 err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error { // 5.1 创建升级记录 upgradeRecord := &model.AgentUpgrade{ AgentId: agent.Id, FromLevel: fromLevel, ToLevel: toLevel, UpgradeType: 1, // 自主付费 UpgradeFee: upgradeFee, RebateAmount: rebateAmount, Status: 1, // 待处理 } if rebateAgentId > 0 { upgradeRecord.RebateAgentId = sql.NullInt64{Int64: rebateAgentId, Valid: true} } upgradeResult, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord) if err != nil { return errors.Wrapf(err, "创建升级记录失败") } upgradeId, _ = upgradeResult.LastInsertId() // 5.2 处理支付(这里假设支付已在外层处理,只记录订单号) // 实际支付应该在创建升级记录之前完成 // 注意:支付订单号需要从支付回调中获取,这里暂时留空 // 5.3 执行升级操作 if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, agent.Id, toLevel, 1, upgradeFee, rebateAmount, "", 0); err != nil { return errors.Wrapf(err, "执行升级操作失败") } // 5.4 更新升级记录状态 upgradeRecord.Id = upgradeId upgradeRecord.Status = 2 // 已完成 upgradeRecord.Remark = lzUtils.StringToNullString("升级成功") if err := l.svcCtx.AgentUpgradeModel.UpdateWithVersion(transCtx, session, upgradeRecord); err != nil { return errors.Wrapf(err, "更新升级记录失败") } return nil }) if err != nil { return nil, err } // 返回响应(订单号需要从支付回调中获取,这里暂时返回空) return &types.ApplyUpgradeResp{ UpgradeId: upgradeId, OrderNo: "", // 需要从支付回调中获取 }, nil } // canUpgrade 检查是否可以升级 func (l *ApplyUpgradeLogic) canUpgrade(fromLevel, toLevel int64, upgradeType int64) bool { if upgradeType == 1 { // 自主付费 if fromLevel == 1 { // 普通 return toLevel == 2 || toLevel == 3 // 可以升级为黄金或钻石 } else if fromLevel == 2 { // 黄金 return toLevel == 3 // 可以升级为钻石 } } return false }