From 78220deb0ebcf924fcf7809ec4ec1ef805895bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E8=BF=9B?= Date: Sat, 24 Oct 2026 15:22:17 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=BD=91=E5=85=B3=E9=99=90=E6=B5=81?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=96=87=E6=A1=A3=E8=A1=A5=E5=85=85=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E3=80=81=E7=B1=BB=E5=88=AB=E4=B8=8E=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 限流组与错误分类的操作数组元素改为具名类型 GatewayOperation,接口文档按元素给出可选值 - 匹配方式、错误类别、状态字段补充 enum 标签;高优先级操作说明补充取值与必填条件 --- internal/model/dto/gateway_rate_limit_dto.go | 56 +++++++++++-------- .../polling/gateway_rate_limit_service.go | 18 ++++-- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/internal/model/dto/gateway_rate_limit_dto.go b/internal/model/dto/gateway_rate_limit_dto.go index 93cf166b..3120d968 100644 --- a/internal/model/dto/gateway_rate_limit_dto.go +++ b/internal/model/dto/gateway_rate_limit_dto.go @@ -8,26 +8,34 @@ type RateLimitGroupListRequest struct { PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"` CarrierID *uint `json:"carrier_id" query:"carrier_id" validate:"omitempty" description:"运营商账户ID筛选"` OnlyGlobal bool `json:"only_global" query:"only_global" description:"只看全局组"` - Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1" description:"状态 (0:停用, 1:启用)"` + Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1" enum:"0,1" description:"状态 (0:停用, 1:启用)"` +} + +// GatewayOperation 卡网关操作(query_flow:查流量, query_status:查状态, query_realname:查实名, stop:停机, start:复机) +type GatewayOperation string + +// Enum 返回卡网关操作的全部取值,供接口文档生成数组元素枚举。 +func (GatewayOperation) Enum() []interface{} { + return []interface{}{"query_flow", "query_status", "query_realname", "stop", "start"} } // SaveRateLimitGroupRequest 新建或修改网关限流组请求 type SaveRateLimitGroupRequest struct { - ID uint `json:"-" description:"限流组ID"` - CarrierID *uint `json:"carrier_id" validate:"omitempty" description:"运营商账户ID,为空表示全局组"` - GroupCode string `json:"group_code" validate:"required,max=50" required:"true" maxLength:"50" description:"组标识,同一账户内唯一"` - GroupName string `json:"group_name" validate:"required,max=100" required:"true" maxLength:"100" description:"组名称"` - MaxQPS int `json:"max_qps" validate:"required,min=1,max=10000" required:"true" minimum:"1" maximum:"10000" description:"每秒请求上限"` - Operations []string `json:"operations" validate:"required,min=1,dive,oneof=query_flow query_status query_realname stop start" required:"true" description:"组内操作 (query_flow:查流量, query_status:查状态, query_realname:查实名, stop:停机, start:复机)"` - HighPriorityOperations []string `json:"high_priority_operations" validate:"omitempty,dive,oneof=query_flow query_status query_realname stop start" description:"高优先级操作,必须属于组内操作"` - ReservedQPS int `json:"reserved_qps" validate:"min=0" minimum:"0" description:"预留给高优先级操作的额度,须小于每秒请求上限"` - Status *int `json:"status" validate:"omitempty,oneof=0 1" description:"状态 (0:停用, 1:启用),新建默认启用"` + ID uint `json:"-" description:"限流组ID"` + CarrierID *uint `json:"carrier_id" validate:"omitempty" description:"运营商账户ID,为空表示全局组"` + GroupCode string `json:"group_code" validate:"required,max=50" required:"true" maxLength:"50" description:"组标识,同一账户内唯一"` + GroupName string `json:"group_name" validate:"required,max=100" required:"true" maxLength:"100" description:"组名称"` + MaxQPS int `json:"max_qps" validate:"required,min=1,max=10000" required:"true" minimum:"1" maximum:"10000" description:"每秒请求上限"` + Operations []GatewayOperation `json:"operations" validate:"required,min=1,dive,oneof=query_flow query_status query_realname stop start" required:"true" minItems:"1" description:"组内操作 (query_flow:查流量, query_status:查状态, query_realname:查实名, stop:停机, start:复机)"` + HighPriorityOperations []GatewayOperation `json:"high_priority_operations" validate:"omitempty,dive,oneof=query_flow query_status query_realname stop start" description:"高优先级操作,必须属于组内操作,设置预留额度时必填 (query_flow:查流量, query_status:查状态, query_realname:查实名, stop:停机, start:复机)"` + ReservedQPS int `json:"reserved_qps" validate:"min=0" minimum:"0" description:"预留给高优先级操作的额度,须小于每秒请求上限"` + Status *int `json:"status" validate:"omitempty,oneof=0 1" enum:"0,1" description:"状态 (0:停用, 1:启用),新建默认启用"` } // UpdateRateLimitGroupStatusRequest 启停网关限流组请求 type UpdateRateLimitGroupStatusRequest struct { ID uint `json:"-" path:"id" description:"限流组ID"` - Status *int `json:"status" validate:"required,oneof=0 1" required:"true" description:"状态 (0:停用, 1:启用);停用后组内操作回落为默认每秒请求上限"` + Status *int `json:"status" validate:"required,oneof=0 1" required:"true" enum:"0,1" description:"状态 (0:停用, 1:启用);停用后组内操作回落为默认每秒请求上限"` } // RateLimitGroupResponse 网关限流组响应 @@ -59,28 +67,28 @@ type RateLimitGroupPageResult struct { type GatewayErrorRuleListRequest struct { Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"` PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"` - Category string `json:"category" query:"category" validate:"omitempty,oneof=rate_limited_upstream terminal already_target transient business account_config" description:"类别筛选 (rate_limited_upstream:上游频率限制, terminal:终态不可操作, already_target:已是目标状态, transient:临时故障, business:业务错误, account_config:账户配置错误)"` - Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1" description:"状态 (0:停用, 1:启用)"` + Category string `json:"category" query:"category" validate:"omitempty,oneof=rate_limited_upstream terminal already_target transient business account_config" enum:"rate_limited_upstream,terminal,already_target,transient,business,account_config" description:"类别筛选 (rate_limited_upstream:上游频率限制, terminal:终态不可操作, already_target:已是目标状态, transient:临时故障, business:业务错误, account_config:账户配置错误)"` + Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1" enum:"0,1" description:"状态 (0:停用, 1:启用)"` Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=100" maxLength:"100" description:"关键字模糊搜索"` } // SaveGatewayErrorRuleRequest 新建或修改上游错误分类规则请求 type SaveGatewayErrorRuleRequest struct { - ID uint `json:"-" description:"规则ID"` - Keyword string `json:"keyword" validate:"required,max=200" required:"true" maxLength:"200" description:"匹配关键字或正则"` - MatchType string `json:"match_type" validate:"required,oneof=contains prefix regex" required:"true" description:"匹配方式 (contains:包含, prefix:前缀, regex:正则)"` - Category string `json:"category" validate:"required,oneof=rate_limited_upstream terminal already_target transient business account_config" required:"true" description:"类别 (rate_limited_upstream:上游频率限制, terminal:终态不可操作, already_target:已是目标状态, transient:临时故障, business:业务错误, account_config:账户配置错误)"` - Operations []string `json:"operations" validate:"omitempty,dive,oneof=query_flow query_status query_realname stop start" description:"适用操作,为空表示全部"` - Priority int `json:"priority" validate:"min=1,max=10000" minimum:"1" maximum:"10000" description:"匹配优先级,越小越先匹配"` - MaybeAccepted bool `json:"maybe_accepted" description:"上游可能已受理(如返回含调用成功、操作进行中、请求被合并)"` - Status *int `json:"status" validate:"omitempty,oneof=0 1" description:"状态 (0:停用, 1:启用),新建默认启用"` - Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注"` + ID uint `json:"-" description:"规则ID"` + Keyword string `json:"keyword" validate:"required,max=200" required:"true" maxLength:"200" description:"匹配关键字或正则"` + MatchType string `json:"match_type" validate:"required,oneof=contains prefix regex" required:"true" enum:"contains,prefix,regex" description:"匹配方式 (contains:包含, prefix:前缀, regex:正则)"` + Category string `json:"category" validate:"required,oneof=rate_limited_upstream terminal already_target transient business account_config" required:"true" enum:"rate_limited_upstream,terminal,already_target,transient,business,account_config" description:"类别 (rate_limited_upstream:上游频率限制, terminal:终态不可操作, already_target:已是目标状态, transient:临时故障, business:业务错误, account_config:账户配置错误)"` + Operations []GatewayOperation `json:"operations" validate:"omitempty,dive,oneof=query_flow query_status query_realname stop start" description:"适用操作,为空表示全部"` + Priority int `json:"priority" validate:"min=1,max=10000" minimum:"1" maximum:"10000" description:"匹配优先级,越小越先匹配"` + MaybeAccepted bool `json:"maybe_accepted" description:"上游可能已受理(如返回含调用成功、操作进行中、请求被合并)"` + Status *int `json:"status" validate:"omitempty,oneof=0 1" enum:"0,1" description:"状态 (0:停用, 1:启用),新建默认启用"` + Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注"` } // UpdateGatewayErrorRuleStatusRequest 启停上游错误分类规则请求 type UpdateGatewayErrorRuleStatusRequest struct { ID uint `json:"-" path:"id" description:"规则ID"` - Status *int `json:"status" validate:"required,oneof=0 1" required:"true" description:"状态 (0:停用, 1:启用)"` + Status *int `json:"status" validate:"required,oneof=0 1" required:"true" enum:"0,1" description:"状态 (0:停用, 1:启用)"` } // GatewayErrorRuleResponse 上游错误分类规则响应 @@ -109,7 +117,7 @@ type GatewayErrorRulePageResult struct { // TestGatewayErrorRuleRequest 测试上游错误分类请求 type TestGatewayErrorRuleRequest struct { - Operation string `json:"operation" validate:"required,oneof=query_flow query_status query_realname stop start" required:"true" description:"操作 (query_flow:查流量, query_status:查状态, query_realname:查实名, stop:停机, start:复机)"` + Operation string `json:"operation" validate:"required,oneof=query_flow query_status query_realname stop start" required:"true" enum:"query_flow,query_status,query_realname,stop,start" description:"操作 (query_flow:查流量, query_status:查状态, query_realname:查实名, stop:停机, start:复机)"` Message string `json:"message" validate:"required,max=1000" required:"true" maxLength:"1000" description:"上游返回信息"` Draft *SaveGatewayErrorRuleRequest `json:"draft" description:"未保存的规则草稿,传入时与已启用规则一起参与匹配(草稿按自身优先级排序)"` } diff --git a/internal/service/polling/gateway_rate_limit_service.go b/internal/service/polling/gateway_rate_limit_service.go index b001c728..aa027493 100644 --- a/internal/service/polling/gateway_rate_limit_service.go +++ b/internal/service/polling/gateway_rate_limit_service.go @@ -240,12 +240,12 @@ func (s *GatewayRateLimitService) validateGroup(ctx context.Context, req *dto.Sa if req.ReservedQPS >= req.MaxQPS { return errors.New(errors.CodeInvalidParam, "预留额度必须小于每秒请求上限") } - ops := uniqueStrings(req.Operations) + ops := uniqueStrings(operationStrings(req.Operations)) opSet := map[string]bool{} for _, op := range ops { opSet[op] = true } - for _, op := range req.HighPriorityOperations { + for _, op := range operationStrings(req.HighPriorityOperations) { if !opSet[op] { return errors.New(errors.CodeInvalidParam, "高优先级操作必须属于组内操作:"+constants.GatewayOperationName(op)) } @@ -304,8 +304,8 @@ func applyGroupRequest(row *model.CarrierRateLimitGroup, req *dto.SaveRateLimitG row.GroupName = strings.TrimSpace(req.GroupName) row.MaxQPS = req.MaxQPS row.ReservedQPS = req.ReservedQPS - row.Operations = encodeStrings(uniqueStrings(req.Operations)) - row.HighPriorityOperations = encodeStrings(uniqueStrings(req.HighPriorityOperations)) + row.Operations = encodeStrings(uniqueStrings(operationStrings(req.Operations))) + row.HighPriorityOperations = encodeStrings(uniqueStrings(operationStrings(req.HighPriorityOperations))) if req.Status != nil { row.Status = *req.Status } @@ -522,7 +522,7 @@ func applyRuleRequest(row *model.GatewayErrorClassification, req *dto.SaveGatewa row.Keyword = strings.TrimSpace(req.Keyword) row.MatchType = req.MatchType row.Category = req.Category - row.Operations = encodeStrings(uniqueStrings(req.Operations)) + row.Operations = encodeStrings(uniqueStrings(operationStrings(req.Operations))) row.Priority = req.Priority if row.Priority == 0 { row.Priority = 100 @@ -594,6 +594,14 @@ func uniqueStrings(values []string) []string { return out } +func operationStrings(values []dto.GatewayOperation) []string { + out := make([]string, 0, len(values)) + for _, value := range values { + out = append(out, string(value)) + } + return out +} + func encodeStrings(values []string) datatypes.JSON { if values == nil { values = []string{}