Files
proxy_server/app/admin/service/member_renewal_log.go
2025-07-28 18:15:40 +08:00

176 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}