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