From 57a59c7c76f21cb05ccc04fdbdfb71cc51d6bd25 Mon Sep 17 00:00:00 2001 From: chiyi Date: Wed, 1 Jul 2026 16:44:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B1=95=E7=A4=BA=E9=81=AE?= =?UTF-8?q?=E7=BD=A9=E6=8C=A1=E4=BD=8F=20=E4=BF=AE=E5=A4=8D=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E5=AD=97=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/http/handler/user_generation.go | 4 +- backend/internal/http/handler/v1.go | 2 +- backend/internal/service/v1.go | 12 +++ frontend/src/components/MediaLightbox.vue | 84 +++++++------------ frontend/src/views/ImagesView.vue | 8 -- frontend/src/views/LogsView.vue | 12 ++- frontend/src/views/PlaygroundView.vue | 13 ++- frontend/src/views/UserLogsTableView.vue | 10 ++- frontend/src/views/UserLogsView.vue | 8 -- 9 files changed, 75 insertions(+), 78 deletions(-) diff --git a/backend/internal/http/handler/user_generation.go b/backend/internal/http/handler/user_generation.go index a38af9b..d432657 100644 --- a/backend/internal/http/handler/user_generation.go +++ b/backend/internal/http/handler/user_generation.go @@ -70,7 +70,7 @@ func (h *UserGenerationHandler) Generate(c *gin.Context) { switch { case errors.Is(err, service.ErrUnknownModel): c.JSON(http.StatusNotFound, gin.H{"detail": err.Error()}) - case errors.Is(err, service.ErrUnsupportedParams): + case errors.Is(err, service.ErrUnsupportedParams), errors.Is(err, service.ErrPromptTooLong): c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) case errors.Is(err, service.ErrInsufficientFunds): c.JSON(http.StatusPaymentRequired, gin.H{"detail": "积分不足"}) @@ -132,7 +132,7 @@ func (h *UserGenerationHandler) Test(c *gin.Context) { switch { case errors.Is(err, service.ErrUnknownModel): c.JSON(http.StatusNotFound, gin.H{"detail": err.Error()}) - case errors.Is(err, service.ErrUnsupportedParams): + case errors.Is(err, service.ErrUnsupportedParams), errors.Is(err, service.ErrPromptTooLong): c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) case errors.Is(err, service.ErrProviderQuota): c.JSON(http.StatusTooManyRequests, gin.H{"detail": err.Error()}) diff --git a/backend/internal/http/handler/v1.go b/backend/internal/http/handler/v1.go index 4bd0827..a5a61af 100644 --- a/backend/internal/http/handler/v1.go +++ b/backend/internal/http/handler/v1.go @@ -316,7 +316,7 @@ func (h *V1Handler) writeV1Error(c *gin.Context, err error, payload map[string]a switch { case errors.Is(err, service.ErrUnknownModel): c.JSON(http.StatusNotFound, gin.H{"detail": err.Error()}) - case errors.Is(err, service.ErrUnsupportedParams): + case errors.Is(err, service.ErrUnsupportedParams), errors.Is(err, service.ErrPromptTooLong): c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) case errors.Is(err, service.ErrInsufficientFunds): c.JSON(http.StatusPaymentRequired, gin.H{"detail": err.Error()}) diff --git a/backend/internal/service/v1.go b/backend/internal/service/v1.go index 737639d..6f7c24b 100644 --- a/backend/internal/service/v1.go +++ b/backend/internal/service/v1.go @@ -14,6 +14,7 @@ import ( "sync" "sync/atomic" "time" + "unicode/utf8" "strconv" @@ -37,6 +38,7 @@ var ( ErrInvalidAPIKey = errors.New("invalid api key") ErrUnknownModel = errors.New("unknown model") ErrUnsupportedParams = errors.New("unsupported or unpriced parameters for this model") + ErrPromptTooLong = errors.New("prompt too long (max 2000 characters)") ErrInsufficientFunds = errors.New("insufficient credits") ErrGenerationPending = errors.New("generation executor not implemented yet") ErrProviderAuth = errors.New("provider token invalid or expired") @@ -57,6 +59,10 @@ var ( ErrVideoNotReady = errors.New("video is not ready yet") ) +// maxPromptRunes caps prompt length (counted as characters, so Chinese = 1), +// matching the 画图台 counter. Enforced for both 画图台 and API-key calls. +const maxPromptRunes = 2000 + // maxReferenceImageBytes bounds a single decoded reference image. 8 MB // comfortably covers real photos/screenshots; anything larger is almost // certainly abuse or a mistake. Mirrors Python core/refs.py. @@ -939,6 +945,9 @@ func (s *V1Service) prepareImage(ctx context.Context, principal *APIPrincipal, i if modelID == "" || prompt == "" { return nil, "", "", 0, errors.New("model and prompt required") } + if utf8.RuneCountInString(prompt) > maxPromptRunes { + return nil, "", "", 0, ErrPromptTooLong + } modelItem, err := s.models.Get(ctx, modelID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { @@ -1002,6 +1011,9 @@ func (s *V1Service) prepareVideo(ctx context.Context, principal *APIPrincipal, i if modelID == "" || prompt == "" { return nil, "", "", "", 0, errors.New("model and prompt required") } + if utf8.RuneCountInString(prompt) > maxPromptRunes { + return nil, "", "", "", 0, ErrPromptTooLong + } if duration == "" { return nil, "", "", "", 0, errors.New("duration required") } diff --git a/frontend/src/components/MediaLightbox.vue b/frontend/src/components/MediaLightbox.vue index 0fe4bf9..ff4cc09 100644 --- a/frontend/src/components/MediaLightbox.vue +++ b/frontend/src/components/MediaLightbox.vue @@ -1,72 +1,50 @@