package models import ( "fmt" "go-admin/app/admin/models/common" orm "go-admin/common/global" "go-admin/logger" "gorm.io/gorm" ) type Category struct { Model Name string `json:"name"` // 分类名称 Number string `json:"number"` // 编号 Display int8 `json:"display"` // 1 展示 0 隐藏 Pid uint32 `json:"pid" gorm:"index"` // 父分类的编号 CooperativeBusinessId uint32 `json:"cooperative_business_id"` // 合作商id } var ( Display = 1 UnDisplay = 0 ) func (c *Category) TableName() string { return "erp_category" } func (c *Category) BeforeCreate(tx *gorm.DB) error { if c.Number == "" { n, err := GenerateNumber(c.CooperativeBusinessId, c.Pid) if err != nil { logger.Error("before create category err", logger.Field("c", c), logger.Field("err", err)) return err } c.Number = n } return nil } // GenerateNumber 生成分类编码 func GenerateNumber(cid uint32, pid uint32) (string, error) { var count int64 var err error err = orm.Eloquent.Model(Category{}). Unscoped(). Scopes(common.ScopeBusiness(cid)). Where("pid", pid). Count(&count). Error if err != nil { return "", err } if pid == 0 { return fmt.Sprintf("%03d", count+1), nil } else { var parent Category err = orm.Eloquent.Model(Category{}). Scopes(common.ScopeBusiness(cid)). Where("id", pid). First(&parent).Error if err != nil { return "", err } return fmt.Sprintf("%s%03d", parent.Number, count+1), nil } } // GetCategoryById 通过id获取分类 func GetCategoryById(id uint32) (*Category, error) { //var c *Category c := new(Category) err := orm.Eloquent.Model(c).Where("id", id).First(c).Error if err != nil { return nil, err } return c, nil } func comparePrefix(a, b string) bool { // 获取字符串 a 的长度 aLen := len(a) // 如果 b 的长度比 a 短,则无法比较 if len(b) < aLen { return false } // 截取 b 的前 aLen 个字符 bPrefix := b[:aLen] // 比较 a 和 b 的前缀部分 return a == bPrefix } // CheckCouponCategory 判断优惠券分类和商品分类是否对应 func CheckCouponCategory(num string, id uint32) bool { categoryInfo, err := GetCategoryById(id) if err != nil || err == RecordNotFound { return false } return comparePrefix(num, categoryInfo.Number) } type CategoryModel struct { Category SubCategory []*CategoryModel `json:"sub_category" gorm:"-"` //子分类 } func ScopeOnlyDisplay(db *gorm.DB) *gorm.DB { return db.Where("display", Display) } // GetCategoryList 分类列表 func GetCategoryList(bid uint32, all bool) ([]*CategoryModel, error) { var list = make([]*CategoryModel, 0) m := orm.Eloquent.Model(Category{}) var scopes = []func(db *gorm.DB) *gorm.DB{common.ScopeBusiness(bid)} if !all { scopes = append(scopes, ScopeOnlyDisplay) } err := m.Scopes(scopes...).Where("pid = ?", 0).Find(&list).Error if err != nil { return nil, err } for _, top := range list { top.SubCategory = findChildCategory(top, all) } return list, nil } // 查询子分类 func findChildCategory(prev *CategoryModel, all bool) []*CategoryModel { var cs []*CategoryModel m := orm.Eloquent.Model(Category{}) if !all { m = m.Scopes(ScopeOnlyDisplay) } err := m.Where("pid", prev.ID).Find(&cs).Error if err != nil { return nil } for _, c := range cs { c.SubCategory = findChildCategory(c, all) } return cs } // CheckCommodityByCategory 检查某个分类下是否有商品 func CheckCommodityByCategory(categoryId uint32) bool { var count int64 err := orm.Eloquent.Table("erp_commodity").Where("erp_category_id = ? and count > 0", categoryId). Count(&count).Error if err != nil { logger.Error("CheckCommodityByCategory err:", logger.Field("err", err)) } return count > 0 } // IsExistingCategory 查询分类资料中某个名称的分类是否存在 func IsExistingCategory(categoryName string) bool { if categoryName == "" { return true } // 查询分类名称是否存在的逻辑 var count int64 orm.Eloquent.Debug().Model(&Category{}). Where("name = ?", categoryName). Count(&count) return count > 0 } // GetSubcategoryIds 获取指定分类的所有子分类ID func GetSubcategoryIds(categoryID uint32) ([]uint32, error) { var subCategories []Category err := orm.Eloquent.Model(&Category{}).Where("pid = ?", categoryID).Find(&subCategories).Error if err != nil { return nil, err } var subCategoryIDs []uint32 for _, subCategory := range subCategories { subCategoryIDs = append(subCategoryIDs, subCategory.ID) // 递归获取子分类的子分类 childIDs, err := GetSubcategoryIds(subCategory.ID) if err != nil { return nil, err } subCategoryIDs = append(subCategoryIDs, childIDs...) } return subCategoryIDs, nil } // TransformErpCategoryIds 转换 ErpCategoryId,将子分类ID添加进来并去重 func TransformErpCategoryIds(categoryIds []uint32) ([]uint32, error) { categoryIDSet := make(map[uint32]struct{}) // 用于去重的集合 // 遍历传入的 ErpCategoryId for _, categoryID := range categoryIds { // 获取当前分类及其所有子分类ID subCategoryIDs, err := GetSubcategoryIds(categoryID) if err != nil { return nil, err } // 将当前分类ID添加到集合中 categoryIDSet[categoryID] = struct{}{} // 将子分类ID添加到集合中 for _, subID := range subCategoryIDs { categoryIDSet[subID] = struct{}{} } } // 将集合转换为切片 var result []uint32 for id := range categoryIDSet { result = append(result, id) } return result, nil } // CategoryLevels 代表分类层级信息 type CategoryLevels struct { Level1 Category `json:"level1"` Level2 Category `json:"level2,omitempty"` Level3 Category `json:"level3,omitempty"` } // GetCategoryLevels 根据商品分类ID获取分类层级信息 func GetCategoryLevels(categoryID uint32) (CategoryLevels, error) { var levels CategoryLevels // 维持当前分类的ID currentID := categoryID levelCount := 0 for currentID != 0 && levelCount < 3 { var currentCategory Category // 查询当前分类 err := orm.Eloquent.Model(&Category{}).Where("id = ?", currentID).First(¤tCategory).Error if err != nil { return levels, err } // 根据分类编号的长度判断层级 numberLength := len(currentCategory.Number) switch numberLength { case 3: levels.Level1 = currentCategory // 一级分类 case 6: levels.Level2 = currentCategory // 二级分类 case 9: levels.Level3 = currentCategory // 三级分类 default: return levels, nil // 超过9位返回空 } // 移动到上级分类 currentID = currentCategory.Pid levelCount++ } return levels, nil } // GetAllCategories 查询所有分类并返回一个映射 func GetAllCategories() (map[uint32]Category, error) { var categories []Category err := orm.Eloquent.Model(&Category{}).Find(&categories).Error if err != nil { return nil, err } categoryMap := make(map[uint32]Category) for _, category := range categories { categoryMap[category.ID] = category } return categoryMap, nil } // GetCategoryLevelsFromMap 从预加载的分类信息中获取层级 func GetCategoryLevelsFromMap(categoryID uint32, categoryMap map[uint32]Category) CategoryLevels { var levels CategoryLevels // 维持当前分类的ID currentID := categoryID levelCount := 0 for currentID != 0 && levelCount < 3 { currentCategory, exists := categoryMap[currentID] if !exists { break } // 根据分类编号的长度判断层级 numberLength := len(currentCategory.Number) switch numberLength { case 3: levels.Level1 = currentCategory // 一级分类 case 6: levels.Level2 = currentCategory // 二级分类 case 9: levels.Level3 = currentCategory // 三级分类 default: return levels // 超过9位返回空 } // 移动到上级分类 currentID = currentCategory.Pid levelCount++ } return levels }