Files
2026-07-29 18:59:07 +08:00

146 lines
4.1 KiB
Go

package dispute
import (
"context"
"strconv"
"strings"
"gorm.io/gorm"
)
func (r *Repository) ListForUser(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
conditions := r.userVisibleQuery(ctx, userID)
var total int64
if err := conditions.Count(&total).Error; err != nil {
return nil, err
}
offset := (page - 1) * pageSize
var rows []disputeRow
err := applyUserVisibleFilter(r.baseQuery(ctx), userID).
Order("d.id DESC").
Offset(offset).Limit(pageSize).
Scan(&rows).Error
if err != nil {
return nil, err
}
return &PaginatedResult{Items: toDTOs(rows), Total: total, Page: page, PageSize: pageSize}, nil
}
func (r *Repository) FindForUser(ctx context.Context, userID uint64, id uint64) (*DisputeDTO, error) {
var row disputeRow
if err := applyUserVisibleFilter(r.baseQuery(ctx).Where("d.id = ?", id), userID).
First(&row).Error; err != nil {
return nil, err
}
dto := row.toDTO()
return &dto, nil
}
func (r *Repository) ListAdmin(ctx context.Context, query AdminListQuery) (*PaginatedResult, error) {
var total int64
countDB := applyAdminListFilters(r.adminFilterQuery(ctx), query)
if err := countDB.Count(&total).Error; err != nil {
return nil, err
}
page := query.Page
pageSize := query.PageSize
if page < 1 {
page = 1
}
if pageSize < 1 {
pageSize = 20
}
offset := (page - 1) * pageSize
var rows []disputeRow
err := applyAdminListFilters(r.baseQuery(ctx), query).
Order("d.id DESC").
Offset(offset).
Limit(pageSize).
Scan(&rows).Error
if err != nil {
return nil, err
}
return &PaginatedResult{Items: toDTOs(rows), Total: total, Page: page, PageSize: pageSize}, nil
}
func (r *Repository) FindAdminByID(ctx context.Context, id uint64) (*DisputeDTO, error) {
var row disputeRow
if err := r.baseQuery(ctx).Where("d.id = ?", id).First(&row).Error; err != nil {
return nil, err
}
dto := row.toDTO()
return &dto, nil
}
func (r *Repository) userVisibleQuery(ctx context.Context, userID uint64) *gorm.DB {
return applyUserVisibleFilter(r.adminFilterQuery(ctx), userID)
}
func applyUserVisibleFilter(db *gorm.DB, userID uint64) *gorm.DB {
return db.Where(
`((d.initiator_type = ? AND d.initiator_id = ?) OR d.target_user_id = ? OR (d.initiator_type = ? AND (o.owner_id = ? OR o.renter_id = ?)))`,
disputeInitiatorUser,
userID,
userID,
disputeInitiatorAdmin,
userID,
userID,
)
}
func (r *Repository) baseQuery(ctx context.Context) *gorm.DB {
return r.adminFilterQuery(ctx).
Select(`d.*, o.order_no, o.status AS order_status, o.handoff_status, o.settlement_status,
o.owner_id, o.renter_id, o.extra_item_original_amount_cent,
owner.phone AS owner_phone, renter.phone AS renter_phone,
l.listing_no, a.title, c.coin_consumed_m AS checkout_coin_consumed_m,
c.consumable_amount_cent AS checkout_consumable_amount_cent`)
}
func (r *Repository) adminFilterQuery(ctx context.Context) *gorm.DB {
return r.db.WithContext(ctx).Table("disputes AS d").
Joins("JOIN rental_orders AS o ON o.id = d.order_id").
Joins("JOIN rental_listings AS l ON l.id = o.listing_id").
Joins("JOIN game_accounts AS a ON a.id = o.account_id").
Joins("JOIN users AS owner ON owner.id = o.owner_id").
Joins("JOIN users AS renter ON renter.id = o.renter_id").
Joins("LEFT JOIN order_checkouts AS c ON c.id = d.checkout_id")
}
func applyAdminListFilters(db *gorm.DB, query AdminListQuery) *gorm.DB {
if query.Status != "" {
db = db.Where("d.status = ?", query.Status)
}
if query.Type != "" {
db = db.Where("d.type = ?", query.Type)
}
if keyword := strings.TrimSpace(query.Keyword); keyword != "" {
like := "%" + keyword + "%"
if id, err := strconv.ParseUint(keyword, 10, 64); err == nil {
db = db.Where(
`(o.order_no LIKE ? OR l.listing_no LIKE ? OR a.title LIKE ? OR owner.phone LIKE ? OR renter.phone LIKE ? OR d.id = ? OR d.order_id = ? OR o.listing_id = ? OR o.owner_id = ? OR o.renter_id = ?)`,
like,
like,
like,
like,
like,
id,
id,
id,
id,
id,
)
} else {
db = db.Where(
`(o.order_no LIKE ? OR l.listing_no LIKE ? OR a.title LIKE ? OR owner.phone LIKE ? OR renter.phone LIKE ?)`,
like,
like,
like,
like,
like,
)
}
}
return db
}