商品已完成优化
This commit is contained in:
@@ -208,7 +208,7 @@ func (r *Repository) Update(ctx context.Context, ownerID uint64, listingID uint6
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if listing.Status == "rented" || listing.InTransaction {
|
||||
if listingLockedForOwnerMutation(listing) {
|
||||
return ErrListingLocked
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ func (r *Repository) SubmitReview(ctx context.Context, ownerID uint64, listingID
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if listing.Status == "rented" || listing.InTransaction {
|
||||
if listingLockedForOwnerMutation(listing) {
|
||||
return ErrListingLocked
|
||||
}
|
||||
listingStatus, reviewStatus, publishedAt := initialPublishState(reviewRequired)
|
||||
@@ -346,7 +346,7 @@ func (r *Repository) Offline(ctx context.Context, ownerID uint64, listingID uint
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if listing.Status == "rented" || listing.InTransaction {
|
||||
if listingLockedForOwnerMutation(listing) {
|
||||
return ErrListingLocked
|
||||
}
|
||||
listing.Status = "offline"
|
||||
@@ -365,3 +365,10 @@ func (r *Repository) Offline(ctx context.Context, ownerID uint64, listingID uint
|
||||
})
|
||||
return dto, err
|
||||
}
|
||||
|
||||
func listingLockedForOwnerMutation(listing *model.RentalListing) bool {
|
||||
if listing == nil {
|
||||
return true
|
||||
}
|
||||
return listing.Status == "rented" || listing.Status == "completed" || listing.InTransaction
|
||||
}
|
||||
|
||||
@@ -213,6 +213,47 @@ func TestRepositoryUpdateAllowsOfflineListingResubmit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepositoryRejectsCompletedListingOwnerMutations(t *testing.T) {
|
||||
db := database.NewTestDB()
|
||||
if err := db.AutoMigrate(&model.GameAccount{}, &model.RentalListing{}); err != nil {
|
||||
t.Fatalf("failed to migrate test db: %v", err)
|
||||
}
|
||||
repo := NewRepository(db, nil)
|
||||
account := model.GameAccount{
|
||||
OwnerID: 1,
|
||||
GameName: "delta_force",
|
||||
ServerRegion: "QQ",
|
||||
LoginPlatform: "QQ账号密码",
|
||||
Title: "已完成账号",
|
||||
Status: "offline",
|
||||
}
|
||||
if err := db.Create(&account).Error; err != nil {
|
||||
t.Fatalf("failed to create account: %v", err)
|
||||
}
|
||||
listing := model.RentalListing{
|
||||
ListingNo: "202606270099",
|
||||
AccountID: account.ID,
|
||||
OwnerID: 1,
|
||||
Status: "completed",
|
||||
ReviewStatus: "approved",
|
||||
PriceCent: 10000,
|
||||
DepositAmountCent: 50000,
|
||||
}
|
||||
if err := db.Create(&listing).Error; err != nil {
|
||||
t.Fatalf("failed to create listing: %v", err)
|
||||
}
|
||||
|
||||
if _, err := repo.Update(t.Context(), 1, listing.ID, validCreateRequest(), false); err != ErrListingLocked {
|
||||
t.Fatalf("Update expected ErrListingLocked, got %v", err)
|
||||
}
|
||||
if _, err := repo.SubmitReview(t.Context(), 1, listing.ID, false); err != ErrListingLocked {
|
||||
t.Fatalf("SubmitReview expected ErrListingLocked, got %v", err)
|
||||
}
|
||||
if _, err := repo.Offline(t.Context(), 1, listing.ID); err != ErrListingLocked {
|
||||
t.Fatalf("Offline expected ErrListingLocked, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func validCreateRequest() CreateRequest {
|
||||
return CreateRequest{
|
||||
Title: "测试账号",
|
||||
|
||||
@@ -63,6 +63,13 @@ func archiveAssets(listing *model.RentalListing, account *model.GameAccount) {
|
||||
account.Status = accountStatusOffline
|
||||
}
|
||||
|
||||
func completeAssets(listing *model.RentalListing, account *model.GameAccount) {
|
||||
listing.Status = listingStatusCompleted
|
||||
listing.InTransaction = false
|
||||
listing.PublishedAt = nil
|
||||
account.Status = accountStatusOffline
|
||||
}
|
||||
|
||||
func markAssetsAbnormal(listing *model.RentalListing, account *model.GameAccount) {
|
||||
listing.Status = listingStatusAbnormal
|
||||
listing.InTransaction = false
|
||||
|
||||
@@ -21,7 +21,7 @@ func (r *Repository) finalizeCheckout(tx *gorm.DB, order *model.RentalOrder, che
|
||||
order.SettlementStatus = settlementStatusSettled
|
||||
order.SettledAt = &now
|
||||
order.OwnerSettledAt = &now
|
||||
archiveAssets(listing, account)
|
||||
completeAssets(listing, account)
|
||||
|
||||
settlement := buildCheckoutSettlement(*order, checkout)
|
||||
if err := appendCheckoutOwnerIncome(tx, order, settlement); err != nil {
|
||||
|
||||
@@ -47,6 +47,7 @@ const (
|
||||
listingStatusPublished = "published"
|
||||
listingStatusRented = "rented"
|
||||
listingStatusOffline = "offline"
|
||||
listingStatusCompleted = "completed"
|
||||
listingStatusAbnormal = "abnormal"
|
||||
|
||||
accountStatusPublished = "published"
|
||||
|
||||
@@ -165,6 +165,31 @@ func TestArchiveAssetsMovesListingOffline(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompleteAssetsMovesListingCompleted(t *testing.T) {
|
||||
now := time.Now()
|
||||
listing := model.RentalListing{
|
||||
Status: listingStatusRented,
|
||||
InTransaction: true,
|
||||
PublishedAt: &now,
|
||||
}
|
||||
account := model.GameAccount{Status: accountStatusRented}
|
||||
|
||||
completeAssets(&listing, &account)
|
||||
|
||||
if listing.Status != listingStatusCompleted {
|
||||
t.Fatalf("listing.Status = %q, want %q", listing.Status, listingStatusCompleted)
|
||||
}
|
||||
if listing.InTransaction {
|
||||
t.Fatal("listing.InTransaction = true, want false")
|
||||
}
|
||||
if listing.PublishedAt != nil {
|
||||
t.Fatal("listing.PublishedAt is not nil")
|
||||
}
|
||||
if account.Status != accountStatusOffline {
|
||||
t.Fatalf("account.Status = %q, want %q", account.Status, accountStatusOffline)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewOrderNoUsesShanghaiTimeWhenLocalIsUTC(t *testing.T) {
|
||||
oldLocal := time.Local
|
||||
time.Local = time.UTC
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
UPDATE rental_listings l
|
||||
JOIN rental_orders o ON o.listing_id = l.id
|
||||
SET l.status = 'completed',
|
||||
l.in_transaction = 0,
|
||||
l.published_at = NULL
|
||||
WHERE o.status = 'completed'
|
||||
AND l.status = 'offline';
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
|
||||
UPDATE rental_listings l
|
||||
JOIN rental_orders o ON o.listing_id = l.id
|
||||
SET l.status = 'offline',
|
||||
l.in_transaction = 0,
|
||||
l.published_at = NULL
|
||||
WHERE o.status = 'completed'
|
||||
AND l.status = 'completed';
|
||||
|
||||
-- +goose StatementEnd
|
||||
Reference in New Issue
Block a user