Files
platforms/backend/api/internal/logic/platform/ec/ec.go

153 lines
4.6 KiB
Go

package ec
import (
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/infra"
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
"github.com/gin-gonic/gin"
)
type categoryRequest struct {
ParentIdentity string `json:"parent_identity"`
Name string `json:"name" binding:"required,max=128"`
SortNo int `json:"sort_no"`
}
type ecCategoryView struct {
Identity string `json:"identity"`
ParentIdentity string `json:"parent_identity,omitempty"`
Name string `json:"name"`
SortNo int `json:"sort_no"`
Status int `json:"status"`
}
func ecCategoryViews(list []models.EcCategory) ([]ecCategoryView, error) {
parents := make(map[uint64]string)
for _, item := range list {
if item.ParentID != 0 {
parents[item.ParentID] = ""
}
}
if len(parents) > 0 {
var rows []struct {
ID uint64
Identity string
}
ids := make([]uint64, 0, len(parents))
for id := range parents {
ids = append(ids, id)
}
if err := impl.DBService.Model(&models.EcCategory{}).Select("id", "identity").Where("id IN ?", ids).Find(&rows).Error; err != nil {
return nil, err
}
for _, row := range rows {
parents[row.ID] = row.Identity
}
}
views := make([]ecCategoryView, 0, len(list))
for _, item := range list {
views = append(views, ecCategoryView{Identity: item.Identity, ParentIdentity: parents[item.ParentID], Name: item.Name, SortNo: item.SortNo, Status: item.Status})
}
return views, nil
}
func ListEcCategory(ctx *gin.Context) {
page, size := common.PageSize(ctx)
var list []models.EcCategory
var total int64
query := common.ActiveRecords(impl.DBService.Model(&models.EcCategory{}))
if err := query.Count(&total).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
if err := query.Order("sort_no asc, id asc").Offset((page - 1) * size).Limit(size).Find(&list).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
views, err := ecCategoryViews(list)
if err != nil {
infra.Response.Error(ctx, err)
return
}
infra.Response.Success(ctx, gin.H{"total": total, "list": views})
}
func GetEcCategory(ctx *gin.Context) {
var category models.EcCategory
if err := impl.DBService.Where("identity = ?", ctx.Param("identity")).First(&category).Error; err != nil {
common.RespondRecordError(ctx, err)
return
}
views, err := ecCategoryViews([]models.EcCategory{category})
if err != nil {
infra.Response.Error(ctx, err)
return
}
infra.Response.Success(ctx, views[0])
}
func CreateEcCategory(ctx *gin.Context) {
var request categoryRequest
if err := ctx.ShouldBindJSON(&request); err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
parentID, err := common.ResolveIdentityID(&models.EcCategory{}, request.ParentIdentity, false)
if err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
category := models.EcCategory{Entity: common.NewEntity(common.StatusDraft), ParentID: parentID, Name: request.Name, SortNo: request.SortNo}
if err := impl.DBService.Create(&category).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
common.RespondCreatedResource(ctx, category)
}
func UpdateEcCategory(ctx *gin.Context) {
var request categoryRequest
if err := ctx.ShouldBindJSON(&request); err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
var category models.EcCategory
if err := impl.DBService.Where("identity = ?", ctx.Param("identity")).First(&category).Error; err != nil {
common.RespondRecordError(ctx, err)
return
}
parentID, err := common.ResolveIdentityID(&models.EcCategory{}, request.ParentIdentity, false)
if err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
var rows []models.EcCategory
if err := impl.DBService.Select("id", "parent_id").Find(&rows).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
parents := make(map[uint64]uint64, len(rows))
for _, row := range rows {
parents[row.ID] = row.ParentID
}
if wouldCreateCategoryCycle(category.ID, parentID, parents) {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
common.UpdateAllowedByIdentity(ctx, &models.EcCategory{}, gin.H{"parent_id": parentID, "name": request.Name, "sort_no": request.SortNo}, []string{"parent_id", "name", "sort_no"})
}
func wouldCreateCategoryCycle(categoryID, parentID uint64, parents map[uint64]uint64) bool {
seen := map[uint64]bool{}
for parentID != 0 {
if parentID == categoryID || seen[parentID] {
return true
}
seen[parentID] = true
parentID = parents[parentID]
}
return false
}