This commit is contained in:
2025-07-15 13:21:34 +08:00
parent 807004f78d
commit 83bf9aea7d
44 changed files with 9798 additions and 8 deletions

View File

@@ -0,0 +1,367 @@
package repositories
import (
"context"
"tyapi-server/internal/domains/product/entities"
"tyapi-server/internal/domains/product/repositories"
"tyapi-server/internal/domains/product/repositories/queries"
"tyapi-server/internal/shared/interfaces"
"go.uber.org/zap"
"gorm.io/gorm"
)
// GormProductCategoryRepository GORM产品分类仓储实现
type GormProductCategoryRepository struct {
db *gorm.DB
logger *zap.Logger
}
// 编译时检查接口实现
var _ repositories.ProductCategoryRepository = (*GormProductCategoryRepository)(nil)
// NewGormProductCategoryRepository 创建GORM产品分类仓储
func NewGormProductCategoryRepository(db *gorm.DB, logger *zap.Logger) repositories.ProductCategoryRepository {
return &GormProductCategoryRepository{
db: db,
logger: logger,
}
}
// Create 创建产品分类
func (r *GormProductCategoryRepository) Create(ctx context.Context, entity entities.ProductCategory) (entities.ProductCategory, error) {
r.logger.Info("创建产品分类", zap.String("id", entity.ID), zap.String("name", entity.Name))
err := r.db.WithContext(ctx).Create(&entity).Error
return entity, err
}
// GetByID 根据ID获取产品分类
func (r *GormProductCategoryRepository) GetByID(ctx context.Context, id string) (entities.ProductCategory, error) {
var entity entities.ProductCategory
err := r.db.WithContext(ctx).Where("id = ?", id).First(&entity).Error
return entity, err
}
// Update 更新产品分类
func (r *GormProductCategoryRepository) Update(ctx context.Context, entity entities.ProductCategory) error {
r.logger.Info("更新产品分类", zap.String("id", entity.ID))
return r.db.WithContext(ctx).Save(&entity).Error
}
// Delete 删除产品分类
func (r *GormProductCategoryRepository) Delete(ctx context.Context, id string) error {
r.logger.Info("删除产品分类", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.ProductCategory{}, "id = ?", id).Error
}
// FindByCode 根据编号查找产品分类
func (r *GormProductCategoryRepository) FindByCode(ctx context.Context, code string) (*entities.ProductCategory, error) {
var entity entities.ProductCategory
err := r.db.WithContext(ctx).Where("code = ?", code).First(&entity).Error
if err != nil {
return nil, err
}
return &entity, nil
}
// FindByParentID 根据父级ID查找产品分类
func (r *GormProductCategoryRepository) FindByParentID(ctx context.Context, parentID *string) ([]*entities.ProductCategory, error) {
var categories []entities.ProductCategory
query := r.db.WithContext(ctx)
if parentID == nil {
query = query.Where("parent_id IS NULL")
} else {
query = query.Where("parent_id = ?", *parentID)
}
err := query.Find(&categories).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.ProductCategory, len(categories))
for i := range categories {
result[i] = &categories[i]
}
return result, nil
}
// FindRootCategories 查找根分类
func (r *GormProductCategoryRepository) FindRootCategories(ctx context.Context) ([]*entities.ProductCategory, error) {
return r.FindByParentID(ctx, nil)
}
// FindVisible 查找可见分类
func (r *GormProductCategoryRepository) FindVisible(ctx context.Context) ([]*entities.ProductCategory, error) {
var categories []entities.ProductCategory
err := r.db.WithContext(ctx).Where("is_visible = ? AND is_enabled = ?", true, true).Find(&categories).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.ProductCategory, len(categories))
for i := range categories {
result[i] = &categories[i]
}
return result, nil
}
// FindEnabled 查找启用分类
func (r *GormProductCategoryRepository) FindEnabled(ctx context.Context) ([]*entities.ProductCategory, error) {
var categories []entities.ProductCategory
err := r.db.WithContext(ctx).Where("is_enabled = ?", true).Find(&categories).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.ProductCategory, len(categories))
for i := range categories {
result[i] = &categories[i]
}
return result, nil
}
// ListCategories 获取分类列表
func (r *GormProductCategoryRepository) ListCategories(ctx context.Context, query *queries.ListCategoriesQuery) ([]*entities.ProductCategory, int64, error) {
var categories []entities.ProductCategory
var total int64
dbQuery := r.db.WithContext(ctx).Model(&entities.ProductCategory{})
// 应用筛选条件
if query.ParentID != nil {
dbQuery = dbQuery.Where("parent_id = ?", *query.ParentID)
}
if query.IsEnabled != nil {
dbQuery = dbQuery.Where("is_enabled = ?", *query.IsEnabled)
}
if query.IsVisible != nil {
dbQuery = dbQuery.Where("is_visible = ?", *query.IsVisible)
}
// 获取总数
if err := dbQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用排序
if query.SortBy != "" {
order := query.SortBy
if query.SortOrder == "desc" {
order += " DESC"
} else {
order += " ASC"
}
dbQuery = dbQuery.Order(order)
} else {
dbQuery = dbQuery.Order("sort_order ASC, created_at DESC")
}
// 应用分页
if query.Page > 0 && query.PageSize > 0 {
offset := (query.Page - 1) * query.PageSize
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
}
// 获取数据
if err := dbQuery.Find(&categories).Error; err != nil {
return nil, 0, err
}
// 转换为指针切片
result := make([]*entities.ProductCategory, len(categories))
for i := range categories {
result[i] = &categories[i]
}
return result, total, nil
}
// GetCategoryTree 获取分类树
func (r *GormProductCategoryRepository) GetCategoryTree(ctx context.Context) ([]*entities.ProductCategory, error) {
var categories []entities.ProductCategory
err := r.db.WithContext(ctx).Where("is_enabled = ?", true).Order("sort_order ASC, created_at ASC").Find(&categories).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.ProductCategory, len(categories))
for i := range categories {
result[i] = &categories[i]
}
return result, nil
}
// FindCategoriesByLevel 根据层级查找分类
func (r *GormProductCategoryRepository) FindCategoriesByLevel(ctx context.Context, level int) ([]*entities.ProductCategory, error) {
var categories []entities.ProductCategory
err := r.db.WithContext(ctx).Where("level = ? AND is_enabled = ?", level, true).Find(&categories).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.ProductCategory, len(categories))
for i := range categories {
result[i] = &categories[i]
}
return result, nil
}
// FindCategoryPath 查找分类路径
func (r *GormProductCategoryRepository) FindCategoryPath(ctx context.Context, categoryID string) ([]*entities.ProductCategory, error) {
// 这里需要递归查找父级分类,简化实现
var entity entities.ProductCategory
err := r.db.WithContext(ctx).Where("id = ?", categoryID).First(&entity).Error
if err != nil {
return nil, err
}
result := []*entities.ProductCategory{&entity}
return result, nil
}
// CountByParent 统计父级下的分类数量
func (r *GormProductCategoryRepository) CountByParent(ctx context.Context, parentID *string) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.ProductCategory{})
if parentID == nil {
query = query.Where("parent_id IS NULL")
} else {
query = query.Where("parent_id = ?", *parentID)
}
err := query.Count(&count).Error
return count, err
}
// CountEnabled 统计启用分类数量
func (r *GormProductCategoryRepository) CountEnabled(ctx context.Context) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.ProductCategory{}).Where("is_enabled = ?", true).Count(&count).Error
return count, err
}
// CountVisible 统计可见分类数量
func (r *GormProductCategoryRepository) CountVisible(ctx context.Context) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.ProductCategory{}).Where("is_visible = ? AND is_enabled = ?", true, true).Count(&count).Error
return count, err
}
// 基础Repository接口方法
// Count 返回分类总数
func (r *GormProductCategoryRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.ProductCategory{})
// 应用筛选条件
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
// 应用搜索条件
if options.Search != "" {
query = query.Where("name LIKE ? OR description LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
}
err := query.Count(&count).Error
return count, err
}
// GetByIDs 根据ID列表获取分类
func (r *GormProductCategoryRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.ProductCategory, error) {
var categories []entities.ProductCategory
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&categories).Error
return categories, err
}
// CreateBatch 批量创建分类
func (r *GormProductCategoryRepository) CreateBatch(ctx context.Context, categories []entities.ProductCategory) error {
return r.db.WithContext(ctx).Create(&categories).Error
}
// UpdateBatch 批量更新分类
func (r *GormProductCategoryRepository) UpdateBatch(ctx context.Context, categories []entities.ProductCategory) error {
return r.db.WithContext(ctx).Save(&categories).Error
}
// DeleteBatch 批量删除分类
func (r *GormProductCategoryRepository) DeleteBatch(ctx context.Context, ids []string) error {
return r.db.WithContext(ctx).Delete(&entities.ProductCategory{}, "id IN ?", ids).Error
}
// List 获取分类列表(基础方法)
func (r *GormProductCategoryRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.ProductCategory, error) {
var categories []entities.ProductCategory
query := r.db.WithContext(ctx).Model(&entities.ProductCategory{})
// 应用筛选条件
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
// 应用搜索条件
if options.Search != "" {
query = query.Where("name LIKE ? OR description LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
}
// 应用排序
if options.Sort != "" {
order := options.Sort
if options.Order == "desc" {
order += " DESC"
} else {
order += " ASC"
}
query = query.Order(order)
}
// 应用分页
if options.Page > 0 && options.PageSize > 0 {
offset := (options.Page - 1) * options.PageSize
query = query.Offset(offset).Limit(options.PageSize)
}
err := query.Find(&categories).Error
return categories, err
}
// Exists 检查分类是否存在
func (r *GormProductCategoryRepository) Exists(ctx context.Context, id string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.ProductCategory{}).Where("id = ?", id).Count(&count).Error
return count > 0, err
}
// SoftDelete 软删除分类
func (r *GormProductCategoryRepository) SoftDelete(ctx context.Context, id string) error {
return r.db.WithContext(ctx).Delete(&entities.ProductCategory{}, "id = ?", id).Error
}
// Restore 恢复软删除的分类
func (r *GormProductCategoryRepository) Restore(ctx context.Context, id string) error {
return r.db.WithContext(ctx).Unscoped().Model(&entities.ProductCategory{}).Where("id = ?", id).Update("deleted_at", nil).Error
}
// WithTx 使用事务
func (r *GormProductCategoryRepository) WithTx(tx interface{}) interfaces.Repository[entities.ProductCategory] {
if gormTx, ok := tx.(*gorm.DB); ok {
return &GormProductCategoryRepository{
db: gormTx,
logger: r.logger,
}
}
return r
}

View File

@@ -0,0 +1,347 @@
package repositories
import (
"context"
"tyapi-server/internal/domains/product/entities"
"tyapi-server/internal/domains/product/repositories"
"tyapi-server/internal/domains/product/repositories/queries"
"tyapi-server/internal/shared/interfaces"
"go.uber.org/zap"
"gorm.io/gorm"
)
// GormProductRepository GORM产品仓储实现
type GormProductRepository struct {
db *gorm.DB
logger *zap.Logger
}
// 编译时检查接口实现
var _ repositories.ProductRepository = (*GormProductRepository)(nil)
// NewGormProductRepository 创建GORM产品仓储
func NewGormProductRepository(db *gorm.DB, logger *zap.Logger) repositories.ProductRepository {
return &GormProductRepository{
db: db,
logger: logger,
}
}
// Create 创建产品
func (r *GormProductRepository) Create(ctx context.Context, entity entities.Product) (entities.Product, error) {
r.logger.Info("创建产品", zap.String("id", entity.ID), zap.String("name", entity.Name))
err := r.db.WithContext(ctx).Create(&entity).Error
return entity, err
}
// GetByID 根据ID获取产品
func (r *GormProductRepository) GetByID(ctx context.Context, id string) (entities.Product, error) {
var entity entities.Product
err := r.db.WithContext(ctx).Where("id = ?", id).First(&entity).Error
return entity, err
}
// Update 更新产品
func (r *GormProductRepository) Update(ctx context.Context, entity entities.Product) error {
r.logger.Info("更新产品", zap.String("id", entity.ID))
return r.db.WithContext(ctx).Save(&entity).Error
}
// Delete 删除产品
func (r *GormProductRepository) Delete(ctx context.Context, id string) error {
r.logger.Info("删除产品", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.Product{}, "id = ?", id).Error
}
// FindByCode 根据编号查找产品
func (r *GormProductRepository) FindByCode(ctx context.Context, code string) (*entities.Product, error) {
var entity entities.Product
err := r.db.WithContext(ctx).Where("code = ?", code).First(&entity).Error
if err != nil {
return nil, err
}
return &entity, nil
}
// FindByCategoryID 根据分类ID查找产品
func (r *GormProductRepository) FindByCategoryID(ctx context.Context, categoryID string) ([]*entities.Product, error) {
var productEntities []entities.Product
err := r.db.WithContext(ctx).Where("category_id = ?", categoryID).Find(&productEntities).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Product, len(productEntities))
for i := range productEntities {
result[i] = &productEntities[i]
}
return result, nil
}
// FindVisible 查找可见产品
func (r *GormProductRepository) FindVisible(ctx context.Context) ([]*entities.Product, error) {
var productEntities []entities.Product
err := r.db.WithContext(ctx).Where("is_visible = ? AND is_enabled = ?", true, true).Find(&productEntities).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Product, len(productEntities))
for i := range productEntities {
result[i] = &productEntities[i]
}
return result, nil
}
// FindEnabled 查找启用产品
func (r *GormProductRepository) FindEnabled(ctx context.Context) ([]*entities.Product, error) {
var productEntities []entities.Product
err := r.db.WithContext(ctx).Where("is_enabled = ?", true).Find(&productEntities).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Product, len(productEntities))
for i := range productEntities {
result[i] = &productEntities[i]
}
return result, nil
}
// ListProducts 获取产品列表
func (r *GormProductRepository) ListProducts(ctx context.Context, query *queries.ListProductsQuery) ([]*entities.Product, int64, error) {
var productEntities []entities.Product
var total int64
dbQuery := r.db.WithContext(ctx).Model(&entities.Product{})
// 应用筛选条件
if query.Keyword != "" {
dbQuery = dbQuery.Where("name LIKE ? OR description LIKE ? OR code LIKE ?",
"%"+query.Keyword+"%", "%"+query.Keyword+"%", "%"+query.Keyword+"%")
}
if query.CategoryID != "" {
dbQuery = dbQuery.Where("category_id = ?", query.CategoryID)
}
if query.MinPrice != nil {
dbQuery = dbQuery.Where("price >= ?", *query.MinPrice)
}
if query.MaxPrice != nil {
dbQuery = dbQuery.Where("price <= ?", *query.MaxPrice)
}
if query.IsEnabled != nil {
dbQuery = dbQuery.Where("is_enabled = ?", *query.IsEnabled)
}
if query.IsVisible != nil {
dbQuery = dbQuery.Where("is_visible = ?", *query.IsVisible)
}
if query.IsPackage != nil {
dbQuery = dbQuery.Where("is_package = ?", *query.IsPackage)
}
// 获取总数
if err := dbQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用排序
if query.SortBy != "" {
order := query.SortBy
if query.SortOrder == "desc" {
order += " DESC"
} else {
order += " ASC"
}
dbQuery = dbQuery.Order(order)
} else {
dbQuery = dbQuery.Order("created_at DESC")
}
// 应用分页
if query.Page > 0 && query.PageSize > 0 {
offset := (query.Page - 1) * query.PageSize
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
}
// 获取数据
if err := dbQuery.Find(&productEntities).Error; err != nil {
return nil, 0, err
}
// 转换为指针切片
result := make([]*entities.Product, len(productEntities))
for i := range productEntities {
result[i] = &productEntities[i]
}
return result, total, nil
}
// FindSubscribableProducts 查找可订阅产品
func (r *GormProductRepository) FindSubscribableProducts(ctx context.Context, userID string) ([]*entities.Product, error) {
var productEntities []entities.Product
err := r.db.WithContext(ctx).Where("is_enabled = ? AND is_visible = ?", true, true).Find(&productEntities).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Product, len(productEntities))
for i := range productEntities {
result[i] = &productEntities[i]
}
return result, nil
}
// FindProductsByIDs 根据ID列表查找产品
func (r *GormProductRepository) FindProductsByIDs(ctx context.Context, ids []string) ([]*entities.Product, error) {
var productEntities []entities.Product
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&productEntities).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Product, len(productEntities))
for i := range productEntities {
result[i] = &productEntities[i]
}
return result, nil
}
// CountByCategory 统计分类下的产品数量
func (r *GormProductRepository) CountByCategory(ctx context.Context, categoryID string) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.Product{})
if categoryID != "" {
query = query.Where("category_id = ?", categoryID)
}
err := query.Count(&count).Error
return count, err
}
// CountEnabled 统计启用产品数量
func (r *GormProductRepository) CountEnabled(ctx context.Context) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Product{}).Where("is_enabled = ?", true).Count(&count).Error
return count, err
}
// CountVisible 统计可见产品数量
func (r *GormProductRepository) CountVisible(ctx context.Context) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Product{}).Where("is_visible = ? AND is_enabled = ?", true, true).Count(&count).Error
return count, err
}
// Count 返回产品总数
func (r *GormProductRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.Product{})
// 应用筛选条件
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
// 应用搜索条件
if options.Search != "" {
query = query.Where("name LIKE ? OR description LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
}
err := query.Count(&count).Error
return count, err
}
// GetByIDs 根据ID列表获取产品
func (r *GormProductRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.Product, error) {
var products []entities.Product
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&products).Error
return products, err
}
// CreateBatch 批量创建产品
func (r *GormProductRepository) CreateBatch(ctx context.Context, products []entities.Product) error {
return r.db.WithContext(ctx).Create(&products).Error
}
// UpdateBatch 批量更新产品
func (r *GormProductRepository) UpdateBatch(ctx context.Context, products []entities.Product) error {
return r.db.WithContext(ctx).Save(&products).Error
}
// DeleteBatch 批量删除产品
func (r *GormProductRepository) DeleteBatch(ctx context.Context, ids []string) error {
return r.db.WithContext(ctx).Delete(&entities.Product{}, "id IN ?", ids).Error
}
// List 获取产品列表(基础方法)
func (r *GormProductRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.Product, error) {
var products []entities.Product
query := r.db.WithContext(ctx).Model(&entities.Product{})
// 应用筛选条件
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
// 应用搜索条件
if options.Search != "" {
query = query.Where("name LIKE ? OR description LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
}
// 应用排序
if options.Sort != "" {
order := options.Sort
if options.Order == "desc" {
order += " DESC"
} else {
order += " ASC"
}
query = query.Order(order)
}
// 应用分页
if options.Page > 0 && options.PageSize > 0 {
offset := (options.Page - 1) * options.PageSize
query = query.Offset(offset).Limit(options.PageSize)
}
err := query.Find(&products).Error
return products, err
}
// Exists 检查产品是否存在
func (r *GormProductRepository) Exists(ctx context.Context, id string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Product{}).Where("id = ?", id).Count(&count).Error
return count > 0, err
}
// SoftDelete 软删除产品
func (r *GormProductRepository) SoftDelete(ctx context.Context, id string) error {
return r.db.WithContext(ctx).Delete(&entities.Product{}, "id = ?", id).Error
}
// Restore 恢复软删除的产品
func (r *GormProductRepository) Restore(ctx context.Context, id string) error {
return r.db.WithContext(ctx).Unscoped().Model(&entities.Product{}).Where("id = ?", id).Update("deleted_at", nil).Error
}
// WithTx 使用事务
func (r *GormProductRepository) WithTx(tx interface{}) interfaces.Repository[entities.Product] {
if gormTx, ok := tx.(*gorm.DB); ok {
return &GormProductRepository{
db: gormTx,
logger: r.logger,
}
}
return r
}

View File

@@ -0,0 +1,374 @@
package repositories
import (
"context"
"time"
"tyapi-server/internal/domains/product/entities"
"tyapi-server/internal/domains/product/repositories"
"tyapi-server/internal/domains/product/repositories/queries"
"tyapi-server/internal/shared/interfaces"
"go.uber.org/zap"
"gorm.io/gorm"
)
// GormSubscriptionRepository GORM订阅仓储实现
type GormSubscriptionRepository struct {
db *gorm.DB
logger *zap.Logger
}
// 编译时检查接口实现
var _ repositories.SubscriptionRepository = (*GormSubscriptionRepository)(nil)
// NewGormSubscriptionRepository 创建GORM订阅仓储
func NewGormSubscriptionRepository(db *gorm.DB, logger *zap.Logger) repositories.SubscriptionRepository {
return &GormSubscriptionRepository{
db: db,
logger: logger,
}
}
// Create 创建订阅
func (r *GormSubscriptionRepository) Create(ctx context.Context, entity entities.Subscription) (entities.Subscription, error) {
r.logger.Info("创建订阅", zap.String("id", entity.ID), zap.String("user_id", entity.UserID))
err := r.db.WithContext(ctx).Create(&entity).Error
return entity, err
}
// GetByID 根据ID获取订阅
func (r *GormSubscriptionRepository) GetByID(ctx context.Context, id string) (entities.Subscription, error) {
var entity entities.Subscription
err := r.db.WithContext(ctx).Where("id = ?", id).First(&entity).Error
return entity, err
}
// Update 更新订阅
func (r *GormSubscriptionRepository) Update(ctx context.Context, entity entities.Subscription) error {
r.logger.Info("更新订阅", zap.String("id", entity.ID))
return r.db.WithContext(ctx).Save(&entity).Error
}
// Delete 删除订阅
func (r *GormSubscriptionRepository) Delete(ctx context.Context, id string) error {
r.logger.Info("删除订阅", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.Subscription{}, "id = ?", id).Error
}
// FindByUserID 根据用户ID查找订阅
func (r *GormSubscriptionRepository) FindByUserID(ctx context.Context, userID string) ([]*entities.Subscription, error) {
var subscriptions []entities.Subscription
err := r.db.WithContext(ctx).Where("user_id = ?", userID).Find(&subscriptions).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, nil
}
// FindByProductID 根据产品ID查找订阅
func (r *GormSubscriptionRepository) FindByProductID(ctx context.Context, productID string) ([]*entities.Subscription, error) {
var subscriptions []entities.Subscription
err := r.db.WithContext(ctx).Where("product_id = ?", productID).Find(&subscriptions).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, nil
}
// FindByUserAndProduct 根据用户和产品查找订阅
func (r *GormSubscriptionRepository) FindByUserAndProduct(ctx context.Context, userID, productID string) (*entities.Subscription, error) {
var entity entities.Subscription
err := r.db.WithContext(ctx).Where("user_id = ? AND product_id = ?", userID, productID).First(&entity).Error
if err != nil {
return nil, err
}
return &entity, nil
}
// FindActive 查找活跃订阅
func (r *GormSubscriptionRepository) FindActive(ctx context.Context) ([]*entities.Subscription, error) {
var subscriptions []entities.Subscription
err := r.db.WithContext(ctx).Where("status = ?", entities.SubscriptionStatusActive).Find(&subscriptions).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, nil
}
// ListSubscriptions 获取订阅列表
func (r *GormSubscriptionRepository) ListSubscriptions(ctx context.Context, query *queries.ListSubscriptionsQuery) ([]*entities.Subscription, int64, error) {
var subscriptions []entities.Subscription
var total int64
dbQuery := r.db.WithContext(ctx).Model(&entities.Subscription{})
// 应用筛选条件
if query.UserID != "" {
dbQuery = dbQuery.Where("user_id = ?", query.UserID)
}
if query.ProductID != "" {
dbQuery = dbQuery.Where("product_id = ?", query.ProductID)
}
if query.Status != "" {
dbQuery = dbQuery.Where("status = ?", query.Status)
}
// 获取总数
if err := dbQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用排序
if query.SortBy != "" {
order := query.SortBy
if query.SortOrder == "desc" {
order += " DESC"
} else {
order += " ASC"
}
dbQuery = dbQuery.Order(order)
} else {
dbQuery = dbQuery.Order("created_at DESC")
}
// 应用分页
if query.Page > 0 && query.PageSize > 0 {
offset := (query.Page - 1) * query.PageSize
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
}
// 获取数据
if err := dbQuery.Find(&subscriptions).Error; err != nil {
return nil, 0, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, total, nil
}
// FindUserActiveSubscriptions 查找用户活跃订阅
func (r *GormSubscriptionRepository) FindUserActiveSubscriptions(ctx context.Context, userID string) ([]*entities.Subscription, error) {
var subscriptions []entities.Subscription
err := r.db.WithContext(ctx).Where("user_id = ? AND status = ?", userID, entities.SubscriptionStatusActive).Find(&subscriptions).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, nil
}
// FindExpiredSubscriptions 查找过期订阅
func (r *GormSubscriptionRepository) FindExpiredSubscriptions(ctx context.Context) ([]*entities.Subscription, error) {
var subscriptions []entities.Subscription
now := time.Now()
err := r.db.WithContext(ctx).Where("end_date IS NOT NULL AND end_date < ? AND status = ?", now, entities.SubscriptionStatusActive).Find(&subscriptions).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, nil
}
// FindSubscriptionsByStatus 根据状态查找订阅
func (r *GormSubscriptionRepository) FindSubscriptionsByStatus(ctx context.Context, status entities.SubscriptionStatus) ([]*entities.Subscription, error) {
var subscriptions []entities.Subscription
err := r.db.WithContext(ctx).Where("status = ?", status).Find(&subscriptions).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, nil
}
// FindSubscriptionsByDateRange 根据日期范围查找订阅
func (r *GormSubscriptionRepository) FindSubscriptionsByDateRange(ctx context.Context, startDate, endDate string) ([]*entities.Subscription, error) {
var subscriptions []entities.Subscription
err := r.db.WithContext(ctx).Where("created_at BETWEEN ? AND ?", startDate, endDate).Find(&subscriptions).Error
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
result[i] = &subscriptions[i]
}
return result, nil
}
// CountByUser 统计用户订阅数量
func (r *GormSubscriptionRepository) CountByUser(ctx context.Context, userID string) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Subscription{}).Where("user_id = ?", userID).Count(&count).Error
return count, err
}
// CountByProduct 统计产品订阅数量
func (r *GormSubscriptionRepository) CountByProduct(ctx context.Context, productID string) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Subscription{}).Where("product_id = ?", productID).Count(&count).Error
return count, err
}
// CountByStatus 根据状态统计订阅数量
func (r *GormSubscriptionRepository) CountByStatus(ctx context.Context, status entities.SubscriptionStatus) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Subscription{}).Where("status = ?", status).Count(&count).Error
return count, err
}
// CountActive 统计活跃订阅数量
func (r *GormSubscriptionRepository) CountActive(ctx context.Context) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Subscription{}).Where("status = ?", entities.SubscriptionStatusActive).Count(&count).Error
return count, err
}
// 基础Repository接口方法
// Count 返回订阅总数
func (r *GormSubscriptionRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.Subscription{})
// 应用筛选条件
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
// 应用搜索条件
if options.Search != "" {
query = query.Where("user_id LIKE ? OR product_id LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
}
err := query.Count(&count).Error
return count, err
}
// GetByIDs 根据ID列表获取订阅
func (r *GormSubscriptionRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.Subscription, error) {
var subscriptions []entities.Subscription
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&subscriptions).Error
return subscriptions, err
}
// CreateBatch 批量创建订阅
func (r *GormSubscriptionRepository) CreateBatch(ctx context.Context, subscriptions []entities.Subscription) error {
return r.db.WithContext(ctx).Create(&subscriptions).Error
}
// UpdateBatch 批量更新订阅
func (r *GormSubscriptionRepository) UpdateBatch(ctx context.Context, subscriptions []entities.Subscription) error {
return r.db.WithContext(ctx).Save(&subscriptions).Error
}
// DeleteBatch 批量删除订阅
func (r *GormSubscriptionRepository) DeleteBatch(ctx context.Context, ids []string) error {
return r.db.WithContext(ctx).Delete(&entities.Subscription{}, "id IN ?", ids).Error
}
// List 获取订阅列表(基础方法)
func (r *GormSubscriptionRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.Subscription, error) {
var subscriptions []entities.Subscription
query := r.db.WithContext(ctx).Model(&entities.Subscription{})
// 应用筛选条件
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
// 应用搜索条件
if options.Search != "" {
query = query.Where("user_id LIKE ? OR product_id LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
}
// 应用排序
if options.Sort != "" {
order := options.Sort
if options.Order == "desc" {
order += " DESC"
} else {
order += " ASC"
}
query = query.Order(order)
}
// 应用分页
if options.Page > 0 && options.PageSize > 0 {
offset := (options.Page - 1) * options.PageSize
query = query.Offset(offset).Limit(options.PageSize)
}
err := query.Find(&subscriptions).Error
return subscriptions, err
}
// Exists 检查订阅是否存在
func (r *GormSubscriptionRepository) Exists(ctx context.Context, id string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Subscription{}).Where("id = ?", id).Count(&count).Error
return count > 0, err
}
// SoftDelete 软删除订阅
func (r *GormSubscriptionRepository) SoftDelete(ctx context.Context, id string) error {
return r.db.WithContext(ctx).Delete(&entities.Subscription{}, "id = ?", id).Error
}
// Restore 恢复软删除的订阅
func (r *GormSubscriptionRepository) Restore(ctx context.Context, id string) error {
return r.db.WithContext(ctx).Unscoped().Model(&entities.Subscription{}).Where("id = ?", id).Update("deleted_at", nil).Error
}
// WithTx 使用事务
func (r *GormSubscriptionRepository) WithTx(tx interface{}) interfaces.Repository[entities.Subscription] {
if gormTx, ok := tx.(*gorm.DB); ok {
return &GormSubscriptionRepository{
db: gormTx,
logger: r.logger,
}
}
return r
}