Browse Source

feat(task): 添加自动续费功能

- 新增 GetGlobalLimitAlmostExpired 方法获取全局即将到期的限制
- 实现 GetGlobalAllHostId 方法获取全局所有主机 ID- 添加 EditGlobalExpired 方法修改全局过期状态
- 实现 EnablePlan 方法续费套餐
- 新增 EditExpired 方法处理续费操作
- 更新 GetAlmostExpiring 方法支持指定到期时间
- 修改 BanServer 方法名称为更准确的描述
fusu 4 weeks ago
parent
commit
6fdfb78354
4 changed files with 153 additions and 5 deletions
  1. 15 0
      internal/repository/globallimit.go
  2. 2 1
      internal/repository/host.go
  3. 1 0
      internal/service/cdn.go
  4. 135 4
      internal/task/waf.go

+ 15 - 0
internal/repository/globallimit.go

@@ -26,6 +26,8 @@ type GlobalLimitRepository interface {
 	GetNodeArea(ctx context.Context, nodeAreaName string) (int64, error)
 	GetNodeArea(ctx context.Context, nodeAreaName string) (int64, error)
 	// 修改套餐状态
 	// 修改套餐状态
 	EditHostState(ctx context.Context, hostId int64, state bool) error
 	EditHostState(ctx context.Context, hostId int64, state bool) error
+	// 获取指定到期时间
+	GetGlobalLimitAlmostExpired(ctx context.Context, addTime int64) ([]model.GlobalLimit, error)
 }
 }
 
 
 func NewGlobalLimitRepository(
 func NewGlobalLimitRepository(
@@ -168,4 +170,17 @@ func (r *globalLimitRepository) EditHostState(ctx context.Context, hostId int64,
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
+}
+
+// 获取指定到期时间
+func (r *globalLimitRepository) GetGlobalLimitAlmostExpired(ctx context.Context, addTime int64) ([]model.GlobalLimit, error) {
+	var res []model.GlobalLimit
+	expiredTime := time.Now().Unix() + addTime
+	if err := r.DB(ctx).
+		Where("nextduedate < ?", expiredTime).
+		Find(&res).Error; err != nil {
+		return nil, err
+	}
+	return res, nil
+
 }
 }

+ 2 - 1
internal/repository/host.go

@@ -98,4 +98,5 @@ func (r *hostRepository) GetAlmostExpired(ctx context.Context, hostId []int,addT
 		return nil, err
 		return nil, err
 	}
 	}
 	return res, nil
 	return res, nil
-}
+}
+

+ 1 - 0
internal/service/cdn.go

@@ -17,6 +17,7 @@ type CdnService interface {
 	AddUser(ctx context.Context, req v1.User) (int64, error)
 	AddUser(ctx context.Context, req v1.User) (int64, error)
 	CreateGroup(ctx context.Context, req v1.Group) (int64, error)
 	CreateGroup(ctx context.Context, req v1.Group) (int64, error)
 	BindPlan(ctx context.Context, req v1.Plan) (int64, error)
 	BindPlan(ctx context.Context, req v1.Plan) (int64, error)
+	// 续费套餐
 	RenewPlan(ctx context.Context, req v1.RenewalPlan) error
 	RenewPlan(ctx context.Context, req v1.RenewalPlan) error
 	CreateWebsite(ctx context.Context, req v1.WebsiteSend) (int64, error)
 	CreateWebsite(ctx context.Context, req v1.WebsiteSend) (int64, error)
 	EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error
 	EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error

+ 135 - 4
internal/task/waf.go

@@ -3,10 +3,12 @@ package task
 import (
 import (
 	"context"
 	"context"
 	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
 	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
+	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
 	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
 	"github.com/go-nunu/nunu-layout-advanced/internal/service"
 	"github.com/go-nunu/nunu-layout-advanced/internal/service"
 	"github.com/hashicorp/go-multierror"
 	"github.com/hashicorp/go-multierror"
 	"sync"
 	"sync"
+	"time"
 )
 )
 
 
 type WafTask interface {
 type WafTask interface {
@@ -18,6 +20,7 @@ func NewWafTask (
 	udpForWardingRep repository.UdpForWardingRepository,
 	udpForWardingRep repository.UdpForWardingRepository,
 	cdn service.CdnService,
 	cdn service.CdnService,
 	hostRep repository.HostRepository,
 	hostRep repository.HostRepository,
+	globalLimitRep repository.GlobalLimitRepository,
 	task *Task,
 	task *Task,
 	) WafTask{
 	) WafTask{
 	return &wafTask{
 	return &wafTask{
@@ -27,6 +30,7 @@ func NewWafTask (
 		udpForWardingRep: udpForWardingRep,
 		udpForWardingRep: udpForWardingRep,
 		cdn: cdn,
 		cdn: cdn,
 		hostRep: hostRep,
 		hostRep: hostRep,
+		globalLimitRep: globalLimitRep,
 	}
 	}
 }
 }
 type wafTask struct {
 type wafTask struct {
@@ -36,6 +40,7 @@ type wafTask struct {
 	udpForWardingRep repository.UdpForWardingRepository
 	udpForWardingRep repository.UdpForWardingRepository
 	cdn service.CdnService
 	cdn service.CdnService
 	hostRep repository.HostRepository
 	hostRep repository.HostRepository
+	globalLimitRep repository.GlobalLimitRepository
 }
 }
 
 
 func (t wafTask) CheckExpiredTask(ctx context.Context) error {
 func (t wafTask) CheckExpiredTask(ctx context.Context) error {
@@ -64,7 +69,7 @@ func (t wafTask) GetCdnWebId(ctx context.Context,hostId int) ([]int, error) {
 	return ids, nil
 	return ids, nil
 }
 }
 
 
-// 禁用网站
+// 启用/禁用 网站
 func (t wafTask) BanServer(ctx context.Context, ids []int, isBan bool) error {
 func (t wafTask) BanServer(ctx context.Context, ids []int, isBan bool) error {
 	var wg sync.WaitGroup
 	var wg sync.WaitGroup
 	errChan := make(chan error, len(ids))
 	errChan := make(chan error, len(ids))
@@ -102,13 +107,139 @@ func (t wafTask) BanServer(ctx context.Context, ids []int, isBan bool) error {
 
 
 
 
 
 
-// 获取到期时间
-func (t wafTask) GetAlmostExpiring(ctx context.Context,hostIds []int) ([]v1.GetAlmostExpireHostResponse,error) {
+// 获取指定到期时间
+func (t wafTask) GetAlmostExpiring(ctx context.Context,hostIds []int,addTime int64) ([]v1.GetAlmostExpireHostResponse,error) {
 	// 3 天
 	// 3 天
-	res, err := t.hostRep.GetAlmostExpired(ctx, hostIds, 259200)
+	res, err := t.hostRep.GetAlmostExpired(ctx, hostIds, addTime)
 	if err != nil {
 	if err != nil {
 		return nil,err
 		return nil,err
 	}
 	}
 
 
 	return res, nil
 	return res, nil
+}
+
+
+// 获取全局到期时间
+func (t wafTask) GetGlobalAlmostExpiring(ctx context.Context,addTime int64) ([]model.GlobalLimit,error) {
+	res, err := t.globalLimitRep.GetGlobalLimitAlmostExpired(ctx, addTime)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+// 获取cdn web id
+
+func (t wafTask) GetGlobalAllHostId(ctx context.Context,addTime int64) (map[int]int64, error) {
+	globalData, err := t.GetGlobalAlmostExpiring(ctx,addTime)
+	if err != nil {
+		return nil, err
+	}
+
+	var hostIds []int
+	for _, v := range globalData {
+		hostIds = append(hostIds, v.HostId)
+	}
+
+	globalDataMap := make(map[int]int64, len(globalData))
+	planMap := make(map[int]int64, len(globalData))
+
+	for _, v := range globalData {
+		globalDataMap[v.HostId] = v.ExpiredAt
+		planMap[v.HostId] = int64(v.RuleId)
+	}
+
+	hostData,err := t.GetAlmostExpiring(ctx,hostIds,addTime)
+	if err != nil {
+		return nil, err
+	}
+
+	hostDataMap := make(map[int]int64, len(hostData))
+	for _, v := range hostData {
+		hostDataMap[v.HostId] = v.ExpiredAt
+	}
+
+	editMap := make(map[int]int64)
+
+	for k, v := range globalDataMap {
+		if hostDataMap[k] != v {
+			editMap[k] = v
+		}
+	}
+
+	planExpireMap := make(map[int]int64)
+	for k, v := range planMap {
+		if _, ok := editMap[k]; ok {
+			planExpireMap[k] = v
+		}
+	}
+
+	return editMap, nil
+}
+
+
+// 修改全局续费
+func (t wafTask) EditGlobalExpired(ctx context.Context,req []struct{
+	hostId int
+	expiredAt int64
+},state bool) error {
+	for _, v := range req {
+		err := t.globalLimitRep.UpdateGlobalLimitByHostId(ctx, &model.GlobalLimit{
+			HostId: v.hostId,
+			ExpiredAt: v.expiredAt,
+			State: state,
+		})
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+
+// 续费套餐
+func (t wafTask) EnablePlan(ctx context.Context,req []struct{
+	planId int
+	expiredAt int64
+}) error {
+	for _, v := range req {
+		err := t.cdn.RenewPlan(ctx, v1.RenewalPlan{
+			UserPlanId: int64(v.planId),
+			IsFree: true,
+			DayTo: time.Unix(v.expiredAt,0).Format("2006-01-02"),
+			Period:     "monthly",
+			CountPeriod: 1,
+			PeriodDayTo: time.Unix(v.expiredAt,0).Format("2006-01-02"),
+		})
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// 续费操作
+func (t wafTask) EditExpired(ctx context.Context,req []struct {
+	hostId int
+	expiredAt int64
+	planId int
+}) error {
+
+	var sendData []struct {
+		hostId int
+		expiredAt int64
+	}
+	for _, v := range req {
+		sendData = append(sendData, struct {
+			hostId int
+			expiredAt int64
+		}{
+			hostId: v.hostId,
+			expiredAt: v.expiredAt,
+		})
+	}
+	if err := t.EditGlobalExpired(ctx,sendData,true); err != nil {
+		return err
+	}
+	return nil
 }
 }