From 9b5ff89ee87ad8a7a21be3f876926257aab462fc Mon Sep 17 00:00:00 2001 From: shanshanzhong147 Date: Tue, 9 Jun 2026 22:56:40 -0700 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D(#17):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=AE=A2=E9=98=85=E6=B5=81=E9=87=8F=E9=99=90=E5=88=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=9C=AA=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes HIF-17 --- apis/admin/user.api | 2 +- .../admin/user/updateUserSubscribeHandler.go | 24 +++----------- .../user/updateUserSubscribeHandler_test.go | 2 +- .../admin/user/updateUserSubscribeLogic.go | 16 +++++++++- .../user/updateUserSubscribeLogic_test.go | 32 +++++++++++++++++++ internal/types/types.go | 16 +++++----- 6 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 internal/logic/admin/user/updateUserSubscribeLogic_test.go diff --git a/apis/admin/user.api b/apis/admin/user.api index d95d791..ce66cf2 100644 --- a/apis/admin/user.api +++ b/apis/admin/user.api @@ -152,7 +152,7 @@ type ( Upload int64 `json:"upload"` Download int64 `json:"download"` SpeedLimit *int64 `json:"speed_limit,omitempty" validate:"omitempty,gte=0"` - TrafficLimit *string `json:"traffic_limit,omitempty"` + TrafficLimit []TrafficLimit `json:"traffic_limit,omitempty"` } GetUserLoginLogsRequest { Page int `form:"page"` diff --git a/internal/handler/admin/user/updateUserSubscribeHandler.go b/internal/handler/admin/user/updateUserSubscribeHandler.go index 4d0c573..b6a3235 100644 --- a/internal/handler/admin/user/updateUserSubscribeHandler.go +++ b/internal/handler/admin/user/updateUserSubscribeHandler.go @@ -1,9 +1,6 @@ package user import ( - "encoding/json" - "errors" - "github.com/gin-gonic/gin" "github.com/perfect-panel/server/internal/logic/admin/user" "github.com/perfect-panel/server/internal/svc" @@ -15,31 +12,18 @@ import ( func UpdateUserSubscribeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { return func(c *gin.Context) { var req types.UpdateUserSubscribeRequest - _ = c.ShouldBind(&req) + if err := c.ShouldBind(&req); err != nil { + result.ParamErrorResult(c, err) + return + } validateErr := svcCtx.Validate(&req) if validateErr != nil { result.ParamErrorResult(c, validateErr) return } - if err := validateUpdateUserSubscribeTrafficLimit(&req); err != nil { - result.ParamErrorResult(c, err) - return - } l := user.NewUpdateUserSubscribeLogic(c.Request.Context(), svcCtx) err := l.UpdateUserSubscribe(&req) result.HttpResult(c, nil, err) } } - -func validateUpdateUserSubscribeTrafficLimit(req *types.UpdateUserSubscribeRequest) error { - if req.TrafficLimit == nil || *req.TrafficLimit == "" { - return nil - } - - var rules []types.TrafficLimit - if err := json.Unmarshal([]byte(*req.TrafficLimit), &rules); err != nil { - return errors.New("traffic_limit must be a valid JSON array") - } - return nil -} diff --git a/internal/handler/admin/user/updateUserSubscribeHandler_test.go b/internal/handler/admin/user/updateUserSubscribeHandler_test.go index 1e7affd..5a26dbf 100644 --- a/internal/handler/admin/user/updateUserSubscribeHandler_test.go +++ b/internal/handler/admin/user/updateUserSubscribeHandler_test.go @@ -24,7 +24,7 @@ func TestUpdateUserSubscribeHandlerRejectsInvalidLimits(t *testing.T) { body: `{"user_subscribe_id":1,"subscribe_id":1,"traffic":0,"expired_at":4102444800000,"upload":0,"download":0,"speed_limit":-1}`, }, { - name: "invalid traffic limit json", + name: "invalid traffic limit type", body: `{"user_subscribe_id":1,"subscribe_id":1,"traffic":0,"expired_at":4102444800000,"upload":0,"download":0,"traffic_limit":"not-json"}`, }, } diff --git a/internal/logic/admin/user/updateUserSubscribeLogic.go b/internal/logic/admin/user/updateUserSubscribeLogic.go index cb131fd..e557b66 100644 --- a/internal/logic/admin/user/updateUserSubscribeLogic.go +++ b/internal/logic/admin/user/updateUserSubscribeLogic.go @@ -2,6 +2,7 @@ package user import ( "context" + "encoding/json" "time" "github.com/perfect-panel/server/internal/model/user" @@ -45,7 +46,11 @@ func (l *UpdateUserSubscribeLogic) UpdateUserSubscribe(req *types.UpdateUserSubs } trafficLimit := userSub.TrafficLimit if req.TrafficLimit != nil { - trafficLimit = req.TrafficLimit + trafficLimit, err = marshalUserSubscribeTrafficLimit(req.TrafficLimit) + if err != nil { + l.Errorw("marshal traffic_limit failed:", logger.Field("error", err.Error())) + return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "marshal traffic_limit failed: %v", err.Error()) + } } err = l.svcCtx.UserModel.UpdateSubscribe(l.ctx, &user.Subscribe{ @@ -96,3 +101,12 @@ func (l *UpdateUserSubscribeLogic) UpdateUserSubscribe(req *types.UpdateUserSubs return nil } + +func marshalUserSubscribeTrafficLimit(rules []types.TrafficLimit) (*string, error) { + val, err := json.Marshal(rules) + if err != nil { + return nil, err + } + trafficLimit := string(val) + return &trafficLimit, nil +} diff --git a/internal/logic/admin/user/updateUserSubscribeLogic_test.go b/internal/logic/admin/user/updateUserSubscribeLogic_test.go new file mode 100644 index 0000000..b9d3fc4 --- /dev/null +++ b/internal/logic/admin/user/updateUserSubscribeLogic_test.go @@ -0,0 +1,32 @@ +package user + +import ( + "testing" + + "github.com/perfect-panel/server/internal/types" +) + +func TestMarshalUserSubscribeTrafficLimit(t *testing.T) { + rules := []types.TrafficLimit{ + { + StatType: "hour", + StatValue: 1, + TrafficUsage: 1, + SpeedLimit: 1, + }, + } + + got, err := marshalUserSubscribeTrafficLimit(rules) + if err != nil { + t.Fatalf("marshalUserSubscribeTrafficLimit() error = %v", err) + } + if got == nil { + t.Fatal("marshalUserSubscribeTrafficLimit() returned nil") + return + } + + want := `[{"stat_type":"hour","stat_value":1,"traffic_usage":1,"speed_limit":1}]` + if *got != want { + t.Fatalf("marshalUserSubscribeTrafficLimit() = %q, want %q", *got, want) + } +} diff --git a/internal/types/types.go b/internal/types/types.go index 2fda0e3..e865fc2 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -3546,14 +3546,14 @@ type UpdateUserSubscribeNoteRequest struct { } type UpdateUserSubscribeRequest struct { - UserSubscribeId int64 `json:"user_subscribe_id"` - SubscribeId int64 `json:"subscribe_id"` - Traffic int64 `json:"traffic"` - ExpiredAt int64 `json:"expired_at"` - Upload int64 `json:"upload"` - Download int64 `json:"download"` - SpeedLimit *int64 `json:"speed_limit,omitempty" validate:"omitempty,gte=0"` - TrafficLimit *string `json:"traffic_limit,omitempty"` + UserSubscribeId int64 `json:"user_subscribe_id"` + SubscribeId int64 `json:"subscribe_id"` + Traffic int64 `json:"traffic"` + ExpiredAt int64 `json:"expired_at"` + Upload int64 `json:"upload"` + Download int64 `json:"download"` + SpeedLimit *int64 `json:"speed_limit,omitempty" validate:"omitempty,gte=0"` + TrafficLimit []TrafficLimit `json:"traffic_limit,omitempty"` } type UpdateUserTicketStatusRequest struct {