All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m9s
- 企业卡授权唯一约束:新增 DB 迁移(000154),卡级部分唯一索引防止同一张卡被多个企业同时持有,Service 层新增跨企业冲突检测 - 单卡列表新增 network_status 过滤参数 - 单卡/设备列表新增 asset_status、asset_status_name、generation 响应字段 - 单卡/设备列表新增企业维度过滤(authorized_enterprise_id、is_authorized_to_enterprise)及响应中企业授权信息(批量加载,无 N+1) - 主钱包流水/退款列表新增 asset_identifier 精确过滤参数 - 企业卡授权/收回接口升级为三模式(list/range/filter),企业设备授权/收回升级为双模式(list/filter) - 升级 sonic v1.14.2 → v1.15.2 以兼容 Go 1.26 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
147 lines
4.5 KiB
Go
147 lines
4.5 KiB
Go
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
|
|
}
|