Files
junhong_cmp_fiber/internal/store/postgres/enterprise_store.go
huang a36e4a79c0 实现用户和组织模型(店铺、企业、个人客户)
核心功能:
- 实现 7 级店铺层级体系(Shop 模型 + 层级校验)
- 实现企业管理模型(Enterprise 模型)
- 实现个人客户管理模型(PersonalCustomer 模型)
- 重构 Account 模型关联关系(基于 EnterpriseID 而非 ParentID)
- 完整的 Store 层和 Service 层实现
- 递归查询下级店铺功能(含 Redis 缓存)
- 全面的单元测试覆盖(Shop/Enterprise/PersonalCustomer Store + Shop Service)

技术要点:
- 显式指定所有 GORM 模型的数据库字段名(column: 标签)
- 统一的字段命名规范(数据库用 snake_case,Go 用 PascalCase)
- 完整的中文字段注释和业务逻辑说明
- 100% 测试覆盖(20+ 测试用例全部通过)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-09 18:02:46 +08:00

128 lines
3.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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/redis/go-redis/v9"
"gorm.io/gorm"
)
// EnterpriseStore 企业数据访问层
type EnterpriseStore struct {
db *gorm.DB
redis *redis.Client
}
// NewEnterpriseStore 创建企业 Store
func NewEnterpriseStore(db *gorm.DB, redis *redis.Client) *EnterpriseStore {
return &EnterpriseStore{
db: db,
redis: redis,
}
}
// Create 创建企业
func (s *EnterpriseStore) Create(ctx context.Context, enterprise *model.Enterprise) error {
return s.db.WithContext(ctx).Create(enterprise).Error
}
// GetByID 根据 ID 获取企业
func (s *EnterpriseStore) GetByID(ctx context.Context, id uint) (*model.Enterprise, error) {
var enterprise model.Enterprise
if err := s.db.WithContext(ctx).First(&enterprise, id).Error; err != nil {
return nil, err
}
return &enterprise, nil
}
// GetByCode 根据企业编号获取企业
func (s *EnterpriseStore) GetByCode(ctx context.Context, code string) (*model.Enterprise, error) {
var enterprise model.Enterprise
if err := s.db.WithContext(ctx).Where("enterprise_code = ?", code).First(&enterprise).Error; err != nil {
return nil, err
}
return &enterprise, nil
}
// Update 更新企业
func (s *EnterpriseStore) Update(ctx context.Context, enterprise *model.Enterprise) error {
return s.db.WithContext(ctx).Save(enterprise).Error
}
// Delete 软删除企业
func (s *EnterpriseStore) Delete(ctx context.Context, id uint) error {
return s.db.WithContext(ctx).Delete(&model.Enterprise{}, id).Error
}
// List 查询企业列表
func (s *EnterpriseStore) List(ctx context.Context, opts *store.QueryOptions, filters map[string]interface{}) ([]*model.Enterprise, int64, error) {
var enterprises []*model.Enterprise
var total int64
query := s.db.WithContext(ctx).Model(&model.Enterprise{})
// 应用过滤条件
if enterpriseName, ok := filters["enterprise_name"].(string); ok && enterpriseName != "" {
query = query.Where("enterprise_name LIKE ?", "%"+enterpriseName+"%")
}
if enterpriseCode, ok := filters["enterprise_code"].(string); ok && enterpriseCode != "" {
query = query.Where("enterprise_code = ?", enterpriseCode)
}
if ownerShopID, ok := filters["owner_shop_id"].(uint); ok {
query = query.Where("owner_shop_id = ?", ownerShopID)
}
if status, ok := filters["status"].(int); ok {
query = query.Where("status = ?", status)
}
// 计算总数
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(&enterprises).Error; err != nil {
return nil, 0, err
}
return enterprises, total, nil
}
// GetByOwnerShopID 根据归属店铺 ID 查询企业列表
func (s *EnterpriseStore) GetByOwnerShopID(ctx context.Context, ownerShopID uint) ([]*model.Enterprise, error) {
var enterprises []*model.Enterprise
if err := s.db.WithContext(ctx).Where("owner_shop_id = ?", ownerShopID).Find(&enterprises).Error; err != nil {
return nil, err
}
return enterprises, nil
}
// GetPlatformEnterprises 获取平台直属企业列表owner_shop_id 为 NULL
func (s *EnterpriseStore) GetPlatformEnterprises(ctx context.Context) ([]*model.Enterprise, error) {
var enterprises []*model.Enterprise
if err := s.db.WithContext(ctx).Where("owner_shop_id IS NULL").Find(&enterprises).Error; err != nil {
return nil, err
}
return enterprises, nil
}