Compare commits

..

2 Commits

Author SHA1 Message Date
050809c471 fix 2025-10-21 18:41:31 +08:00
84046e51e7 fix 2025-10-21 18:41:08 +08:00
15 changed files with 958 additions and 82 deletions

View File

@@ -14,6 +14,10 @@ service main {
@handler GetAgentPromotionQrcode @handler GetAgentPromotionQrcode
get /promotion/qrcode (GetAgentPromotionQrcodeReq) get /promotion/qrcode (GetAgentPromotionQrcodeReq)
// 获取会员开通信息
@handler GetMembershipInfo
get /membership/info returns (GetMembershipInfoResp)
} }
type ( type (
@@ -21,6 +25,32 @@ type (
QrcodeType string `form:"qrcode_type"` QrcodeType string `form:"qrcode_type"`
QrcodeUrl string `form:"qrcode_url"` 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 { type AgentProductConfig {

View File

@@ -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)
}
}

View File

@@ -639,6 +639,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes( server.AddRoutes(
[]rest.Route{ []rest.Route{
{
Method: http.MethodGet,
Path: "/membership/info",
Handler: agent.GetMembershipInfoHandler(serverCtx),
},
{ {
Method: http.MethodGet, Method: http.MethodGet,
Path: "/promotion/qrcode", Path: "/promotion/qrcode",

View File

@@ -353,6 +353,15 @@ func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status in
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新扣税记录失败: %v", err) 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 return nil
}) })

View File

@@ -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
}

View File

@@ -151,22 +151,40 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter,
return fmt.Errorf("修改代理会员订单信息失败: %+v", updateErr) return fmt.Errorf("修改代理会员订单信息失败: %+v", updateErr)
} }
// 记录旧等级,用于判断是否为升级
oldLevel := agentModel.LevelName
// 设置会员等级 // 设置会员等级
agentModel.LevelName = agentOrder.LevelName agentModel.LevelName = agentOrder.LevelName
// 延长会员时间 // 延长会员时间
// 检查是否是同级续费并记录到日志 // 检查是否是有效期内续费(不发放奖励)还是重新激活(发放奖励)
isRenewal := agentModel.LevelName == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid isValidRenewal := oldLevel == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid && agentModel.MembershipExpiryTime.Time.After(time.Now())
if isRenewal { if isValidRenewal {
logx.Infof("代理会员续费成功会员ID%d等级%s", agentModel.Id, agentModel.LevelName) logx.Infof("代理会员有效期内续费成功会员ID%d等级%s", agentModel.Id, agentModel.LevelName)
} else { } 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) agentModel.MembershipExpiryTime = lzUtils.RenewMembership(agentModel.MembershipExpiryTime)
if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil { if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil {
return fmt.Errorf("修改代理信息失败: %+v", updateErr) 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 return nil
}) })
if err != nil { if err != nil {

View File

@@ -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) 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 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 { if user.Inside == 1 {
amount = 0.01 amount = 0.01
} }

View File

@@ -150,21 +150,40 @@ func (l *WechatPayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWrite
return fmt.Errorf("修改代理会员订单信息失败: %+v", updateErr) return fmt.Errorf("修改代理会员订单信息失败: %+v", updateErr)
} }
// 记录旧等级,用于判断是否为升级
oldLevel := agentModel.LevelName
// 设置会员等级 // 设置会员等级
agentModel.LevelName = agentOrder.LevelName agentModel.LevelName = agentOrder.LevelName
// 延长会员时间 // 延长会员时间
isRenewal := agentModel.LevelName == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid // 检查是否是有效期内续费(不发放奖励)还是重新激活(发放奖励)
if isRenewal { isValidRenewal := oldLevel == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid && agentModel.MembershipExpiryTime.Time.After(time.Now())
logx.Infof("代理会员续费成功会员ID%d等级%s", agentModel.Id, agentModel.LevelName) if isValidRenewal {
logx.Infof("代理会员有效期内续费成功会员ID%d等级%s", agentModel.Id, agentModel.LevelName)
} else { } 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) agentModel.MembershipExpiryTime = lzUtils.RenewMembership(agentModel.MembershipExpiryTime)
if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil { if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil {
return fmt.Errorf("修改代理信息失败: %+v", updateErr) 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 return nil
}) })

View File

@@ -5,6 +5,7 @@ import (
"database/sql" "database/sql"
"hm-server/app/main/api/internal/svc" "hm-server/app/main/api/internal/svc"
"hm-server/app/main/model" "hm-server/app/main/model"
"hm-server/common/globalkey"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@@ -73,11 +74,11 @@ func (l *WechatPayRefundCallbackLogic) handleQueryOrderRefund(orderNo string, st
} }
} }
// 更新退款记录状态 // 查找最新的pending状态的退款记录
refund, err := l.svcCtx.OrderRefundModel.FindOneByOrderId(ctx, order.Id) refund, err := l.findLatestPendingRefund(ctx, order.Id)
if err != nil { if err != nil {
if err == model.ErrNotFound { if err == model.ErrNotFound {
logx.Errorf("未找到订单对应的退款记录: orderNo=%s, orderId=%d", orderNo, order.Id) logx.Errorf("未找到订单对应的待处理退款记录: orderNo=%s, orderId=%d", orderNo, order.Id)
return nil // 没有退款记录时不报错,只记录警告 return nil // 没有退款记录时不报错,只记录警告
} }
return errors.Wrapf(err, "查找退款记录失败: orderNo=%s", orderNo) return errors.Wrapf(err, "查找退款记录失败: orderNo=%s", orderNo)
@@ -213,3 +214,23 @@ func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWr
l.sendSuccessResponse(w) l.sendSuccessResponse(w)
return nil return nil
} }
// findLatestPendingRefund 查找订单最新的pending状态退款记录
func (l *WechatPayRefundCallbackLogic) findLatestPendingRefund(ctx context.Context, orderId int64) (*model.OrderRefund, error) {
// 使用SelectBuilder查询最新的pending状态退款记录
builder := l.svcCtx.OrderRefundModel.SelectBuilder().
Where("order_id = ? AND status = ? AND del_state = ?", orderId, model.OrderRefundStatusPending, globalkey.DelStateNo).
OrderBy("id DESC").
Limit(1)
refunds, err := l.svcCtx.OrderRefundModel.FindAll(ctx, builder, "")
if err != nil {
return nil, err
}
if len(refunds) == 0 {
return nil, model.ErrNotFound
}
return refunds[0], nil
}

View File

@@ -99,10 +99,10 @@ func (l *AgentService) AgentProcess(ctx context.Context, order *model.Order) err
if AgentClosureModel != nil { if AgentClosureModel != nil {
AncestorId := AgentClosureModel.AncestorId AncestorId := AgentClosureModel.AncestorId
AncestorModel, findAgentModelErr := l.AgentModel.FindOne(transCtx, 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 return findAgentModelErr
} }
if AgentClosureModel != nil { if AncestorModel != nil {
if AncestorModel.LevelName == "" { if AncestorModel.LevelName == "" {
AncestorModel.LevelName = model.AgentLeveNameNormal AncestorModel.LevelName = model.AgentLeveNameNormal
} }
@@ -332,13 +332,193 @@ func (l *AgentService) CommissionPricing(ctx context.Context, descendantId int64
return 0, nil return 0, nil
} }
//func (l *AgentService) UpgradeVip(ctx context.Context, agentID int64, leve string, session sqlx.Session) error { // GiveUpgradeReward 给上级代理发放下级升级奖励
// agentModel, err := l.AgentModel.FindOne(ctx, agentID) func (l *AgentService) GiveUpgradeReward(ctx context.Context, agentID int64, oldLevel, newLevel string, session sqlx.Session) error {
// if err != nil { // 查找上级代理
// return err agentClosureModel, err := l.AgentClosureModel.FindOneByDescendantIdDepth(ctx, agentID, 1)
// } if err != nil {
// if agentModel.LevelName != model.AgentLeveNameNormal { if errors.Is(err, model.ErrNotFound) {
// return fmt.Errorf("已经是会员") // 没有上级代理,直接返回
// } return nil
// 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
}

View File

@@ -1329,6 +1329,12 @@ type GetLinkDataResp struct {
Product Product
} }
type GetMembershipInfoResp struct {
NormalConfig MembershipConfigInfo `json:"normal_config"` // 普通代理配置
VipConfig MembershipConfigInfo `json:"vip_config"` // VIP会员配置
SvipConfig MembershipConfigInfo `json:"svip_config"` // SVIP会员配置
}
type GetMenuAllReq struct { type GetMenuAllReq struct {
} }
@@ -1506,6 +1512,24 @@ type IapCallbackReq struct {
TransactionReceipt string `json:"transaction_receipt" validate:"required"` 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 { type MenuListItem struct {
Id int64 `json:"id"` // 菜单ID Id int64 `json:"id"` // 菜单ID
Pid int64 `json:"pid"` // 父菜单ID Pid int64 `json:"pid"` // 父菜单ID

View File

@@ -10,8 +10,6 @@ import (
"time" "time"
"hm-server/common/globalkey"
"github.com/Masterminds/squirrel" "github.com/Masterminds/squirrel"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/builder" "github.com/zeromicro/go-zero/core/stores/builder"
@@ -19,6 +17,7 @@ import (
"github.com/zeromicro/go-zero/core/stores/sqlc" "github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx" "github.com/zeromicro/go-zero/core/stringx"
"hm-server/common/globalkey"
) )
var ( var (
@@ -27,17 +26,15 @@ var (
orderRefundRowsExpectAutoSet = strings.Join(stringx.Remove(orderRefundFieldNames, "`id`", "`create_time`", "`update_time`"), ",") orderRefundRowsExpectAutoSet = strings.Join(stringx.Remove(orderRefundFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
orderRefundRowsWithPlaceHolder = strings.Join(stringx.Remove(orderRefundFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?" orderRefundRowsWithPlaceHolder = strings.Join(stringx.Remove(orderRefundFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
cacheHmOrderRefundIdPrefix = "cache:hm:orderRefund:id:" cacheTydataOrderRefundIdPrefix = "cache:tydata:orderRefund:id:"
cacheHmOrderRefundOrderIdPrefix = "cache:hm:orderRefund:orderId:" cacheTydataOrderRefundPlatformRefundIdPrefix = "cache:tydata:orderRefund:platformRefundId:"
cacheHmOrderRefundPlatformRefundIdPrefix = "cache:hm:orderRefund:platformRefundId:" cacheTydataOrderRefundRefundNoPrefix = "cache:tydata:orderRefund:refundNo:"
cacheHmOrderRefundRefundNoPrefix = "cache:hm:orderRefund:refundNo:"
) )
type ( type (
orderRefundModel interface { orderRefundModel interface {
Insert(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error) Insert(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*OrderRefund, error) FindOne(ctx context.Context, id int64) (*OrderRefund, error)
FindOneByOrderId(ctx context.Context, orderId int64) (*OrderRefund, error)
FindOneByPlatformRefundId(ctx context.Context, platformRefundId sql.NullString) (*OrderRefund, error) FindOneByPlatformRefundId(ctx context.Context, platformRefundId sql.NullString) (*OrderRefund, error)
FindOneByRefundNo(ctx context.Context, refundNo string) (*OrderRefund, error) FindOneByRefundNo(ctx context.Context, refundNo string) (*OrderRefund, error)
Update(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error) Update(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error)
@@ -89,23 +86,22 @@ func newOrderRefundModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultOrderRefu
func (m *defaultOrderRefundModel) Insert(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error) { func (m *defaultOrderRefundModel) Insert(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error) {
data.DelState = globalkey.DelStateNo data.DelState = globalkey.DelStateNo
hmOrderRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundIdPrefix, data.Id) tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, data.Id)
hmOrderRefundOrderIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundOrderIdPrefix, data.OrderId) tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
hmOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId) tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
hmOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheHmOrderRefundRefundNoPrefix, data.RefundNo)
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, orderRefundRowsExpectAutoSet) query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, orderRefundRowsExpectAutoSet)
if session != nil { if session != nil {
return session.ExecCtx(ctx, query, data.RefundNo, data.OrderId, data.UserId, data.ProductId, data.PlatformRefundId, data.RefundAmount, data.RefundReason, data.Status, data.DelState, data.Version, data.RefundTime, data.CloseTime, data.DeleteTime) return session.ExecCtx(ctx, query, data.RefundNo, data.OrderId, data.UserId, data.ProductId, data.PlatformRefundId, data.RefundAmount, data.RefundReason, data.Status, data.DelState, data.Version, data.RefundTime, data.CloseTime, data.DeleteTime)
} }
return conn.ExecCtx(ctx, query, data.RefundNo, data.OrderId, data.UserId, data.ProductId, data.PlatformRefundId, data.RefundAmount, data.RefundReason, data.Status, data.DelState, data.Version, data.RefundTime, data.CloseTime, data.DeleteTime) return conn.ExecCtx(ctx, query, data.RefundNo, data.OrderId, data.UserId, data.ProductId, data.PlatformRefundId, data.RefundAmount, data.RefundReason, data.Status, data.DelState, data.Version, data.RefundTime, data.CloseTime, data.DeleteTime)
}, hmOrderRefundIdKey, hmOrderRefundOrderIdKey, hmOrderRefundPlatformRefundIdKey, hmOrderRefundRefundNoKey) }, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
} }
func (m *defaultOrderRefundModel) FindOne(ctx context.Context, id int64) (*OrderRefund, error) { func (m *defaultOrderRefundModel) FindOne(ctx context.Context, id int64) (*OrderRefund, error) {
hmOrderRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundIdPrefix, id) tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, id)
var resp OrderRefund var resp OrderRefund
err := m.QueryRowCtx(ctx, &resp, hmOrderRefundIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error { err := m.QueryRowCtx(ctx, &resp, tydataOrderRefundIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", orderRefundRows, m.table) query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", orderRefundRows, m.table)
return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo) return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo)
}) })
@@ -119,30 +115,10 @@ func (m *defaultOrderRefundModel) FindOne(ctx context.Context, id int64) (*Order
} }
} }
func (m *defaultOrderRefundModel) FindOneByOrderId(ctx context.Context, orderId int64) (*OrderRefund, error) {
hmOrderRefundOrderIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundOrderIdPrefix, orderId)
var resp OrderRefund
err := m.QueryRowIndexCtx(ctx, &resp, hmOrderRefundOrderIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
query := fmt.Sprintf("select %s from %s where `order_id` = ? and del_state = ? limit 1", orderRefundRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, orderId, globalkey.DelStateNo); err != nil {
return nil, err
}
return resp.Id, nil
}, m.queryPrimary)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) FindOneByPlatformRefundId(ctx context.Context, platformRefundId sql.NullString) (*OrderRefund, error) { func (m *defaultOrderRefundModel) FindOneByPlatformRefundId(ctx context.Context, platformRefundId sql.NullString) (*OrderRefund, error) {
hmOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundPlatformRefundIdPrefix, platformRefundId) tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, platformRefundId)
var resp OrderRefund var resp OrderRefund
err := m.QueryRowIndexCtx(ctx, &resp, hmOrderRefundPlatformRefundIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { err := m.QueryRowIndexCtx(ctx, &resp, tydataOrderRefundPlatformRefundIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
query := fmt.Sprintf("select %s from %s where `platform_refund_id` = ? and del_state = ? limit 1", orderRefundRows, m.table) query := fmt.Sprintf("select %s from %s where `platform_refund_id` = ? and del_state = ? limit 1", orderRefundRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, platformRefundId, globalkey.DelStateNo); err != nil { if err := conn.QueryRowCtx(ctx, &resp, query, platformRefundId, globalkey.DelStateNo); err != nil {
return nil, err return nil, err
@@ -160,9 +136,9 @@ func (m *defaultOrderRefundModel) FindOneByPlatformRefundId(ctx context.Context,
} }
func (m *defaultOrderRefundModel) FindOneByRefundNo(ctx context.Context, refundNo string) (*OrderRefund, error) { func (m *defaultOrderRefundModel) FindOneByRefundNo(ctx context.Context, refundNo string) (*OrderRefund, error) {
hmOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheHmOrderRefundRefundNoPrefix, refundNo) tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, refundNo)
var resp OrderRefund var resp OrderRefund
err := m.QueryRowIndexCtx(ctx, &resp, hmOrderRefundRefundNoKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { err := m.QueryRowIndexCtx(ctx, &resp, tydataOrderRefundRefundNoKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
query := fmt.Sprintf("select %s from %s where `refund_no` = ? and del_state = ? limit 1", orderRefundRows, m.table) query := fmt.Sprintf("select %s from %s where `refund_no` = ? and del_state = ? limit 1", orderRefundRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, refundNo, globalkey.DelStateNo); err != nil { if err := conn.QueryRowCtx(ctx, &resp, query, refundNo, globalkey.DelStateNo); err != nil {
return nil, err return nil, err
@@ -184,17 +160,16 @@ func (m *defaultOrderRefundModel) Update(ctx context.Context, session sqlx.Sessi
if err != nil { if err != nil {
return nil, err return nil, err
} }
hmOrderRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundIdPrefix, data.Id) tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, data.Id)
hmOrderRefundOrderIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundOrderIdPrefix, data.OrderId) tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
hmOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId) tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
hmOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheHmOrderRefundRefundNoPrefix, data.RefundNo)
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, orderRefundRowsWithPlaceHolder) query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, orderRefundRowsWithPlaceHolder)
if session != nil { if session != nil {
return session.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id) return session.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id)
} }
return conn.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id) return conn.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id)
}, hmOrderRefundIdKey, hmOrderRefundOrderIdKey, hmOrderRefundPlatformRefundIdKey, hmOrderRefundRefundNoKey) }, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
} }
func (m *defaultOrderRefundModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *OrderRefund) error { func (m *defaultOrderRefundModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *OrderRefund) error {
@@ -209,17 +184,16 @@ func (m *defaultOrderRefundModel) UpdateWithVersion(ctx context.Context, session
if err != nil { if err != nil {
return err return err
} }
hmOrderRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundIdPrefix, data.Id) tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, data.Id)
hmOrderRefundOrderIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundOrderIdPrefix, data.OrderId) tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
hmOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId) tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
hmOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheHmOrderRefundRefundNoPrefix, data.RefundNo)
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, orderRefundRowsWithPlaceHolder) query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, orderRefundRowsWithPlaceHolder)
if session != nil { if session != nil {
return session.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id, oldVersion) return session.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id, oldVersion)
} }
return conn.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id, oldVersion) return conn.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id, oldVersion)
}, hmOrderRefundIdKey, hmOrderRefundOrderIdKey, hmOrderRefundPlatformRefundIdKey, hmOrderRefundRefundNoKey) }, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
if err != nil { if err != nil {
return err return err
} }
@@ -442,21 +416,20 @@ func (m *defaultOrderRefundModel) Delete(ctx context.Context, session sqlx.Sessi
return err return err
} }
hmOrderRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundIdPrefix, id) tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, id)
hmOrderRefundOrderIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundOrderIdPrefix, data.OrderId) tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
hmOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheHmOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId) tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
hmOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheHmOrderRefundRefundNoPrefix, data.RefundNo)
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table) query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
if session != nil { if session != nil {
return session.ExecCtx(ctx, query, id) return session.ExecCtx(ctx, query, id)
} }
return conn.ExecCtx(ctx, query, id) return conn.ExecCtx(ctx, query, id)
}, hmOrderRefundIdKey, hmOrderRefundOrderIdKey, hmOrderRefundPlatformRefundIdKey, hmOrderRefundRefundNoKey) }, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
return err return err
} }
func (m *defaultOrderRefundModel) formatPrimary(primary interface{}) string { func (m *defaultOrderRefundModel) formatPrimary(primary interface{}) string {
return fmt.Sprintf("%s%v", cacheHmOrderRefundIdPrefix, primary) return fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, primary)
} }
func (m *defaultOrderRefundModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error { func (m *defaultOrderRefundModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", orderRefundRows, m.table) query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", orderRefundRows, m.table)

View File

@@ -1,7 +1,7 @@
# 设置输出编码为UTF-8 # 设置输出编码为UTF-8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 数据库连接信息 - 修改了URL格式 # 数据库连接信息 - 修改了URL格式
$DB_URL = "hm:5vg67b3UNHu8@(127.0.0.1:21001)/hm" $DB_URL = "tydata:5vg67b3UNHu8@(127.0.0.1:21001)/tydata"
$OUTPUT_DIR = "./model" $OUTPUT_DIR = "./model"
$TEMPLATE_DIR = "../template" $TEMPLATE_DIR = "../template"
@@ -24,12 +24,12 @@ $tables = @(
# "agent_wallet", # "agent_wallet",
# "agent_real_name" # "agent_real_name"
# "agent_withdrawal" # "agent_withdrawal"
"agent_withdrawal_tax" # "agent_withdrawal_tax"
# "agent_withdrawal_tax_exemption" # "agent_withdrawal_tax_exemption"
# "feature", # "feature",
# "global_notifications" # "global_notifications"
# "order", # "order",
# "order_refund" "order_refund"
# "product", # "product",
# "product_feature", # "product_feature",
# "query", # "query",
@@ -58,5 +58,5 @@ $tables = @(
# 为每个表生成模型 # 为每个表生成模型
foreach ($table in $tables) { foreach ($table in $tables) {
goctl model mysql datasource -url="hm:5vg67b3UNHu8@tcp(127.0.0.1:21001)/hm" -table="$table" -dir="./model" --home="../template" -cache=true --style=goZero goctl model mysql datasource -url="tydata:5vg67b3UNHu8@tcp(127.0.0.1:21001)/tydata" -table="$table" -dir="./model" --home="../template" -cache=true --style=goZero
} }

View File

@@ -0,0 +1,27 @@
package model
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ OrderRefundModel = (*customOrderRefundModel)(nil)
type (
// OrderRefundModel is an interface to be customized, add more methods here,
// and implement the added methods in customOrderRefundModel.
OrderRefundModel interface {
orderRefundModel
}
customOrderRefundModel struct {
*defaultOrderRefundModel
}
)
// NewOrderRefundModel returns a model for the database table.
func NewOrderRefundModel(conn sqlx.SqlConn, c cache.CacheConf) OrderRefundModel {
return &customOrderRefundModel{
defaultOrderRefundModel: newOrderRefundModel(conn, c),
}
}

View File

@@ -0,0 +1,441 @@
// Code generated by goctl. DO NOT EDIT!
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/Masterminds/squirrel"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
"hm-server/common/globalkey"
)
var (
orderRefundFieldNames = builder.RawFieldNames(&OrderRefund{})
orderRefundRows = strings.Join(orderRefundFieldNames, ",")
orderRefundRowsExpectAutoSet = strings.Join(stringx.Remove(orderRefundFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
orderRefundRowsWithPlaceHolder = strings.Join(stringx.Remove(orderRefundFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
cacheTydataOrderRefundIdPrefix = "cache:tydata:orderRefund:id:"
cacheTydataOrderRefundPlatformRefundIdPrefix = "cache:tydata:orderRefund:platformRefundId:"
cacheTydataOrderRefundRefundNoPrefix = "cache:tydata:orderRefund:refundNo:"
)
type (
orderRefundModel interface {
Insert(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*OrderRefund, error)
FindOneByPlatformRefundId(ctx context.Context, platformRefundId sql.NullString) (*OrderRefund, error)
FindOneByRefundNo(ctx context.Context, refundNo string) (*OrderRefund, error)
Update(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error)
UpdateWithVersion(ctx context.Context, session sqlx.Session, data *OrderRefund) error
Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error
SelectBuilder() squirrel.SelectBuilder
DeleteSoft(ctx context.Context, session sqlx.Session, data *OrderRefund) error
FindSum(ctx context.Context, sumBuilder squirrel.SelectBuilder, field string) (float64, error)
FindCount(ctx context.Context, countBuilder squirrel.SelectBuilder, field string) (int64, error)
FindAll(ctx context.Context, rowBuilder squirrel.SelectBuilder, orderBy string) ([]*OrderRefund, error)
FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*OrderRefund, error)
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*OrderRefund, int64, error)
FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*OrderRefund, error)
FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*OrderRefund, error)
Delete(ctx context.Context, session sqlx.Session, id int64) error
}
defaultOrderRefundModel struct {
sqlc.CachedConn
table string
}
OrderRefund struct {
Id int64 `db:"id"` // 主键ID
RefundNo string `db:"refund_no"` // 退款单号
OrderId int64 `db:"order_id"` // 关联的订单ID
UserId int64 `db:"user_id"` // 用户ID
ProductId int64 `db:"product_id"` // 产品ID
PlatformRefundId sql.NullString `db:"platform_refund_id"` // 支付平台退款单号
RefundAmount float64 `db:"refund_amount"` // 退款金额
RefundReason sql.NullString `db:"refund_reason"` // 退款原因
Status string `db:"status"` // 退款状态
DelState int64 `db:"del_state"` // 删除状态
Version int64 `db:"version"` // 版本号
CreateTime time.Time `db:"create_time"` // 创建时间
UpdateTime time.Time `db:"update_time"` // 更新时间
RefundTime sql.NullTime `db:"refund_time"` // 退款成功时间
CloseTime sql.NullTime `db:"close_time"` // 退款关闭时间
DeleteTime sql.NullTime `db:"delete_time"` // 删除时间
}
)
func newOrderRefundModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultOrderRefundModel {
return &defaultOrderRefundModel{
CachedConn: sqlc.NewConn(conn, c),
table: "`order_refund`",
}
}
func (m *defaultOrderRefundModel) Insert(ctx context.Context, session sqlx.Session, data *OrderRefund) (sql.Result, error) {
data.DelState = globalkey.DelStateNo
tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, data.Id)
tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, orderRefundRowsExpectAutoSet)
if session != nil {
return session.ExecCtx(ctx, query, data.RefundNo, data.OrderId, data.UserId, data.ProductId, data.PlatformRefundId, data.RefundAmount, data.RefundReason, data.Status, data.DelState, data.Version, data.RefundTime, data.CloseTime, data.DeleteTime)
}
return conn.ExecCtx(ctx, query, data.RefundNo, data.OrderId, data.UserId, data.ProductId, data.PlatformRefundId, data.RefundAmount, data.RefundReason, data.Status, data.DelState, data.Version, data.RefundTime, data.CloseTime, data.DeleteTime)
}, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
}
func (m *defaultOrderRefundModel) FindOne(ctx context.Context, id int64) (*OrderRefund, error) {
tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, id)
var resp OrderRefund
err := m.QueryRowCtx(ctx, &resp, tydataOrderRefundIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", orderRefundRows, m.table)
return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo)
})
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) FindOneByPlatformRefundId(ctx context.Context, platformRefundId sql.NullString) (*OrderRefund, error) {
tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, platformRefundId)
var resp OrderRefund
err := m.QueryRowIndexCtx(ctx, &resp, tydataOrderRefundPlatformRefundIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
query := fmt.Sprintf("select %s from %s where `platform_refund_id` = ? and del_state = ? limit 1", orderRefundRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, platformRefundId, globalkey.DelStateNo); err != nil {
return nil, err
}
return resp.Id, nil
}, m.queryPrimary)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) FindOneByRefundNo(ctx context.Context, refundNo string) (*OrderRefund, error) {
tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, refundNo)
var resp OrderRefund
err := m.QueryRowIndexCtx(ctx, &resp, tydataOrderRefundRefundNoKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
query := fmt.Sprintf("select %s from %s where `refund_no` = ? and del_state = ? limit 1", orderRefundRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, refundNo, globalkey.DelStateNo); err != nil {
return nil, err
}
return resp.Id, nil
}, m.queryPrimary)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) Update(ctx context.Context, session sqlx.Session, newData *OrderRefund) (sql.Result, error) {
data, err := m.FindOne(ctx, newData.Id)
if err != nil {
return nil, err
}
tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, data.Id)
tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, orderRefundRowsWithPlaceHolder)
if session != nil {
return session.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id)
}
return conn.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id)
}, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
}
func (m *defaultOrderRefundModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *OrderRefund) error {
oldVersion := newData.Version
newData.Version += 1
var sqlResult sql.Result
var err error
data, err := m.FindOne(ctx, newData.Id)
if err != nil {
return err
}
tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, data.Id)
tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, orderRefundRowsWithPlaceHolder)
if session != nil {
return session.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id, oldVersion)
}
return conn.ExecCtx(ctx, query, newData.RefundNo, newData.OrderId, newData.UserId, newData.ProductId, newData.PlatformRefundId, newData.RefundAmount, newData.RefundReason, newData.Status, newData.DelState, newData.Version, newData.RefundTime, newData.CloseTime, newData.DeleteTime, newData.Id, oldVersion)
}, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
if err != nil {
return err
}
updateCount, err := sqlResult.RowsAffected()
if err != nil {
return err
}
if updateCount == 0 {
return ErrNoRowsUpdate
}
return nil
}
func (m *defaultOrderRefundModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *OrderRefund) error {
data.DelState = globalkey.DelStateYes
data.DeleteTime = sql.NullTime{Time: time.Now(), Valid: true}
if err := m.UpdateWithVersion(ctx, session, data); err != nil {
return errors.Wrapf(errors.New("delete soft failed "), "OrderRefundModel delete err : %+v", err)
}
return nil
}
func (m *defaultOrderRefundModel) FindSum(ctx context.Context, builder squirrel.SelectBuilder, field string) (float64, error) {
if len(field) == 0 {
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
}
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
if err != nil {
return 0, err
}
var resp float64
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
switch err {
case nil:
return resp, nil
default:
return 0, err
}
}
func (m *defaultOrderRefundModel) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64, error) {
if len(field) == 0 {
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
}
builder = builder.Columns("COUNT(" + field + ")")
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
if err != nil {
return 0, err
}
var resp int64
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
switch err {
case nil:
return resp, nil
default:
return 0, err
}
}
func (m *defaultOrderRefundModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*OrderRefund, error) {
builder = builder.Columns(orderRefundRows)
if orderBy == "" {
builder = builder.OrderBy("id DESC")
} else {
builder = builder.OrderBy(orderBy)
}
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
if err != nil {
return nil, err
}
var resp []*OrderRefund
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*OrderRefund, error) {
builder = builder.Columns(orderRefundRows)
if orderBy == "" {
builder = builder.OrderBy("id DESC")
} else {
builder = builder.OrderBy(orderBy)
}
if page < 1 {
page = 1
}
offset := (page - 1) * pageSize
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil, err
}
var resp []*OrderRefund
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*OrderRefund, int64, error) {
total, err := m.FindCount(ctx, builder, "id")
if err != nil {
return nil, 0, err
}
builder = builder.Columns(orderRefundRows)
if orderBy == "" {
builder = builder.OrderBy("id DESC")
} else {
builder = builder.OrderBy(orderBy)
}
if page < 1 {
page = 1
}
offset := (page - 1) * pageSize
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil, total, err
}
var resp []*OrderRefund
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
switch err {
case nil:
return resp, total, nil
default:
return nil, total, err
}
}
func (m *defaultOrderRefundModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*OrderRefund, error) {
builder = builder.Columns(orderRefundRows)
if preMinId > 0 {
builder = builder.Where(" id < ? ", preMinId)
}
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil, err
}
var resp []*OrderRefund
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*OrderRefund, error) {
builder = builder.Columns(orderRefundRows)
if preMaxId > 0 {
builder = builder.Where(" id > ? ", preMaxId)
}
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil, err
}
var resp []*OrderRefund
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *defaultOrderRefundModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
return fn(ctx, session)
})
}
func (m *defaultOrderRefundModel) SelectBuilder() squirrel.SelectBuilder {
return squirrel.Select().From(m.table)
}
func (m *defaultOrderRefundModel) Delete(ctx context.Context, session sqlx.Session, id int64) error {
data, err := m.FindOne(ctx, id)
if err != nil {
return err
}
tydataOrderRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, id)
tydataOrderRefundPlatformRefundIdKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundPlatformRefundIdPrefix, data.PlatformRefundId)
tydataOrderRefundRefundNoKey := fmt.Sprintf("%s%v", cacheTydataOrderRefundRefundNoPrefix, data.RefundNo)
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
if session != nil {
return session.ExecCtx(ctx, query, id)
}
return conn.ExecCtx(ctx, query, id)
}, tydataOrderRefundIdKey, tydataOrderRefundPlatformRefundIdKey, tydataOrderRefundRefundNoKey)
return err
}
func (m *defaultOrderRefundModel) formatPrimary(primary interface{}) string {
return fmt.Sprintf("%s%v", cacheTydataOrderRefundIdPrefix, primary)
}
func (m *defaultOrderRefundModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", orderRefundRows, m.table)
return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo)
}
func (m *defaultOrderRefundModel) tableName() string {
return m.table
}