// Package handler provides HTTP handlers for various endpoints. package handler import ( "context" "fmt" "net/http" "time" "modelRT/constant" "modelRT/database" "modelRT/diagram" "modelRT/logger" "modelRT/model" "modelRT/network" "modelRT/orm" "github.com/gin-gonic/gin" "github.com/gofrs/uuid" "go.uber.org/zap" "gorm.io/gorm/clause" ) // CircuitDiagramDeleteHandler define circuit diagram delete process API func CircuitDiagramDeleteHandler(c *gin.Context) { logger := logger.GetLoggerInstance() pgClient := database.GetPostgresDBClient() var request network.CircuitDiagramDeleteRequest if err := c.ShouldBindJSON(&request); err != nil { logger.Error("unmarshal circuit diagram del info failed", zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, } c.JSON(http.StatusOK, resp) return } graph, err := diagram.GetGraphMap(request.PageID) if err != nil { logger.Error("get topologic data from set by pageID failed", zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, 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("format uuid from string failed", zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, 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("delete topologic info into DB failed", zap.Any("topologic_info", topologicDelInfo), zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, 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("delete topologic info failed", zap.Any("topologic_info", topologicDelInfo), zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, 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("format uuid from string failed", zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, 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", constant.ErrDeleteRowZero) } logger.Error("query component info into postgresDB failed", zap.String("component_global_uuid", componentInfo.UUID), zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, 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", constant.ErrDeleteRowZero) } logger.Error("delete component info into postgresDB failed", zap.String("component_global_uuid", componentInfo.UUID), zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, PayLoad: map[string]interface{}{ "uuid": componentInfo.UUID, }, } c.JSON(http.StatusOK, resp) return } modelStruct := model.SelectModelByType(component.ComponentType) modelStruct.SetComponentID(component.ID) result = tx.WithContext(cancelCtx).Where("component_id = ?", component.ID).Delete(modelStruct) if result.Error != nil || result.RowsAffected == 0 { tx.Rollback() err := result.Error if result.RowsAffected == 0 { err = fmt.Errorf("%w:please check uuid conditions", constant.ErrDeleteRowZero) } msg := fmt.Sprintf("delete component info from table %s failed", modelStruct.ReturnTableName()) logger.Error(msg, zap.String("component_global_uuid", componentInfo.UUID), zap.Error(err)) header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} resp := network.FailureResponse{ FailResponseHeader: header, PayLoad: map[string]interface{}{ "uuid": componentInfo.UUID, }, } c.JSON(http.StatusOK, resp) return } diagram.DeleteComponentMap(componentInfo.UUID) } if len(request.FreeVertexs) > 0 { for _, freeVertex := range request.FreeVertexs { delete(graph.FreeVertexs, freeVertex) } } // commit transaction tx.Commit() resp := network.SuccessResponse{ SuccessResponseHeader: network.SuccessResponseHeader{Status: http.StatusOK}, PayLoad: map[string]interface{}{ "page_id": request.PageID, }, } c.JSON(http.StatusOK, resp) }