package service import ( "errors" "fmt" "github.com/jinzhu/copier" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "sort" "xorm.io/xorm" ) type AlertClassSvc struct { User entity.SystemUserInfo } func (a *AlertClassSvc) Add(session *xorm.Session, req request.AddAlertClass) (classId int, err error) { now := jsontime.Now() data := entity.AlertClass{ CreatedBy: a.User.SystemAccount, CreatedAt: now, UpdatedBy: a.User.SystemAccount, UpdatedAt: now, } if req.Source != constant.SourceCustom { req.Source = constant.SourceDefault } _ = copier.Copy(&data, &req) var max int if data.SortOrder >= 0 { max, err = a.SortOrderMax(data.ParentId) if err != nil { return } data.SortOrder = max + 1 } _, err = session.Insert(&data) classId = data.ClassId return } func (a *AlertClassSvc) Update(session *xorm.Session, req request.UpdateAlertClass) error { now := jsontime.Now() data := entity.AlertClass{ UpdatedBy: a.User.SystemAccount, UpdatedAt: now, } _ = copier.Copy(&data, &req) _, err := session.Cols("class_name", "updated_by", "updated_at").ID(data.ClassId).Update(&data) if err != nil { return err } return nil } func (a *AlertClassSvc) Move(req request.MoveAlertClass) (err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return err } now := jsontime.Now() data := entity.AlertClass{} _ = copier.Copy(&data, &req) var list []entity.AlertClass _, err = db.NewSession().Where("class_id = ?", req.ClassId).Get(&data) err = db.NewSession().Where("parent_id = ?", data.ParentId).Where("source = 1").OrderBy("sort_order asc").Find(&list) var previousIndex int var nextIndex int for i := 0; i < len(list); i++ { if list[i].ClassId == req.ClassId { previousIndex = i - 1 nextIndex = i + 1 break } } var ( mover entity.AlertClass moved entity.AlertClass ) switch req.Direction { case "up": if previousIndex < 0 { err = errors.New("top data cannot be moved") return } list[previousIndex].SortOrder, list[previousIndex+1].SortOrder = list[previousIndex+1].SortOrder, list[previousIndex].SortOrder mover, moved = list[previousIndex+1], list[previousIndex] case "down": if nextIndex > len(list)-1 { err = errors.New("bottom data cannot be moved") return } list[nextIndex-1].SortOrder, list[nextIndex].SortOrder = list[nextIndex].SortOrder, list[nextIndex-1].SortOrder mover, moved = list[nextIndex-1], list[nextIndex] } mover.UpdatedBy, moved.UpdatedBy = "", "" mover.UpdatedAt, moved.UpdatedAt = now, now session := db.NewSession() defer session.Close() err = session.Begin() _, err = session.Cols("sort_order", "updated_by", "updated_at").ID(mover.ClassId).Update(&mover) if err != nil { err = session.Rollback() return } _, err = session.Cols("sort_order", "updated_by", "updated_at").ID(moved.ClassId).Update(&moved) if err != nil { err = session.Rollback() return } err = session.Commit() if err != nil { return } return nil } func (a *AlertClassSvc) GetDataById(req request.DetailAlertClass) (resp response.AlertClassItem, err error) { db, err := client.GetDbClient() if err != nil { return } _, err = db.NewSession().Table(resp.TableName()).ID(req.ClassId).Get(&resp) return } func (a *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertClassList, err error) { db, err := client.GetDbClient() if err != nil { return } session := db.NewSession() defer session.Close() session.Where("source = 1") if req.ClassId != 0 { session.Where("class_id = ?", req.ClassId) } if req.ClassName != "" { session.Where("class_name LIKE ?", "%"+req.ClassName+"%") } resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()). OrderBy("sort_order").FindAndCount(&resp.List) return } func (a *AlertClassSvc) AlertObjectList() (resp response.AlertClassList, err error) { db, err := client.GetDbClient() if err != nil { return } session := db.NewSession() defer session.Close() session.Where("parent_id <> 0") resp.TotalCount, err = session.OrderBy("sort_order").FindAndCount(&resp.List) return } func (a *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.AlertClassNode, err error) { db, err := client.GetDbClient() if err != nil { return } session := db.NewSession() defer session.Close() var list []entity.AlertClass session.Where("source = 1") _, err = session.OrderBy("sort_order").FindAndCount(&list) // TODO 对req进行过滤 resp, err = AlertClassTree(list) return } func AlertClassTree(nodes []entity.AlertClass) ([]*response.AlertClassNode, error) { nodeMap := make(map[int]*response.AlertClassNode) // 创建所有节点并存储到映射表中 for _, node := range nodes { tree := &response.AlertClassNode{ AlertClass: node, Children: []*response.AlertClassNode{}, } nodeMap[node.ClassId] = tree } var rootNodes []*response.AlertClassNode for _, node := range nodes { if node.ParentId == 0 { rootNodes = append(rootNodes, nodeMap[node.ClassId]) } else { parent := nodeMap[node.ParentId] if parent == nil { return nil, fmt.Errorf("parent node not found for ClassId: %d", node.ClassId) } parent.Children = append(parent.Children, nodeMap[node.ClassId]) } } sortTree(rootNodes) return rootNodes, nil } func sortTree(nodes []*response.AlertClassNode) { sort.Slice(nodes, func(i, j int) bool { return nodes[i].SortOrder < nodes[j].SortOrder }) for _, node := range nodes { sortTree(node.Children) } } func (a *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) { db, err := client.GetDbClient() if err != nil { return } _, err = db.NewSession().Table(new(entity.AlertClass)). Select("max(sort_order)"). Where("parent_id = ?", parentId).Where("source = 1").Get(&max) return } func (a *AlertClassSvc) Delete(ids []int) (err error) { db, err := client.GetDbClient() if err != nil { return } _, err = db.NewSession().In("class_id", ids).Delete(&entity.AlertClass{}) return }