From 050809c4719ed104c45a89e47e51758dea18890b Mon Sep 17 00:00:00 2001 From: liangzai <2440983361@qq.com> Date: Tue, 21 Oct 2025 18:41:31 +0800 Subject: [PATCH] fix --- app/main/api/desc/front/agent.api | 30 +++ .../handler/agent/getmembershipinfohandler.go | 17 ++ app/main/api/internal/handler/routes.go | 5 + .../logic/agent/agentwithdrawallogic.go | 9 + .../logic/agent/getmembershipinfologic.go | 101 +++++++++ .../internal/logic/pay/alipaycallbacklogic.go | 28 ++- .../api/internal/logic/pay/paymentlogic.go | 11 + .../logic/pay/wechatpaycallbacklogic.go | 27 ++- app/main/api/internal/service/agentService.go | 204 ++++++++++++++++-- app/main/api/internal/types/types.go | 24 +++ 10 files changed, 435 insertions(+), 21 deletions(-) create mode 100644 app/main/api/internal/handler/agent/getmembershipinfohandler.go create mode 100644 app/main/api/internal/logic/agent/getmembershipinfologic.go diff --git a/app/main/api/desc/front/agent.api b/app/main/api/desc/front/agent.api index 79a3a51..90e7c60 100644 --- a/app/main/api/desc/front/agent.api +++ b/app/main/api/desc/front/agent.api @@ -14,6 +14,10 @@ service main { @handler GetAgentPromotionQrcode get /promotion/qrcode (GetAgentPromotionQrcodeReq) + // 获取会员开通信息 + @handler GetMembershipInfo + get /membership/info returns (GetMembershipInfoResp) + } type ( @@ -21,6 +25,32 @@ type ( QrcodeType string `form:"qrcode_type"` QrcodeUrl string `form:"qrcode_url"` } + + // 会员配置信息 + MembershipConfigInfo { + Id int64 `json:"id"` // 主键 + LevelName string `json:"level_name"` // 会员级别名称 + Price float64 `json:"price"` // 会员年费 + ReportCommission float64 `json:"report_commission"` // 直推报告收益 + LowerActivityReward float64 `json:"lower_activity_reward"` // 下级活跃奖励金额 + NewActivityReward float64 `json:"new_activity_reward"` // 新增活跃奖励金额 + LowerStandardCount int64 `json:"lower_standard_count"` // 活跃下级达标个数 + NewLowerStandardCount int64 `json:"new_lower_standard_count"` // 新增活跃下级达标个数 + LowerWithdrawRewardRatio float64 `json:"lower_withdraw_reward_ratio"` // 下级提现奖励比例 + LowerConvertVipReward float64 `json:"lower_convert_vip_reward"` // 下级转化VIP奖励 + LowerConvertSvipReward float64 `json:"lower_convert_svip_reward"` // 下级转化SVIP奖励 + ExemptionAmount float64 `json:"exemption_amount"` // 免审核金额 + PriceIncreaseMax float64 `json:"price_increase_max"` // 提价最高金额 + PriceRatio float64 `json:"price_ratio"` // 提价区间收取比例 + PriceIncreaseAmount float64 `json:"price_increase_amount"` // 在原本成本上加价的金额 + } + + // 获取会员开通信息响应 + GetMembershipInfoResp { + NormalConfig MembershipConfigInfo `json:"normal_config"` // 普通代理配置 + VipConfig MembershipConfigInfo `json:"vip_config"` // VIP会员配置 + SvipConfig MembershipConfigInfo `json:"svip_config"` // SVIP会员配置 + } ) // 代理服务基本类型定义 type AgentProductConfig { diff --git a/app/main/api/internal/handler/agent/getmembershipinfohandler.go b/app/main/api/internal/handler/agent/getmembershipinfohandler.go new file mode 100644 index 0000000..6930038 --- /dev/null +++ b/app/main/api/internal/handler/agent/getmembershipinfohandler.go @@ -0,0 +1,17 @@ +package agent + +import ( + "net/http" + + "hm-server/app/main/api/internal/logic/agent" + "hm-server/app/main/api/internal/svc" + "hm-server/common/result" +) + +func GetMembershipInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := agent.NewGetMembershipInfoLogic(r.Context(), svcCtx) + resp, err := l.GetMembershipInfo() + result.HttpResult(r, w, resp, err) + } +} diff --git a/app/main/api/internal/handler/routes.go b/app/main/api/internal/handler/routes.go index 510f0b6..56c39c3 100644 --- a/app/main/api/internal/handler/routes.go +++ b/app/main/api/internal/handler/routes.go @@ -639,6 +639,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { server.AddRoutes( []rest.Route{ + { + Method: http.MethodGet, + Path: "/membership/info", + Handler: agent.GetMembershipInfoHandler(serverCtx), + }, { Method: http.MethodGet, Path: "/promotion/qrcode", diff --git a/app/main/api/internal/logic/agent/agentwithdrawallogic.go b/app/main/api/internal/logic/agent/agentwithdrawallogic.go index e49560f..0e22dcd 100644 --- a/app/main/api/internal/logic/agent/agentwithdrawallogic.go +++ b/app/main/api/internal/logic/agent/agentwithdrawallogic.go @@ -353,6 +353,15 @@ func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status in return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新扣税记录失败: %v", err) } } + + // 提现成功后,给上级代理发放提现奖励 + withdrawRewardErr := l.svcCtx.AgentService.GiveWithdrawReward(ctx, record.AgentId, record.Amount, session) + if withdrawRewardErr != nil { + l.Logger.Errorf("发放提现奖励失败,代理ID:%d,提现金额:%f,错误:%+v", record.AgentId, record.Amount, withdrawRewardErr) + // 提现奖励失败不影响主流程,只记录日志 + } else { + l.Logger.Infof("发放提现奖励成功,代理ID:%d,提现金额:%f", record.AgentId, record.Amount) + } } return nil }) diff --git a/app/main/api/internal/logic/agent/getmembershipinfologic.go b/app/main/api/internal/logic/agent/getmembershipinfologic.go new file mode 100644 index 0000000..024722c --- /dev/null +++ b/app/main/api/internal/logic/agent/getmembershipinfologic.go @@ -0,0 +1,101 @@ +package agent + +import ( + "context" + "hm-server/app/main/model" + "hm-server/common/xerr" + "hm-server/pkg/lzkit/lzUtils" + + "github.com/jinzhu/copier" + "github.com/pkg/errors" + + "hm-server/app/main/api/internal/svc" + "hm-server/app/main/api/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetMembershipInfoLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetMembershipInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMembershipInfoLogic { + return &GetMembershipInfoLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetMembershipInfoLogic) GetMembershipInfo() (resp *types.GetMembershipInfoResp, err error) { + // 获取普通代理配置 + normalConfig, err := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, model.AgentLeveNameNormal) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取普通代理配置失败: %v", err) + } + + // 获取VIP会员配置 + vipConfig, err := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, model.AgentLeveNameVIP) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取VIP会员配置失败: %v", err) + } + + // 获取SVIP会员配置 + svipConfig, err := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, model.AgentLeveNameSVIP) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取SVIP会员配置失败: %v", err) + } + + // 转换配置的辅助函数 + convertConfig := func(config *model.AgentMembershipConfig) (types.MembershipConfigInfo, error) { + var configInfo types.MembershipConfigInfo + err := copier.Copy(&configInfo, config) + if err != nil { + return configInfo, err + } + // 转换Null类型字段 + configInfo.Price = lzUtils.NullFloat64ToFloat64(config.Price) + configInfo.ReportCommission = lzUtils.NullFloat64ToFloat64(config.ReportCommission) + configInfo.LowerActivityReward = lzUtils.NullFloat64ToFloat64(config.LowerActivityReward) + configInfo.NewActivityReward = lzUtils.NullFloat64ToFloat64(config.NewActivityReward) + configInfo.LowerStandardCount = lzUtils.NullInt64ToInt64(config.LowerStandardCount) + configInfo.NewLowerStandardCount = lzUtils.NullInt64ToInt64(config.NewLowerStandardCount) + configInfo.LowerWithdrawRewardRatio = lzUtils.NullFloat64ToFloat64(config.LowerWithdrawRewardRatio) + configInfo.LowerConvertVipReward = lzUtils.NullFloat64ToFloat64(config.LowerConvertVipReward) + configInfo.LowerConvertSvipReward = lzUtils.NullFloat64ToFloat64(config.LowerConvertSvipReward) + configInfo.ExemptionAmount = lzUtils.NullFloat64ToFloat64(config.ExemptionAmount) + configInfo.PriceIncreaseMax = lzUtils.NullFloat64ToFloat64(config.PriceIncreaseMax) + configInfo.PriceRatio = lzUtils.NullFloat64ToFloat64(config.PriceRatio) + configInfo.PriceIncreaseAmount = lzUtils.NullFloat64ToFloat64(config.PriceIncreaseAmount) + return configInfo, nil + } + + // 转换普通代理配置 + normalConfigInfo, err := convertConfig(normalConfig) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "转换普通代理配置失败: %v", err) + } + + // 转换VIP配置 + vipConfigInfo, err := convertConfig(vipConfig) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "转换VIP配置失败: %v", err) + } + + // 转换SVIP配置 + svipConfigInfo, err := convertConfig(svipConfig) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "转换SVIP配置失败: %v", err) + } + + // 构建响应数据 + resp = &types.GetMembershipInfoResp{ + NormalConfig: normalConfigInfo, + VipConfig: vipConfigInfo, + SvipConfig: svipConfigInfo, + } + + return resp, nil +} diff --git a/app/main/api/internal/logic/pay/alipaycallbacklogic.go b/app/main/api/internal/logic/pay/alipaycallbacklogic.go index a1e495a..2e7486d 100644 --- a/app/main/api/internal/logic/pay/alipaycallbacklogic.go +++ b/app/main/api/internal/logic/pay/alipaycallbacklogic.go @@ -151,22 +151,40 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter, return fmt.Errorf("修改代理会员订单信息失败: %+v", updateErr) } + // 记录旧等级,用于判断是否为升级 + oldLevel := agentModel.LevelName + // 设置会员等级 agentModel.LevelName = agentOrder.LevelName // 延长会员时间 - // 检查是否是同级续费并记录到日志 - isRenewal := agentModel.LevelName == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid - if isRenewal { - logx.Infof("代理会员续费成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) + // 检查是否是有效期内续费(不发放奖励)还是重新激活(发放奖励) + isValidRenewal := oldLevel == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid && agentModel.MembershipExpiryTime.Time.After(time.Now()) + if isValidRenewal { + logx.Infof("代理会员有效期内续费成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) } else { - logx.Infof("代理会员新购或升级成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) + logx.Infof("代理会员新购、升级或重新激活成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) } agentModel.MembershipExpiryTime = lzUtils.RenewMembership(agentModel.MembershipExpiryTime) if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil { return fmt.Errorf("修改代理信息失败: %+v", updateErr) } + + // 如果不是有效期内续费,给上级代理发放升级奖励 + if !isValidRenewal && (agentOrder.LevelName == model.AgentLeveNameVIP || agentOrder.LevelName == model.AgentLeveNameSVIP) { + // 验证升级路径的有效性 + if oldLevel != agentOrder.LevelName { + upgradeRewardErr := l.svcCtx.AgentService.GiveUpgradeReward(transCtx, agentModel.Id, oldLevel, agentOrder.LevelName, session) + if upgradeRewardErr != nil { + logx.Errorf("发放升级奖励失败,代理ID:%d,旧等级:%s,新等级:%s,错误:%+v", agentModel.Id, oldLevel, agentOrder.LevelName, upgradeRewardErr) + // 升级奖励失败不影响主流程,只记录日志 + } else { + logx.Infof("发放升级奖励成功,代理ID:%d,旧等级:%s,新等级:%s", agentModel.Id, oldLevel, agentOrder.LevelName) + } + } + } + return nil }) if err != nil { diff --git a/app/main/api/internal/logic/pay/paymentlogic.go b/app/main/api/internal/logic/pay/paymentlogic.go index 651c000..91a5ab9 100644 --- a/app/main/api/internal/logic/pay/paymentlogic.go +++ b/app/main/api/internal/logic/pay/paymentlogic.go @@ -188,7 +188,18 @@ func (l *PaymentLogic) AgentVipOrderPayment(req *types.PaymentReq, session sqlx. return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取代理会员配置失败, %+v", err) } + // 验证会员配置价格是否有效 + if !agentMembershipConfig.Price.Valid { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 会员等级%s的价格配置无效", agentVipCache.Type) + } + amount := agentMembershipConfig.Price.Float64 + // 验证价格是否合理 + if amount <= 0 { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 会员等级%s的价格配置无效: %f", agentVipCache.Type, amount) + } + + // 内部用户测试金额 if user.Inside == 1 { amount = 0.01 } diff --git a/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go b/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go index e2dc720..0c75647 100644 --- a/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go +++ b/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go @@ -150,21 +150,40 @@ func (l *WechatPayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWrite return fmt.Errorf("修改代理会员订单信息失败: %+v", updateErr) } + // 记录旧等级,用于判断是否为升级 + oldLevel := agentModel.LevelName + // 设置会员等级 agentModel.LevelName = agentOrder.LevelName // 延长会员时间 - isRenewal := agentModel.LevelName == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid - if isRenewal { - logx.Infof("代理会员续费成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) + // 检查是否是有效期内续费(不发放奖励)还是重新激活(发放奖励) + isValidRenewal := oldLevel == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid && agentModel.MembershipExpiryTime.Time.After(time.Now()) + if isValidRenewal { + logx.Infof("代理会员有效期内续费成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) } else { - logx.Infof("代理会员新购或升级成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) + logx.Infof("代理会员新购、升级或重新激活成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) } agentModel.MembershipExpiryTime = lzUtils.RenewMembership(agentModel.MembershipExpiryTime) if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil { return fmt.Errorf("修改代理信息失败: %+v", updateErr) } + + // 如果不是有效期内续费,给上级代理发放升级奖励 + if !isValidRenewal && (agentOrder.LevelName == model.AgentLeveNameVIP || agentOrder.LevelName == model.AgentLeveNameSVIP) { + // 验证升级路径的有效性 + if oldLevel != agentOrder.LevelName { + upgradeRewardErr := l.svcCtx.AgentService.GiveUpgradeReward(transCtx, agentModel.Id, oldLevel, agentOrder.LevelName, session) + if upgradeRewardErr != nil { + logx.Errorf("发放升级奖励失败,代理ID:%d,旧等级:%s,新等级:%s,错误:%+v", agentModel.Id, oldLevel, agentOrder.LevelName, upgradeRewardErr) + // 升级奖励失败不影响主流程,只记录日志 + } else { + logx.Infof("发放升级奖励成功,代理ID:%d,旧等级:%s,新等级:%s", agentModel.Id, oldLevel, agentOrder.LevelName) + } + } + } + return nil }) diff --git a/app/main/api/internal/service/agentService.go b/app/main/api/internal/service/agentService.go index afba883..d57e5db 100644 --- a/app/main/api/internal/service/agentService.go +++ b/app/main/api/internal/service/agentService.go @@ -99,10 +99,10 @@ func (l *AgentService) AgentProcess(ctx context.Context, order *model.Order) err if AgentClosureModel != nil { AncestorId := AgentClosureModel.AncestorId AncestorModel, findAgentModelErr := l.AgentModel.FindOne(transCtx, AncestorId) - if findAgentModelErr != nil != errors.Is(findAgentModelErr, model.ErrNotFound) { + if findAgentModelErr != nil && !errors.Is(findAgentModelErr, model.ErrNotFound) { return findAgentModelErr } - if AgentClosureModel != nil { + if AncestorModel != nil { if AncestorModel.LevelName == "" { AncestorModel.LevelName = model.AgentLeveNameNormal } @@ -332,13 +332,193 @@ func (l *AgentService) CommissionPricing(ctx context.Context, descendantId int64 return 0, nil } -//func (l *AgentService) UpgradeVip(ctx context.Context, agentID int64, leve string, session sqlx.Session) error { -// agentModel, err := l.AgentModel.FindOne(ctx, agentID) -// if err != nil { -// return err -// } -// if agentModel.LevelName != model.AgentLeveNameNormal { -// return fmt.Errorf("已经是会员") -// } -// return nil -//} +// GiveUpgradeReward 给上级代理发放下级升级奖励 +func (l *AgentService) GiveUpgradeReward(ctx context.Context, agentID int64, oldLevel, newLevel string, session sqlx.Session) error { + // 查找上级代理 + agentClosureModel, err := l.AgentClosureModel.FindOneByDescendantIdDepth(ctx, agentID, 1) + if err != nil { + if errors.Is(err, model.ErrNotFound) { + // 没有上级代理,直接返回 + return nil + } + return err + } + + ancestorID := agentClosureModel.AncestorId + ancestorModel, err := l.AgentModel.FindOne(ctx, ancestorID) + if err != nil { + if errors.Is(err, model.ErrNotFound) { + // 上级代理不存在,直接返回 + return nil + } + return err + } + if ancestorModel == nil { + // 上级代理不存在,直接返回 + return nil + } + + // 获取上级代理的等级配置 + if ancestorModel.LevelName == "" { + ancestorModel.LevelName = model.AgentLeveNameNormal + } + agentMembershipConfigModel, err := l.AgentMembershipConfigModel.FindOneByLevelName(ctx, ancestorModel.LevelName) + if err != nil { + return err + } + + // 根据升级路径计算奖励金额差额 + var rewardAmount float64 + var rewardType string + + // 获取各等级的奖励金额 + var vipRewardAmount float64 + var svipRewardAmount float64 + + if agentMembershipConfigModel.LowerConvertVipReward.Valid { + vipRewardAmount = agentMembershipConfigModel.LowerConvertVipReward.Float64 + } + if agentMembershipConfigModel.LowerConvertSvipReward.Valid { + svipRewardAmount = agentMembershipConfigModel.LowerConvertSvipReward.Float64 + } + + // 根据升级路径计算实际奖励金额 + switch { + case oldLevel == "" || oldLevel == model.AgentLeveNameNormal: + // 普通代理升级 + switch newLevel { + case model.AgentLeveNameVIP: + rewardAmount = vipRewardAmount + rewardType = model.AgentRewardsTypeDescendantUpgradeVip + case model.AgentLeveNameSVIP: + rewardAmount = svipRewardAmount + rewardType = model.AgentRewardsTypeDescendantUpgradeSvip + default: + // 无效的升级路径,直接返回 + return nil + } + case oldLevel == model.AgentLeveNameVIP && newLevel == model.AgentLeveNameSVIP: + // VIP升级到SVIP,发放差额奖励 + rewardAmount = svipRewardAmount - vipRewardAmount + rewardType = model.AgentRewardsTypeDescendantUpgradeSvip + // 如果差额为负数或零,不发放奖励 + if rewardAmount <= 0 { + return nil + } + default: + // 其他无效的升级路径(如SVIP降级等),直接返回 + return nil + } + + // 如果有奖励金额,则发放奖励 + if rewardAmount > 0 { + // 创建奖励记录 + agentRewards := model.AgentRewards{ + AgentId: ancestorID, + Amount: rewardAmount, + RelationAgentId: lzUtils.Int64ToNullInt64(agentID), + Type: rewardType, + } + + _, err = l.AgentRewardsModel.Insert(ctx, session, &agentRewards) + if err != nil { + return err + } + + // 更新上级代理钱包 + ancestorWallet, err := l.AgentWalletModel.FindOneByAgentId(ctx, ancestorID) + if err != nil { + return err + } + + ancestorWallet.Balance += rewardAmount + ancestorWallet.TotalEarnings += rewardAmount + err = l.AgentWalletModel.UpdateWithVersion(ctx, session, ancestorWallet) + if err != nil { + return err + } + } + + return nil +} + +// GiveWithdrawReward 给上级代理发放下级提现奖励 +func (l *AgentService) GiveWithdrawReward(ctx context.Context, agentID int64, withdrawAmount float64, session sqlx.Session) error { + // 验证提现金额 + if withdrawAmount <= 0 { + return nil + } + // 查找上级代理 + agentClosureModel, err := l.AgentClosureModel.FindOneByDescendantIdDepth(ctx, agentID, 1) + if err != nil { + if errors.Is(err, model.ErrNotFound) { + // 没有上级代理,直接返回 + return nil + } + return err + } + + ancestorID := agentClosureModel.AncestorId + ancestorModel, err := l.AgentModel.FindOne(ctx, ancestorID) + if err != nil { + if errors.Is(err, model.ErrNotFound) { + // 上级代理不存在,直接返回 + return nil + } + return err + } + if ancestorModel == nil { + // 上级代理不存在,直接返回 + return nil + } + + // 获取上级代理的等级配置 + if ancestorModel.LevelName == "" { + ancestorModel.LevelName = model.AgentLeveNameNormal + } + agentMembershipConfigModel, err := l.AgentMembershipConfigModel.FindOneByLevelName(ctx, ancestorModel.LevelName) + if err != nil { + return err + } + + // 计算提现奖励金额 + if agentMembershipConfigModel.LowerWithdrawRewardRatio.Valid { + rewardRatio := agentMembershipConfigModel.LowerWithdrawRewardRatio.Float64 + // 验证奖励比例的有效性(0-1之间) + if rewardRatio < 0 || rewardRatio > 1 { + // 无效的奖励比例,直接返回 + return nil + } + rewardAmount := withdrawAmount * rewardRatio + + if rewardAmount > 0 { + // 创建奖励记录 + agentRewards := model.AgentRewards{ + AgentId: ancestorID, + Amount: rewardAmount, + RelationAgentId: lzUtils.Int64ToNullInt64(agentID), + Type: model.AgentRewardsTypeDescendantWithdraw, + } + + _, err = l.AgentRewardsModel.Insert(ctx, session, &agentRewards) + if err != nil { + return err + } + + // 更新上级代理钱包 + ancestorWallet, err := l.AgentWalletModel.FindOneByAgentId(ctx, ancestorID) + if err != nil { + return err + } + + ancestorWallet.Balance += rewardAmount + ancestorWallet.TotalEarnings += rewardAmount + err = l.AgentWalletModel.UpdateWithVersion(ctx, session, ancestorWallet) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/app/main/api/internal/types/types.go b/app/main/api/internal/types/types.go index 3e76068..e84d3cf 100644 --- a/app/main/api/internal/types/types.go +++ b/app/main/api/internal/types/types.go @@ -1329,6 +1329,12 @@ type GetLinkDataResp struct { Product } +type GetMembershipInfoResp struct { + NormalConfig MembershipConfigInfo `json:"normal_config"` // 普通代理配置 + VipConfig MembershipConfigInfo `json:"vip_config"` // VIP会员配置 + SvipConfig MembershipConfigInfo `json:"svip_config"` // SVIP会员配置 +} + type GetMenuAllReq struct { } @@ -1506,6 +1512,24 @@ type IapCallbackReq struct { TransactionReceipt string `json:"transaction_receipt" validate:"required"` } +type MembershipConfigInfo struct { + Id int64 `json:"id"` // 主键 + LevelName string `json:"level_name"` // 会员级别名称 + Price float64 `json:"price"` // 会员年费 + ReportCommission float64 `json:"report_commission"` // 直推报告收益 + LowerActivityReward float64 `json:"lower_activity_reward"` // 下级活跃奖励金额 + NewActivityReward float64 `json:"new_activity_reward"` // 新增活跃奖励金额 + LowerStandardCount int64 `json:"lower_standard_count"` // 活跃下级达标个数 + NewLowerStandardCount int64 `json:"new_lower_standard_count"` // 新增活跃下级达标个数 + LowerWithdrawRewardRatio float64 `json:"lower_withdraw_reward_ratio"` // 下级提现奖励比例 + LowerConvertVipReward float64 `json:"lower_convert_vip_reward"` // 下级转化VIP奖励 + LowerConvertSvipReward float64 `json:"lower_convert_svip_reward"` // 下级转化SVIP奖励 + ExemptionAmount float64 `json:"exemption_amount"` // 免审核金额 + PriceIncreaseMax float64 `json:"price_increase_max"` // 提价最高金额 + PriceRatio float64 `json:"price_ratio"` // 提价区间收取比例 + PriceIncreaseAmount float64 `json:"price_increase_amount"` // 在原本成本上加价的金额 +} + type MenuListItem struct { Id int64 `json:"id"` // 菜单ID Pid int64 `json:"pid"` // 父菜单ID