package postgres import ( "context" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/store" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/middleware" "gorm.io/gorm" ) // RefundListFilters 退款列表筛选条件 type RefundListFilters struct { Status *int `json:"status"` OrderID *uint `json:"order_id"` ShopID *uint `json:"shop_id"` AssetIdentifier string `json:"asset_identifier"` } // RefundStore 退款申请数据访问层 type RefundStore struct { db *gorm.DB } // NewRefundStore 创建退款申请 Store 实例 func NewRefundStore(db *gorm.DB) *RefundStore { return &RefundStore{db: db} } // Create 创建退款申请记录 func (s *RefundStore) Create(ctx context.Context, req *model.RefundRequest) error { return s.db.WithContext(ctx).Create(req).Error } // GetByID 根据 ID 查询退款申请(含数据权限过滤) func (s *RefundStore) GetByID(ctx context.Context, id uint) (*model.RefundRequest, error) { var req model.RefundRequest query := s.db.WithContext(ctx). Model(&model.RefundRequest{}). Select("tb_refund_request.*, tb_shop.shop_name AS shop_name"). Joins("LEFT JOIN tb_shop ON tb_shop.id = tb_refund_request.shop_id AND tb_shop.deleted_at IS NULL"). Where("tb_refund_request.id = ?", id) query = applyRefundScope(ctx, query) if err := query.First(&req).Error; err != nil { return nil, err } return &req, nil } // Update 更新退款申请记录(全字段保存) func (s *RefundStore) Update(ctx context.Context, req *model.RefundRequest) error { return s.db.WithContext(ctx).Save(req).Error } // UpdateFields 按字段更新退款申请(用于条件更新场景) func (s *RefundStore) UpdateFields(ctx context.Context, id uint, updates map[string]any) error { return s.db.WithContext(ctx). Model(&model.RefundRequest{}). Where("id = ?", id). Updates(updates).Error } // List 分页查询退款申请列表(含数据权限过滤和筛选条件) func (s *RefundStore) List(ctx context.Context, opts *store.QueryOptions, filters *RefundListFilters) ([]*model.RefundRequest, int64, error) { var requests []*model.RefundRequest var total int64 query := s.db.WithContext(ctx). Model(&model.RefundRequest{}). Select("tb_refund_request.*, tb_shop.shop_name AS shop_name"). Joins("LEFT JOIN tb_shop ON tb_shop.id = tb_refund_request.shop_id AND tb_shop.deleted_at IS NULL") query = applyRefundScope(ctx, query) if filters != nil { if filters.Status != nil { query = query.Where("tb_refund_request.status = ?", *filters.Status) } if filters.OrderID != nil { query = query.Where("tb_refund_request.order_id = ?", *filters.OrderID) } if filters.ShopID != nil { query = query.Where("tb_refund_request.shop_id = ?", *filters.ShopID) } if filters.AssetIdentifier != "" { query = query.Where("tb_refund_request.asset_identifier = ?", filters.AssetIdentifier) } } if err := query.Count(&total).Error; err != nil { return nil, 0, err } if opts == nil { opts = &store.QueryOptions{ Page: 1, PageSize: constants.DefaultPageSize, } } offset := (opts.Page - 1) * opts.PageSize query = query.Offset(offset).Limit(opts.PageSize) if opts.OrderBy != "" { query = query.Order(opts.OrderBy) } else { query = query.Order("tb_refund_request.created_at DESC") } if err := query.Find(&requests).Error; err != nil { return nil, 0, err } return requests, total, nil } // applyRefundScope 应用退款单专属数据权限。 // 退款申请对代理按创建人隔离,避免上级代理通过店铺层级看到下级申请。 func applyRefundScope(ctx context.Context, query *gorm.DB) *gorm.DB { switch middleware.GetUserTypeFromContext(ctx) { case constants.UserTypeSuperAdmin, constants.UserTypePlatform: return query case constants.UserTypeAgent: userID := middleware.GetUserIDFromContext(ctx) if userID == 0 { return query.Where("1 = 0") } return query.Where("tb_refund_request.creator = ?", userID) default: return query.Where("1 = 0") } } // FindActiveByOrderID 查找订单关联的活跃退款申请(状态为待审批、已通过) func (s *RefundStore) FindActiveByOrderID(ctx context.Context, orderID uint) (*model.RefundRequest, error) { var req model.RefundRequest err := s.db.WithContext(ctx). Where("order_id = ? AND status IN ?", orderID, []int{ model.RefundStatusPending, model.RefundStatusApproved, }). First(&req).Error if err != nil { return nil, err } return &req, nil }