// Package handler provides HTTP handlers for various endpoints. package handler import ( "context" "fmt" "net/http" "time" "modelRT/common/errcode" "modelRT/database" "modelRT/diagram" "modelRT/logger" "modelRT/network" "modelRT/orm" "github.com/gin-gonic/gin" "github.com/gofrs/uuid" "gorm.io/gorm/clause" ) // CircuitDiagramDeleteHandler define circuit diagram delete process API func CircuitDiagramDeleteHandler(c *gin.Context) { pgClient := database.GetPostgresDBClient() var request network.CircuitDiagramDeleteRequest if err := c.ShouldBindJSON(&request); err != nil { logger.Error(c, "unmarshal circuit diagram del info failed", "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), } c.JSON(http.StatusOK, resp) return } graph, err := diagram.GetGraphMap(request.PageID) if err != nil { logger.Error(c, "get topologic data from set by pageID failed", "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), PayLoad: map[string]interface{}{ "page_id": request.PageID, }, } c.JSON(http.StatusOK, resp) return } var topologicDelInfos []network.TopologicUUIDDelInfo for _, topologicLink := range request.TopologicLinks { var delInfo network.TopologicUUIDDelInfo UUIDFrom, err1 := uuid.FromString(topologicLink.UUIDFrom) UUIDTo, err2 := uuid.FromString(topologicLink.UUIDTo) if err1 != nil || err2 != nil { var err error if err1 != nil && err2 == nil { err = fmt.Errorf("convert uuid from string failed:%w", err1) } else if err1 == nil && err2 != nil { err = fmt.Errorf("convert uuid from string failed:%w", err2) } else { err = fmt.Errorf("convert uuid from string failed:%w:%w", err1, err2) } logger.Error(c, "format uuid from string failed", "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), PayLoad: map[string]interface{}{ "topologic_info": topologicLink, }, } c.JSON(http.StatusOK, resp) return } delInfo.UUIDFrom = UUIDFrom delInfo.UUIDTo = UUIDTo topologicDelInfos = append(topologicDelInfos, delInfo) } // open transaction tx := pgClient.Begin() for _, topologicDelInfo := range topologicDelInfos { err = database.DeleteTopologicIntoDB(c, tx, request.PageID, topologicDelInfo) if err != nil { tx.Rollback() logger.Error(c, "delete topologic info into DB failed", "topologic_info", topologicDelInfo, "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), PayLoad: map[string]interface{}{ "topologic_info": topologicDelInfo, }, } c.JSON(http.StatusOK, resp) return } err = graph.DelEdge(topologicDelInfo.UUIDFrom, topologicDelInfo.UUIDTo) if err != nil { tx.Rollback() logger.Error(c, "delete topologic info failed", "topologic_info", topologicDelInfo, "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), PayLoad: map[string]interface{}{ "topologic_info": topologicDelInfo, }, } c.JSON(http.StatusOK, resp) return } } if len(graph.VerticeLinks) == 0 && len(graph.FreeVertexs) == 0 { diagram.DeleteGraphMap(request.PageID) } for _, componentInfo := range request.ComponentInfos { cancelCtx, cancel := context.WithTimeout(c, 5*time.Second) defer cancel() globalUUID, err := uuid.FromString(componentInfo.UUID) if err != nil { tx.Rollback() logger.Error(c, "format uuid from string failed", "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), PayLoad: map[string]interface{}{ "uuid": componentInfo.UUID, }, } c.JSON(http.StatusOK, resp) return } var component orm.Component result := tx.WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).Where("global_uuid = ?", globalUUID).Find(&component) if result.Error != nil || result.RowsAffected == 0 { tx.Rollback() err := result.Error if result.RowsAffected == 0 { err = fmt.Errorf("%w:please check uuid conditions", errcode.ErrDeleteRowZero) } logger.Error(c, "query component info into postgresDB failed", "component_global_uuid", componentInfo.UUID, "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), PayLoad: map[string]interface{}{ "uuid": componentInfo.UUID, }, } c.JSON(http.StatusOK, resp) return } result = tx.WithContext(cancelCtx).Delete(component) if result.Error != nil || result.RowsAffected == 0 { tx.Rollback() err := result.Error if result.RowsAffected == 0 { err = fmt.Errorf("%w:please check uuid conditions", errcode.ErrDeleteRowZero) } logger.Error(c, "delete component info into postgresDB failed", "component_global_uuid", componentInfo.UUID, "error", err) resp := network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), PayLoad: map[string]interface{}{ "uuid": componentInfo.UUID, }, } c.JSON(http.StatusOK, resp) return } diagram.DeleteComponentMap(component.GlobalUUID.String()) } if len(request.FreeVertexs) > 0 { for _, freeVertex := range request.FreeVertexs { delete(graph.FreeVertexs, freeVertex) } } // commit transaction tx.Commit() resp := network.SuccessResponse{ Code: http.StatusOK, Msg: "success", PayLoad: map[string]interface{}{ "page_id": request.PageID, }, } c.JSON(http.StatusOK, resp) }