diff --git a/backend/internal/modules/listing/handler.go b/backend/internal/modules/listing/handler.go index 9918a74..0609b28 100644 --- a/backend/internal/modules/listing/handler.go +++ b/backend/internal/modules/listing/handler.go @@ -254,11 +254,12 @@ func (h *Handler) Offline(c *gin.Context) { if !ok { return } - if err := h.service.Offline(ownerID, id); err != nil { + item, err := h.service.Offline(ownerID, id) + if err != nil { writeListingError(c, err) return } - response.OK(c, gin.H{"offline": true}) + response.OK(c, item) } func (h *Handler) ListPublic(c *gin.Context) { diff --git a/backend/internal/modules/listing/repository.go b/backend/internal/modules/listing/repository.go index 8dd8794..d726d25 100644 --- a/backend/internal/modules/listing/repository.go +++ b/backend/internal/modules/listing/repository.go @@ -252,7 +252,7 @@ func (r *Repository) SubmitReview(ownerID uint64, listingID uint64, reviewRequir func (r *Repository) ListPendingReview() ([]ListingDTO, error) { var rows []listingRow err := r.baseQuery(). - Where("l.review_status = ?", "pending"). + Where("l.review_status = ? AND l.status <> ?", "pending", "offline"). Order("l.updated_at ASC, l.id ASC"). Limit(200). Scan(&rows).Error @@ -612,8 +612,9 @@ func (r *Repository) Reject(listingID uint64, req ReviewRequest) (*ListingDTO, e return dto, err } -func (r *Repository) Offline(ownerID uint64, listingID uint64) error { - return r.db.Transaction(func(tx *gorm.DB) error { +func (r *Repository) Offline(ownerID uint64, listingID uint64) (*ListingDTO, error) { + var dto *ListingDTO + err := r.db.Transaction(func(tx *gorm.DB) error { listing, account, err := r.findOwnedForUpdate(tx, ownerID, listingID) if err != nil { return err @@ -622,12 +623,20 @@ func (r *Repository) Offline(ownerID uint64, listingID uint64) error { return ErrListingLocked } listing.Status = "offline" + listing.ReviewStatus = "none" + listing.ReviewReason = "号主已手动下架" + listing.PublishedAt = nil account.Status = "offline" if err := tx.Save(account).Error; err != nil { return err } - return tx.Save(listing).Error + if err := tx.Save(listing).Error; err != nil { + return err + } + dto = toDTO(*account, *listing) + return nil }) + return dto, err } func (r *Repository) ListPublic(query PublicListQuery) (*PublicListResult, error) { @@ -1382,6 +1391,7 @@ func applySellerListingPrice(item *ListingDTO) { func (row listingRow) toDTO() ListingDTO { assetSummary := decodeAssetSummary(row.AssetSummary) screenshotURLS := cleanScreenshotURLs(decodeScreenshots(row.ScreenshotURLS)) + reviewStatus, reviewReason := normalizedReviewState(row.Status, row.ReviewStatus, row.ReviewReason) return ListingDTO{ ID: row.ID, AccountID: row.AccountID, @@ -1403,8 +1413,8 @@ func (row listingRow) toDTO() ListingDTO { IsAccelerated: isAcceleratedSale(assetSummary), InTransaction: row.InTransaction, Status: row.Status, - ReviewStatus: row.ReviewStatus, - ReviewReason: row.ReviewReason, + ReviewStatus: reviewStatus, + ReviewReason: reviewReason, PublishedAt: row.PublishedAt, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, @@ -1414,6 +1424,7 @@ func (row listingRow) toDTO() ListingDTO { func toDTO(account model.GameAccount, listing model.RentalListing) *ListingDTO { assetSummary := decodeAssetSummary(account.AssetSummary) screenshotURLS := cleanScreenshotURLs(decodeScreenshots(account.ScreenshotURLS)) + reviewStatus, reviewReason := normalizedReviewState(listing.Status, listing.ReviewStatus, listing.ReviewReason) return &ListingDTO{ ID: listing.ID, AccountID: account.ID, @@ -1433,14 +1444,21 @@ func toDTO(account model.GameAccount, listing model.RentalListing) *ListingDTO { IsAccelerated: isAcceleratedSale(assetSummary), InTransaction: listing.InTransaction, Status: listing.Status, - ReviewStatus: listing.ReviewStatus, - ReviewReason: listing.ReviewReason, + ReviewStatus: reviewStatus, + ReviewReason: reviewReason, PublishedAt: listing.PublishedAt, CreatedAt: listing.CreatedAt, UpdatedAt: listing.UpdatedAt, } } +func normalizedReviewState(status string, reviewStatus string, reviewReason string) (string, string) { + if status == "offline" { + return "none", reviewReason + } + return reviewStatus, reviewReason +} + func marshalScreenshots(urls []string) (datatypes.JSON, error) { cleaned := cleanScreenshotURLs(urls) if len(cleaned) > 12 { diff --git a/backend/internal/modules/listing/service.go b/backend/internal/modules/listing/service.go index 7227abe..dc2f639 100644 --- a/backend/internal/modules/listing/service.go +++ b/backend/internal/modules/listing/service.go @@ -266,9 +266,9 @@ func (s *Service) Reject(id uint64, req ReviewRequest) (*ListingDTO, error) { return s.repo.Reject(id, req) } -func (s *Service) Offline(ownerID uint64, id uint64) error { +func (s *Service) Offline(ownerID uint64, id uint64) (*ListingDTO, error) { if s.repo == nil { - return ErrDependencyUnavailable + return nil, ErrDependencyUnavailable } return s.repo.Offline(ownerID, id) } diff --git a/frontend/src/features/listings/api/listings.ts b/frontend/src/features/listings/api/listings.ts index 1f48e52..4bca5fb 100644 --- a/frontend/src/features/listings/api/listings.ts +++ b/frontend/src/features/listings/api/listings.ts @@ -129,7 +129,7 @@ export async function submitListingReview(id: number) { } export async function offlineListing(id: number) { - const { data } = await apiClient.delete>(`/listings/${id}`) + const { data } = await apiClient.delete>(`/listings/${id}`) return data.data } diff --git a/frontend/src/features/seller/views/SellerListingsView.vue b/frontend/src/features/seller/views/SellerListingsView.vue index ef1a6b8..f6e4b4b 100644 --- a/frontend/src/features/seller/views/SellerListingsView.vue +++ b/frontend/src/features/seller/views/SellerListingsView.vue @@ -1,13 +1,30 @@ + +