From f5a1630a278bc96cab43d6f9d644e1254d55c7c5 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Fri, 3 Jul 2026 08:28:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(listing):=20=E7=BC=96=E8=BE=91=E5=B7=B2?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E8=B4=A6=E5=8F=B7=E9=9C=80=E5=85=88=E4=B8=8B?= =?UTF-8?q?=E6=9E=B6,=20=E7=BC=96=E5=8F=B7=E4=BF=9D=E6=8C=81=E4=B8=8D?= =?UTF-8?q?=E5=8F=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update 增加前置校验, 仅 draft/offline 状态可编辑, published 必须 先主动下架; 编辑后由 initialPublishState 推进到待审核, 审核通过 才重新展示. ListingNo 仅在 Create 时生成, 全程同行更新不变 --- .../internal/modules/listing/handler_error.go | 2 + backend/internal/modules/listing/mutation.go | 4 ++ backend/internal/modules/listing/service.go | 41 ++++++++++--------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/backend/internal/modules/listing/handler_error.go b/backend/internal/modules/listing/handler_error.go index 5a68bf3..8acf673 100644 --- a/backend/internal/modules/listing/handler_error.go +++ b/backend/internal/modules/listing/handler_error.go @@ -58,6 +58,8 @@ func writeListingError(c *gin.Context, err error) { response.BadRequest(c, "发布信息不符合规则") case errors.Is(err, ErrListingLocked): response.Error(c, http.StatusConflict, "listing_locked", "当前发布不可修改") + case errors.Is(err, ErrListingMustOfflineToEdit): + response.BadRequest(c, "请先下架后再编辑") case errors.Is(err, ErrPublishCooldown): response.Error(c, http.StatusTooManyRequests, "publish_cooldown", publishCooldownMessage(err)) case IsNotFound(err): diff --git a/backend/internal/modules/listing/mutation.go b/backend/internal/modules/listing/mutation.go index d65bb30..3157526 100644 --- a/backend/internal/modules/listing/mutation.go +++ b/backend/internal/modules/listing/mutation.go @@ -211,6 +211,10 @@ func (r *Repository) Update(ctx context.Context, ownerID uint64, listingID uint6 if listingLockedForOwnerMutation(listing) { return ErrListingLocked } + // 仅允许草稿/已下架状态编辑;已上架的必须先主动下架,避免在线编辑影响正在出租的账号 + if listing.Status != "draft" && listing.Status != "offline" { + return ErrListingMustOfflineToEdit + } account.Title = req.Title account.Description = req.Description diff --git a/backend/internal/modules/listing/service.go b/backend/internal/modules/listing/service.go index 16154a3..9c24f1d 100644 --- a/backend/internal/modules/listing/service.go +++ b/backend/internal/modules/listing/service.go @@ -8,26 +8,27 @@ import ( ) var ( - ErrDependencyUnavailable = errors.New("dependency unavailable") - ErrInvalidInput = errors.New("invalid listing input") - ErrListingLocked = errors.New("listing locked") - ErrPublishCooldown = errors.New("listing publish cooldown") - ErrMissingTitle = errors.New("missing listing title") - ErrMissingServerRegion = errors.New("missing server region") - ErrInvalidPrice = errors.New("invalid listing price") - ErrInvalidDeposit = errors.New("invalid listing deposit") - ErrDepositTooLow = errors.New("listing deposit too low") - ErrInvalidHafCoin = errors.New("invalid haf coin amount") - ErrMissingScreenshot = errors.New("missing screenshot") - ErrMissingOnlineTime = errors.New("missing online time") - ErrInvalidOnlineTime = errors.New("invalid online time") - ErrAgreementRequired = errors.New("listing publish agreement required") - ErrTargetOwnerInvalid = errors.New("target owner invalid") - ErrMissingUploaderName = errors.New("missing uploader name") - ErrMissingUploadData = errors.New("missing upload data") - ErrUploaderNotFound = errors.New("uploader not found") - ErrUploaderAmbiguous = errors.New("uploader ambiguous") - ErrTooManyUploadItems = errors.New("too many upload items") + ErrDependencyUnavailable = errors.New("dependency unavailable") + ErrInvalidInput = errors.New("invalid listing input") + ErrListingLocked = errors.New("listing locked") + ErrListingMustOfflineToEdit = errors.New("listing must be offline to edit") + ErrPublishCooldown = errors.New("listing publish cooldown") + ErrMissingTitle = errors.New("missing listing title") + ErrMissingServerRegion = errors.New("missing server region") + ErrInvalidPrice = errors.New("invalid listing price") + ErrInvalidDeposit = errors.New("invalid listing deposit") + ErrDepositTooLow = errors.New("listing deposit too low") + ErrInvalidHafCoin = errors.New("invalid haf coin amount") + ErrMissingScreenshot = errors.New("missing screenshot") + ErrMissingOnlineTime = errors.New("missing online time") + ErrInvalidOnlineTime = errors.New("invalid online time") + ErrAgreementRequired = errors.New("listing publish agreement required") + ErrTargetOwnerInvalid = errors.New("target owner invalid") + ErrMissingUploaderName = errors.New("missing uploader name") + ErrMissingUploadData = errors.New("missing upload data") + ErrUploaderNotFound = errors.New("uploader not found") + ErrUploaderAmbiguous = errors.New("uploader ambiguous") + ErrTooManyUploadItems = errors.New("too many upload items") ) type Service struct {