继续补齐核心模块 Context 超时控制

This commit is contained in:
yml2213
2026-06-10 11:50:27 +08:00
parent 334436f381
commit d2858c529d
26 changed files with 552 additions and 515 deletions
+53 -52
View File
@@ -1,6 +1,7 @@
package listing
import (
"context"
"encoding/json"
"errors"
"fmt"
@@ -47,9 +48,9 @@ func initialPublishState(reviewRequired bool) (string, string, *time.Time) {
return "published", "approved", &now
}
func (r *Repository) Create(ownerID uint64, req CreateRequest, reviewRequired bool) (*ListingDTO, error) {
func (r *Repository) Create(ctx context.Context, ownerID uint64, req CreateRequest, reviewRequired bool) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listingNo, err := r.nextListingNo(tx, time.Now())
if err != nil {
return err
@@ -107,9 +108,9 @@ type externalUploadCreate struct {
ParsedPayload []byte
}
func (r *Repository) CreateFromExternalUpload(upload externalUploadCreate, req CreateRequest) (*ListingDTO, error) {
func (r *Repository) CreateFromExternalUpload(ctx context.Context, upload externalUploadCreate, req CreateRequest) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listingNo, err := r.nextListingNo(tx, time.Now())
if err != nil {
return err
@@ -182,9 +183,9 @@ func (r *Repository) CreateFromExternalUpload(upload externalUploadCreate, req C
return dto, err
}
func (r *Repository) Update(ownerID uint64, listingID uint64, req UpdateRequest, reviewRequired bool) (*ListingDTO, error) {
func (r *Repository) Update(ctx context.Context, ownerID uint64, listingID uint64, req UpdateRequest, reviewRequired bool) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listing, account, err := r.findOwnedForUpdate(tx, ownerID, listingID)
if err != nil {
return err
@@ -230,9 +231,9 @@ func (r *Repository) Update(ownerID uint64, listingID uint64, req UpdateRequest,
return dto, err
}
func (r *Repository) SubmitReview(ownerID uint64, listingID uint64, reviewRequired bool) (*ListingDTO, error) {
func (r *Repository) SubmitReview(ctx context.Context, ownerID uint64, listingID uint64, reviewRequired bool) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listing, account, err := r.findOwnedForUpdate(tx, ownerID, listingID)
if err != nil {
return err
@@ -258,9 +259,9 @@ func (r *Repository) SubmitReview(ownerID uint64, listingID uint64, reviewRequir
return dto, err
}
func (r *Repository) ListPendingReview() ([]ListingDTO, error) {
func (r *Repository) ListPendingReview(ctx context.Context) ([]ListingDTO, error) {
var rows []listingRow
err := r.baseQuery().
err := r.baseQuery(ctx).
Where("l.review_status = ? AND l.status <> ?", "pending", "offline").
Order("l.updated_at ASC, l.id ASC").
Limit(200).
@@ -271,7 +272,7 @@ func (r *Repository) ListPendingReview() ([]ListingDTO, error) {
return rowsToDTO(rows), nil
}
func (r *Repository) ListAdmin(query AdminListQuery) (*AdminListResult, error) {
func (r *Repository) ListAdmin(ctx context.Context, query AdminListQuery) (*AdminListResult, error) {
page := query.Page
if page <= 0 {
page = 1
@@ -287,13 +288,13 @@ func (r *Repository) ListAdmin(query AdminListQuery) (*AdminListResult, error) {
pageSize = 100
}
countDB := r.applyAdminListFilters(r.db.Table("rental_listings AS l"), query)
countDB := r.applyAdminListFilters(r.db.WithContext(ctx).Table("rental_listings AS l"), query)
var total int64
if err := countDB.Count(&total).Error; err != nil {
return nil, err
}
db := r.applyAdminListFilters(r.baseQuery(), query)
db := r.applyAdminListFilters(r.baseQuery(ctx), query)
offset := (page - 1) * pageSize
if offset < 0 {
offset = 0
@@ -386,21 +387,21 @@ func (r *Repository) ensureUploadOwnerUser(tx *gorm.DB, admin *model.AdminUser)
return &user, nil
}
func (r *Repository) FindAdmin(listingID uint64) (*ListingDTO, error) {
return r.findDTO("l.id = ?", listingID)
func (r *Repository) FindAdmin(ctx context.Context, listingID uint64) (*ListingDTO, error) {
return r.findDTO(ctx, "l.id = ?", listingID)
}
func (r *Repository) AdminOffline(adminID uint64, listingID uint64, req AdminActionRequest, meta AuditMeta) (*ListingDTO, error) {
return r.adminUpdateStatus(adminID, listingID, req, meta, "offline", "offline", "listing.admin_offline", "商品已被后台下架", "你的租号商品已被后台下架,请查看原因后处理。")
func (r *Repository) AdminOffline(ctx context.Context, adminID uint64, listingID uint64, req AdminActionRequest, meta AuditMeta) (*ListingDTO, error) {
return r.adminUpdateStatus(ctx, adminID, listingID, req, meta, "offline", "offline", "listing.admin_offline", "商品已被后台下架", "你的租号商品已被后台下架,请查看原因后处理。")
}
func (r *Repository) AdminMarkAbnormal(adminID uint64, listingID uint64, req AdminActionRequest, meta AuditMeta) (*ListingDTO, error) {
return r.adminUpdateStatus(adminID, listingID, req, meta, "abnormal", "abnormal", "listing.mark_abnormal", "商品已被标记异常", "你的租号商品已被后台标记异常,请联系客服处理。")
func (r *Repository) AdminMarkAbnormal(ctx context.Context, adminID uint64, listingID uint64, req AdminActionRequest, meta AuditMeta) (*ListingDTO, error) {
return r.adminUpdateStatus(ctx, adminID, listingID, req, meta, "abnormal", "abnormal", "listing.mark_abnormal", "商品已被标记异常", "你的租号商品已被后台标记异常,请联系客服处理。")
}
func (r *Repository) adminUpdateStatus(adminID uint64, listingID uint64, req AdminActionRequest, meta AuditMeta, listingStatus string, accountStatus string, action string, title string, content string) (*ListingDTO, error) {
func (r *Repository) adminUpdateStatus(ctx context.Context, adminID uint64, listingID uint64, req AdminActionRequest, meta AuditMeta, listingStatus string, accountStatus string, action string, title string, content string) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listing, account, err := r.findForReviewUpdate(tx, listingID)
if err != nil {
return err
@@ -453,9 +454,9 @@ func (r *Repository) adminUpdateStatus(adminID uint64, listingID uint64, req Adm
return dto, err
}
func (r *Repository) Approve(listingID uint64) (*ListingDTO, error) {
func (r *Repository) Approve(ctx context.Context, listingID uint64) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listing, account, err := r.findForReviewUpdate(tx, listingID)
if err != nil {
return err
@@ -492,9 +493,9 @@ func (r *Repository) Approve(listingID uint64) (*ListingDTO, error) {
return dto, err
}
func (r *Repository) AdjustReviewPrice(adminID uint64, listingID uint64, req AdminPriceAdjustRequest, meta AuditMeta) (*ListingDTO, error) {
func (r *Repository) AdjustReviewPrice(ctx context.Context, adminID uint64, listingID uint64, req AdminPriceAdjustRequest, meta AuditMeta) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listing, account, err := r.findForReviewUpdate(tx, listingID)
if err != nil {
return err
@@ -583,9 +584,9 @@ func (r *Repository) AdjustReviewPrice(adminID uint64, listingID uint64, req Adm
return dto, err
}
func (r *Repository) Reject(listingID uint64, req ReviewRequest) (*ListingDTO, error) {
func (r *Repository) Reject(ctx context.Context, listingID uint64, req ReviewRequest) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listing, account, err := r.findForReviewUpdate(tx, listingID)
if err != nil {
return err
@@ -621,9 +622,9 @@ func (r *Repository) Reject(listingID uint64, req ReviewRequest) (*ListingDTO, e
return dto, err
}
func (r *Repository) Offline(ownerID uint64, listingID uint64) (*ListingDTO, error) {
func (r *Repository) Offline(ctx context.Context, ownerID uint64, listingID uint64) (*ListingDTO, error) {
var dto *ListingDTO
err := r.db.Transaction(func(tx *gorm.DB) error {
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
listing, account, err := r.findOwnedForUpdate(tx, ownerID, listingID)
if err != nil {
return err
@@ -648,14 +649,14 @@ func (r *Repository) Offline(ownerID uint64, listingID uint64) (*ListingDTO, err
return dto, err
}
func (r *Repository) ListPublic(query PublicListQuery) (*PublicListResult, error) {
func (r *Repository) ListPublic(ctx context.Context, query PublicListQuery) (*PublicListResult, error) {
page, pageSize := normalizedPublicPage(query)
if canListPublicWithSQL(query) {
return r.listPublicPage(query, page, pageSize)
return r.listPublicPage(ctx, query, page, pageSize)
}
var rows []listingRow
err := r.baseQuery().
err := r.baseQuery(ctx).
Where("l.status = ? AND l.review_status = ? AND l.in_transaction = ?", "published", "approved", false).
Order("l.published_at DESC, l.id DESC").
Scan(&rows).Error
@@ -694,9 +695,9 @@ func (r *Repository) ListPublic(query PublicListQuery) (*PublicListResult, error
}, nil
}
func (r *Repository) listPublicPage(query PublicListQuery, page int, pageSize int) (*PublicListResult, error) {
func (r *Repository) listPublicPage(ctx context.Context, query PublicListQuery, page int, pageSize int) (*PublicListResult, error) {
var total int64
if err := r.db.Table("rental_listings AS l").
if err := r.db.WithContext(ctx).Table("rental_listings AS l").
Where("l.status = ? AND l.review_status = ? AND l.in_transaction = ?", "published", "approved", false).
Count(&total).Error; err != nil {
return nil, err
@@ -704,7 +705,7 @@ func (r *Repository) listPublicPage(query PublicListQuery, page int, pageSize in
var rows []listingRow
offset := (page - 1) * pageSize
err := applyPublicSQLSort(r.baseQuery(), query.Sort).
err := applyPublicSQLSort(r.baseQuery(ctx), query.Sort).
Where("l.status = ? AND l.review_status = ? AND l.in_transaction = ?", "published", "approved", false).
Limit(pageSize).
Offset(offset).
@@ -712,7 +713,7 @@ func (r *Repository) listPublicPage(query PublicListQuery, page int, pageSize in
if err != nil {
return nil, err
}
zoneCounts, err := r.publicZoneCountsCached()
zoneCounts, err := r.publicZoneCountsCached(ctx)
if err != nil {
return nil, err
}
@@ -786,7 +787,7 @@ func applyPublicSQLSort(db *gorm.DB, sortKey string) *gorm.DB {
}
}
func (r *Repository) publicZoneCountsCached() (map[string]int64, error) {
func (r *Repository) publicZoneCountsCached(ctx context.Context) (map[string]int64, error) {
now := time.Now()
r.publicZoneCountsMu.Lock()
defer r.publicZoneCountsMu.Unlock()
@@ -795,7 +796,7 @@ func (r *Repository) publicZoneCountsCached() (map[string]int64, error) {
}
var rows []publicZoneRow
err := r.db.Table("rental_listings AS l").
err := r.db.WithContext(ctx).Table("rental_listings AS l").
Select("a.login_platform, a.haf_coin_amount, a.asset_summary").
Joins("JOIN game_accounts AS a ON a.id = l.account_id").
Where("l.status = ? AND l.review_status = ? AND l.in_transaction = ?", "published", "approved", false).
@@ -844,9 +845,9 @@ func copyPublicZoneCounts(counts map[string]int64) map[string]int64 {
return copied
}
func (r *Repository) ListMine(ownerID uint64) ([]ListingDTO, error) {
func (r *Repository) ListMine(ctx context.Context, ownerID uint64) ([]ListingDTO, error) {
var rows []listingRow
err := r.baseQuery().
err := r.baseQuery(ctx).
Where("l.owner_id = ?", ownerID).
Order("l.id DESC").
Scan(&rows).Error
@@ -1232,8 +1233,8 @@ func timeRangeCoversHour(start int, end int, hour int) bool {
return hour >= start || hour <= end
}
func (r *Repository) FindPublic(id uint64) (*ListingDTO, error) {
dto, err := r.findDTO("l.id = ? AND l.status = ? AND l.review_status = ? AND l.in_transaction = ?", id, "published", "approved", false)
func (r *Repository) FindPublic(ctx context.Context, id uint64) (*ListingDTO, error) {
dto, err := r.findDTO(ctx, "l.id = ? AND l.status = ? AND l.review_status = ? AND l.in_transaction = ?", id, "published", "approved", false)
if err != nil {
return nil, err
}
@@ -1241,15 +1242,15 @@ func (r *Repository) FindPublic(id uint64) (*ListingDTO, error) {
return dto, nil
}
func (r *Repository) FindPublicCoverKey(id uint64) (string, error) {
return r.FindPublicScreenshotKey(id, 0)
func (r *Repository) FindPublicCoverKey(ctx context.Context, id uint64) (string, error) {
return r.FindPublicScreenshotKey(ctx, id, 0)
}
func (r *Repository) FindPublicScreenshotKey(id uint64, index int) (string, error) {
func (r *Repository) FindPublicScreenshotKey(ctx context.Context, id uint64, index int) (string, error) {
if index < 0 {
return "", gorm.ErrRecordNotFound
}
dto, err := r.findDTO("l.id = ? AND l.status = ? AND l.review_status = ? AND l.in_transaction = ?", id, "published", "approved", false)
dto, err := r.findDTO(ctx, "l.id = ? AND l.status = ? AND l.review_status = ? AND l.in_transaction = ?", id, "published", "approved", false)
if err != nil {
return "", err
}
@@ -1262,8 +1263,8 @@ func (r *Repository) FindPublicScreenshotKey(id uint64, index int) (string, erro
return "", gorm.ErrRecordNotFound
}
func (r *Repository) FindMine(ownerID uint64, id uint64) (*ListingDTO, error) {
dto, err := r.findDTO("l.id = ? AND l.owner_id = ?", id, ownerID)
func (r *Repository) FindMine(ctx context.Context, ownerID uint64, id uint64) (*ListingDTO, error) {
dto, err := r.findDTO(ctx, "l.id = ? AND l.owner_id = ?", id, ownerID)
if err != nil {
return nil, err
}
@@ -1283,9 +1284,9 @@ func (r *Repository) findOwnedForUpdate(tx *gorm.DB, ownerID uint64, listingID u
return &listing, &account, nil
}
func (r *Repository) findDTO(where string, args ...any) (*ListingDTO, error) {
func (r *Repository) findDTO(ctx context.Context, where string, args ...any) (*ListingDTO, error) {
var row listingRow
err := r.baseQuery().
err := r.baseQuery(ctx).
Where(where, args...).
First(&row).Error
if err != nil {
@@ -1295,8 +1296,8 @@ func (r *Repository) findDTO(where string, args ...any) (*ListingDTO, error) {
return &dto, nil
}
func (r *Repository) baseQuery() *gorm.DB {
return r.db.Table("rental_listings AS l").
func (r *Repository) baseQuery(ctx context.Context) *gorm.DB {
return r.db.WithContext(ctx).Table("rental_listings AS l").
Select(`l.*, a.title, a.description, a.game_name, a.server_region, a.login_platform, a.rank_level,
a.haf_coin_amount, a.asset_summary, a.screenshot_urls, COALESCE(u.phone, '') AS owner_phone, COALESCE(u.nickname, '') AS owner_nickname`).
Joins("JOIN game_accounts AS a ON a.id = l.account_id").