This commit is contained in:
2025-07-20 20:53:26 +08:00
parent 83bf9aea7d
commit 8ad1d7288e
158 changed files with 18156 additions and 13188 deletions

View File

@@ -2,13 +2,15 @@ package repositories
import (
"context"
"errors"
"go.uber.org/zap"
"gorm.io/gorm"
"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产品分类仓储实现
@@ -39,7 +41,13 @@ func (r *GormProductCategoryRepository) Create(ctx context.Context, entity entit
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
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return entities.ProductCategory{}, gorm.ErrRecordNotFound
}
return entities.ProductCategory{}, err
}
return entity, nil
}
// Update 更新产品分类
@@ -59,40 +67,14 @@ func (r *GormProductCategoryRepository) FindByCode(ctx context.Context, code str
var entity entities.ProductCategory
err := r.db.WithContext(ctx).Where("code = ?", code).First(&entity).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, gorm.ErrRecordNotFound
}
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
@@ -133,9 +115,6 @@ func (r *GormProductCategoryRepository) ListCategories(ctx context.Context, quer
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)
}
@@ -158,7 +137,8 @@ func (r *GormProductCategoryRepository) ListCategories(ctx context.Context, quer
}
dbQuery = dbQuery.Order(order)
} else {
dbQuery = dbQuery.Order("sort_order ASC, created_at DESC")
// 默认按排序字段和创建时间排序
dbQuery = dbQuery.Order("sort ASC, created_at ASC")
}
// 应用分页
@@ -181,66 +161,6 @@ func (r *GormProductCategoryRepository) ListCategories(ctx context.Context, quer
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

View File

@@ -2,6 +2,7 @@ package repositories
import (
"context"
"errors"
"tyapi-server/internal/domains/product/entities"
"tyapi-server/internal/domains/product/repositories"
"tyapi-server/internal/domains/product/repositories/queries"
@@ -38,8 +39,14 @@ func (r *GormProductRepository) Create(ctx context.Context, entity entities.Prod
// 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
err := r.db.WithContext(ctx).Preload("Category").Where("id = ?", id).First(&entity).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return entities.Product{}, gorm.ErrRecordNotFound
}
return entities.Product{}, err
}
return entity, nil
}
// Update 更新产品
@@ -57,8 +64,11 @@ func (r *GormProductRepository) Delete(ctx context.Context, id string) 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
err := r.db.WithContext(ctx).Preload("Category").Where("code = ?", code).First(&entity).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, gorm.ErrRecordNotFound
}
return nil, err
}
return &entity, nil
@@ -67,7 +77,7 @@ func (r *GormProductRepository) FindByCode(ctx context.Context, code string) (*e
// 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
err := r.db.WithContext(ctx).Preload("Category").Where("category_id = ?", categoryID).Find(&productEntities).Error
if err != nil {
return nil, err
}
@@ -83,7 +93,7 @@ func (r *GormProductRepository) FindByCategoryID(ctx context.Context, categoryID
// 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
err := r.db.WithContext(ctx).Preload("Category").Where("is_visible = ? AND is_enabled = ?", true, true).Find(&productEntities).Error
if err != nil {
return nil, err
}
@@ -99,7 +109,7 @@ func (r *GormProductRepository) FindVisible(ctx context.Context) ([]*entities.Pr
// 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
err := r.db.WithContext(ctx).Preload("Category").Where("is_enabled = ?", true).Find(&productEntities).Error
if err != nil {
return nil, err
}
@@ -167,8 +177,8 @@ func (r *GormProductRepository) ListProducts(ctx context.Context, query *queries
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
}
// 获取数据
if err := dbQuery.Find(&productEntities).Error; err != nil {
// 预加载分类信息并获取数据
if err := dbQuery.Preload("Category").Find(&productEntities).Error; err != nil {
return nil, 0, err
}

View File

@@ -2,14 +2,15 @@ package repositories
import (
"context"
"time"
"errors"
"go.uber.org/zap"
"gorm.io/gorm"
"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订阅仓储实现
@@ -40,7 +41,13 @@ func (r *GormSubscriptionRepository) Create(ctx context.Context, entity entities
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
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return entities.Subscription{}, gorm.ErrRecordNotFound
}
return entities.Subscription{}, err
}
return entity, nil
}
// Update 更新订阅
@@ -62,7 +69,7 @@ func (r *GormSubscriptionRepository) FindByUserID(ctx context.Context, userID st
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
@@ -78,7 +85,7 @@ func (r *GormSubscriptionRepository) FindByProductID(ctx context.Context, produc
if err != nil {
return nil, err
}
// 转换为指针切片
result := make([]*entities.Subscription, len(subscriptions))
for i := range subscriptions {
@@ -92,50 +99,36 @@ func (r *GormSubscriptionRepository) FindByUserAndProduct(ctx context.Context, u
var entity entities.Subscription
err := r.db.WithContext(ctx).Where("user_id = ? AND product_id = ?", userID, productID).First(&entity).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, gorm.ErrRecordNotFound
}
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)
// 这里筛选的是关联的Product实体里的name或code字段只有当keyword匹配关联Product的name或code时才返回
if query.Keyword != "" {
dbQuery = dbQuery.Joins("LEFT JOIN product ON product.id = subscription.product_id").
Where("product.name LIKE ? OR product.code LIKE ?", "%"+query.Keyword+"%", "%"+query.Keyword+"%")
}
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
@@ -148,92 +141,34 @@ func (r *GormSubscriptionRepository) ListSubscriptions(ctx context.Context, quer
} 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 {
// 预加载Product的id、name、code字段并同时预加载ProductCategory的id、name、code字段
if err := dbQuery.
Preload("Product", func(db *gorm.DB) *gorm.DB {
return db.Select("id", "name", "code", "category_id").
Preload("Category", func(db2 *gorm.DB) *gorm.DB {
return db2.Select("id", "name", "code")
})
}).
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
@@ -248,39 +183,25 @@ func (r *GormSubscriptionRepository) CountByProduct(ctx context.Context, product
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
}
@@ -311,19 +232,19 @@ func (r *GormSubscriptionRepository) DeleteBatch(ctx context.Context, ids []stri
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
@@ -334,13 +255,13 @@ func (r *GormSubscriptionRepository) List(ctx context.Context, options interface
}
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
}
@@ -371,4 +292,4 @@ func (r *GormSubscriptionRepository) WithTx(tx interface{}) interfaces.Repositor
}
}
return r
}
}