浏览代码

feat(api): 重构 TCP转发相关接口和数据结构- 重新定义了 TcpForwardingRequest 和 TcpForwardingData 结构体
- 更新了 TCP转发相关的 API 接口- 重构了 TCP 转发的数据库模型和仓库方法- 优化了主机配置获取逻辑,支持获取域名信息
-移除了全局限制中不必要的网关组相关操作

fusu 2 月之前
父节点
当前提交
7c9514df36

+ 0 - 1
api/v1/globalLimit.go

@@ -4,7 +4,6 @@ type GlobalLimitRequest struct {
 	Uid     int    `json:"uid" form:"uid" binding:"required"`
 	HostId  int    `json:"host_id" form:"host_id" binding:"required"`
 	Comment string `json:"comment" form:"comment" binding:"required"`
-	Domain  string `json:"domain" form:"domain"`
 }
 type GlobalLimitSendRequest struct {
 	Tag           string `json:"tag" form:"tag" binding:"required"`

+ 2 - 0
api/v1/host.go

@@ -26,4 +26,6 @@ type GameShieldHostBackendConfigResponse struct {
 type GlobalLimitConfigResponse struct {
 	MaxBytesMonth string `default:"0"`
 	Bps           string `default:"0"`
+	PortCount     int
+	DomainCount   int
 }

+ 19 - 9
api/v1/tcpForwarding.go

@@ -1,20 +1,16 @@
 package v1
 
-type TcpForwardingRequest struct {
+type TcpForwardingData struct {
 	WafTcpId          int    `form:"waf_tcp_id" json:"waf_tcp_id"`
 	Tag               string `form:"tag" json:"tag" binding:"required"`
 	Port              int    `form:"port" json:"port" binding:"required"`
 	WafGatewayGroupId int    `form:"waf_gateway_group_id" json:"waf_gateway_group_id"`
-	CcCount           int    `form:"cc_count" json:"cc_count"`
+	WafTcpLimitRuleId int    `form:"waf_tcp_limit_id" json:"waf_tcp_limit_id"`
+	CcCount           int    `form:"cc_count" json:"cc_count" default:"0"`
 	CcDuration        string `form:"cc_duration" json:"cc_duration" default:"0s"`
-	CcBlockCount      int    `form:"cc_block_count" json:"cc_block_count"`
+	CcBlockCount      int    `form:"cc_block_count" json:"cc_block_count" default:"0"`
 	CcBlockDuration   string `form:"cc_block_duration" json:"cc_block_duration" default:"0s"`
-	ConnCount         int    `form:"conn_count" json:"conn_count"`
-	ConnDuration      string `form:"conn_duration" json:"conn_duration" default:"0s"`
-	MaxConnCount      int    `form:"max_conn_count" json:"max_conn_count"`
-	Bps               string `form:"bps" json:"bps" default:"0"`
-	MaxBytesMonth     int    `form:"max_bytes_month" json:"max_bytes_month" default:"0"`
-	BackendProtocol   string `form:"backend_protocol" json:"backend_protocol"`
+	BackendProtocol   string `form:"backend_protocol" json:"backend_protocol" default:"tcp"`
 	BackendTimeout    string `form:"backend_timeout" json:"backend_timeout" default:"5s"`
 	BackendList       string `form:"backend_list" json:"backend_list"`
 	AllowIpList       string `form:"allow_ip_list" json:"allow_ip_list"`
@@ -26,3 +22,17 @@ type TcpForwardingRequest struct {
 type DeleteTcpForwardingRequest struct {
 	WafTcpId int `form:"waf_tcp_id" json:"waf_tcp_id" binding:"required"`
 }
+
+type TcpForwardingRequest struct {
+	HostId            int `form:"host_id" json:"host_id" binding:"required"`
+	Uid               int `form:"uid" json:"uid" binding:"required"`
+	TcpForwardingData TcpForwardingData
+}
+type TcpForwardingRequire struct {
+	HostId            int    `form:"host_id" json:"host_id" binding:"required"`
+	Uid               int    `form:"uid" json:"uid" binding:"required"`
+	Comment           string `form:"comment" json:"comment" binding:"required"`
+	WafGatewayGroupId int    `form:"waf_gateway_group_id" json:"waf_gateway_group_id"`
+	WafTcpLimitRuleId int    `form:"waf_tcp_limit_id" json:"waf_tcp_limit_id"`
+	Tag               string `form:"tag" json:"tag" binding:"required"`
+}

+ 21 - 12
api/v1/udpForwarding.go

@@ -1,27 +1,21 @@
 package v1
 
-type UdpForwardingRequest struct {
+type UdpForwardingData struct {
 	WafUdpId          int    `form:"waf_udp_id" json:"waf_udp_id"`
 	Tag               string `form:"tag" json:"tag" binding:"required"`
 	Port              int    `form:"port" json:"port" binding:"required"`
 	WafGatewayGroupId int    `form:"waf_gateway_group_id" json:"waf_gateway_group_id"`
-	CcPacketCount     int    `form:"cc_packet_count" json:"cc_packet_count"`
+	WafUdpLimitId     int    `form:"waf_udp_limit_id" json:"waf_udp_limit_id"`
+	CcPacketCount     int    `form:"cc_packet_count" json:"cc_packet_count" default:"0"`
 	CcPacketDuration  string `form:"cc_packet_duration" json:"cc_packet_duration" default:"0s"`
-	CcCount           int    `form:"cc_count" json:"cc_count"`
+	CcCount           int    `form:"cc_count" json:"cc_count" default:"0"`
 	CcDuration        string `form:"cc_duration" json:"cc_duration" default:"0s"`
-	CcBlockCount      int    `form:"cc_block_count" json:"cc_block_count"`
+	CcBlockCount      int    `form:"cc_block_count" json:"cc_block_count" default:"0"`
 	CcBlockDuration   string `form:"cc_block_duration" json:"cc_block_duration" default:"0s"`
-	QosPacketCount    int    `form:"qos_packet_count" json:"qos_packet_count"`
-	QosPacketDuration string `form:"qos_packet_duration" json:"qos_packet_duration" default:"0s"`
-	Bps               string `form:"bps" json:"bps" default:"0"`
-	MaxConnCount      int    `form:"max_conn_count" json:"max_conn_count"`
-	SessionTimeout    string `form:"session_timeout" json:"session_timeout" default:"60s"`
-	MaxBytesMonth     int    `form:"max_bytes_month" json:"max_bytes_month" default:"0"`
+	SessionTimeout    int    `form:"session_timeout" json:"session_timeout" default:"0s"`
 	BackendList       string `form:"backend_list" json:"backend_list"`
 	AllowIpList       string `form:"allow_ip_list" json:"allow_ip_list"`
 	DenyIpList        string `form:"deny_ip_list" json:"deny_ip_list"`
-	BackendProtocol   string `form:"backend_protocol" json:"backend_protocol"`
-	BackendTimeout    string `form:"backend_timeout" json:"backend_timeout" default:"5s"`
 	AccessRule        string `form:"access_rule" json:"access_rule"`
 	Comment           string `form:"comment" json:"comment"`
 }
@@ -29,3 +23,18 @@ type UdpForwardingRequest struct {
 type DeleteUdpForwardingRequest struct {
 	WafUdpId int `form:"waf_udp_id" json:"waf_udp_id" binding:"required"`
 }
+
+type UdpForwardingRequest struct {
+	HostId            int `form:"host_id" json:"host_id" binding:"required"`
+	Uid               int `form:"uid" json:"uid" binding:"required"`
+	UdpForwardingData UdpForwardingData
+}
+
+type UdpForwardingRequire struct {
+	HostId            int    `form:"host_id" json:"host_id" binding:"required"`
+	Uid               int    `form:"uid" json:"uid" binding:"required"`
+	Comment           string `form:"comment" json:"comment" binding:"required"`
+	WafGatewayGroupId int    `form:"waf_gateway_group_id" json:"waf_gateway_group_id"`
+	WafUdpLimitRuleId int    `form:"waf_udp_limit_id" json:"waf_udp_limit_id"`
+	Tag               string `form:"tag" json:"tag" binding:"required"`
+}

+ 10 - 0
api/v1/wafformatter.go

@@ -0,0 +1,10 @@
+package v1
+
+type GlobalRequire struct {
+	HostId            int    `form:"host_id" json:"host_id" binding:"required"`
+	Uid               int    `form:"uid" json:"uid" binding:"required"`
+	Comment           string `form:"comment" json:"comment" binding:"required"`
+	WafGatewayGroupId int    `form:"waf_gateway_group_id" json:"waf_gateway_group_id"`
+	LimitRuleId       int    `form:"limit_id" json:"limit_id"`
+	Tag               string `form:"tag" json:"tag" binding:"required"`
+}

+ 30 - 20
api/v1/webForwarding.go

@@ -1,38 +1,48 @@
 package v1
 
-type WebForwardingRequest struct {
+type WebForwardingData struct {
 	WafWebId           int    `form:"waf_web_id" json:"waf_web_id"`
 	Tag                string `form:"tag" json:"tag" binding:"required"`
 	Port               int    `form:"port" json:"port" binding:"required"`
 	Domain             string `form:"domain" json:"domain"`
 	CustomHost         string `form:"custom_host" json:"custom_host"`
-	Bps                string `form:"bps" json:"bps"`
-	MaxBytesMonth      int    `form:"max_bytes_month" json:"max_bytes_month"`
 	WafGatewayGroupId  int    `form:"waf_gateway_group_id" json:"waf_gateway_group_id"`
-	Backend            string `form:"backend" json:"backend"`
-	IsHttps            bool   `form:"is_https" json:"is_https"`
-	HttpsCert          string `form:"https_cert" json:"https_cert"`
-	HttpsKey           string `form:"https_key" json:"https_key"`
-	AllowIpList        string `form:"allow_ip_list" json:"allow_ip_list"`
-	DenyIpList         string `form:"deny_ip_list" json:"deny_ip_list"`
-	AccessRule         string `form:"access_rule" json:"access_rule"`
-	QpsCount           int    `form:"qps_count" json:"qps_count"`
-	QpsDuration        string `form:"qps_duration" json:"qps_duration" default:"0s"`
-	CcCount            int    `form:"cc_count" json:"cc_count"`
+	WafWebLimitId      int    `form:"waf_web_limit_id" json:"waf_web_limit_id"`
+	CcCount            int    `form:"cc_count" json:"cc_count" default:"0"`
 	CcDuration         string `form:"cc_duration" json:"cc_duration" default:"0s"`
-	CcBlockCount       int    `form:"cc_block_count" json:"cc_block_count"`
+	CcBlockCount       int    `form:"cc_block_count" json:"cc_block_count" default:"0"`
 	CcBlockDuration    string `form:"cc_block_duration" json:"cc_block_duration" default:"0s"`
-	Cc4xxCount         int    `form:"cc_4xx_count" json:"cc4xx_count"`
-	Cc4xxDuration      string `form:"cc_4xx_duration" json:"cc4xx_duration" default:"0s"`
-	Cc4xxBlockCount    int    `form:"cc_4xx_block_count" json:"cc_4xx_block_count"`
+	Cc4xxCount         int    `form:"cc_4xx_count" json:"cc_4xx_count" default:"0"`
+	Cc4xxDuration      string `form:"cc_4xx_duration" json:"cc_4xx_duration" default:"0s"`
+	Cc4xxBlockCount    int    `form:"cc_4xx_block_count" json:"cc_4xx_block_count" default:"0"`
 	Cc4xxBlockDuration string `form:"cc_4xx_block_duration" json:"cc_4xx_block_duration" default:"0s"`
-	Cc5xxCount         int    `form:"cc_5xx_count" json:"cc5xx_count"`
-	Cc5xxDuration      string `form:"cc_5xx_duration" json:"cc5xx_duration" default:"0s"`
-	Cc5xxBlockCount    int    `form:"cc_5xx_block_count" json:"cc_5xx_block_count"`
+	Cc5xxCount         int    `form:"cc_5xx_count" json:"cc_5xx_count" default:"0"`
+	Cc5xxDuration      string `form:"cc_5xx_duration" json:"cc_5xx_duration" default:"0s"`
+	Cc5xxBlockCount    int    `form:"cc_5xx_block_count" json:"cc_5xx_block_count" default:"0"`
 	Cc5xxBlockDuration string `form:"cc_5xx_block_duration" json:"cc_5xx_block_duration" default:"0s"`
+	BackendList        string `form:"backend_list" json:"backend_list"`
+	AllowIpList        string `form:"allow_ip_list" json:"allow_ip_list"`
+	DenyIpList         string `form:"deny_ip_list" json:"deny_ip_list"`
+	AccessRule         string `form:"access_rule" json:"access_rule"`
+	IsHttps            int    `form:"is_https" json:"is_https" default:"0"`
 	Comment            string `form:"comment" json:"comment"`
 }
 
 type DeleteWebForwardingRequest struct {
 	WafWebId int `form:"waf_web_id" json:"waf_web_id" binding:"required"`
 }
+
+type WebForwardingRequest struct {
+	HostId            int `form:"host_id" json:"host_id" binding:"required"`
+	Uid               int `form:"uid" json:"uid" binding:"required"`
+	WebForwardingData WebForwardingData
+}
+
+type WebForwardingRequire struct {
+	HostId            int    `form:"host_id" json:"host_id" binding:"required"`
+	Uid               int    `form:"uid" json:"uid" binding:"required"`
+	Comment           string `form:"comment" json:"comment" binding:"required"`
+	WafGatewayGroupId int    `form:"waf_gateway_group_id" json:"waf_gateway_group_id"`
+	WafWebLimitRuleId int    `form:"waf_web_limit_id" json:"waf_web_limit_id"`
+	Tag               string `form:"tag" json:"tag" binding:"required"`
+}

+ 1 - 0
cmd/server/wire/wire.go

@@ -64,6 +64,7 @@ var serviceSet = wire.NewSet(
 	service.NewHostService,
 	service.NewGlobalLimitService,
 	service.NewGatewayGroupService,
+	service.NewWafFormatterService,
 )
 
 var handlerSet = wire.NewSet(

+ 7 - 6
cmd/server/wire/wire_gen.go

@@ -57,16 +57,18 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 	gameShieldBackendService := service.NewGameShieldBackendService(serviceService, gameShieldBackendRepository, gameShieldRepository, crawlerService, gameShieldPublicIpService, duedateService, formatterService, parserService, requiredService, viperViper, gameShieldService, hostService)
 	gameShieldBackendHandler := handler.NewGameShieldBackendHandler(handlerHandler, gameShieldBackendService)
 	webForwardingRepository := repository.NewWebForwardingRepository(repositoryRepository)
-	webForwardingService := service.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService)
+	globalLimitRepository := repository.NewGlobalLimitRepository(repositoryRepository)
+	wafFormatterService := service.NewWafFormatterService(serviceService, globalLimitRepository, hostRepository)
+	webForwardingService := service.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService, wafFormatterService)
 	webForwardingHandler := handler.NewWebForwardingHandler(handlerHandler, webForwardingService)
 	webLimitRepository := repository.NewWebLimitRepository(repositoryRepository)
 	webLimitService := service.NewWebLimitService(serviceService, webLimitRepository, requiredService, parserService, crawlerService, hostService)
 	webLimitHandler := handler.NewWebLimitHandler(handlerHandler, webLimitService)
 	tcpforwardingRepository := repository.NewTcpforwardingRepository(repositoryRepository)
-	tcpforwardingService := service.NewTcpforwardingService(serviceService, tcpforwardingRepository, parserService, requiredService, crawlerService)
+	tcpforwardingService := service.NewTcpforwardingService(serviceService, tcpforwardingRepository, parserService, requiredService, crawlerService, globalLimitRepository, hostRepository, wafFormatterService)
 	tcpforwardingHandler := handler.NewTcpforwardingHandler(handlerHandler, tcpforwardingService)
 	udpForWardingRepository := repository.NewUdpForWardingRepository(repositoryRepository)
-	udpForWardingService := service.NewUdpForWardingService(serviceService, udpForWardingRepository, requiredService, parserService, crawlerService)
+	udpForWardingService := service.NewUdpForWardingService(serviceService, udpForWardingRepository, requiredService, parserService, crawlerService, globalLimitRepository, hostRepository, wafFormatterService)
 	udpForWardingHandler := handler.NewUdpForWardingHandler(handlerHandler, udpForWardingService)
 	tcpLimitRepository := repository.NewTcpLimitRepository(repositoryRepository)
 	tcpLimitService := service.NewTcpLimitService(serviceService, tcpLimitRepository, requiredService, parserService, crawlerService, hostService)
@@ -74,10 +76,9 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 	udpLimitRepository := repository.NewUdpLimitRepository(repositoryRepository)
 	udpLimitService := service.NewUdpLimitService(serviceService, udpLimitRepository, requiredService, crawlerService, parserService, hostService)
 	udpLimitHandler := handler.NewUdpLimitHandler(handlerHandler, udpLimitService)
-	globalLimitRepository := repository.NewGlobalLimitRepository(repositoryRepository)
 	gatewayGroupRepository := repository.NewGatewayGroupRepository(repositoryRepository)
 	gatewayGroupService := service.NewGatewayGroupService(serviceService, gatewayGroupRepository, requiredService, parserService)
-	globalLimitService := service.NewGlobalLimitService(serviceService, globalLimitRepository, duedateService, crawlerService, viperViper, requiredService, parserService, hostService, tcpLimitService, udpLimitService, webLimitService, gatewayGroupService)
+	globalLimitService := service.NewGlobalLimitService(serviceService, globalLimitRepository, duedateService, crawlerService, viperViper, requiredService, parserService, hostService, tcpLimitService, udpLimitService, webLimitService, gatewayGroupService, hostRepository)
 	globalLimitHandler := handler.NewGlobalLimitHandler(handlerHandler, globalLimitService)
 	httpServer := server.NewHTTPServer(logger, viperViper, jwtJWT, limiterLimiter, handlerFunc, userHandler, gameShieldHandler, gameShieldBackendHandler, webForwardingHandler, webLimitHandler, tcpforwardingHandler, udpForWardingHandler, tcpLimitHandler, udpLimitHandler, globalLimitHandler)
 	jobJob := job.NewJob(transaction, logger, sidSid)
@@ -92,7 +93,7 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 
 var repositorySet = wire.NewSet(repository.NewDB, repository.NewRepository, repository.NewTransaction, repository.NewUserRepository, repository.NewGameShieldRepository, repository.NewGameShieldPublicIpRepository, repository.NewWebForwardingRepository, repository.NewTcpforwardingRepository, repository.NewUdpForWardingRepository, repository.NewGameShieldUserIpRepository, repository.NewWebLimitRepository, repository.NewTcpLimitRepository, repository.NewUdpLimitRepository, repository.NewGameShieldBackendRepository, repository.NewGameShieldSdkIpRepository, repository.NewHostRepository, repository.NewGlobalLimitRepository, repository.NewGatewayGroupRepository)
 
-var serviceSet = wire.NewSet(service.NewService, service.NewUserService, service.NewGameShieldService, service.NewCrawlerService, service.NewGameShieldPublicIpService, service.NewDuedateService, service.NewFormatterService, service.NewParserService, service.NewRequiredService, service.NewWebForwardingService, service.NewTcpforwardingService, service.NewUdpForWardingService, service.NewGameShieldUserIpService, service.NewWebLimitService, service.NewTcpLimitService, service.NewUdpLimitService, service.NewGameShieldBackendService, service.NewGameShieldSdkIpService, service.NewHostService, service.NewGlobalLimitService, service.NewGatewayGroupService)
+var serviceSet = wire.NewSet(service.NewService, service.NewUserService, service.NewGameShieldService, service.NewCrawlerService, service.NewGameShieldPublicIpService, service.NewDuedateService, service.NewFormatterService, service.NewParserService, service.NewRequiredService, service.NewWebForwardingService, service.NewTcpforwardingService, service.NewUdpForWardingService, service.NewGameShieldUserIpService, service.NewWebLimitService, service.NewTcpLimitService, service.NewUdpLimitService, service.NewGameShieldBackendService, service.NewGameShieldSdkIpService, service.NewHostService, service.NewGlobalLimitService, service.NewGatewayGroupService, service.NewWafFormatterService)
 
 var handlerSet = wire.NewSet(handler.NewHandler, handler.NewUserHandler, handler.NewGameShieldHandler, handler.NewGameShieldPublicIpHandler, handler.NewWebForwardingHandler, handler.NewTcpforwardingHandler, handler.NewUdpForWardingHandler, handler.NewGameShieldUserIpHandler, handler.NewWebLimitHandler, handler.NewTcpLimitHandler, handler.NewUdpLimitHandler, handler.NewGameShieldBackendHandler, handler.NewGameShieldSdkIpHandler, handler.NewHostHandler, handler.NewGlobalLimitHandler, handler.NewGatewayGroupHandler)
 

+ 5 - 0
config/prod.yml

@@ -21,6 +21,11 @@ data:
   #    user:
   #      driver: postgres
   #      dsn: host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai
+  mongodb:
+    uri: "mongodb://mongodb:27017"
+    database: "nunu"
+    timeout: 10s
+    max_pool_size: 100
   redis:
     addr: 127.0.0.1:6350
     password: ""

+ 8 - 1
go.mod

@@ -66,6 +66,7 @@ require (
 	github.com/gobwas/glob v0.2.3 // indirect
 	github.com/goccy/go-json v0.10.5 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
+	github.com/golang/snappy v0.0.4 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/google/uuid v1.3.1 // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
@@ -80,7 +81,7 @@ require (
 	github.com/jinzhu/now v1.1.5 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/klauspost/compress v1.15.0 // indirect
+	github.com/klauspost/compress v1.16.7 // indirect
 	github.com/klauspost/cpuid/v2 v2.2.10 // indirect
 	github.com/leodido/go-urn v1.2.4 // indirect
 	github.com/magiconair/properties v1.8.10 // indirect
@@ -91,6 +92,7 @@ require (
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/montanaflynn/stats v0.7.1 // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.9 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
@@ -108,12 +110,17 @@ require (
 	github.com/ugorji/go/codec v1.2.12 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
 	github.com/valyala/fasthttp v1.34.0 // indirect
+	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
+	github.com/xdg-go/scram v1.1.2 // indirect
+	github.com/xdg-go/stringprep v1.0.4 // indirect
 	github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect
 	github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
+	github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
 	github.com/yudai/gojsondiff v1.0.0 // indirect
 	github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
+	go.mongodb.org/mongo-driver v1.17.4 // indirect
 	go.uber.org/atomic v1.11.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	golang.org/x/arch v0.3.0 // indirect

+ 17 - 0
go.sum

@@ -200,6 +200,8 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -305,6 +307,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
 github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
 github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U=
 github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
+github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
 github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
@@ -355,6 +359,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
+github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
 github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -456,6 +462,12 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
 github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4=
 github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0=
 github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
+github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
+github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
+github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
+github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
 github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
 github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -465,6 +477,8 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
+github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
+github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
 github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
 github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
 github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
@@ -480,6 +494,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
 go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
 go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
 go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
+go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=
+go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -719,6 +735,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=

+ 2 - 2
internal/handler/tcpforwarding.go

@@ -35,12 +35,12 @@ func (h *TcpforwardingHandler) AddTcpForwarding(ctx *gin.Context) {
 		return
 	}
 	defaults.SetDefaults(req)
-	res, err := h.tcpforwardingService.AddTcpForwarding(ctx, req)
+	err := h.tcpforwardingService.AddTcpForwarding(ctx, req)
 	if err != nil {
 		v1.HandleError(ctx, http.StatusInternalServerError, err, err.Error())
 		return
 	}
-	v1.HandleSuccess(ctx, res)
+	v1.HandleSuccess(ctx, nil)
 }
 
 func (h *TcpforwardingHandler) EditTcpForwarding(ctx *gin.Context) {

+ 15 - 4
internal/model/tcpforwarding.go

@@ -1,11 +1,22 @@
 package model
 
-import "gorm.io/gorm"
-
 type Tcpforwarding struct {
-	gorm.Model
+	Id                   int `gorm:"primary"`
+	HostId               int `gorm:"not null"`
+	RuleId               int `gorm:"not null"`
+	Tag                  string `gorm:"null"`
+	Port                 string `gorm:"not null"`
+	WafGatewayGroupId    int `gorm:"null"`
+	TcpLimitRuleId       int `gorm:"not null"`
+	CcCount              int `gorm:"default:0"`
+	CcDuration           string `gorm:"default:0s"`
+	CcBlockCount         int `gorm:"default:0"`
+	CcBlockDuration      string `gorm:"null"`
+	BackendProtocol      string `gorm:"default:tcp"`
+	BackendTimeout       string `gorm:"null"`
+	Comment              string `gorm:"null"`
 }
 
 func (m *Tcpforwarding) TableName() string {
-    return "tcpforwarding"
+    return "shd_waf_tcp"
 }

+ 18 - 4
internal/model/udpforwarding.go

@@ -1,11 +1,25 @@
 package model
 
-import "gorm.io/gorm"
-
 type UdpForWarding struct {
-	gorm.Model
+	Id                   int `gorm:"primary"`
+	HostId               int `gorm:"not null"`
+	RuleId               int `gorm:"not null"`
+	Tag                  string `gorm:"null"`
+	Port                 string `gorm:"not null"`
+	WafGatewayGroupId    int `gorm:"not null"`
+	UdpLimitRuleId       int `gorm:"not null"`
+	CcPacketCount        int `gorm:"null"`
+	CcPacketDuration     string `gorm:"null"`
+	CcPacketBlockCount   int `gorm:"null"`
+	CcPacketBlockDuration string `gorm:"null"`
+	CcCount              int `gorm:"null"`
+	CcDuration           string `gorm:"null"`
+	CcBlockCount         int `gorm:"null"`
+	CcBlockDuration      string `gorm:"null"`
+	SessionTimeout       string `gorm:"null"`
+	Comment              string `gorm:"null"`
 }
 
 func (m *UdpForWarding) TableName() string {
-    return "udp_for_warding"
+    return "shd_waf_udp"
 }

+ 24 - 4
internal/model/webforwarding.go

@@ -1,11 +1,31 @@
 package model
 
-import "gorm.io/gorm"
-
 type WebForwarding struct {
-	gorm.Model
+	Id                   int `gorm:"primary"`
+	HostId               int `gorm:"not null"`
+	RuleId               int `gorm:"not null"`
+	Tag                  string `gorm:"null"`
+	Port                 string `gorm:"not null"`
+	Domain               string `gorm:"null"`
+	CustomHost           string `gorm:"null"`
+	WafGatewayGroupId    int `gorm:"not null"`
+	WebLimitRuleId       int `gorm:"not null"`
+	CcCount              int `gorm:"null"`
+	CcDuration           string `gorm:"null"`
+	CcBlockCount         int `gorm:"null"`
+	CcBlockDuration      string `gorm:"null"`
+	Cc4xxCount           int `gorm:"null"`
+	Cc4xxDuration        string `gorm:"null"`
+	Cc4xxBlockCount      int `gorm:"null"`
+	Cc4xxBlockDuration   string `gorm:"null"`
+	Cc5xxCount           int `gorm:"null"`
+	Cc5xxDuration        string `gorm:"null"`
+	Cc5xxBlockCount      int `gorm:"null"`
+	Cc5xxBlockDuration   string `gorm:"null"`
+	IsHttps              int `gorm:"null"`
+	Comment              string `gorm:"null"`
 }
 
 func (m *WebForwarding) TableName() string {
-    return "web_forwarding"
+    return "shd_waf_web"
 }

+ 10 - 0
internal/repository/globallimit.go

@@ -11,6 +11,7 @@ type GlobalLimitRepository interface {
 	UpdateGlobalLimitByHostId(ctx context.Context, req *model.GlobalLimit) error
 	DeleteGlobalLimitByHostId(ctx context.Context, hostId int64) error
 	IsGlobalLimitExistByHostId(ctx context.Context, hostId int64) (bool, error)
+	GetGlobalLimitByHostId(ctx context.Context, hostId int64) (*model.GlobalLimit, error)
 }
 
 func NewGlobalLimitRepository(
@@ -62,3 +63,12 @@ func (r *globalLimitRepository) IsGlobalLimitExistByHostId(ctx context.Context,
 
 	return count > 0, nil
 }
+
+func (r *globalLimitRepository) GetGlobalLimitByHostId(ctx context.Context, hostId int64) (*model.GlobalLimit, error) {
+	var globalLimit model.GlobalLimit
+	if err := r.DB(ctx).Where("host_id = ?", hostId).First(&globalLimit).Error; err != nil {
+		return nil, err
+	}
+	return &globalLimit, nil
+
+}

+ 11 - 0
internal/repository/host.go

@@ -11,6 +11,7 @@ type HostRepository interface {
 	GetHostConfig(ctx context.Context, hostId int) ([]*model.Host, error)
 	GetProductConfigOption(ctx context.Context, id []int) ([]v1.ProductConfigOption, error)
 	GetProductConfigOptionSub(ctx context.Context, id []int) ([]v1.ProductConfigOptionSub, error)
+	GetDomainById(ctx context.Context, id int) (string, error)
 }
 
 func NewHostRepository(
@@ -54,3 +55,13 @@ func (r *hostRepository) GetProductConfigOptionSub(ctx context.Context, id []int
 	}
 	return res, nil
 }
+
+func (r *hostRepository) GetDomainById(ctx context.Context, id int) (string, error) {
+	var res string
+	if err := r.DB(ctx).Table("shd_host").
+		Where("id = ?", id).
+		Pluck("domain", &res).Error; err != nil {
+		return "", err
+	}
+	return res, nil
+}

+ 20 - 0
internal/repository/repository.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"github.com/glebarez/sqlite"
 	"github.com/go-nunu/nunu-layout-advanced/pkg/log"
+	"github.com/go-nunu/nunu-layout-advanced/pkg/mongo"
 	"github.com/go-nunu/nunu-layout-advanced/pkg/zapgorm2"
 	"github.com/redis/go-redis/v9"
 	"github.com/spf13/viper"
@@ -20,6 +21,7 @@ const ctxTxKey = "TxKey"
 type Repository struct {
 	db *gorm.DB
 	//rdb    *redis.Client
+	//mongodb *mongo.MongoDB
 	logger *log.Logger
 }
 
@@ -27,10 +29,12 @@ func NewRepository(
 	logger *log.Logger,
 	db *gorm.DB,
 	// rdb *redis.Client,
+	//mongodb *mongo.MongoDB,
 ) *Repository {
 	return &Repository{
 		db: db,
 		//rdb:    rdb,
+		//mongodb: mongodb,
 		logger: logger,
 	}
 }
@@ -149,3 +153,19 @@ func NewRedis(conf *viper.Viper) *redis.Client {
 
 	return rdb
 }
+
+func NewMongoDB(conf *viper.Viper) *mongo.MongoDB {
+	config := &mongo.Config{
+		URI:         conf.GetString("data.mongodb.uri"),
+		Database:    conf.GetString("data.mongodb.database"),
+		Timeout:     conf.GetDuration("data.mongodb.timeout"),
+		MaxPoolSize: conf.GetUint64("data.mongodb.max_pool_size"),
+	}
+
+	mongoDB, err := mongo.New(config)
+	if err != nil {
+		panic(fmt.Sprintf("mongodb error: %s", err.Error()))
+	}
+
+	return mongoDB
+}

+ 25 - 1
internal/repository/tcpforwarding.go

@@ -1,12 +1,15 @@
 package repository
 
 import (
-    "context"
+	"context"
 	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 )
 
 type TcpforwardingRepository interface {
 	GetTcpforwarding(ctx context.Context, id int64) (*model.Tcpforwarding, error)
+	AddTcpforwarding(ctx context.Context, req *model.Tcpforwarding) error
+	EditTcpforwarding(ctx context.Context, req *model.Tcpforwarding) error
+	DeleteTcpforwarding(ctx context.Context, id int64) error
 }
 
 func NewTcpforwardingRepository(
@@ -26,3 +29,24 @@ func (r *tcpforwardingRepository) GetTcpforwarding(ctx context.Context, id int64
 
 	return &tcpforwarding, nil
 }
+
+func (r *tcpforwardingRepository) AddTcpforwarding(ctx context.Context, req *model.Tcpforwarding) error {
+	if err := r.db.Create(&req).Error; err != nil {
+		return err
+	}
+	return nil
+}
+
+func (r *tcpforwardingRepository) EditTcpforwarding(ctx context.Context, req *model.Tcpforwarding) error {
+	if err := r.db.Updates(&req).Error; err != nil {
+		return err
+	}
+	return nil
+}
+
+func (r *tcpforwardingRepository) DeleteTcpforwarding(ctx context.Context, id int64) error {
+	if err := r.db.Where("id = ?", id).Delete(&model.Tcpforwarding{}).Error; err != nil {
+		return err
+	}
+	return nil
+}

+ 25 - 1
internal/repository/udpforwarding.go

@@ -1,12 +1,15 @@
 package repository
 
 import (
-    "context"
+	"context"
 	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 )
 
 type UdpForWardingRepository interface {
 	GetUdpForWarding(ctx context.Context, id int64) (*model.UdpForWarding, error)
+	AddUdpForwarding(ctx context.Context, req *model.UdpForWarding) error
+	EditUdpForwarding(ctx context.Context, req *model.UdpForWarding) error
+	DeleteUdpForwarding(ctx context.Context, id int64) error
 }
 
 func NewUdpForWardingRepository(
@@ -26,3 +29,24 @@ func (r *udpForWardingRepository) GetUdpForWarding(ctx context.Context, id int64
 
 	return &udpForWarding, nil
 }
+
+func (r *udpForWardingRepository) AddUdpForwarding(ctx context.Context, req *model.UdpForWarding) error {
+	if err := r.db.Create(&req).Error; err != nil {
+		return err
+	}
+	return nil
+}
+
+func (r *udpForWardingRepository) EditUdpForwarding(ctx context.Context, req *model.UdpForWarding) error {
+	if err := r.db.Updates(&req).Error; err != nil {
+		return err
+	}
+	return nil
+}
+
+func (r *udpForWardingRepository) DeleteUdpForwarding(ctx context.Context, id int64) error {
+	if err := r.db.Delete(&model.UdpForWarding{}, id).Error; err != nil {
+		return err
+	}
+	return nil
+}

+ 25 - 1
internal/repository/webforwarding.go

@@ -1,12 +1,15 @@
 package repository
 
 import (
-    "context"
+	"context"
 	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 )
 
 type WebForwardingRepository interface {
 	GetWebForwarding(ctx context.Context, id int64) (*model.WebForwarding, error)
+	AddWebForwarding(ctx context.Context, req *model.WebForwarding) error
+	EditWebForwarding(ctx context.Context, req *model.WebForwarding) error
+	DeleteWebForwarding(ctx context.Context, id int64) error
 }
 
 func NewWebForwardingRepository(
@@ -26,3 +29,24 @@ func (r *webForwardingRepository) GetWebForwarding(ctx context.Context, id int64
 
 	return &webForwarding, nil
 }
+
+func (r *webForwardingRepository) AddWebForwarding(ctx context.Context, req *model.WebForwarding) error {
+	if err := r.db.Create(&req).Error; err != nil {
+		return err
+	}
+	return nil
+}
+
+func (r *webForwardingRepository) EditWebForwarding(ctx context.Context, req *model.WebForwarding) error {
+	if err := r.db.Updates(&req).Error; err != nil {
+		return err
+	}
+	return nil
+}
+
+func (r *webForwardingRepository) DeleteWebForwarding(ctx context.Context, id int64) error {
+	if err := r.db.Where("id = ?", id).Delete(&model.WebForwarding{}).Error; err != nil {
+		return err
+	}
+	return nil
+}

+ 11 - 22
internal/service/globallimit.go

@@ -34,6 +34,7 @@ func NewGlobalLimitService(
 	udpLimit UdpLimitService,
 	webLimit WebLimitService,
 	gateWayGroup GatewayGroupService,
+	hostRep repository.HostRepository,
 ) GlobalLimitService {
 	return &globalLimitService{
 		Service:               service,
@@ -48,6 +49,7 @@ func NewGlobalLimitService(
 		udpLimit:              udpLimit,
 		webLimit:              webLimit,
 		gateWayGroup:          gateWayGroup,
+		hostRep:                hostRep,
 	}
 }
 
@@ -64,6 +66,7 @@ type globalLimitService struct {
 	udpLimit              UdpLimitService
 	webLimit              WebLimitService
 	gateWayGroup          GatewayGroupService
+	hostRep               repository.HostRepository
 }
 
 func (s *globalLimitService) GlobalLimitRequire(ctx context.Context, req v1.GlobalLimitRequest) (res v1.GlobalLimitRequireResponse, err error) {
@@ -82,9 +85,14 @@ func (s *globalLimitService) GlobalLimitRequire(ctx context.Context, req v1.Glob
 	if err != nil {
 		return v1.GlobalLimitRequireResponse{}, fmt.Errorf("获取配置限制失败: %w", err)
 	}
+
 	res.Bps = configCount.Bps
 	res.MaxBytesMonth = configCount.MaxBytesMonth
-	res.GlobalLimitName = strconv.Itoa(req.Uid) + "_" + strconv.Itoa(req.HostId) + "_" + req.Domain
+	domain, err := s.hostRep.GetDomainById(ctx, req.HostId)
+	if err != nil {
+		return v1.GlobalLimitRequireResponse{}, err
+	}
+	res.GlobalLimitName = strconv.Itoa(req.Uid) + "_" + strconv.Itoa(req.HostId) + "_" + domain
 	return res, nil
 }
 
@@ -123,17 +131,12 @@ func (s *globalLimitService) AddGlobalLimit(ctx context.Context, req v1.GlobalLi
 		return err
 	}
 	// 使用conc库并发执行API调用
-	var tcpLimitRuleId, udpLimitRuleId, webLimitRuleId, gateWayGroupId int
+	var tcpLimitRuleId, udpLimitRuleId, webLimitRuleId int
 	var mu sync.Mutex // 用于保护共享变量
 
 	// 为每个并发调用创建独立的请求参数(深拷贝)
 	// 避免共享同一个指针可能导致的数据竞争
 
-	// 创建网关组请求参数
-	gateWayReq := v1.AddGateWayGroupRequest{
-		Name:    require.GlobalLimitName,
-		Comment: req.Comment,
-	}
 
 	// 创建一个WaitGroup来协调多个并发任务
 	wg := conc.NewWaitGroup()
@@ -201,20 +204,6 @@ func (s *globalLimitService) AddGlobalLimit(ctx context.Context, req v1.GlobalLi
 		}
 	})
 
-	// 启动gatewayGroup调用
-	wg.Go(func() {
-		result, e := s.gateWayGroup.AddGatewayGroup(ctx, gateWayReq)
-		if e != nil {
-			// 只在修改共享的错误变量时加锁
-			mu.Lock()
-			err = e
-			mu.Unlock()
-		} else {
-			// 不需要加锁,因为gateWayGroupId只被这一个goroutine修改
-			gateWayGroupId = result
-		}
-	})
-
 	// 等待所有调用完成
 	wg.Wait()
 
@@ -230,7 +219,7 @@ func (s *globalLimitService) AddGlobalLimit(ctx context.Context, req v1.GlobalLi
 		TcpLimitRuleId:  tcpLimitRuleId,
 		UdpLimitRuleId:  udpLimitRuleId,
 		WebLimitRuleId:  webLimitRuleId,
-		GatewayGroupId:  gateWayGroupId,
+		GatewayGroupId:  5,
 	})
 	if err != nil {
 		return err

+ 53 - 68
internal/service/host.go

@@ -6,6 +6,7 @@ import (
 	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
 	"github.com/spf13/cast"
+	"strconv"
 	"strings"
 )
 
@@ -35,16 +36,10 @@ const (
 	ConfigRuleEntries          = "规则条目"
 	ConfigMaxBandwidth         = "高带宽转发规则条目"
 	ConfigSourceMachines       = "支持源机"
-	ConfigBps                  = "最大带宽"
-	ConfigMaxBytesMonth        = "每月流量"
-	ConfigTcpConnCount         = "TCP连接次数"
-	ConfigTcpConnDuration      = "TCP连接时长"
-	ConfigTcpMaxConnCount      = "TCP最大连接数"
-	ConfigUdpQosPacketCount    = "UDPQPS包数"
-	ConfigUdpQosPacketDuration = "UDPQPS周期"
-	ConfigUdpMaxConnCount      = "UDP最大会话数"
-	ConfigWebQpsCount          = "WebQPS连接次数"
-	ConfigWebQpsDuration       = "WebQPS周期"
+	ConfigBps                  = "带宽"
+	ConfigMaxBytesMonth        = "高防防护能力"
+	ConfigPortCount 		   = "防御端口数量"
+	ConfigDomainCount          = "防御域名(需要备案)"
 )
 
 // unitSuffixMap 存储需要去除的单位后缀
@@ -69,15 +64,26 @@ func (s *hostService) GetHostConfig(ctx context.Context, hostId int) ([]map[stri
 	if err != nil {
 		return nil, err
 	}
-	// 2. 收集ID和建立映射关系
+
+	// 2. 收集ID和建立映射关系 (优化部分)
 	var configIDs []int
-	var optionIDs []int
+	// 只收集那些我们需要查询详情的 option ID
+	var optionIDsToFetch []int
 	optionMap := make(map[int]int)
+	qtyMap := make(map[int]int)
+
 	for _, item := range configOptions {
 		configIDs = append(configIDs, item.Configid)
-		optionIDs = append(optionIDs, item.Optionid)
-		optionMap[item.Configid] = item.Optionid
+		qtyMap[item.Configid] = item.Qty
+
+		// 核心优化:只有当数量为0时,我们才需要Option的名称,
+		// 因此才需要记录其ID用于后续查询,并建立 configID -> optionID 的映射。
+		if item.Qty == 0 {
+			optionIDsToFetch = append(optionIDsToFetch, item.Optionid)
+			optionMap[item.Configid] = item.Optionid
+		}
 	}
+
 	// 3. 获取配置和选项数据
 	var configs []v1.ProductConfigOption
 	if len(configIDs) > 0 {
@@ -86,27 +92,37 @@ func (s *hostService) GetHostConfig(ctx context.Context, hostId int) ([]map[stri
 			return nil, err
 		}
 	}
+
+	// 只有在确实需要查询的情况下才执行
 	var options []v1.ProductConfigOptionSub
-	if len(optionIDs) > 0 {
-		options, err = s.hostRepository.GetProductConfigOptionSub(ctx, optionIDs)
+	if len(optionIDsToFetch) > 0 {
+		options, err = s.hostRepository.GetProductConfigOptionSub(ctx, optionIDsToFetch)
 		if err != nil {
 			return nil, err
 		}
 	}
+
 	// 4. 转换选项为关联数组
 	optionsByID := make(map[int]v1.ProductConfigOptionSub)
 	for _, option := range options {
 		optionsByID[option.ID] = option
 	}
 
-	// 5. 构建结果数据
+	// 5. 构建结果数据 (逻辑更清晰)
 	var data []map[string]string
 	for _, config := range configs {
-		optionID := optionMap[config.ID]
-
 		var optionName string
-		if opt, ok := optionsByID[optionID]; ok {
-			optionName = opt.OptionName
+
+		// 直接通过qtyMap判断,逻辑更直接
+		if qty := qtyMap[config.ID]; qty != 0 {
+			// 如果数量不为0,直接使用数量作为名称
+			optionName = strconv.Itoa(qty)
+		} else {
+			// 否则,我们知道它一定在 optionMap 和 optionsByID 中 (如果数据一致)
+			optionID := optionMap[config.ID] // 这个查找现在是必要的
+			if opt, ok := optionsByID[optionID]; ok {
+				optionName = opt.OptionName
+			}
 		}
 
 		data = append(data, map[string]string{
@@ -196,12 +212,24 @@ func (s *hostService) GetGlobalLimitConfig(ctx context.Context, hostId int) (v1.
 	if val, ok := configsMap[ConfigMaxBytesMonth]; ok {
 		data.MaxBytesMonth = val
 	}
+	if val, ok := configsMap[ConfigPortCount]; ok {
+		data.PortCount, err = cast.ToIntE(val)
+		if err != nil {
+			return data, err
+		}
+	}
+	if val, ok := configsMap[ConfigDomainCount]; ok {
+		data.DomainCount, err = cast.ToIntE(val)
+		if err != nil {
+			return data, err
+		}
+	}
 	return data, nil
 }
 
 // GetTcpLimitConfig 修正返回类型,并使用新的辅助函数
 func (s *hostService) GetTcpLimitConfig(ctx context.Context, hostId int) (v1.TcpLimitRequest, error) {
-	configsMap, err := s.getHostConfigsMap(ctx, hostId)
+	_, err := s.getHostConfigsMap(ctx, hostId)
 	if err != nil {
 		return v1.TcpLimitRequest{}, err
 	}
@@ -210,29 +238,12 @@ func (s *hostService) GetTcpLimitConfig(ctx context.Context, hostId int) (v1.Tcp
 		ConnDuration: "0s",
 		MaxConnCount: 0,
 	}
-	var parseErr error
-
-	if val, ok := configsMap[ConfigTcpConnCount]; ok {
-		data.ConnCount, parseErr = cast.ToIntE(val)
-		if parseErr != nil {
-			return data, parseErr
-		}
-	}
-	if val, ok := configsMap[ConfigTcpConnDuration]; ok {
-		data.ConnDuration = val
-	}
-	if val, ok := configsMap[ConfigTcpMaxConnCount]; ok {
-		data.MaxConnCount, parseErr = cast.ToIntE(val)
-		if parseErr != nil {
-			return data, parseErr
-		}
-	}
 	return data, nil // 返回结构体
 }
 
 // GetUdpLimitConfig
 func (s *hostService) GetUdpLimitConfig(ctx context.Context, hostId int) (v1.UdpLimitRequest, error) {
-	configsMap, err := s.getHostConfigsMap(ctx, hostId)
+	_, err := s.getHostConfigsMap(ctx, hostId)
 	if err != nil {
 		return v1.UdpLimitRequest{}, err
 	}
@@ -241,29 +252,12 @@ func (s *hostService) GetUdpLimitConfig(ctx context.Context, hostId int) (v1.Udp
 		QosPacketDuration: "0s",
 		MaxConnCount:      0,
 	}
-	var parseErr error
-
-	if val, ok := configsMap[ConfigUdpQosPacketCount]; ok {
-		data.QosPacketCount, parseErr = cast.ToIntE(val)
-		if parseErr != nil {
-			return data, parseErr
-		}
-	}
-	if val, ok := configsMap[ConfigUdpQosPacketDuration]; ok {
-		data.QosPacketDuration = val
-	}
-	if val, ok := configsMap[ConfigUdpMaxConnCount]; ok {
-		data.MaxConnCount, parseErr = cast.ToIntE(val)
-		if parseErr != nil {
-			return data, parseErr
-		}
-	}
 	return data, nil
 }
 
 // GetWebLimitConfig 修正返回类型,并使用新的辅助函数
 func (s *hostService) GetWebLimitConfig(ctx context.Context, hostId int) (v1.WebLimitRequest, error) {
-	configsMap, err := s.getHostConfigsMap(ctx, hostId)
+	_, err := s.getHostConfigsMap(ctx, hostId)
 	if err != nil {
 		return v1.WebLimitRequest{}, err
 	}
@@ -271,16 +265,7 @@ func (s *hostService) GetWebLimitConfig(ctx context.Context, hostId int) (v1.Web
 		QpsCount:    0,
 		QpsDuration: "0s",
 	}
-	var parseErr error
 
-	if val, ok := configsMap[ConfigWebQpsCount]; ok {
-		data.QpsCount, parseErr = cast.ToIntE(val)
-		if parseErr != nil {
-			return data, parseErr
-		}
-	}
-	if val, ok := configsMap[ConfigWebQpsDuration]; ok {
-		data.QpsDuration = val
-	}
+
 	return data, nil
 }

+ 1 - 1
internal/service/parser.go

@@ -99,7 +99,7 @@ func (s *parserService) GetRuleIdByColumnName(ctx context.Context, htmlBytes []b
 	// 3. 动态查找第一个匹配的“关键字列”的索引。
 	headerRow := doc.Find("table.table tbody tr:first-child")
 	if headerRow.Length() == 0 {
-		return "", fmt.Errorf("table header row not found")
+		return "", nil
 	}
 
 	keyColumnIndex := -1

+ 96 - 51
internal/service/tcpforwarding.go

@@ -6,12 +6,13 @@ import (
 	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/spf13/cast"
 	"strconv"
 )
 
 type TcpforwardingService interface {
 	GetTcpforwarding(ctx context.Context, id int64) (*model.Tcpforwarding, error)
-	AddTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) (string, error)
+	AddTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest)  error
 	EditTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) (string, error)
 	DeleteTcpForwarding(ctx context.Context, wafTcpId int) (string, error)
 }
@@ -22,6 +23,9 @@ func NewTcpforwardingService(
 	parser ParserService,
 	required RequiredService,
 	crawler CrawlerService,
+	globalRep repository.GlobalLimitRepository,
+	hostRep repository.HostRepository,
+	wafformatter WafFormatterService,
 ) TcpforwardingService {
 	return &tcpforwardingService{
 		Service:                 service,
@@ -29,6 +33,9 @@ func NewTcpforwardingService(
 		parser:                  parser,
 		required:                required,
 		crawler:                 crawler,
+		globalRep:               globalRep,
+		hostRep:                 hostRep,
+		wafformatter:            wafformatter,
 	}
 }
 
@@ -38,78 +45,116 @@ type tcpforwardingService struct {
 	parser                  ParserService
 	required                RequiredService
 	crawler                 CrawlerService
+	globalRep               repository.GlobalLimitRepository
+	hostRep      repository.HostRepository
+	wafformatter WafFormatterService
 }
 
 func (s *tcpforwardingService) GetTcpforwarding(ctx context.Context, id int64) (*model.Tcpforwarding, error) {
 	return s.tcpforwardingRepository.GetTcpforwarding(ctx, id)
 }
 
-func (s *tcpforwardingService) AddTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) (string, error) {
+func (s *tcpforwardingService) require(ctx context.Context,req v1.GlobalRequire) (v1.GlobalRequire, error) {
+	res, err := s.wafformatter.require(ctx, req, "tcp")
+	if err != nil {
+		return v1.GlobalRequire{}, err
+	}
+	return res, nil
+}
+
+func (s *tcpforwardingService) AddTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest)  error {
+	require, err := s.require(ctx, v1.GlobalRequire{
+		HostId: req.HostId,
+		Uid:    req.Uid,
+		Comment: req.TcpForwardingData.Comment,
+	})
+	if err != nil {
+		return  err
+	}
 	formData := map[string]interface{}{
-		"tag":                  req.Tag,
-		"port":                 req.Port,
-		"waf_gateway_group_id": req.WafGatewayGroupId,
-		"cc_count":             req.CcCount,
-		"cc_duration":          req.CcDuration,
-		"cc_block_count":       req.CcBlockCount,
-		"cc_block_duration":    req.CcBlockDuration,
-		"max_bytes_month":      req.MaxBytesMonth,
-		"conn_count":           req.ConnCount,
-		"conn_duration":        req.ConnDuration,
-		"max_conn_count":       req.MaxConnCount,
-		"bps":                  req.Bps,
-		"backend_protocol":     req.BackendProtocol,
-		"backend_timeout":      req.BackendTimeout,
-		"backend_list":         req.BackendList,
-		"allow_ip_list":        req.AllowIpList,
-		"deny_ip_list":         req.DenyIpList,
-		"access_rule":          req.AccessRule,
-		"comment":              req.Comment,
+		"tag":                  require.Tag,
+		"port":                 req.TcpForwardingData.Port,
+		"waf_gateway_group_id": require.WafGatewayGroupId,
+		"waf_tcp_limit_id": 	require.LimitRuleId,
+		"cc_count":             req.TcpForwardingData.CcCount,
+		"cc_duration":          req.TcpForwardingData.CcDuration,
+		"cc_block_count":       req.TcpForwardingData.CcBlockCount,
+		"cc_block_duration":    req.TcpForwardingData.CcBlockDuration,
+		"backend_protocol":     req.TcpForwardingData.BackendProtocol,
+		"backend_timeout":      req.TcpForwardingData.BackendTimeout,
+		"comment":              req.TcpForwardingData.Comment,
+		"backend_list":         req.TcpForwardingData.BackendList,
+		"allow_ip_list":        req.TcpForwardingData.AllowIpList,
+		"deny_ip_list":         req.TcpForwardingData.DenyIpList,
+		"access_rule":          req.TcpForwardingData.AccessRule,
 	}
 	respBody, err := s.required.SendForm(ctx, "admin/info/waf_tcp/new", "admin/new/waf_tcp", formData)
 	if err != nil {
-		return "", err
+		return err
 	}
 	// 解析响应内容中的 alert 消息
 	res, err := s.parser.ParseAlert(string(respBody))
 	if err != nil {
-		return "", err
+		return err
 	}
 	if res != "" {
-		return "", fmt.Errorf(res)
+		return fmt.Errorf(res)
 	}
-	wafTcpId, err := s.parser.GetRuleId(ctx, respBody)
+	wafTcpIdStr, err := s.parser.GetRuleId(ctx, respBody)
 	if err != nil {
-		return "", err
+		return err
 	}
-	fmt.Println("=================================================", wafTcpId)
-	return "", nil
+	wafTcpId, err := cast.ToIntE(wafTcpIdStr)
+	if err != nil {
+		return err
+	}
+
+	if err = s.tcpforwardingRepository.AddTcpforwarding(ctx, &model.Tcpforwarding{
+		HostId:  req.HostId,
+		RuleId: wafTcpId,
+		Port: strconv.Itoa(req.TcpForwardingData.Port),
+		Tag:     require.Tag,
+		Comment: req.TcpForwardingData.Comment,
+		WafGatewayGroupId: require.WafGatewayGroupId,
+		CcCount: req.TcpForwardingData.CcCount,
+		CcDuration: req.TcpForwardingData.CcDuration,
+		CcBlockCount: req.TcpForwardingData.CcBlockCount,
+		CcBlockDuration: req.TcpForwardingData.CcBlockDuration,
+		BackendProtocol: req.TcpForwardingData.BackendProtocol,
+		BackendTimeout: req.TcpForwardingData.BackendTimeout,
+	}) ; err != nil {
+		return err
+	}
+	return  nil
 }
 
 func (s *tcpforwardingService) EditTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) (string, error) {
+	require, err := s.require(ctx, v1.GlobalRequire{
+		HostId: req.HostId,
+		Uid:    req.Uid,
+		Comment: req.TcpForwardingData.Comment,
+	})
+	if err != nil {
+		return "", err
+	}
 	formData := map[string]interface{}{
-		"waf_tcp_id":           req.WafTcpId,
-		"tag":                  req.Tag,
-		"port":                 req.Port,
-		"waf_gateway_group_id": req.WafGatewayGroupId,
-		"cc_count":             req.CcCount,
-		"cc_duration":          req.CcDuration,
-		"cc_block_count":       req.CcBlockCount,
-		"cc_block_duration":    req.CcBlockDuration,
-		"max_bytes_month":      req.MaxBytesMonth,
-		"conn_count":           req.ConnCount,
-		"conn_duration":        req.ConnDuration,
-		"max_conn_count":       req.MaxConnCount,
-		"bps":                  req.Bps,
-		"backend_protocol":     req.BackendProtocol,
-		"backend_timeout":      req.BackendTimeout,
-		"backend_list":         req.BackendList,
-		"allow_ip_list":        req.AllowIpList,
-		"deny_ip_list":         req.DenyIpList,
-		"access_rule":          req.AccessRule,
-		"comment":              req.Comment,
-	}
-	respBody, err := s.required.SendForm(ctx, "admin/info/waf_tcp/edit?&__goadmin_edit_pk="+strconv.Itoa(req.WafTcpId), "admin/edit/waf_tcp", formData)
+		"tag":                  require.Tag,
+		"port":                 req.TcpForwardingData.Port,
+		"waf_gateway_group_id": require.WafGatewayGroupId,
+		"waf_tcp_limit_id": 	require.LimitRuleId,
+		"cc_count":             req.TcpForwardingData.CcCount,
+		"cc_duration":          req.TcpForwardingData.CcDuration,
+		"cc_block_count":       req.TcpForwardingData.CcBlockCount,
+		"cc_block_duration":    req.TcpForwardingData.CcBlockDuration,
+		"backend_protocol":     req.TcpForwardingData.BackendProtocol,
+		"backend_timeout":      req.TcpForwardingData.BackendTimeout,
+		"comment":              req.TcpForwardingData.Comment,
+		"backend_list":         req.TcpForwardingData.BackendList,
+		"allow_ip_list":        req.TcpForwardingData.AllowIpList,
+		"deny_ip_list":         req.TcpForwardingData.DenyIpList,
+		"access_rule":          req.TcpForwardingData.AccessRule,
+	}
+	respBody, err := s.required.SendForm(ctx, "admin/info/waf_tcp/edit?&__goadmin_edit_pk="+strconv.Itoa(req.TcpForwardingData.WafTcpId), "admin/edit/waf_tcp", formData)
 	if err != nil {
 		return "", err
 	}
@@ -130,4 +175,4 @@ func (s *tcpforwardingService) DeleteTcpForwarding(ctx context.Context, wafTcpId
 		return "", err
 	}
 	return res, nil
-}
+}

+ 43 - 46
internal/service/udpforwarding.go

@@ -22,6 +22,9 @@ func NewUdpForWardingService(
 	required RequiredService,
 	parser ParserService,
 	crawler CrawlerService,
+	globalRep repository.GlobalLimitRepository,
+	hostRep repository.HostRepository,
+	wafformatter WafFormatterService,
 ) UdpForWardingService {
 	return &udpForWardingService{
 		Service:                 service,
@@ -29,6 +32,9 @@ func NewUdpForWardingService(
 		required:                required,
 		parser:                  parser,
 		crawler:                 crawler,
+		globalRep:               globalRep,
+		hostRep:                 hostRep,
+		wafformatter:            wafformatter,
 	}
 }
 
@@ -38,36 +44,49 @@ type udpForWardingService struct {
 	required                RequiredService
 	parser                  ParserService
 	crawler                 CrawlerService
+	globalRep               repository.GlobalLimitRepository
+	hostRep      repository.HostRepository
+	wafformatter WafFormatterService
 }
 
+
+func (s *udpForWardingService) require(ctx context.Context,req v1.GlobalRequire) (v1.GlobalRequire, error) {
+	res, err := s.wafformatter.require(ctx, req, "udp")
+	if err != nil {
+		return v1.GlobalRequire{}, err
+	}
+	return res, nil
+}
 func (s *udpForWardingService) GetUdpForWarding(ctx context.Context, id int64) (*model.UdpForWarding, error) {
 	return s.udpForWardingRepository.GetUdpForWarding(ctx, id)
 }
 
 func (s *udpForWardingService) AddUdpForwarding(ctx context.Context, req *v1.UdpForwardingRequest) (string, error) {
+	require, err := s.require(ctx, v1.GlobalRequire{
+		HostId: req.HostId,
+		Uid:    req.Uid,
+		Comment: req.UdpForwardingData.Comment,
+	})
+	if err != nil {
+		return "", err
+	}
 	formData := map[string]interface{}{
-		"tag":                  req.Tag,
-		"port":                 req.Port,
-		"waf_gateway_group_id": req.WafGatewayGroupId,
-		"cc_packet_count":      req.CcPacketCount,
-		"cc_packet_duration":   req.CcPacketDuration,
-		"cc_count":             req.CcCount,
-		"cc_duration":          req.CcDuration,
-		"cc_block_count":       req.CcBlockCount,
-		"cc_block_duration":    req.CcBlockDuration,
-		"qos_packet_count":     req.QosPacketCount,
-		"qos_packet_duration":  req.QosPacketDuration,
-		"max_bytes_month":      req.MaxBytesMonth,
-		"max_conn_count":       req.MaxConnCount,
-		"session_timeout":      req.SessionTimeout,
-		"bps":                  req.Bps,
-		"backend_protocol":     req.BackendProtocol,
-		"backend_timeout":      req.BackendTimeout,
-		"backend_list":         req.BackendList,
-		"allow_ip_list":        req.AllowIpList,
-		"deny_ip_list":         req.DenyIpList,
-		"access_rule":          req.AccessRule,
-		"comment":              req.Comment,
+		"tag":               require.Tag,
+		"port":              req.UdpForwardingData.Port,
+		"waf_gateway_group_id": require.WafGatewayGroupId,
+		"waf_udp_limit_id":     require.LimitRuleId,
+		"cc_packet_count":      req.UdpForwardingData.CcPacketCount,
+		"cc_packet_duration":   req.UdpForwardingData.CcPacketDuration,
+		"cc_count":             req.UdpForwardingData.CcCount,
+		"cc_duration":          req.UdpForwardingData.CcDuration,
+		"cc_block_count":       req.UdpForwardingData.CcBlockCount,
+		"cc_block_duration":    req.UdpForwardingData.CcBlockDuration,
+		"session_timeout":      req.UdpForwardingData.SessionTimeout,
+		"backend_list":         req.UdpForwardingData.BackendList,
+		"allow_ip_list":        req.UdpForwardingData.AllowIpList,
+		"deny_ip_list":         req.UdpForwardingData.DenyIpList,
+		"access_rule":          req.UdpForwardingData.AccessRule,
+		"comment":              req.UdpForwardingData.Comment,
 	}
 	respBody, err := s.required.SendForm(ctx, "admin/info/waf_udp/new", "admin/new/waf_udp", formData)
 	if err != nil {
@@ -92,31 +111,9 @@ func (s *udpForWardingService) AddUdpForwarding(ctx context.Context, req *v1.Udp
 
 func (s *udpForWardingService) EditUdpForwarding(ctx context.Context, req *v1.UdpForwardingRequest) (string, error) {
 	formData := map[string]interface{}{
-		"waf_udp_id":           req.WafUdpId,
-		"tag":                  req.Tag,
-		"port":                 req.Port,
-		"waf_gateway_group_id": req.WafGatewayGroupId,
-		"cc_packet_count":      req.CcPacketCount,
-		"cc_packet_duration":   req.CcPacketDuration,
-		"cc_count":             req.CcCount,
-		"cc_duration":          req.CcDuration,
-		"cc_block_count":       req.CcBlockCount,
-		"cc_block_duration":    req.CcBlockDuration,
-		"qos_packet_count":     req.QosPacketCount,
-		"qos_packet_duration":  req.QosPacketDuration,
-		"max_bytes_month":      req.MaxBytesMonth,
-		"max_conn_count":       req.MaxConnCount,
-		"session_timeout":      req.SessionTimeout,
-		"bps":                  req.Bps,
-		"backend_protocol":     req.BackendProtocol,
-		"backend_timeout":      req.BackendTimeout,
-		"backend_list":         req.BackendList,
-		"allow_ip_list":        req.AllowIpList,
-		"deny_ip_list":         req.DenyIpList,
-		"access_rule":          req.AccessRule,
-		"comment":              req.Comment,
+
 	}
-	respBody, err := s.required.SendForm(ctx, "admin/info/waf_udp/edit?&__goadmin_edit_pk="+strconv.Itoa(req.WafUdpId), "admin/edit/waf_udp", formData)
+	respBody, err := s.required.SendForm(ctx, "admin/info/waf_udp/edit?&__goadmin_edit_pk="+strconv.Itoa(req.UdpForwardingData.WafUdpId), "admin/edit/waf_udp", formData)
 	if err != nil {
 		return "", err
 	}

+ 45 - 44
internal/service/webforwarding.go

@@ -22,6 +22,7 @@ func NewWebForwardingService(
 	webForwardingRepository repository.WebForwardingRepository,
 	crawler CrawlerService,
 	parser ParserService,
+	wafformatter WafFormatterService,
 ) WebForwardingService {
 	return &webForwardingService{
 		Service:                 service,
@@ -29,6 +30,7 @@ func NewWebForwardingService(
 		required:                required,
 		parser:                  parser,
 		crawler:                 crawler,
+		wafformatter:            wafformatter,
 	}
 }
 
@@ -38,6 +40,15 @@ type webForwardingService struct {
 	required                RequiredService
 	parser                  ParserService
 	crawler                 CrawlerService
+	wafformatter 			WafFormatterService
+}
+
+func (s *webForwardingService) require(ctx context.Context,req v1.GlobalRequire) (v1.GlobalRequire, error) {
+	res, err := s.wafformatter.require(ctx, req, "web")
+	if err != nil {
+		return v1.GlobalRequire{}, err
+	}
+	return res, nil
 }
 
 func (s *webForwardingService) GetWebForwarding(ctx context.Context, id int64) (*model.WebForwarding, error) {
@@ -45,28 +56,39 @@ func (s *webForwardingService) GetWebForwarding(ctx context.Context, id int64) (
 }
 
 func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.WebForwardingRequest) (string, error) {
+	require, err := s.require(ctx, v1.GlobalRequire{
+		HostId: req.HostId,
+		Uid:    req.Uid,
+		Comment: req.WebForwardingData.Comment,
+	})
+	if err != nil {
+		return "", err
+	}
 	formData := map[string]interface{}{
-		"tag":                   req.Tag,
-		"port":                  req.Port,
-		"waf_gateway_group_id":  req.WafGatewayGroupId,
-		"backend":               req.Backend,
-		"is_https":              req.IsHttps,
-		"bps":                   req.QpsCount,
-		"max_bytes_month":       req.MaxBytesMonth,
-		"qps_count":             req.QpsCount,
-		"qps_duration":          req.QpsDuration,
-		"cc_count":              req.CcCount,
-		"cc_duration":           req.CcDuration,
-		"cc_block_count":        req.CcBlockCount,
-		"cc_block_duration":     req.CcBlockDuration,
-		"cc_4xx_count":          req.Cc4xxCount,
-		"cc_4xx_duration":       req.Cc4xxDuration,
-		"cc_4xx_block_count":    req.Cc4xxBlockCount,
-		"cc_4xx_block_duration": req.Cc4xxBlockDuration,
-		"cc_5xx_count":          req.Cc5xxCount,
-		"cc_5xx_duration":       req.Cc5xxDuration,
-		"cc_5xx_block_count":    req.Cc5xxBlockCount,
-		"cc_5xx_block_duration": req.Cc5xxBlockDuration,
+		"tag": req.WebForwardingData.Tag,
+		"port": req.WebForwardingData.Port,
+		"domain": req.WebForwardingData.Domain,
+		"custom_host": req.WebForwardingData.CustomHost,
+		"waf_gateway_group_id": require.WafGatewayGroupId,
+		"waf_web_limit_id": require.LimitRuleId,
+		"cc_count": req.WebForwardingData.CcCount,
+		"cc_duration": req.WebForwardingData.CcDuration,
+		"cc_block_count": req.WebForwardingData.CcBlockCount,
+		"cc_block_duration": req.WebForwardingData.CcBlockDuration,
+		"cc_4xx_count": req.WebForwardingData.Cc4xxCount,
+		"cc_4xx_duration": req.WebForwardingData.Cc4xxDuration,
+		"cc_4xx_block_count": req.WebForwardingData.Cc4xxBlockCount,
+		"cc_4xx_block_duration": req.WebForwardingData.Cc4xxBlockDuration,
+		"cc_5xx_count": req.WebForwardingData.Cc5xxCount,
+		"cc_5xx_duration": req.WebForwardingData.Cc5xxDuration,
+		"cc_5xx_block_count": req.WebForwardingData.Cc5xxBlockCount,
+		"cc_5xx_block_duration": req.WebForwardingData.Cc5xxBlockDuration,
+		"backend_list": req.WebForwardingData.BackendList,
+		"allow_ip_list": req.WebForwardingData.AllowIpList,
+		"deny_ip_list": req.WebForwardingData.DenyIpList,
+		"access_rule": req.WebForwardingData.AccessRule,
+		"is_https": req.WebForwardingData.IsHttps,
+		"comment": req.WebForwardingData.Comment,
 	}
 	respBody, err := s.required.SendForm(ctx, "admin/info/waf_web/new", "admin/new/waf_web", formData)
 	if err != nil {
@@ -90,30 +112,9 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 
 func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.WebForwardingRequest) (string, error) {
 	formData := map[string]interface{}{
-		"waf_web_id":            req.WafWebId,
-		"tag":                   req.Tag,
-		"port":                  req.Port,
-		"waf_gateway_group_id":  req.WafGatewayGroupId,
-		"backend":               req.Backend,
-		"is_https":              req.IsHttps,
-		"bps":                   req.QpsCount,
-		"max_bytes_month":       req.MaxBytesMonth,
-		"qps_count":             req.QpsCount,
-		"qps_duration":          req.QpsDuration,
-		"cc_count":              req.CcCount,
-		"cc_duration":           req.CcDuration,
-		"cc_block_count":        req.CcBlockCount,
-		"cc_block_duration":     req.CcBlockDuration,
-		"cc_4xx_count":          req.Cc4xxCount,
-		"cc_4xx_duration":       req.Cc4xxDuration,
-		"cc_4xx_block_count":    req.Cc4xxBlockCount,
-		"cc_4xx_block_duration": req.Cc4xxBlockDuration,
-		"cc_5xx_count":          req.Cc5xxCount,
-		"cc_5xx_duration":       req.Cc5xxDuration,
-		"cc_5xx_block_count":    req.Cc5xxBlockCount,
-		"cc_5xx_block_duration": req.Cc5xxBlockDuration,
+
 	}
-	respBody, err := s.required.SendForm(ctx, "admin/info/waf_web/edit?&__goadmin_edit_pk="+strconv.Itoa(req.WafWebId), "admin/edit/waf_web", formData)
+	respBody, err := s.required.SendForm(ctx, "admin/info/waf_web/edit?&__goadmin_edit_pk="+strconv.Itoa(req.WebForwardingData.WafWebId), "admin/edit/waf_web", formData)
 	if err != nil {
 		return "", err
 	}