2023-10-17 07:33:05 +00:00
|
|
|
|
package models
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"go-admin/app/admin/models/common"
|
2023-10-17 08:14:39 +00:00
|
|
|
|
orm "go-admin/common/global"
|
2023-10-19 03:36:28 +00:00
|
|
|
|
"go-admin/logger"
|
2023-10-17 07:33:05 +00:00
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Category struct {
|
|
|
|
|
Model
|
|
|
|
|
|
|
|
|
|
Name string `json:"name"` // 分类名称
|
2023-11-10 09:49:44 +00:00
|
|
|
|
Number string `json:"number"` // 编号
|
2023-10-19 02:04:13 +00:00
|
|
|
|
Display int8 `json:"display"` // 1 展示 0 隐藏
|
2023-11-10 09:49:44 +00:00
|
|
|
|
Pid uint32 `json:"pid" gorm:"index"` // 父分类的编号
|
|
|
|
|
CooperativeBusinessId uint32 `json:"cooperative_business_id"` // 合作商id
|
2023-10-17 07:33:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-19 02:04:13 +00:00
|
|
|
|
var (
|
|
|
|
|
Display = 1
|
|
|
|
|
UnDisplay = 0
|
|
|
|
|
)
|
|
|
|
|
|
2023-10-17 07:33:05 +00:00
|
|
|
|
func (c *Category) TableName() string {
|
|
|
|
|
return "erp_category"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Category) BeforeCreate(tx *gorm.DB) error {
|
|
|
|
|
if c.Number == "" {
|
2023-10-17 08:14:39 +00:00
|
|
|
|
n, err := GenerateNumber(c.CooperativeBusinessId, c.Pid)
|
|
|
|
|
if err != nil {
|
2023-10-19 03:36:28 +00:00
|
|
|
|
logger.Error("before create category err", logger.Field("c", c), logger.Field("err", err))
|
2023-10-17 08:14:39 +00:00
|
|
|
|
return err
|
2023-10-17 07:33:05 +00:00
|
|
|
|
}
|
2023-10-17 08:14:39 +00:00
|
|
|
|
c.Number = n
|
2023-10-17 07:33:05 +00:00
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-10-17 08:14:39 +00:00
|
|
|
|
|
|
|
|
|
// GenerateNumber 生成分类编码
|
|
|
|
|
func GenerateNumber(cid uint32, pid uint32) (string, error) {
|
|
|
|
|
var count int64
|
|
|
|
|
var err error
|
2023-10-19 03:36:28 +00:00
|
|
|
|
|
|
|
|
|
err = orm.Eloquent.Model(Category{}).
|
|
|
|
|
Unscoped().
|
|
|
|
|
Scopes(common.ScopeBusiness(cid)).
|
|
|
|
|
Where("pid", pid).
|
|
|
|
|
Count(&count).
|
|
|
|
|
Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
2023-10-17 08:14:39 +00:00
|
|
|
|
if pid == 0 {
|
2023-10-19 03:36:28 +00:00
|
|
|
|
return fmt.Sprintf("%03d", count+1), nil
|
2023-10-17 08:14:39 +00:00
|
|
|
|
} else {
|
|
|
|
|
var parent Category
|
2023-10-19 03:36:28 +00:00
|
|
|
|
err = orm.Eloquent.Model(Category{}).
|
2023-10-17 08:14:39 +00:00
|
|
|
|
Scopes(common.ScopeBusiness(cid)).
|
|
|
|
|
Where("id", pid).
|
|
|
|
|
First(&parent).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
2023-10-19 03:36:28 +00:00
|
|
|
|
return fmt.Sprintf("%s%03d", parent.Number, count+1), nil
|
2023-10-17 08:14:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-18 02:06:16 +00:00
|
|
|
|
// GetCategoryById 通过id获取分类
|
2023-10-17 08:14:39 +00:00
|
|
|
|
func GetCategoryById(id uint32) (*Category, error) {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
//var c *Category
|
|
|
|
|
c := new(Category)
|
2023-10-17 08:14:39 +00:00
|
|
|
|
err := orm.Eloquent.Model(c).Where("id", id).First(c).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c, nil
|
|
|
|
|
}
|
2023-10-18 08:22:54 +00:00
|
|
|
|
|
2024-09-14 09:31:16 +00:00
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-18 08:22:54 +00:00
|
|
|
|
type CategoryModel struct {
|
|
|
|
|
Category
|
2023-10-19 06:12:23 +00:00
|
|
|
|
SubCategory []*CategoryModel `json:"sub_category" gorm:"-"` //子分类
|
2023-10-18 08:22:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-19 02:04:13 +00:00
|
|
|
|
func ScopeOnlyDisplay(db *gorm.DB) *gorm.DB {
|
|
|
|
|
return db.Where("display", Display)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetCategoryList 分类列表
|
|
|
|
|
func GetCategoryList(bid uint32, all bool) ([]*CategoryModel, error) {
|
2023-10-18 08:22:54 +00:00
|
|
|
|
var list = make([]*CategoryModel, 0)
|
|
|
|
|
m := orm.Eloquent.Model(Category{})
|
2023-10-19 02:04:13 +00:00
|
|
|
|
|
|
|
|
|
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
|
2023-10-18 08:22:54 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
for _, top := range list {
|
2023-10-19 02:04:13 +00:00
|
|
|
|
top.SubCategory = findChildCategory(top, all)
|
2023-10-18 08:22:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return list, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-19 02:04:13 +00:00
|
|
|
|
// 查询子分类
|
|
|
|
|
func findChildCategory(prev *CategoryModel, all bool) []*CategoryModel {
|
2023-10-18 08:22:54 +00:00
|
|
|
|
var cs []*CategoryModel
|
2023-10-19 02:04:13 +00:00
|
|
|
|
m := orm.Eloquent.Model(Category{})
|
|
|
|
|
if !all {
|
|
|
|
|
m = m.Scopes(ScopeOnlyDisplay)
|
|
|
|
|
}
|
|
|
|
|
err := m.Where("pid", prev.ID).Find(&cs).Error
|
2023-10-18 08:22:54 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, c := range cs {
|
2023-10-19 02:04:13 +00:00
|
|
|
|
c.SubCategory = findChildCategory(c, all)
|
2023-10-18 08:22:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cs
|
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|
2024-11-01 12:27:50 +00:00
|
|
|
|
|
2024-11-26 11:04:36 +00:00
|
|
|
|
// IsExistingCategoryByNumber 查询分类资料中某个名称的分类是否存在
|
|
|
|
|
func IsExistingCategoryByNumber(number string) bool {
|
|
|
|
|
if number == "" {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
// 查询分类名称是否存在的逻辑
|
|
|
|
|
var count int64
|
|
|
|
|
orm.Eloquent.Debug().Model(&Category{}).
|
|
|
|
|
Where("number = ?", number).
|
|
|
|
|
Count(&count)
|
|
|
|
|
|
|
|
|
|
return count > 0
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-01 12:27:50 +00:00
|
|
|
|
// 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
|
|
|
|
|
}
|
2024-11-04 10:07:04 +00:00
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|
2024-11-05 12:40:49 +00:00
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|
2024-11-08 10:58:41 +00:00
|
|
|
|
|
|
|
|
|
// GetAllFirstCategories 查询所有1级分类
|
|
|
|
|
func GetAllFirstCategories() ([]Category, error) {
|
|
|
|
|
var categories []Category
|
|
|
|
|
err := orm.Eloquent.Model(&Category{}).Where("pid = 0 and display = 1").Find(&categories).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return categories, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getCategoryNameByID 获取分类名称
|
|
|
|
|
func getCategoryNameByCategoryID(categoryID uint32) string {
|
|
|
|
|
// 假设有一个GetCategoryByID函数返回分类信息
|
|
|
|
|
category, err := GetCategoryById(categoryID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "未知分类"
|
|
|
|
|
}
|
|
|
|
|
return category.Name
|
|
|
|
|
}
|