Bladeren bron

feat(internal): 添加网关 IP相关的模型、仓库和处理器

- 新增 Gatewayip 模型,用于管理网关 IP信息
- 实现 GatewayipRepository 接口,提供网关 IP 相关的数据库操作
- 添加 GatewayipHandler 结构体和 GetGatewayip 方法,用于处理网关 IP 的 HTTP 请求
- 创建 GatewayipService 接口和实现,提供网关 IP 的业务逻辑服务
- 在 GlobalLimitRequireResponse 结构体中添加 HostId 字段
fusu 3 weken geleden
bovenliggende
commit
9176535d5d
5 gewijzigde bestanden met toevoegingen van 199 en 0 verwijderingen
  1. 1 0
      api/v1/globalLimit.go
  2. 25 0
      internal/handler/gatewayip.go
  3. 22 0
      internal/model/gatewayip.go
  4. 122 0
      internal/repository/gatewayip.go
  5. 29 0
      internal/service/gatewayip.go

+ 1 - 0
api/v1/globalLimit.go

@@ -14,6 +14,7 @@ type GlobalLimitEditRequest struct {
 }
 
 type GlobalLimitRequireResponse struct {
+	HostId          int
 	ExpiredAt       string
 	GlobalLimitName string
 	HostName        string

+ 25 - 0
internal/handler/gatewayip.go

@@ -0,0 +1,25 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-nunu/nunu-layout-advanced/internal/service"
+)
+
+type GatewayipHandler struct {
+	*Handler
+	gatewayipService service.GatewayipService
+}
+
+func NewGatewayipHandler(
+    handler *Handler,
+    gatewayipService service.GatewayipService,
+) *GatewayipHandler {
+	return &GatewayipHandler{
+		Handler:      handler,
+		gatewayipService: gatewayipService,
+	}
+}
+
+func (h *GatewayipHandler) GetGatewayip(ctx *gin.Context) {
+
+}

+ 22 - 0
internal/model/gatewayip.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"time"
+)
+
+type Gatewayip struct {
+	Id           int `gorm:"primary"`
+	HostId       int `gorm:"not null"`
+	Ip           string `gorm:"not null"`
+	Name         string `gorm:"null"`
+	Operator     int `gorm:"not null;default:1"`
+	BanOverseas  int `gorm:"null;default:0"`
+	BanUdp       int `gorm:"null;default:0"`
+	Comment      string `gorm:"null"`
+	CreatedAt    time.Time `json:"createdAt" form:"createdAt"`
+	UpdatedAt    time.Time `json:"updatedAt" form:"updatedAt"`
+}
+
+func (m *Gatewayip) TableName() string {
+    return "shd_waf_gateway_group"
+}

+ 122 - 0
internal/repository/gatewayip.go

@@ -0,0 +1,122 @@
+package repository
+
+import (
+    "context"
+	"fmt"
+	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
+	"github.com/go-nunu/nunu-layout-advanced/internal/model"
+	"gorm.io/gorm"
+)
+
+type GatewayipRepository interface {
+	GetGatewayip(ctx context.Context, id int64) (*model.Gatewayip, error)
+	AddGatewayip(ctx context.Context, req model.Gatewayip) error
+	EditGatewayip(ctx context.Context, req model.Gatewayip) error
+	DeleteGatewayip(ctx context.Context, req model.Gatewayip) error
+	GetGatewayipByHostId(ctx context.Context, hostId int64) (*model.Gatewayip, error)
+	GetGatewayipByHostIdAll(ctx context.Context, hostId int64) error
+	UpdateGatewayipByHostId(ctx context.Context, req model.Gatewayip) error
+	DeleteGatewayipByHostId(ctx context.Context, hostId int64) error
+	GetIpWhereHostIdNull(ctx context.Context,req v1.GlobalLimitRequireResponse) error
+	CleanIPByHostId(ctx context.Context, hostId []int64) error
+}
+
+func NewGatewayipRepository(
+	repository *Repository,
+) GatewayipRepository {
+	return &gatewayipRepository{
+		Repository: repository,
+	}
+}
+
+type gatewayipRepository struct {
+	*Repository
+}
+
+func (r *gatewayipRepository) GetGatewayip(ctx context.Context, id int64) (*model.Gatewayip, error) {
+	var req model.Gatewayip
+	return &req, r.DB(ctx).Where("id = ?", id).First(&req).Error
+}
+
+func (r *gatewayipRepository) AddGatewayip(ctx context.Context, req model.Gatewayip) error {
+	return r.DB(ctx).Create(&req).Error
+}
+
+func (r *gatewayipRepository) EditGatewayip(ctx context.Context, req model.Gatewayip) error {
+	return r.DB(ctx).Model(&model.Gatewayip{}).Where("id = ?", req.Id).Updates(req).Error
+}
+
+func (r *gatewayipRepository) DeleteGatewayip(ctx context.Context, req model.Gatewayip) error {
+	return r.DB(ctx).Model(&model.Gatewayip{}).Where("id = ?", req.Id).Delete(req).Error
+}
+
+func (r *gatewayipRepository) GetGatewayipByHostId(ctx context.Context, hostId int64) (*model.Gatewayip, error) {
+	var req model.Gatewayip
+	return &req, r.DB(ctx).Where("host_id = ?", hostId).First(&req).Error
+}
+
+func (r *gatewayipRepository) GetGatewayipByHostIdAll(ctx context.Context, hostId int64) error {
+	var req model.Gatewayip
+	return r.DB(ctx).Where("host_id = ?", hostId).Find(&req).Error
+}
+
+func (r *gatewayipRepository) UpdateGatewayipByHostId(ctx context.Context, req model.Gatewayip) error {
+	return r.DB(ctx).Where("host_id = ?", req.HostId).Updates(&req).Error
+}
+
+func (r *gatewayipRepository) DeleteGatewayipByHostId(ctx context.Context, hostId int64) error {
+	return r.DB(ctx).Model(&model.Gatewayip{}).Where("host_id = ?", hostId).Delete(&model.Gatewayip{}).Error
+}
+
+
+func (r *gatewayipRepository) GetIpWhereHostIdNull(ctx context.Context,req v1.GlobalLimitRequireResponse) error {
+	if req.IpCount <= 0 {
+		return fmt.Errorf("套餐IP数量错误, 请联系客服")
+	}
+
+	// 使用事务保证操作的原子性
+	return r.DB(ctx).Transaction(func(tx *gorm.DB) error {
+		var idsToAssign []uint // 只需一个切片来接收ID
+
+		// 步骤 1: 查询所需数量的可用IP ID。使用 Limit 可以提升性能,避免捞出所有可用IP。
+		err := tx.Model(&model.Gatewayip{}).
+			Where("operator = ?", req.Operator).
+			Where("ban_udp = ?", req.IsBanUdp).
+			Where("ban_overseas = ?", req.IsBanOverseas).
+			Where("host_id IS NULL OR host_id = ?", 0).
+			Order("id ASC").
+			Limit(req.IpCount). // 优化点:直接用Limit限制查询数量
+			Pluck("id", &idsToAssign).Error
+
+		if err != nil {
+			return err // 查询出错,事务回滚
+		}
+
+		// 步骤 2: 判断实际查到的数量是否足够
+		if len(idsToAssign) < req.IpCount {
+			return fmt.Errorf("库存不足, 请联系客服补充") // 数量不足,返回特定错误,事务回滚
+		}
+
+		// 步骤 3: 更新这些IP的 host_id
+		// 注意:因为上面已经Limit了,所以idsToAssign的长度就是我们要更新的数量
+		updateResult := tx.Model(&model.Gatewayip{}).
+			Where("id IN ?", idsToAssign).
+			Update("host_id", req.HostId)
+
+		if updateResult.Error != nil {
+			return updateResult.Error // 更新失败,事务回滚
+		}
+
+		// (可选) 健壮性检查
+		if updateResult.RowsAffected != int64(req.IpCount) {
+			return fmt.Errorf("IP分配异常: 期望更新 %d 条记录, 实际更新了 %d 条", req.IpCount, updateResult.RowsAffected)
+		}
+
+		// 返回 nil, GORM 会提交事务
+		return nil
+	})
+}
+
+func (r *gatewayipRepository) CleanIPByHostId(ctx context.Context, hostId []int64) error {
+	return r.DB(ctx).Model(&model.Gatewayip{}).Where("host_id IN ?", hostId).Update("host_id", 0).Error
+}

+ 29 - 0
internal/service/gatewayip.go

@@ -0,0 +1,29 @@
+package service
+
+import (
+    "context"
+	"github.com/go-nunu/nunu-layout-advanced/internal/model"
+	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
+)
+
+type GatewayipService interface {
+	GetGatewayip(ctx context.Context, id int64) (*model.Gatewayip, error)
+}
+func NewGatewayipService(
+    service *Service,
+    gatewayipRepository repository.GatewayipRepository,
+) GatewayipService {
+	return &gatewayipService{
+		Service:        service,
+		gatewayipRepository: gatewayipRepository,
+	}
+}
+
+type gatewayipService struct {
+	*Service
+	gatewayipRepository repository.GatewayipRepository
+}
+
+func (s *gatewayipService) GetGatewayip(ctx context.Context, id int64) (*model.Gatewayip, error) {
+	return s.gatewayipRepository.GetGatewayip(ctx, id)
+}