From 3899cda8efd29c7f11c48ffa7d5090a71d6084b4 Mon Sep 17 00:00:00 2001 From: douxu Date: Mon, 2 Dec 2024 16:13:16 +0800 Subject: [PATCH] preliminary completion of circuit diagram update handler code writing --- config/config.go | 2 +- config/model_config.go | 1 + database/query_page.go | 1 - database/query_topologic.go | 2 +- diagram/component_map.go | 16 +++++- diagram/topologic_set.go | 16 +++++- handler/circuit_diagram_load.go | 2 - handler/circuit_diagram_update.go | 89 ++++++++++++++++++++++++++++++- main.go | 4 +- model/model_parse.go | 3 +- model/model_select.go | 17 +++++- {model => orm}/busbar_section.go | 8 ++- 12 files changed, 144 insertions(+), 17 deletions(-) rename {model => orm}/busbar_section.go (96%) diff --git a/config/config.go b/config/config.go index 23ec548..0fe55a9 100644 --- a/config/config.go +++ b/config/config.go @@ -1,4 +1,4 @@ -// Package config define config struct of wave record project +// Package config define config struct of model runtime service package config import ( diff --git a/config/model_config.go b/config/model_config.go index 6e775a4..9d0e6ee 100644 --- a/config/model_config.go +++ b/config/model_config.go @@ -1,3 +1,4 @@ +// Package config define config struct of model runtime service package config import ( diff --git a/database/query_page.go b/database/query_page.go index d85ba2e..b8231e5 100644 --- a/database/query_page.go +++ b/database/query_page.go @@ -17,7 +17,6 @@ func QueryAllPages(ctx context.Context, logger *zap.Logger, gridID, zoneID, stat // ctx超时判断 cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - // result := _globalPostgresClient.Model(&orm.Page{}).WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).Select("Page.id, Page.Name, Page.status,Page.context").InnerJoins("Station on Station.id = Page.station_id").InnerJoins("Zone on Zone.id = Station.zone_id").InnerJoins("Grid on Grid.id = Zone.grid_id").Scan(&pages) result := _globalPostgresClient.Model(&orm.Page{}).WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).Select(`"Page".id, "Page".Name, "Page".status,"Page".context`).Joins(`inner join "Station" on "Station".id = "Page".station_id`).Joins(`inner join "Zone" on "Zone".id = "Station".zone_id`).Joins(`inner join "Grid" on "Grid".id = "Zone".grid_id`).Where(`"Grid".id = ? and "Zone".id = ? and "Station".id = ?`, gridID, zoneID, stationID).Scan(&pages) diff --git a/database/query_topologic.go b/database/query_topologic.go index 0867e17..7e2f6fd 100644 --- a/database/query_topologic.go +++ b/database/query_topologic.go @@ -57,7 +57,7 @@ func InitCircuitDiagramTopologic(pageID int64, topologicNodes []orm.Topologic) e } topologicSet.AddEdge(node.UUIDFrom, node.UUIDTo) } - diagram.DiagramsOverview.Store(pageID, topologicSet) + diagram.StoreGraphMap(pageID, topologicSet) return nil } diff --git a/diagram/component_map.go b/diagram/component_map.go index 2d7e37d..9583e76 100644 --- a/diagram/component_map.go +++ b/diagram/component_map.go @@ -9,11 +9,11 @@ import ( ) // DiagramsOverview define struct of storage all circuit diagram data -var DiagramsOverview sync.Map +var diagramsOverview sync.Map // GetComponentMap define func of get circuit diagram data by global uuid func GetComponentMap(uuid string) (*cmap.ConcurrentMap[string, any], error) { - value, ok := DiagramsOverview.Load(uuid) + value, ok := diagramsOverview.Load(uuid) if !ok { return nil, fmt.Errorf("can not find graph by global uuid:%s", uuid) } @@ -23,3 +23,15 @@ func GetComponentMap(uuid string) (*cmap.ConcurrentMap[string, any], error) { } return paramsMap, nil } + +// UpdateComponentMap define func of update circuit diagram data by global uuid and component info +func UpdateComponentMap(uuid string, componentInfo *cmap.ConcurrentMap[string, any]) bool { + _, result := diagramsOverview.Swap(uuid, componentInfo) + return result +} + +// StoreComponentMap define func of store circuit diagram data with global uuid and component info +func StoreComponentMap(uuid string, componentInfo *cmap.ConcurrentMap[string, any]) { + diagramsOverview.Store(uuid, componentInfo) + return +} diff --git a/diagram/topologic_set.go b/diagram/topologic_set.go index 0b8fa83..4b66945 100644 --- a/diagram/topologic_set.go +++ b/diagram/topologic_set.go @@ -7,11 +7,11 @@ import ( ) // GraphOverview define struct of storage all circuit diagram topologic data -var GraphOverview sync.Map +var graphOverview sync.Map // GetGraphMap define func of get circuit diagram topologic data by pageID func GetGraphMap(pageID int64) (*Graph, error) { - value, ok := GraphOverview.Load(pageID) + value, ok := graphOverview.Load(pageID) if !ok { return nil, fmt.Errorf("can not find graph by pageID:%d", pageID) } @@ -21,3 +21,15 @@ func GetGraphMap(pageID int64) (*Graph, error) { } return graph, nil } + +// UpdateGrapMap define func of update circuit diagram data by pageID and topologic info +func UpdateGrapMap(pageID int64, graphInfo *Graph) bool { + _, result := diagramsOverview.Swap(pageID, graphInfo) + return result +} + +// StoreGraphMap define func of store circuit diagram topologic data with pageID and topologic info +func StoreGraphMap(pageID int64, graphInfo *Graph) { + diagramsOverview.Store(pageID, graphInfo) + return +} diff --git a/handler/circuit_diagram_load.go b/handler/circuit_diagram_load.go index 9dc588d..5f0efde 100644 --- a/handler/circuit_diagram_load.go +++ b/handler/circuit_diagram_load.go @@ -1,7 +1,6 @@ package handler import ( - "fmt" "net/http" "strconv" @@ -49,7 +48,6 @@ func CircuitDiagramLoadHandler(c *gin.Context) { componentParamMap := make(map[string][]byte) for _, VerticeLink := range topologicInfo.VerticeLinks { - fmt.Println(VerticeLink) for _, componentUUID := range VerticeLink { UUIDStr := componentUUID.String() componentParams, err := diagram.GetComponentMap(UUIDStr) diff --git a/handler/circuit_diagram_update.go b/handler/circuit_diagram_update.go index 618fbbd..07b1f55 100644 --- a/handler/circuit_diagram_update.go +++ b/handler/circuit_diagram_update.go @@ -1,21 +1,27 @@ package handler import ( + "errors" "fmt" "net/http" + "modelRT/database" "modelRT/diagram" "modelRT/log" + "modelRT/model" "modelRT/network" "github.com/gin-gonic/gin" "github.com/gofrs/uuid" + jsoniter "github.com/json-iterator/go" + cmap "github.com/orcaman/concurrent-map/v2" "go.uber.org/zap" ) // CircuitDiagramUpdateHandler define circuit diagram update process API func CircuitDiagramUpdateHandler(c *gin.Context) { logger := log.GetLoggerInstance() + pgClient := database.GetPostgresDBClient() var request network.CircuitDiagramUpdateRequest if err := c.ShouldBindJSON(&request); err != nil { @@ -42,6 +48,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) { return } + // TODO 开启事务保证数据一致性 for _, newTopologicLink := range request.TopologicLinks { fromUUID, err1 := uuid.FromString(newTopologicLink.FromUUID) toUUID, err2 := uuid.FromString(newTopologicLink.ToUUID) @@ -68,7 +75,85 @@ func CircuitDiagramUpdateHandler(c *gin.Context) { return } graph.AddEdge(fromUUID, toUUID) - // TODO 修改 component 先关信息 - fmt.Println(request.ComponentInfos) + // TODO 同步更新到 pg 数据表中 } + + for _, componentInfo := range request.ComponentInfos { + parseStruct := model.SelectModelByType(componentInfo.ComponentType) + if parseStruct == nil { + err := fmt.Errorf("can not get component model by model type %d", componentInfo.ComponentType) + logger.Error("get component model by model type failed", zap.String("uuid", componentInfo.UUID), zap.Int("component_type", componentInfo.ComponentType), zap.Error(err)) + header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} + resp := network.BasicResponse{ + ResponseHeader: header, + PayLoad: map[string]interface{}{ + "uuid": componentInfo.UUID, + "component_type": componentInfo.ComponentType, + }, + } + c.JSON(http.StatusOK, resp) + return + } + + err := jsoniter.Unmarshal([]byte(componentInfo.Params), parseStruct) + if err != nil { + componentStructName := model.SelectModelNameByType(componentInfo.ComponentType) + logger.Error("unmarshal component info by component struct failed", zap.String("component_struct_name", componentStructName), zap.Error(err)) + header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} + resp := network.BasicResponse{ + ResponseHeader: header, + PayLoad: map[string]interface{}{ + "uuid": componentInfo.UUID, + "component_type": componentInfo.ComponentType, + "component_struct_name": componentStructName, + }, + } + c.JSON(http.StatusOK, resp) + return + } + + result := pgClient.Where("uuid = ?", componentInfo.UUID).Save(parseStruct) + if result.Error != nil || result.RowsAffected == 0 { + err := result.Error + if result.RowsAffected == 0 { + err = errors.New("update component info by uuid failed,affected rows zero") + } + logger.Error("store component info into postgresDB failed", zap.Any("component_params", parseStruct), zap.Error(err)) + header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} + resp := network.BasicResponse{ + ResponseHeader: header, + PayLoad: map[string]interface{}{ + "uuid": componentInfo.UUID, + "component_params": parseStruct, + }, + } + c.JSON(http.StatusOK, resp) + return + } + + parseMap := cmap.New[any]() + err = parseMap.UnmarshalJSON([]byte(componentInfo.Params)) + if err != nil { + logger.Error("unmarshal component info by concurrent map failed", zap.String("component_params", componentInfo.Params), zap.Error(err)) + header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()} + resp := network.BasicResponse{ + ResponseHeader: header, + PayLoad: map[string]interface{}{ + "uuid": componentInfo.UUID, + "component_params": componentInfo.Params, + }, + } + c.JSON(http.StatusOK, resp) + return + } + diagram.UpdateComponentMap(componentInfo.UUID, &parseMap) + } + + resp := network.BasicResponse{ + ResponseHeader: network.ResponseHeader{Status: http.StatusOK}, + PayLoad: map[string]interface{}{ + "page_id": request.PageID, + }, + } + c.JSON(http.StatusOK, resp) } diff --git a/main.go b/main.go index 076c0f0..87ae375 100644 --- a/main.go +++ b/main.go @@ -37,7 +37,7 @@ var ( logger *zap.Logger ) -// TODO 使用 wire 依赖注入 +// TODO 使用 wire 依赖注入管理 DVIE 面板注册的 panel func main() { flag.Parse() ctx := context.TODO() @@ -83,7 +83,7 @@ func main() { engine.Use(limiter.Middleware) engine.GET("/model/diagram_load", handler.CircuitDiagramLoadHandler) engine.POST("/model/diagram_create", nil) - engine.POST("/model/diagram_update", nil) + engine.POST("/model/diagram_update", handler.CircuitDiagramUpdateHandler) engine.POST("/model/diagram_delete", nil) // start route with 8080 port diff --git a/model/model_parse.go b/model/model_parse.go index 8df2abf..b16a6b1 100644 --- a/model/model_parse.go +++ b/model/model_parse.go @@ -1,3 +1,4 @@ +// Package model define model struct of model runtime service package model import ( @@ -31,7 +32,7 @@ var ParseFunc = func(parseConfig interface{}) { panic(err) } - tableName := SelectModelByType(modelParseConfig.ComponentInfo.ComponentType) + tableName := SelectModelNameByType(modelParseConfig.ComponentInfo.ComponentType) result := pgClient.Table(tableName).WithContext(cancelCtx).Find(&unmarshalMap) if result.Error != nil { logger.Error("query component detail info failed", zap.Error(result.Error)) diff --git a/model/model_select.go b/model/model_select.go index 1b454f8..1552744 100644 --- a/model/model_select.go +++ b/model/model_select.go @@ -1,8 +1,21 @@ +// Package model define model struct of model runtime service package model -import "modelRT/constant" +import ( + "modelRT/constant" + "modelRT/orm" +) -func SelectModelByType(modelType int) string { +// SelectModelByType define select the data structure for parsing based on the input model type +func SelectModelByType(modelType int) any { + if modelType == constant.BusbarType { + return &orm.BusbarSection{} + } + return nil +} + +// SelectModelNameByType define select the data structure name for parsing based on the input model type +func SelectModelNameByType(modelType int) string { if modelType == constant.BusbarType { return "BusBarSection" } diff --git a/model/busbar_section.go b/orm/busbar_section.go similarity index 96% rename from model/busbar_section.go rename to orm/busbar_section.go index cff4c4b..94c26c0 100644 --- a/model/busbar_section.go +++ b/orm/busbar_section.go @@ -1,4 +1,5 @@ -package model +// Package orm define database data struct +package orm import "github.com/gofrs/uuid" @@ -61,6 +62,11 @@ type BusbarSection struct { StatusMeasurementPoint []string // 状态测点测点 } +// TableName func respresent return table name of BusbarSection +func (b *BusbarSection) TableName() string { + return "BusbarSection" +} + func NewBusbarSection(name string) (*BusbarSection, error) { uuid, err := uuid.NewV4() if err != nil {