176 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package service
 | ||
| 
 | ||
| import (
 | ||
| 	"errors"
 | ||
| 	"fmt"
 | ||
| 	"go-admin/app/admin/models"
 | ||
| 	"go-admin/app/admin/service/dto"
 | ||
| 	"go-admin/utils/utility"
 | ||
| 
 | ||
| 	"github.com/go-admin-team/go-admin-core/sdk/service"
 | ||
| 	"github.com/shopspring/decimal"
 | ||
| 	"gorm.io/gorm"
 | ||
| )
 | ||
| 
 | ||
| type MemberRenewalLog struct {
 | ||
| 	service.Service
 | ||
| }
 | ||
| 
 | ||
| // 定时过期
 | ||
| func (e MemberRenewalLog) ExpireProxy() error {
 | ||
| 	if err := e.Orm.Exec("UPDATE member_proxy SET status =2 WHERE expired < NOW() AND status =1").Error; err != nil {
 | ||
| 		return err
 | ||
| 	}
 | ||
| 
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // AutoRenewal 自动续费
 | ||
| func (e *MemberRenewalLog) AutoRenewal() error {
 | ||
| 	proxyService := MemberProxy{Service: e.Service}
 | ||
| 	balanceService := MemberBalance{Service: e.Service}
 | ||
| 	configService := SysConfig{Service: e.Service}
 | ||
| 	configResp := dto.GetSysConfigByKEYForServiceResp{}
 | ||
| 	configService.GetWithKey(&dto.SysConfigByKeyReq{ConfigKey: "ip_renew_deduction_standard"}, &configResp)
 | ||
| 
 | ||
| 	if configResp.ConfigValue == "" {
 | ||
| 		e.Log.Error("没有设置扣费标准,不自动续期")
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 
 | ||
| 	amount, err := decimal.NewFromString(configResp.ConfigValue)
 | ||
| 
 | ||
| 	if err != nil {
 | ||
| 		e.Log.Error("扣费标准设置错误,不自动续期")
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 
 | ||
| 	autoProxys, err := proxyService.GetAutoRenewalProxys()
 | ||
| 
 | ||
| 	if err != nil {
 | ||
| 		e.Log.Errorf("获取需要自动续费的代理,%v", err)
 | ||
| 		return err
 | ||
| 	}
 | ||
| 
 | ||
| 	if len(autoProxys) == 0 {
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 
 | ||
| 	userIds := make([]int, 0)
 | ||
| 	for _, proxy := range autoProxys {
 | ||
| 		if !utility.ContainsInt(userIds, proxy.UserId) {
 | ||
| 			userIds = append(userIds, proxy.UserId)
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	userBalanceMap := balanceService.GetUserBalanceMap(userIds)
 | ||
| 	if userBalanceMap == nil {
 | ||
| 		e.Log.Error("用户余额获取失败,userBalanceMap 为 nil")
 | ||
| 		return fmt.Errorf("userBalanceMap is nil")
 | ||
| 	}
 | ||
| 
 | ||
| 	for _, proxy := range autoProxys {
 | ||
| 		if proxy.Type == 0 {
 | ||
| 			continue
 | ||
| 		}
 | ||
| 
 | ||
| 		if balance, ok := userBalanceMap[proxy.UserId]; ok {
 | ||
| 			if balance.GreaterThan(decimal.Zero) {
 | ||
| 				err = e.DoRenewal(proxy, amount)
 | ||
| 
 | ||
| 				if err == nil {
 | ||
| 					userBalanceMap[proxy.UserId] = balance.Sub(amount)
 | ||
| 				}
 | ||
| 			}
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // 执行续费
 | ||
| func (e *MemberRenewalLog) DoRenewal(proxy models.MemberProxy, amount decimal.Decimal) error {
 | ||
| 	renewalLog := models.MemberRenewalLog{}
 | ||
| 	renewalLog.UserId = proxy.UserId
 | ||
| 	renewalLog.Type = proxy.Type
 | ||
| 	renewalLog.Amount = amount
 | ||
| 	renewalLog.Day = 30
 | ||
| 	renewalLog.ProxyId = proxy.Id
 | ||
| 	cliproxyService := CliProxyService{Service: e.Service}
 | ||
| 
 | ||
| 	err := e.Orm.Transaction(func(tx *gorm.DB) error {
 | ||
| 		if err := tx.Save(&renewalLog).Error; err != nil {
 | ||
| 			return err
 | ||
| 		}
 | ||
| 
 | ||
| 		db := tx.Exec("UPDATE member_balance SET balance = balance -? WHERE user_id =? AND balance >= ?", amount, proxy.UserId, amount)
 | ||
| 
 | ||
| 		if db.RowsAffected != 1 {
 | ||
| 			e.Log.Errorf("续费扣费失败,ip:%s,err:%s", proxy.Ip, "余额不足")
 | ||
| 			return errors.New("余额不足")
 | ||
| 		}
 | ||
| 
 | ||
| 		if db.Error != nil {
 | ||
| 			e.Log.Errorf("续费扣费失败,ip:%s,err:%s", proxy.Ip, db.Error.Error())
 | ||
| 			return db.Error
 | ||
| 		}
 | ||
| 
 | ||
| 		if err := tx.Model(&proxy).Update("expired", proxy.Expired.AddDate(0, 0, 30)).Error; err != nil {
 | ||
| 			e.Log.Errorf("续费修改过期时间失败,ip:%s,err:%s", proxy.Ip, err.Error())
 | ||
| 
 | ||
| 			return err
 | ||
| 		}
 | ||
| 
 | ||
| 		if err := cliproxyService.Renewal(proxy.Ip, 30); err != nil {
 | ||
| 			e.Log.Errorf("续费失败,ip:%s,err:%s", proxy.Ip, err.Error())
 | ||
| 			return err
 | ||
| 		}
 | ||
| 
 | ||
| 		return nil
 | ||
| 	})
 | ||
| 	return err
 | ||
| }
 | ||
| 
 | ||
| // UserRenewal 用户续费
 | ||
| func (e *MemberRenewalLog) UserRenewal(req *dto.MemberProxyUserRenewalReq, userId int) (decimal.Decimal, error) {
 | ||
| 	configService := SysConfig{Service: e.Service}
 | ||
| 	configResp := dto.GetSysConfigByKEYForServiceResp{}
 | ||
| 	configService.GetWithKey(&dto.SysConfigByKeyReq{ConfigKey: "ip_renew_deduction_standard"}, &configResp)
 | ||
| 
 | ||
| 	if configResp.ConfigValue == "" {
 | ||
| 		e.Log.Error("没有设置扣费标准,无法续期")
 | ||
| 		return decimal.Zero, nil
 | ||
| 	}
 | ||
| 
 | ||
| 	amount, err := decimal.NewFromString(configResp.ConfigValue)
 | ||
| 
 | ||
| 	if err != nil {
 | ||
| 		e.Log.Error("扣费标准设置错误,无法续期")
 | ||
| 		return decimal.Zero, errors.New("续费失败,请联系管理员")
 | ||
| 	}
 | ||
| 
 | ||
| 	balanceService := MemberBalance{Service: e.Service}
 | ||
| 	balance := balanceService.GetBalance(userId)
 | ||
| 
 | ||
| 	if balance.GreaterThan(amount) {
 | ||
| 
 | ||
| 	} else {
 | ||
| 		return balance, errors.New("余额不足,请充值")
 | ||
| 	}
 | ||
| 
 | ||
| 	proxyService := MemberProxy{Service: e.Service}
 | ||
| 	proxy, err := proxyService.GetProxyById(req.ProxyId)
 | ||
| 
 | ||
| 	if err != nil {
 | ||
| 		return balance, errors.New("代理不存在")
 | ||
| 	}
 | ||
| 
 | ||
| 	if proxy.Type == 0 {
 | ||
| 		return balance, errors.New("短效ip不支持续费")
 | ||
| 	}
 | ||
| 
 | ||
| 	err = e.DoRenewal(proxy, amount)
 | ||
| 
 | ||
| 	return balance, err
 | ||
| }
 |