feat: 新增退款管理模块 — 完整的退款审批流程、佣金回扣和资产重置
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
新增退款申请全生命周期管理:创建/列表/详情/审批通过/拒绝/退回/重新提交 审批通过后异步执行佣金全额回扣(扣减各代理佣金钱包)和资产重置(套餐失效+停机+世代重置) 新增 tb_refund_request 表(迁移 000093)、RefundRequest Model、8 个 DTO 新增 Store/Service/Handler/路由注册,仅平台用户可访问
This commit is contained in:
119
internal/store/postgres/refund_store.go
Normal file
119
internal/store/postgres/refund_store.go
Normal file
@@ -0,0 +1,119 @@
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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).Where("id = ?", id)
|
||||
query = middleware.ApplyShopFilter(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{})
|
||||
query = middleware.ApplyShopFilter(ctx, query)
|
||||
|
||||
if filters != nil {
|
||||
if filters.Status != nil {
|
||||
query = query.Where("status = ?", *filters.Status)
|
||||
}
|
||||
if filters.OrderID != nil {
|
||||
query = query.Where("order_id = ?", *filters.OrderID)
|
||||
}
|
||||
if filters.ShopID != nil {
|
||||
query = query.Where("shop_id = ?", *filters.ShopID)
|
||||
}
|
||||
}
|
||||
|
||||
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("created_at DESC")
|
||||
}
|
||||
|
||||
if err := query.Find(&requests).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return requests, total, nil
|
||||
}
|
||||
|
||||
// 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,
|
||||
model.RefundStatusReturned,
|
||||
}).
|
||||
First(&req).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &req, nil
|
||||
}
|
||||
Reference in New Issue
Block a user