Quellcode durchsuchen

优化-通用分类

hsun vor 7 Monaten
Ursprung
Commit
c511137209

+ 44 - 0
controllers/trade_analysis/warehouse_process.go

@@ -0,0 +1,44 @@
+package trade_analysis
+
+import (
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage/trade_analysis"
+	"eta/eta_api/services/data"
+	"fmt"
+)
+
+// WareHouseController 建仓过程
+type WareHouseController struct {
+	controllers.BaseAuthController
+}
+
+func (c *WareHouseController) ClassifyMove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var pars data.CommonClassifyMoveReq
+
+	classifyOb := new(trade_analysis.WareHouseProcessClassify)
+	ctx := data.NewCommonClassifyCtx(classifyOb)
+
+	tips, e := data.CommonClassifyMove(pars, ctx)
+	if tips != "" {
+		br.Msg = tips
+		return
+	}
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("移动失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 69 - 0
models/common_classify.go

@@ -0,0 +1,69 @@
+package models
+
+import "time"
+
+// CommonClassify 通用分类
+type CommonClassify struct {
+	ClassifyId   int       `description:"分类ID"`
+	ClassifyName string    `description:"分类名称"`
+	ParentId     int       `description:"父级ID"`
+	RootId       int       `description:"顶级ID"`
+	Level        int       `description:"层级"`
+	LevelPath    string    `description:"层级路径"`
+	Sort         int       `description:"排序"`
+	CreateTime   time.Time `description:"创建时间"`
+	ModifyTime   time.Time `description:"修改时间"`
+}
+
+// CommonClassifyCols 通用分类基本字段
+type CommonClassifyCols struct {
+	ClassifyId   string `description:"分类ID"`
+	ClassifyName string `description:"分类名称"`
+	ParentId     string `description:"父级id"`
+	RootId       string `description:"顶级id"`
+	Level        string `description:"层级"`
+	LevelPath    string `description:"层级路径"`
+	Sort         string `description:"排序字段,越小越靠前,默认值:10"`
+	CreateTime   string `description:"创建时间"`
+	ModifyTime   string `description:"修改时间"`
+}
+
+// CommonClassifyObj 通用分类对象
+type CommonClassifyObj struct {
+	ObjectId   int       `description:"对象ID"`
+	ClassifyId int       `description:"分类ID"`
+	Sort       int       `description:"排序"`
+	CreateTime time.Time `description:"创建时间"`
+	ModifyTime time.Time `description:"修改时间"`
+}
+
+// CommonClassifyObjCols 通用分类对象基本字段
+type CommonClassifyObjCols struct {
+	ObjectId   string `description:"对象ID"`
+	ClassifyId string `description:"分类ID"`
+	Sort       string `description:"排序"`
+	CreateTime string `description:"创建时间"`
+	ModifyTime string `description:"修改时间"`
+}
+
+// ExtraPermissionClassifyStrategy 是一个带有额外权限校验的装饰器
+//type ExtraPermissionClassifyStrategy struct {
+//	BaseClassifyStrategy
+//}
+
+// UpdateCommonClassify 覆盖基础策略的UpdateClassify方法,并添加额外的权限校验
+//func (s *ExtraPermissionClassifyStrategy) UpdateCommonClassify(classify *CommonClassify) error {
+//	// 额外的权限校验
+//	if !checkExtraPermission(classify) {
+//		return fmt.Errorf("无操作权限")
+//	}
+//
+//	// 调用基础策略的UpdateClassify方法
+//	return s.BaseClassifyStrategy.UpdateCommonClassify(classify)
+//}
+//
+//// checkExtraPermission 进行额外的权限校验
+//func checkExtraPermission(classify *CommonClassify) bool {
+//	// 实现额外权限校验逻辑
+//	return true
+//}

+ 340 - 0
models/data_manage/trade_analysis/warehouse_process_classify.go

@@ -0,0 +1,340 @@
+package trade_analysis
+
+import (
+	"eta/eta_api/models"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// WareHouseProcessClassify 建仓过程分类表
+type WareHouseProcessClassify struct {
+	WareHouseProcessClassifyId int       `orm:"column(warehouse_process_classify_id);pk"`
+	ClassifyName               string    `description:"分类名称"`
+	ClassifyNameEn             string    `description:"英文分类名称"`
+	ParentId                   int       `description:"父级ID"`
+	SysUserId                  int       `description:"创建人ID"`
+	SysUserRealName            string    `description:"创建人姓名"`
+	Level                      int       `description:"层级"`
+	Sort                       int       `description:"排序"`
+	RootId                     int       `description:"顶级分类ID"`
+	LevelPath                  string    `description:"层级路径"`
+	UniqueCode                 string    `description:"唯一编码"`
+	CreateTime                 time.Time `description:"创建时间"`
+	ModifyTime                 time.Time `description:"修改时间"`
+}
+
+func (m *WareHouseProcessClassify) TableName() string {
+	return "warehouse_process_classify"
+}
+
+type WareHouseProcessClassifyCols struct {
+	PrimaryId       string
+	ClassifyName    string
+	ClassifyNameEn  string
+	ParentId        string
+	SysUserId       string
+	SysUserRealName string
+	Level           string
+	Sort            string
+	RootId          string
+	LevelPath       string
+	UniqueCode      string
+	CreateTime      string
+	ModifyTime      string
+}
+
+func (m *WareHouseProcessClassify) Cols() WareHouseProcessClassifyCols {
+	return WareHouseProcessClassifyCols{
+		PrimaryId:       "warehouse_process_classify_id",
+		ClassifyName:    "classify_name",
+		ClassifyNameEn:  "classify_name_en",
+		ParentId:        "parent_id",
+		SysUserId:       "sys_user_id",
+		SysUserRealName: "sys_user_real_name",
+		Level:           "level",
+		Sort:            "sort",
+		RootId:          "root_id",
+		LevelPath:       "level_path",
+		UniqueCode:      "unique_code",
+		CreateTime:      "create_time",
+		ModifyTime:      "modify_time",
+	}
+}
+
+func (m *WareHouseProcessClassify) Create() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	id, err := o.Insert(m)
+	if err != nil {
+		return
+	}
+	m.WareHouseProcessClassifyId = int(id)
+	return
+}
+
+func (m *WareHouseProcessClassify) CreateMulti(items []*WareHouseProcessClassify) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+func (m *WareHouseProcessClassify) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(m, cols...)
+	return
+}
+
+func (m *WareHouseProcessClassify) Remove() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
+	_, err = o.Raw(sql, m.WareHouseProcessClassifyId).Exec()
+	return
+}
+
+func (m *WareHouseProcessClassify) MultiRemove(ids []int) (err error) {
+	if len(ids) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
+	_, err = o.Raw(sql, ids).Exec()
+	return
+}
+
+func (m *WareHouseProcessClassify) RemoveByCondition(condition string, pars []interface{}) (err error) {
+	if condition == "" {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition)
+	_, err = o.Raw(sql, pars).Exec()
+	return
+}
+
+func (m *WareHouseProcessClassify) GetItemById(id int) (item *WareHouseProcessClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+func (m *WareHouseProcessClassify) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *WareHouseProcessClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+func (m *WareHouseProcessClassify) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func (m *WareHouseProcessClassify) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*WareHouseProcessClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func (m *WareHouseProcessClassify) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*WareHouseProcessClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// WareHouseProcessClassifyItem 建仓过程分类信息
+type WareHouseProcessClassifyItem struct {
+	ClassifyId     int                             `description:"分类ID"`
+	ClassifyName   string                          `description:"分类名称"`
+	ClassifyNameEn string                          `description:"英文分类名称"`
+	ParentId       int                             `description:"父级ID"`
+	Level          int                             `description:"层级"`
+	Sort           int                             `description:"排序"`
+	LevelPath      string                          `description:"层级路径"`
+	UniqueCode     string                          `description:"唯一编码"`
+	Children       []*WareHouseProcessClassifyItem `description:"子分类"`
+}
+
+func (m *WareHouseProcessClassify) Format2Item() (item *WareHouseProcessClassifyItem) {
+	item = new(WareHouseProcessClassifyItem)
+	item.ClassifyId = m.WareHouseProcessClassifyId
+	item.ClassifyName = m.ClassifyName
+	item.ClassifyNameEn = m.ClassifyNameEn
+	item.ParentId = m.ParentId
+	item.Level = m.Level
+	item.Sort = m.Sort
+	item.LevelPath = m.LevelPath
+	item.UniqueCode = m.UniqueCode
+	item.Children = make([]*WareHouseProcessClassifyItem, 0)
+	return
+}
+
+// ------------------------------------------------ 通用分类 ------------------------------------------------
+
+// GetCommonClassifyCols 通用分类字段映射
+func (m *WareHouseProcessClassify) GetCommonClassifyCols() models.CommonClassifyCols {
+	return models.CommonClassifyCols{
+		ClassifyId:   m.Cols().PrimaryId,
+		ClassifyName: m.Cols().ClassifyName,
+		ParentId:     m.Cols().ParentId,
+		Sort:         m.Cols().ParentId,
+		RootId:       m.Cols().RootId,
+		Level:        m.Cols().Level,
+		LevelPath:    m.Cols().LevelPath,
+		CreateTime:   m.Cols().CreateTime,
+		ModifyTime:   m.Cols().ModifyTime,
+	}
+}
+
+// GetCommonClassifyById 获取通用分类
+func (m *WareHouseProcessClassify) GetCommonClassifyById(classifyId int) (commonClassify *models.CommonClassify, err error) {
+	item, e := m.GetItemById(classifyId)
+	if e != nil {
+		err = e
+		return
+	}
+	commonClassify = new(models.CommonClassify)
+	commonClassify.ClassifyId = item.WareHouseProcessClassifyId
+	commonClassify.ClassifyName = item.ClassifyName
+	commonClassify.ParentId = item.ParentId
+	commonClassify.RootId = item.RootId
+	commonClassify.Level = item.Level
+	commonClassify.LevelPath = item.LevelPath
+	commonClassify.Sort = item.Sort
+	commonClassify.CreateTime = item.CreateTime
+	commonClassify.ModifyTime = item.ModifyTime
+	return
+}
+
+// GetClassifyByParentIdAndName 实现获取分类信息的方法
+func (m *WareHouseProcessClassify) GetClassifyByParentIdAndName(parentId int, name string, excludeId int) (*models.CommonClassify, error) {
+	// 实现获取分类信息的逻辑
+	return nil, nil
+}
+
+// UpdateCommonClassify 实现更新分类信息的方法
+func (m *WareHouseProcessClassify) UpdateCommonClassify(classify *models.CommonClassify, updateCols []string) (err error) {
+	return
+}
+
+func (m *WareHouseProcessClassify) UpdateClassifyChildByParentId(classifyIds []int, rootId int, stepLevel int) (err error) {
+	//	o := orm.NewOrmUsingDB("data")
+	//	var pars []interface{}
+	//	pars = append(pars, rootId, levelStep)
+	//	pars = append(pars, classifyIds)
+	//	// 更新相关联的二级分类的parentId,和classify_name_second
+	//	sql := `update edb_classify
+	//SET root_id = ?, level = level+?
+	//where classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `)`
+	//	_, err = o.Raw(sql, pars).Exec()
+	//	if err != nil {
+	//		return
+	//	}
+	return
+}
+
+// GetClassifySortMaxByParentId 实现获取分类排序的方法
+func (m *WareHouseProcessClassify) GetClassifySortMaxByParentId(parentId int) (sortMax int, err error) {
+	//	o := orm.NewOrmUsingDB("data")
+	//	sql := `SELECT Max(sort) AS sort FROM edb_classify WHERE parent_id=? AND classify_type=? `
+	//	err = o.Raw(sql, parentId, classifyType).QueryRow(&sort)
+	//	return
+	return
+}
+
+func (m *WareHouseProcessClassify) GetFirstClassifyByParentId(parentId int) (item *models.CommonClassify, err error) {
+	//o := orm.NewOrmUsingDB("data")
+	//sql := ` SELECT * FROM edb_classify WHERE parent_id=? order by sort asc,classify_id asc limit 1`
+	//err = o.Raw(sql, parentId).QueryRow(&item)
+	return
+}
+
+// SetClassifySortByParentId 实现设置分类排序的方法
+func (m *WareHouseProcessClassify) SetClassifySortByParentId(parentId, classifyId, sort int, sortUpdate string) (err error) {
+	//o := orm.NewOrmUsingDB("data")
+	//sql := ` update edb_classify set sort = ` + updateSort + ` WHERE parent_id=? AND sort > ? AND classify_type = ? `
+	//if classifyId > 0 {
+	//	sql += ` or ( classify_id > ` + fmt.Sprint(classifyId) + ` and sort = ` + fmt.Sprint(nowSort) + `)`
+	//}
+	//_, err = o.Raw(sql, parentId, nowSort, classifyType).Exec()
+	return
+}
+
+// GetCommonClassifyObjCols 通用分类对象字段映射
+func (m *WareHouseProcessClassify) GetCommonClassifyObjCols() models.CommonClassifyObjCols {
+	// TODO: 完善
+	return models.CommonClassifyObjCols{
+		ObjectId:   m.Cols().ClassifyName,
+		ClassifyId: m.Cols().PrimaryId,
+		Sort:       m.Cols().ParentId,
+	}
+}
+
+func (m *WareHouseProcessClassify) GetObjectById(objectId int) (*models.CommonClassifyObj, error) {
+	// 实现获取分类信息的逻辑
+	return nil, nil
+}
+
+// GetObjectSortMaxByClassifyId 获取分类下最大排序
+func (m *WareHouseProcessClassify) GetObjectSortMaxByClassifyId(classifyId int) (sortMax int, err error) {
+	//	o := orm.NewOrmUsingDB("data")
+	//	sql := `SELECT Max(sort) AS sort FROM edb_info WHERE classify_id=? `
+	//	err = o.Raw(sql, classifyId).QueryRow(&sort)
+	//	return
+	return
+}
+
+func (m *WareHouseProcessClassify) GetFirstObjectByClassifyId(classifyId int) (item *models.CommonClassifyObj, err error) {
+	//o := orm.NewOrmUsingDB("data")
+	//sql := ` SELECT * FROM edb_info WHERE classify_id=? order by sort asc,edb_info_id asc limit 1`
+	//err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+func (m *WareHouseProcessClassify) SetObjectSortByClassifyId(classifyId, sort, prevObjectId int, sortUpdate string) (err error) {
+	//o := orm.NewOrmUsingDB("data")
+	//sql := ` update edb_info set sort = ` + updateSort + ` WHERE classify_id=?`
+	//if prevEdbInfoId > 0 {
+	//	sql += ` AND ( sort > ? or ( edb_info_id > ` + fmt.Sprint(prevEdbInfoId) + ` and sort=` + fmt.Sprint(nowSort) + ` )) `
+	//} else {
+	//	sql += ` AND ( sort > ? )`
+	//}
+	//_, err = o.Raw(sql, classifyId, nowSort).Exec()
+	return
+}
+
+// UpdateCommonClassifyObj 更新通用分类对象
+func (m *WareHouseProcessClassify) UpdateCommonClassifyObj(object *models.CommonClassifyObj, updateCols []string) (err error) {
+	return
+}
+
+// ------------------------------------------------ 通用分类 ------------------------------------------------

+ 496 - 0
services/data/common_classify.go

@@ -0,0 +1,496 @@
+package data
+
+import (
+	"eta/eta_api/models"
+	"eta/eta_api/utils"
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// CommonClassifyMoveReq 移动分类
+type CommonClassifyMoveReq struct {
+	ClassifyId       int `description:"分类ID"`
+	ParentClassifyId int `description:"父级分类ID"`
+	PrevClassifyId   int `description:"上一个兄弟节点分类ID"`
+	NextClassifyId   int `description:"下一个兄弟节点分类ID"`
+	ObjectId         int `description:"对象ID(指标/图表..), 如果对象ID>0则移动对象, 否则认为移动分类"`
+	PrevObjectId     int `description:"上一个对象ID"`
+	NextObjectId     int `description:"下一个对象ID"`
+}
+
+func CommonClassifyMove(req CommonClassifyMoveReq, strategy CommonClassifyStrategy) (tips string, err error) {
+	ctx := NewCommonClassifyCtx(strategy)
+
+	var (
+		classify       *models.CommonClassify
+		parentClassify *models.CommonClassify
+		prevClassify   *models.CommonClassify
+		nextClassify   *models.CommonClassify
+		object         *models.CommonClassifyObj
+		prevObject     *models.CommonClassifyObj
+		nextObject     *models.CommonClassifyObj
+		sortPrev       int
+		sortNext       int
+	)
+
+	// 获取父级分类
+	if req.ParentClassifyId > 0 {
+		c, e := ctx.GetCommonClassifyById(req.ParentClassifyId)
+		if e != nil {
+			err = fmt.Errorf("获取上级分类失败, %v", e)
+			return
+		}
+		parentClassify = c
+	}
+
+	// 兄弟节点
+	if req.PrevClassifyId > 0 {
+		c, e := ctx.GetCommonClassifyById(req.PrevClassifyId)
+		if e != nil {
+			if e.Error() == utils.ErrNoRow() {
+				tips = "上一个分类不存在, 请刷新页面"
+				return
+			}
+			err = fmt.Errorf("获取上一个分类失败, %v", e)
+			return
+		}
+		prevClassify = c
+		sortPrev = prevClassify.Sort
+	} else if req.PrevObjectId > 0 {
+		obj, e := ctx.GetObjectById(req.PrevObjectId)
+		if e != nil {
+			if e.Error() == utils.ErrNoRow() {
+				tips = "上一个移动对象不存在, 请刷新页面"
+				return
+			}
+			err = fmt.Errorf("获取上一个移动对象失败, %v", e)
+			return
+		}
+		prevObject = obj
+		sortPrev = prevObject.Sort
+	}
+	if req.NextClassifyId > 0 {
+		c, e := ctx.GetCommonClassifyById(req.NextClassifyId)
+		if e != nil {
+			if e.Error() == utils.ErrNoRow() {
+				tips = "下一个分类不存在, 请刷新页面"
+				return
+			}
+			err = fmt.Errorf("获取下一个分类失败, %v", e)
+			return
+		}
+		nextClassify = c
+		sortNext = nextClassify.Sort
+	} else if req.NextObjectId > 0 {
+		obj, e := ctx.GetObjectById(req.NextObjectId)
+		if e != nil {
+			if e.Error() == utils.ErrNoRow() {
+				tips = "下一个移动对象不存在, 请刷新页面"
+				return
+			}
+			err = fmt.Errorf("获取下一个移动对象失败, %v", e)
+			return
+		}
+		nextObject = obj
+		sortNext = nextObject.Sort
+	}
+
+	// 移动分类
+	if req.ObjectId == 0 {
+		c, e := ctx.GetCommonClassifyById(req.ClassifyId)
+		if e != nil {
+			if e.Error() == utils.ErrNoRow() {
+				tips = "当前分类不存在, 请刷新页面"
+				return
+			}
+			err = fmt.Errorf("获取当前分类失败, %v", e)
+			return
+		}
+		classify = c
+		return moveCommonClassify(ctx, req, classify, parentClassify, prevClassify, nextClassify, prevObject, nextObject, sortPrev, sortNext)
+	}
+
+	// 移动对象
+	if req.ObjectId > 0 {
+		obj, e := ctx.GetObjectById(req.ObjectId)
+		if e != nil {
+			if e.Error() == utils.ErrNoRow() {
+				tips = "移动对象不存在, 请刷新页面"
+				return
+			}
+			err = fmt.Errorf("获取移动对象失败, %v", e)
+			return
+		}
+		if req.ParentClassifyId <= 0 {
+			tips = "移动对象必须挂在分类下"
+			return
+		}
+		object = obj
+
+		// TODO:对象的不同实现, 如指标校验权限
+
+		return moveCommonClassifyObj(ctx, req, prevClassify, nextClassify, object, prevObject, nextObject, sortPrev, sortNext)
+	}
+	return
+}
+
+func moveCommonClassify(ctx *CommonClassifyCtx, req CommonClassifyMoveReq, classify, parentClassify, prevClassify, nextClassify *models.CommonClassify, prevObject, nextObject *models.CommonClassifyObj, sortPrev, sortNext int) (tips string, err error) {
+	// 校验层级以及父级分类下同名分类
+	if req.ParentClassifyId > 0 && parentClassify.Level == 6 {
+		tips = "最高只支持添加6级分类"
+		return
+	}
+	exists, e := ctx.GetClassifyByParentIdAndName(req.ParentClassifyId, classify.ClassifyName, classify.ClassifyId)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = fmt.Errorf("获取父级分类下的同名分类失败, %v", e)
+		return
+	}
+	if exists != nil {
+		tips = "当前父级分类下存在相同名称"
+		return
+	}
+
+	// TODO:分类的非通用实现, 如指标分类需校验权限, 可以采用适配器模式兼容进来
+
+	var classifyChildIds []int
+	var classifyUpdateCols []string
+	originParentId := classify.ParentId
+	originLevel := classify.Level
+
+	// 需更新子层级分类ID
+	if originParentId != req.ParentClassifyId {
+		// TODO:此处如果要兼容以前的分类表, 那么要提出来处理
+		levelPathArr := strings.Split(classify.LevelPath, ",")
+		for _, p := range levelPathArr {
+			d, _ := strconv.Atoi(p)
+			if d > 0 {
+				classifyChildIds = append(classifyChildIds, d)
+			}
+		}
+	}
+
+	colsMapping := ctx.GetCommonClassifyCols() // 分类表实际的字段映射
+
+	// 判断上级ID是否一致, 不一致的话需要移动该分类层级
+	if classify.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
+		if classify.Level != parentClassify.Level+1 { //禁止层级调整
+			tips = "不支持目录层级变更"
+			return
+		}
+		classify.ParentId = parentClassify.ClassifyId
+		classify.RootId = parentClassify.RootId
+		classify.Level = parentClassify.Level + 1
+		classify.ModifyTime = time.Now()
+		classifyUpdateCols = append(classifyUpdateCols, colsMapping.ParentId, colsMapping.RootId, colsMapping.Level, colsMapping.ModifyTime)
+	}
+	if classify.ParentId != req.ParentClassifyId && req.ParentClassifyId == 0 {
+		tips = "不支持目录层级变更"
+		return
+	}
+
+	if sortPrev > 0 {
+		// 移动至两个兄弟之间
+		if sortNext > 0 {
+			// 如果上一个兄弟与下一个兄弟的排序权重是一致的, 那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2, 自己变成上一个兄弟的排序权重+1
+			if sortPrev == sortNext || sortPrev == classify.Sort {
+				sortUpdate := `sort + 2`
+				if prevClassify != nil {
+					if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, sortUpdate); e != nil {
+						err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, sortUpdate, e)
+						return
+					}
+				} else {
+					if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, 0, sortPrev, sortUpdate); e != nil {
+						err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, sortPrev, sortUpdate, e)
+						return
+					}
+				}
+
+				if prevObject != nil {
+					if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate); e != nil {
+						err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate, e)
+						return
+					}
+				} else {
+					if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, 0, sortUpdate); e != nil {
+						err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, 0, sortUpdate, e)
+						return
+					}
+				}
+			} else {
+				// 如果下一个兄弟的排序权重正好是上个兄弟节点的下一层, 那么需要再加一层
+				if sortNext-sortPrev == 1 {
+					sortUpdate := `sort + 1`
+					if prevClassify != nil {
+						if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, prevClassify.ClassifyId, sortPrev, sortUpdate); e != nil {
+							err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, prevClassify.ClassifyId, sortPrev, sortUpdate, e)
+							return
+						}
+					} else {
+						if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, 0, sortPrev, sortUpdate); e != nil {
+							err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, sortPrev, sortUpdate, e)
+							return
+						}
+					}
+
+					if prevObject != nil {
+						if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate); e != nil {
+							err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate, e)
+							return
+						}
+					} else {
+						if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, 0, sortUpdate); e != nil {
+							err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, 0, sortUpdate, e)
+							return
+						}
+					}
+				}
+			}
+		}
+
+		classify.Sort = sortPrev + 1
+		classify.ModifyTime = time.Now()
+		classifyUpdateCols = append(classifyUpdateCols, colsMapping.Sort, colsMapping.ModifyTime)
+	} else if prevClassify == nil && nextClassify == nil && prevObject == nil && nextObject == nil && req.ParentClassifyId > 0 {
+		// 处理只拖动到目录里, 默认放到目录底部的情况
+		m, e := GetCommonClassifySortMaxByParentId(req.ParentClassifyId, ctx)
+		if e != nil {
+			err = fmt.Errorf("GetCommonClassifySortMaxByParentId, %v", e)
+			return
+		}
+		classify.Sort = m + 1
+		classify.ModifyTime = time.Now()
+		classifyUpdateCols = append(classifyUpdateCols, colsMapping.Sort, colsMapping.ModifyTime)
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, e := ctx.GetFirstClassifyByParentId(req.ParentClassifyId)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			//tips = "移动失败"
+			err = fmt.Errorf("GetFirstClassifyByParentId, %v", e)
+			return
+		}
+
+		// 如果该分类下存在其他分类, 且第一个其他分类的排序等于0, 那么需要调整排序
+		if firstClassify != nil && firstClassify.Sort == 0 {
+			sortUpdate := ` sort + 1 `
+			if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, firstClassify.ClassifyId-1, 0, sortUpdate); e != nil {
+				err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, firstClassify.ClassifyId-1, 0, sortUpdate, e)
+				return
+			}
+			// 该分类下的所有指标也需要+1
+			if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, 0, 0, sortUpdate); e != nil {
+				err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, 0, sortUpdate, e)
+				return
+			}
+		} else {
+			// 如果该分类下存在指标, 且第一个指标的排序等于0, 那么需要调整排序
+			firstObject, e := ctx.GetFirstObjectByClassifyId(req.ParentClassifyId)
+			if e != nil && e.Error() != utils.ErrNoRow() {
+				err = fmt.Errorf("GetFirstObjectByClassifyId, %v", e)
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstObject != nil && firstObject.Sort == 0 {
+				sortUpdate := ` sort + 1 `
+				if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, 0, firstObject.ObjectId-1, sortUpdate); e != nil {
+					err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, firstObject.ObjectId-1, sortUpdate, e)
+					return
+				}
+				if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, 0, 0, sortUpdate); e != nil {
+					err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, 0, sortUpdate, e)
+					return
+				}
+			}
+		}
+
+		classify.Sort = 0 // 那就是排在第一位
+		classify.ModifyTime = time.Now()
+		classifyUpdateCols = append(classifyUpdateCols, colsMapping.Sort, colsMapping.ModifyTime)
+	}
+
+	// 更新分类
+	if len(classifyUpdateCols) > 0 {
+		if e = ctx.UpdateCommonClassify(classify, classifyUpdateCols); e != nil {
+			err = fmt.Errorf("UpdateCommonClassify, %v", e)
+			return
+		}
+
+		// 更新对应分类的root_id和层级
+		if originParentId != req.ParentClassifyId {
+			if len(classifyChildIds) > 0 {
+				stepLevel := classify.Level - originLevel
+				if e = ctx.UpdateClassifyChildByParentId(classifyChildIds, classify.RootId, stepLevel); e != nil {
+					err = fmt.Errorf("UpdateClassifyChildByParentId, parentId: %d, classifyId: %d, stepLevel: %d, err: %v", req.ParentClassifyId, classify.ClassifyId, stepLevel, e)
+					return
+				}
+			}
+		}
+	}
+	return
+}
+
+func moveCommonClassifyObj(ctx *CommonClassifyCtx, req CommonClassifyMoveReq, prevClassify, nextClassify *models.CommonClassify, object, prevObject, nextObject *models.CommonClassifyObj, sortPrev, sortNext int) (tips string, err error) {
+	var objUpdateCols []string
+	colsMapping := ctx.GetCommonClassifyObjCols() // 分类对象表实际的字段映射
+
+	// 分类变更的情况
+	if object.ClassifyId != req.ParentClassifyId {
+		object.ClassifyId = req.ParentClassifyId
+		object.ModifyTime = time.Now()
+		objUpdateCols = append(objUpdateCols, colsMapping.ClassifyId, colsMapping.ModifyTime)
+	}
+
+	if sortPrev > 0 {
+		// 移动至两个兄弟之间
+		if sortNext > 0 {
+			// 如果上一个兄弟与下一个兄弟的排序权重是一致的, 那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2, 自己变成上一个兄弟的排序权重+1
+			if sortPrev == sortNext || sortPrev == object.Sort {
+				sortUpdate := `sort + 2`
+
+				if prevClassify != nil {
+					if e := ctx.SetClassifySortByParentId(req.ParentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, sortUpdate); e != nil {
+						err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, sortUpdate, e)
+						return
+					}
+				} else {
+					if e := ctx.SetClassifySortByParentId(req.ParentClassifyId, 0, sortPrev, sortUpdate); e != nil {
+						err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, sortPrev, sortUpdate, e)
+						return
+					}
+				}
+
+				if prevObject != nil {
+					if e := ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate); e != nil {
+						err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate, e)
+						return
+					}
+				} else {
+					if e := ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, 0, sortUpdate); e != nil {
+						err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, 0, sortUpdate, e)
+						return
+					}
+				}
+			} else {
+				// 如果下一个兄弟的排序权重正好是上个兄弟节点的下一层, 那么需要再加一层
+				if sortNext-sortPrev == 1 {
+					sortUpdate := `sort + 1`
+
+					if prevClassify != nil {
+						if e := ctx.SetClassifySortByParentId(req.ParentClassifyId, prevClassify.ClassifyId, sortPrev, sortUpdate); e != nil {
+							err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, prevClassify.ClassifyId, sortPrev, sortUpdate, e)
+							return
+						}
+					} else {
+						if e := ctx.SetClassifySortByParentId(req.ParentClassifyId, 0, sortPrev, sortUpdate); e != nil {
+							err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, sortPrev, sortUpdate, e)
+							return
+						}
+					}
+
+					if prevObject != nil {
+						if e := ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate); e != nil {
+							err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, prevObject.ObjectId, sortUpdate, e)
+							return
+						}
+					} else {
+						if e := ctx.SetObjectSortByClassifyId(req.ParentClassifyId, sortPrev, 0, sortUpdate); e != nil {
+							err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, sortPrev, 0, sortUpdate, e)
+							return
+						}
+					}
+				}
+			}
+		}
+
+		object.Sort = sortPrev + 1
+		object.ModifyTime = time.Now()
+		objUpdateCols = append(objUpdateCols, colsMapping.Sort, colsMapping.ModifyTime)
+	} else if prevClassify == nil && nextClassify == nil && prevObject == nil && nextObject == nil && req.ParentClassifyId > 0 {
+		// 处理只拖动到目录里, 默认放到目录底部的情况
+		m, e := GetCommonClassifySortMaxByParentId(req.ParentClassifyId, ctx)
+		if e != nil {
+			err = fmt.Errorf("GetCommonClassifySortMaxByParentId, %v", e)
+			return
+		}
+		object.Sort = m + 1 //那就是排在组内最后一位
+		object.ModifyTime = time.Now()
+		objUpdateCols = append(objUpdateCols, colsMapping.Sort, colsMapping.ModifyTime)
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, e := ctx.GetFirstClassifyByParentId(req.ParentClassifyId)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			err = fmt.Errorf("GetFirstClassifyByParentId, %v", e)
+			return
+		}
+
+		// 如果该分类下存在其他分类, 且第一个其他分类的排序等于0, 那么需要调整排序
+		if firstClassify != nil && firstClassify.Sort == 0 {
+			sortUpdate := ` sort + 1 `
+			if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, firstClassify.ClassifyId-1, 0, sortUpdate); e != nil {
+				err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, firstClassify.ClassifyId-1, 0, sortUpdate, e)
+				return
+			}
+			// 该分类下的所有指标也需要+1
+			if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, 0, 0, sortUpdate); e != nil {
+				err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, 0, sortUpdate, e)
+				return
+			}
+		} else {
+			// 如果该分类下存在对象, 且第一个对象的排序等于0, 那么需要调整排序
+			firstObject, e := ctx.GetFirstObjectByClassifyId(req.ParentClassifyId)
+			if e != nil && e.Error() != utils.ErrNoRow() {
+				err = fmt.Errorf("GetFirstObjectByClassifyId, %v", e)
+				return
+			}
+
+			// 如果该分类下存在其他分类, 且第一个其他分类的排序等于0, 那么需要调整排序
+			if firstObject != nil && firstObject.Sort == 0 {
+				sortUpdate := ` sort + 1 `
+				if e = ctx.SetObjectSortByClassifyId(req.ParentClassifyId, 0, firstObject.ObjectId-1, sortUpdate); e != nil {
+					err = fmt.Errorf("SetObjectSortByClassifyId, classifyId: %d, sort: %d, objectId: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, firstObject.ObjectId-1, sortUpdate, e)
+					return
+				}
+				if e = ctx.SetClassifySortByParentId(req.ParentClassifyId, 0, 0, sortUpdate); e != nil {
+					err = fmt.Errorf("SetClassifySortByParentId, parentId: %d, classifyId: %d, sort: %d, sortUpdate: %s, err: %v", req.ParentClassifyId, 0, 0, sortUpdate, e)
+					return
+				}
+			}
+		}
+
+		object.Sort = 0 // 那就是排在第一位
+		object.ModifyTime = time.Now()
+		objUpdateCols = append(objUpdateCols, colsMapping.Sort, colsMapping.ModifyTime)
+	}
+
+	// 更新分类对象
+	if len(objUpdateCols) > 0 {
+		if e := ctx.UpdateCommonClassifyObj(object, objUpdateCols); e != nil {
+			err = fmt.Errorf("UpdateCommonClassifyObj, %v", e)
+			return
+		}
+	}
+	return
+}
+
+// GetCommonClassifySortMaxByParentId 获取分类下最大排序
+func GetCommonClassifySortMaxByParentId(parentId int, ctx *CommonClassifyCtx) (sortMax int, err error) {
+	// 比对分类和对象的最大排序
+	classifyMax, e := ctx.GetClassifySortMaxByParentId(parentId)
+	if e != nil {
+		err = fmt.Errorf("GetClassifySortMaxByParentId, %v", e)
+		return
+	}
+	sortMax = classifyMax
+	objectMax, e := ctx.GetObjectSortMaxByClassifyId(parentId)
+	if e != nil {
+		err = fmt.Errorf("GetObjectSortMaxByClassifyId, %v", e)
+		return
+	}
+	if sortMax < objectMax {
+		sortMax = objectMax
+	}
+	return
+}

+ 106 - 0
services/data/common_classify_ctx.go

@@ -0,0 +1,106 @@
+package data
+
+import (
+	"eta/eta_api/models"
+)
+
+// CommonClassifyStrategy 通用分类策略接口
+type CommonClassifyStrategy interface {
+	GetCommonClassifyCols() models.CommonClassifyCols
+	GetCommonClassifyById(classifyId int) (*models.CommonClassify, error)
+	GetClassifyByParentIdAndName(parentId int, name string, excludeId int) (*models.CommonClassify, error)
+	GetClassifySortMaxByParentId(parentId int) (int, error)
+	GetFirstClassifyByParentId(parentId int) (*models.CommonClassify, error)
+
+	SetClassifySortByParentId(parentId, classifyId, sort int, sortUpdate string) error
+	UpdateCommonClassify(classify *models.CommonClassify, updateCols []string) error
+	UpdateClassifyChildByParentId(classifyIds []int, rootId int, stepLevel int) error
+
+	GetCommonClassifyObjCols() models.CommonClassifyObjCols
+	GetObjectById(objectId int) (*models.CommonClassifyObj, error)
+	GetObjectSortMaxByClassifyId(classifyId int) (int, error)
+	GetFirstObjectByClassifyId(classifyId int) (*models.CommonClassifyObj, error)
+
+	SetObjectSortByClassifyId(classifyId, sort, prevObjectId int, sortUpdate string) error
+	UpdateCommonClassifyObj(object *models.CommonClassifyObj, updateCols []string) (err error)
+}
+
+// CommonClassifyCtx 通用分类上下文
+type CommonClassifyCtx struct {
+	strategy CommonClassifyStrategy
+}
+
+// NewCommonClassifyCtx New一个通用分类上下文
+func NewCommonClassifyCtx(strategy CommonClassifyStrategy) *CommonClassifyCtx {
+	return &CommonClassifyCtx{strategy: strategy}
+}
+
+// GetCommonClassifyCols 通用分类字段映射
+func (c *CommonClassifyCtx) GetCommonClassifyCols() models.CommonClassifyCols {
+	return c.strategy.GetCommonClassifyCols()
+}
+
+// GetCommonClassifyById 通过策略获取分类信息
+func (c *CommonClassifyCtx) GetCommonClassifyById(classifyId int) (*models.CommonClassify, error) {
+	return c.strategy.GetCommonClassifyById(classifyId)
+}
+
+// GetClassifyByParentIdAndName 通过策略获取分类信息
+func (c *CommonClassifyCtx) GetClassifyByParentIdAndName(parentId int, name string, excludeId int) (*models.CommonClassify, error) {
+	return c.strategy.GetClassifyByParentIdAndName(parentId, name, excludeId)
+}
+
+// GetClassifySortMaxByParentId 获取父级分类下最大排序
+func (c *CommonClassifyCtx) GetClassifySortMaxByParentId(parentId int) (int, error) {
+	return c.strategy.GetClassifySortMaxByParentId(parentId)
+}
+
+// GetFirstClassifyByParentId 获取父级分类下首个分类
+func (c *CommonClassifyCtx) GetFirstClassifyByParentId(parentId int) (*models.CommonClassify, error) {
+	return c.strategy.GetFirstClassifyByParentId(parentId)
+}
+
+// SetClassifySortByParentId 通过父级ID更新分类排序
+func (c *CommonClassifyCtx) SetClassifySortByParentId(parentId, classifyId, sort int, sortUpdate string) error {
+	return c.strategy.SetClassifySortByParentId(parentId, classifyId, sort, sortUpdate)
+}
+
+// UpdateCommonClassify 更新通用分类
+func (c *CommonClassifyCtx) UpdateCommonClassify(classify *models.CommonClassify, updateCols []string) error {
+	return c.strategy.UpdateCommonClassify(classify, updateCols)
+}
+
+// UpdateClassifyChildByParentId 更新分类子节点RootId
+func (c *CommonClassifyCtx) UpdateClassifyChildByParentId(classifyIds []int, rootId int, stepLevel int) error {
+	return c.strategy.UpdateClassifyChildByParentId(classifyIds, rootId, stepLevel)
+}
+
+// GetCommonClassifyObjCols 通用分类对象字段映射
+func (c *CommonClassifyCtx) GetCommonClassifyObjCols() models.CommonClassifyObjCols {
+	return c.strategy.GetCommonClassifyObjCols()
+}
+
+// GetObjectById 获取分类对象
+func (c *CommonClassifyCtx) GetObjectById(objectId int) (*models.CommonClassifyObj, error) {
+	return c.strategy.GetObjectById(objectId)
+}
+
+// GetObjectSortMaxByClassifyId 获取分类下最大排序
+func (c *CommonClassifyCtx) GetObjectSortMaxByClassifyId(classifyId int) (int, error) {
+	return c.strategy.GetObjectSortMaxByClassifyId(classifyId)
+}
+
+// GetFirstObjectByClassifyId 获取分类下首个对象
+func (c *CommonClassifyCtx) GetFirstObjectByClassifyId(classifyId int) (*models.CommonClassifyObj, error) {
+	return c.strategy.GetFirstObjectByClassifyId(classifyId)
+}
+
+// SetObjectSortByClassifyId 通过分类ID更新对象排序
+func (c *CommonClassifyCtx) SetObjectSortByClassifyId(classifyId, sort, prevObjectId int, sortUpdate string) error {
+	return c.strategy.SetObjectSortByClassifyId(classifyId, sort, prevObjectId, sortUpdate)
+}
+
+// UpdateCommonClassifyObj 更新分类对象
+func (c *CommonClassifyCtx) UpdateCommonClassifyObj(object *models.CommonClassifyObj, updateCols []string) (err error) {
+	return c.strategy.UpdateCommonClassifyObj(object, updateCols)
+}