optimize circuit diagram update handler and complete circuit diagram create handler code writing
This commit is contained in:
parent
ebe86539d4
commit
410c08b132
|
|
@ -11,6 +11,9 @@ var ErrUpdateRowZero = errors.New("update affected rows is zero")
|
||||||
// ErrDeleteRowZero define error of delete affected row zero
|
// ErrDeleteRowZero define error of delete affected row zero
|
||||||
var ErrDeleteRowZero = errors.New("delete affected rows is zero")
|
var ErrDeleteRowZero = errors.New("delete affected rows is zero")
|
||||||
|
|
||||||
|
// ErrInsertRowUnexpected define error of insert affected row not reach expected number
|
||||||
|
var ErrInsertRowUnexpected = errors.New("the number of inserted data rows don't reach the expected value")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrUUIDFromCheckT1 define error of check uuid from value failed in uuid from change type
|
// ErrUUIDFromCheckT1 define error of check uuid from value failed in uuid from change type
|
||||||
ErrUUIDFromCheckT1 = errors.New("in uuid from change type, value of new uuid_from is equal value of old uuid_from")
|
ErrUUIDFromCheckT1 = errors.New("in uuid from change type, value of new uuid_from is equal value of old uuid_from")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Package database define database operation functions
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"modelRT/constant"
|
||||||
|
"modelRT/network"
|
||||||
|
"modelRT/orm"
|
||||||
|
|
||||||
|
"github.com/gofrs/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateComponentIntoDB define create component info of the circuit diagram into DB
|
||||||
|
func CreateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfos []network.ComponentCreateInfo) error {
|
||||||
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var componentSlice []orm.Component
|
||||||
|
for _, info := range componentInfos {
|
||||||
|
globalUUID, err := uuid.FromString(info.UUID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("format uuid from string type failed:%w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentInfo := orm.Component{
|
||||||
|
GlobalUUID: globalUUID,
|
||||||
|
GridID: info.GridID,
|
||||||
|
ZoneID: info.ZoneID,
|
||||||
|
StationID: info.StationID,
|
||||||
|
ComponentType: info.ComponentType,
|
||||||
|
State: info.State,
|
||||||
|
ConnectedBus: info.ConnectedBus,
|
||||||
|
Name: info.Name,
|
||||||
|
VisibleID: info.Name,
|
||||||
|
Description: info.Description,
|
||||||
|
Context: info.Context,
|
||||||
|
Comment: info.Comment,
|
||||||
|
InService: info.InService,
|
||||||
|
}
|
||||||
|
componentSlice = append(componentSlice, componentInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := tx.WithContext(cancelCtx).Create(&componentSlice)
|
||||||
|
|
||||||
|
if result.Error != nil || result.RowsAffected != int64(len(componentSlice)) {
|
||||||
|
err := result.Error
|
||||||
|
if result.RowsAffected != int64(len(componentSlice)) {
|
||||||
|
err = fmt.Errorf("%w:please check insert component slice", constant.ErrInsertRowUnexpected)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("insert component info failed:%w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Package database define database operation functions
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"modelRT/constant"
|
||||||
|
"modelRT/model"
|
||||||
|
"modelRT/network"
|
||||||
|
|
||||||
|
"github.com/gofrs/uuid"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateModelIntoDB define create component model params of the circuit diagram into DB
|
||||||
|
func CreateModelIntoDB(ctx context.Context, tx *gorm.DB, componentInfos []network.ComponentCreateInfo) error {
|
||||||
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
for _, componentInfo := range componentInfos {
|
||||||
|
modelStruct := model.SelectModelByType(componentInfo.ComponentType)
|
||||||
|
globalUUID, err := uuid.FromString(componentInfo.UUID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("format uuid from string type failed:%w", err)
|
||||||
|
}
|
||||||
|
modelStruct.SetUUID(globalUUID)
|
||||||
|
err = jsoniter.Unmarshal([]byte(componentInfo.Params), modelStruct)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unmarshal component model params failed:%w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := tx.Model(modelStruct).WithContext(cancelCtx).Create(modelStruct)
|
||||||
|
if result.Error != nil || result.RowsAffected == 0 {
|
||||||
|
err := result.Error
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
err = fmt.Errorf("%w:please check insert model params", constant.ErrInsertRowUnexpected)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("insert component model params into table %s failed:%w", modelStruct.ReturnTableName(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Package database define database operation functions
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"modelRT/constant"
|
||||||
|
"modelRT/network"
|
||||||
|
"modelRT/orm"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateTopologicIntoDB define create topologic info of the circuit diagram query by pageID and topologic info
|
||||||
|
func CreateTopologicIntoDB(ctx context.Context, tx *gorm.DB, pageID int64, topologicInfos []network.TopologicUUIDCreateInfo) error {
|
||||||
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var topologicSlice []orm.Topologic
|
||||||
|
for _, info := range topologicInfos {
|
||||||
|
topologicInfo := orm.Topologic{
|
||||||
|
PageID: pageID,
|
||||||
|
UUIDFrom: info.UUIDFrom,
|
||||||
|
UUIDTo: info.UUIDTo,
|
||||||
|
Flag: info.Flag,
|
||||||
|
Comment: info.Comment,
|
||||||
|
}
|
||||||
|
topologicSlice = append(topologicSlice, topologicInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := tx.WithContext(cancelCtx).Create(&topologicSlice)
|
||||||
|
|
||||||
|
if result.Error != nil || result.RowsAffected != int64(len(topologicSlice)) {
|
||||||
|
err := result.Error
|
||||||
|
if result.RowsAffected != int64(len(topologicSlice)) {
|
||||||
|
err = fmt.Errorf("%w:please check insert topologic slice", constant.ErrInsertRowUnexpected)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("insert topologic link failed:%w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeleteTopologicIntoDB define delete topologic info of the circuit diagram query by pageID and topologic info
|
// DeleteTopologicIntoDB define delete topologic info of the circuit diagram query by pageID and topologic info
|
||||||
func DeleteTopologicIntoDB(ctx context.Context, tx *gorm.DB, pageID int64, delInfo network.TopologicUUIDDelInfos) error {
|
func DeleteTopologicIntoDB(ctx context.Context, tx *gorm.DB, pageID int64, delInfo network.TopologicUUIDDelInfo) error {
|
||||||
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Package database define database operation functions
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"modelRT/constant"
|
||||||
|
"modelRT/network"
|
||||||
|
"modelRT/orm"
|
||||||
|
|
||||||
|
"github.com/gofrs/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpdateComponentIntoDB define update component info of the circuit diagram into DB
|
||||||
|
func UpdateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfos []network.ComponentUpdateInfo) error {
|
||||||
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
for _, info := range componentInfos {
|
||||||
|
globalUUID, err := uuid.FromString(info.UUID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("format uuid from string type failed:%w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentInfo := orm.Component{
|
||||||
|
GlobalUUID: globalUUID,
|
||||||
|
GridID: info.GridID,
|
||||||
|
ZoneID: info.ZoneID,
|
||||||
|
StationID: info.StationID,
|
||||||
|
ComponentType: info.ComponentType,
|
||||||
|
State: info.State,
|
||||||
|
ConnectedBus: info.ConnectedBus,
|
||||||
|
Name: info.Name,
|
||||||
|
VisibleID: info.Name,
|
||||||
|
Description: info.Description,
|
||||||
|
Context: info.Context,
|
||||||
|
Comment: info.Comment,
|
||||||
|
InService: info.InService,
|
||||||
|
}
|
||||||
|
result := tx.Model(&orm.Component{}).WithContext(cancelCtx).Updates(&componentInfo)
|
||||||
|
if result.Error != nil || result.RowsAffected == 0 {
|
||||||
|
err := result.Error
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
err = fmt.Errorf("%w:please check update component conditions", constant.ErrUpdateRowZero)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("update component info failed:%w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Package database define database operation functions
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"modelRT/constant"
|
||||||
|
"modelRT/model"
|
||||||
|
"modelRT/network"
|
||||||
|
|
||||||
|
"github.com/gofrs/uuid"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpdateModelIntoDB define update component model params of the circuit diagram into DB
|
||||||
|
func UpdateModelIntoDB(ctx context.Context, tx *gorm.DB, componentInfos []network.ComponentUpdateInfo) error {
|
||||||
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
for _, componentInfo := range componentInfos {
|
||||||
|
modelStruct := model.SelectModelByType(componentInfo.ComponentType)
|
||||||
|
if modelStruct == nil {
|
||||||
|
return fmt.Errorf("can not get component model by model type %d", componentInfo.ComponentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := jsoniter.Unmarshal([]byte(componentInfo.Params), modelStruct)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unmarshal component info by component struct %s,failed", model.SelectModelNameByType(componentInfo.ComponentType))
|
||||||
|
}
|
||||||
|
|
||||||
|
globalUUID, err := uuid.FromString(componentInfo.UUID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("format uuid from string type failed:%w", err)
|
||||||
|
}
|
||||||
|
modelStruct.SetUUID(globalUUID)
|
||||||
|
|
||||||
|
result := tx.Model(modelStruct).WithContext(cancelCtx).Where("uuid = ?", componentInfo.UUID).Updates(modelStruct)
|
||||||
|
if result.Error != nil || result.RowsAffected == 0 {
|
||||||
|
err := result.Error
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
err = fmt.Errorf("%w:please check where conditions", constant.ErrUpdateRowZero)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"page_id":1,
|
||||||
|
"topologics":[
|
||||||
|
{
|
||||||
|
"uuid_from":"12311-111",
|
||||||
|
"uuid_to":"12311-114"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uuid_from":"12311-115",
|
||||||
|
"uuid_to":"12311-116"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"free_vertex":[
|
||||||
|
"12311-111",
|
||||||
|
"12311-112",
|
||||||
|
"12311-115"
|
||||||
|
],
|
||||||
|
"component_infos":[
|
||||||
|
{
|
||||||
|
"grid_id":1,
|
||||||
|
"zone":1,
|
||||||
|
"station_id":1,
|
||||||
|
"uuid":"12311-114",
|
||||||
|
"name":"母线 1",
|
||||||
|
"component_type":1,
|
||||||
|
"in_service":true,
|
||||||
|
"connected_bus":1,
|
||||||
|
"state":1,
|
||||||
|
"visible_id":"",
|
||||||
|
"description":"",
|
||||||
|
"context":"",
|
||||||
|
"comment":"",
|
||||||
|
"params":""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"grid_id":1,
|
||||||
|
"zone":1,
|
||||||
|
"station_id":1,
|
||||||
|
"uuid":"12311-116",
|
||||||
|
"name":"发电机 1",
|
||||||
|
"component_type":1,
|
||||||
|
"in_service":true,
|
||||||
|
"connected_bus":1,
|
||||||
|
"state":1,
|
||||||
|
"visible_id":"",
|
||||||
|
"description":"",
|
||||||
|
"context":"",
|
||||||
|
"comment":"",
|
||||||
|
"params":""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
"page_id":1,
|
"page_id":1,
|
||||||
"topologics":[
|
"topologics":[
|
||||||
{
|
{
|
||||||
|
|
||||||
"uuid_from":"12311-111",
|
"uuid_from":"12311-111",
|
||||||
"uuid_to":"12311-114"
|
"uuid_to":"12311-114"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,42 @@
|
||||||
"new_uuid_to":"12311-116"
|
"new_uuid_to":"12311-116"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"free_vertex":[
|
||||||
|
"12311-111",
|
||||||
|
"12311-112",
|
||||||
|
"12311-115"
|
||||||
|
],
|
||||||
"component_infos":[
|
"component_infos":[
|
||||||
{
|
{
|
||||||
"uuid":"12311-113",
|
"grid_id":1,
|
||||||
|
"zone":1,
|
||||||
|
"station_id":1,
|
||||||
|
"uuid":"12311-114",
|
||||||
|
"name":"母线 1",
|
||||||
"component_type":1,
|
"component_type":1,
|
||||||
|
"in_service":true,
|
||||||
|
"connected_bus":1,
|
||||||
|
"state":1,
|
||||||
|
"visible_id":"",
|
||||||
|
"description":"",
|
||||||
|
"context":"",
|
||||||
|
"comment":"",
|
||||||
"params":""
|
"params":""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"uuid":"12311-114",
|
"grid_id":1,
|
||||||
|
"zone":1,
|
||||||
|
"station_id":1,
|
||||||
|
"uuid":"12311-116",
|
||||||
|
"name":"发电机 1",
|
||||||
"component_type":1,
|
"component_type":1,
|
||||||
|
"in_service":true,
|
||||||
|
"connected_bus":1,
|
||||||
|
"state":1,
|
||||||
|
"visible_id":"",
|
||||||
|
"description":"",
|
||||||
|
"context":"",
|
||||||
|
"comment":"",
|
||||||
"params":""
|
"params":""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -6,6 +6,7 @@ require (
|
||||||
github.com/confluentinc/confluent-kafka-go v1.9.2
|
github.com/confluentinc/confluent-kafka-go v1.9.2
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible
|
github.com/gofrs/uuid v4.4.0+incompatible
|
||||||
|
github.com/json-iterator/go v1.1.12
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||||
github.com/orcaman/concurrent-map/v2 v2.0.1
|
github.com/orcaman/concurrent-map/v2 v2.0.1
|
||||||
github.com/panjf2000/ants/v2 v2.10.0
|
github.com/panjf2000/ants/v2 v2.10.0
|
||||||
|
|
@ -35,7 +36,6 @@ require (
|
||||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,161 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"modelRT/database"
|
||||||
|
"modelRT/diagram"
|
||||||
|
"modelRT/log"
|
||||||
|
"modelRT/network"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gofrs/uuid"
|
||||||
|
cmap "github.com/orcaman/concurrent-map/v2"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CircuitDiagramCreateHandler define circuit diagram create process API
|
||||||
|
func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
|
logger := log.GetLoggerInstance()
|
||||||
|
pgClient := database.GetPostgresDBClient()
|
||||||
|
|
||||||
|
var request network.CircuitDiagramCreateRequest
|
||||||
|
if err := c.ShouldBindJSON(&request); err != nil {
|
||||||
|
logger.Error("unmarshal circuit diagram create info failed", zap.Error(err))
|
||||||
|
header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: 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.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: header,
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"page_id": request.PageID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var topologicCreateInfos []network.TopologicUUIDCreateInfo
|
||||||
|
for _, topologicLink := range request.TopologicLinks {
|
||||||
|
var createInfo network.TopologicUUIDCreateInfo
|
||||||
|
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.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: header,
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"topologic_info": topologicLink,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
createInfo.UUIDFrom = UUIDFrom
|
||||||
|
createInfo.UUIDTo = UUIDTo
|
||||||
|
topologicCreateInfos = append(topologicCreateInfos, createInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// open transaction
|
||||||
|
tx := pgClient.Begin()
|
||||||
|
|
||||||
|
err = database.CreateTopologicIntoDB(c, tx, request.PageID, topologicCreateInfos)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
|
||||||
|
logger.Error("create topologic info into DB failed", zap.Any("topologic_info", topologicCreateInfos), zap.Error(err))
|
||||||
|
header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: header,
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"topologic_infos": topologicCreateInfos,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, topologicCreateInfo := range topologicCreateInfos {
|
||||||
|
graph.AddEdge(topologicCreateInfo.UUIDFrom, topologicCreateInfo.UUIDTo)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = database.CreateComponentIntoDB(c, tx, request.ComponentInfos)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
|
||||||
|
logger.Error("insert component info into DB failed", zap.Error(err))
|
||||||
|
header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: header,
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"component_infos": request.ComponentInfos,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = database.CreateModelIntoDB(c, tx, request.ComponentInfos)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("create component model into DB failed", zap.Any("component_infos", request.ComponentInfos), zap.Error(err))
|
||||||
|
header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: header,
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"uuid": request.PageID,
|
||||||
|
"component_infos": request.ComponentInfos,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, componentInfo := range request.ComponentInfos {
|
||||||
|
componentMap := cmap.New[any]()
|
||||||
|
err = componentMap.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.StoreComponentMap(componentInfo.UUID, &componentMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// commit transsction
|
||||||
|
tx.Commit()
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: network.ResponseHeader{Status: http.StatusOK},
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"page_id": request.PageID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
}
|
||||||
|
|
@ -49,9 +49,9 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var topologicDelInfos []network.TopologicUUIDDelInfos
|
var topologicDelInfos []network.TopologicUUIDDelInfo
|
||||||
for _, topologicLink := range request.TopologicLinks {
|
for _, topologicLink := range request.TopologicLinks {
|
||||||
var delInfo network.TopologicUUIDDelInfos
|
var delInfo network.TopologicUUIDDelInfo
|
||||||
UUIDFrom, err1 := uuid.FromString(topologicLink.UUIDFrom)
|
UUIDFrom, err1 := uuid.FromString(topologicLink.UUIDFrom)
|
||||||
UUIDTo, err2 := uuid.FromString(topologicLink.UUIDTo)
|
UUIDTo, err2 := uuid.FromString(topologicLink.UUIDTo)
|
||||||
if err1 != nil || err2 != nil {
|
if err1 != nil || err2 != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"modelRT/constant"
|
|
||||||
"modelRT/database"
|
"modelRT/database"
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
"modelRT/log"
|
"modelRT/log"
|
||||||
"modelRT/model"
|
|
||||||
"modelRT/network"
|
"modelRT/network"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
cmap "github.com/orcaman/concurrent-map/v2"
|
cmap "github.com/orcaman/concurrent-map/v2"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
@ -102,67 +98,39 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = database.UpdateComponentIntoDB(c, tx, request.ComponentInfos)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("udpate component info into DB failed", zap.Error(err))
|
||||||
|
header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: header,
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"page_id": request.PageID,
|
||||||
|
"component_info": request.ComponentInfos,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = database.UpdateModelIntoDB(c, tx, request.ComponentInfos)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("udpate component model info into DB failed", zap.Error(err))
|
||||||
|
header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
resp := network.BasicResponse{
|
||||||
|
ResponseHeader: header,
|
||||||
|
PayLoad: map[string]interface{}{
|
||||||
|
"page_id": request.PageID,
|
||||||
|
"component_info": request.ComponentInfos,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for _, componentInfo := range request.ComponentInfos {
|
for _, componentInfo := range request.ComponentInfos {
|
||||||
parseStruct := model.SelectModelByType(componentInfo.ComponentType)
|
componentMap := cmap.New[any]()
|
||||||
if parseStruct == nil {
|
err = componentMap.UnmarshalJSON([]byte(componentInfo.Params))
|
||||||
tx.Rollback()
|
|
||||||
|
|
||||||
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 {
|
|
||||||
tx.Rollback()
|
|
||||||
|
|
||||||
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 := tx.Where("uuid = ?", componentInfo.UUID).Save(parseStruct)
|
|
||||||
if result.Error != nil || result.RowsAffected == 0 {
|
|
||||||
tx.Rollback()
|
|
||||||
|
|
||||||
err := result.Error
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
err = fmt.Errorf("%w:please check where conditions", constant.ErrUpdateRowZero)
|
|
||||||
}
|
|
||||||
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 {
|
if err != nil {
|
||||||
logger.Error("unmarshal component info by concurrent map failed", zap.String("component_params", componentInfo.Params), zap.Error(err))
|
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()}
|
header := network.ResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
|
||||||
|
|
@ -176,7 +144,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
diagram.UpdateComponentMap(componentInfo.UUID, &parseMap)
|
diagram.UpdateComponentMap(componentInfo.UUID, &componentMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// commit transsction
|
// commit transsction
|
||||||
|
|
|
||||||
10
main.go
10
main.go
|
|
@ -11,7 +11,8 @@ import (
|
||||||
"modelRT/handler"
|
"modelRT/handler"
|
||||||
"modelRT/log"
|
"modelRT/log"
|
||||||
"modelRT/middleware"
|
"modelRT/middleware"
|
||||||
"modelRT/model"
|
"modelRT/pool"
|
||||||
|
subscription "modelRT/real-time-data"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
|
|
@ -59,7 +60,7 @@ func main() {
|
||||||
defer logger.Sync()
|
defer logger.Sync()
|
||||||
|
|
||||||
// init ants pool
|
// init ants pool
|
||||||
pool, err := ants.NewPoolWithFunc(modelRTConfig.ParseConcurrentQuantity, model.ParseFunc)
|
pool, err := ants.NewPoolWithFunc(modelRTConfig.ParseConcurrentQuantity, pool.ParseFunc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("init concurrent parse task pool failed", zap.Error(err))
|
logger.Error("init concurrent parse task pool failed", zap.Error(err))
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -79,10 +80,13 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO 完成订阅数据分析
|
||||||
|
go subscription.RealTimeDataComputer(ctx, nil, []string{}, "")
|
||||||
|
|
||||||
engine := gin.Default()
|
engine := gin.Default()
|
||||||
engine.Use(limiter.Middleware)
|
engine.Use(limiter.Middleware)
|
||||||
engine.GET("/model/diagram_load", handler.CircuitDiagramLoadHandler)
|
engine.GET("/model/diagram_load", handler.CircuitDiagramLoadHandler)
|
||||||
engine.POST("/model/diagram_create", nil)
|
engine.POST("/model/diagram_create", handler.CircuitDiagramCreateHandler)
|
||||||
engine.POST("/model/diagram_update", handler.CircuitDiagramUpdateHandler)
|
engine.POST("/model/diagram_update", handler.CircuitDiagramUpdateHandler)
|
||||||
engine.POST("/model/diagram_delete", handler.CircuitDiagramDeleteHandler)
|
engine.POST("/model/diagram_delete", handler.CircuitDiagramDeleteHandler)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Package network define struct of network operation
|
||||||
|
package network
|
||||||
|
|
||||||
|
import "github.com/gofrs/uuid"
|
||||||
|
|
||||||
|
// TopologicCreateInfo defines circuit diagram topologic create info
|
||||||
|
type TopologicCreateInfo struct {
|
||||||
|
UUIDFrom string `json:"uuid_from"`
|
||||||
|
UUIDTo string `json:"uuid_to"`
|
||||||
|
Flag int `json:"flag"`
|
||||||
|
Comment int `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TopologicUUIDCreateInfo defines circuit diagram topologic uuid create info
|
||||||
|
type TopologicUUIDCreateInfo struct {
|
||||||
|
UUIDFrom uuid.UUID `json:"uuid_from"`
|
||||||
|
UUIDTo uuid.UUID `json:"uuid_to"`
|
||||||
|
Flag int `json:"flag"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComponentCreateInfo defines circuit diagram component create index info
|
||||||
|
type ComponentCreateInfo struct {
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
VisibleID string `json:"visible_id"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Context string `json:"context"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
|
Params string `json:"params"`
|
||||||
|
GridID int64 `json:"grid_id"`
|
||||||
|
ZoneID int64 `json:"zone_id"`
|
||||||
|
StationID int64 `json:"station_id"`
|
||||||
|
ComponentType int `json:"component_type"`
|
||||||
|
State int `json:"state"`
|
||||||
|
ConnectedBus int `json:"connected_bus"`
|
||||||
|
InService bool `json:"in_service"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CircuitDiagramCreateRequest defines request params of circuit diagram create api
|
||||||
|
type CircuitDiagramCreateRequest struct {
|
||||||
|
PageID int64 `json:"page_id"`
|
||||||
|
TopologicLinks []TopologicCreateInfo `json:"topologics"`
|
||||||
|
ComponentInfos []ComponentCreateInfo `json:"component_infos"`
|
||||||
|
}
|
||||||
|
|
@ -9,8 +9,8 @@ type TopologicDelInfo struct {
|
||||||
UUIDTo string `json:"uuid_to"`
|
UUIDTo string `json:"uuid_to"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TopologicUUIDDelInfos defines circuit diagram topologic uuid delete info
|
// TopologicUUIDDelInfo defines circuit diagram topologic uuid delete info
|
||||||
type TopologicUUIDDelInfos struct {
|
type TopologicUUIDDelInfo struct {
|
||||||
UUIDFrom uuid.UUID `json:"uuid_from"`
|
UUIDFrom uuid.UUID `json:"uuid_from"`
|
||||||
UUIDTo uuid.UUID `json:"uuid_to"`
|
UUIDTo uuid.UUID `json:"uuid_to"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,20 +31,32 @@ type TopologicUUIDChangeInfos struct {
|
||||||
Comment string `json:"comment"`
|
Comment string `json:"comment"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComponentInfo defines circuit diagram component params info
|
// ComponentUpdateInfo defines circuit diagram component params info
|
||||||
type ComponentInfo struct {
|
type ComponentUpdateInfo struct {
|
||||||
UUID string `json:"uuid"`
|
UUID string `json:"uuid"`
|
||||||
ComponentType int `json:"component_type"`
|
Name string `json:"name"`
|
||||||
|
VisibleID string `json:"visible_id"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Context string `json:"context"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
Params string `json:"params"`
|
Params string `json:"params"`
|
||||||
|
GridID int64 `json:"grid_id"`
|
||||||
|
ZoneID int64 `json:"zone_id"`
|
||||||
|
StationID int64 `json:"station_id"`
|
||||||
|
ComponentType int `json:"component_type"`
|
||||||
|
State int `json:"state"`
|
||||||
|
ConnectedBus int `json:"connected_bus"`
|
||||||
|
InService bool `json:"in_service"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CircuitDiagramUpdateRequest defines request params of circuit diagram update api
|
// CircuitDiagramUpdateRequest defines request params of circuit diagram update api
|
||||||
type CircuitDiagramUpdateRequest struct {
|
type CircuitDiagramUpdateRequest struct {
|
||||||
PageID int64 `json:"page_id"`
|
PageID int64 `json:"page_id"`
|
||||||
TopologicLinks []TopologicChangeInfo `json:"topologics"`
|
TopologicLinks []TopologicChangeInfo `json:"topologics"`
|
||||||
ComponentInfos []ComponentInfo `json:"component_infos"`
|
ComponentInfos []ComponentUpdateInfo `json:"component_infos"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseUUID define parse UUID by change type in topologic change struct
|
||||||
func ParseUUID(info TopologicChangeInfo) (TopologicUUIDChangeInfos, error) {
|
func ParseUUID(info TopologicChangeInfo) (TopologicUUIDChangeInfos, error) {
|
||||||
var UUIDChangeInfo TopologicUUIDChangeInfos
|
var UUIDChangeInfo TopologicUUIDChangeInfos
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
// Component structure define abstracted info set of electrical component
|
// Component structure define abstracted info set of electrical component
|
||||||
type Component struct {
|
type Component struct {
|
||||||
ID int64 `gorm:"column:id"`
|
ID int64 `gorm:"column:id"`
|
||||||
GlobalUUID uuid.UUID `gorm:"column:global_uuid"`
|
GlobalUUID uuid.UUID `gorm:"column:global_uuid;primaryKey"`
|
||||||
GridID int64 `gorm:"column:grid"`
|
GridID int64 `gorm:"column:grid"`
|
||||||
ZoneID int64 `gorm:"column:zone"`
|
ZoneID int64 `gorm:"column:zone"`
|
||||||
StationID int64 `gorm:"column:station"`
|
StationID int64 `gorm:"column:station"`
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Package model define model struct of model runtime service
|
// Package pool define concurrency call function in ants
|
||||||
package model
|
package pool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"modelRT/config"
|
"modelRT/config"
|
||||||
"modelRT/database"
|
"modelRT/database"
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
|
"modelRT/model"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
@ -32,7 +33,7 @@ var ParseFunc = func(parseConfig interface{}) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tableName := SelectModelNameByType(modelParseConfig.ComponentInfo.ComponentType)
|
tableName := model.SelectModelNameByType(modelParseConfig.ComponentInfo.ComponentType)
|
||||||
result := pgClient.Table(tableName).WithContext(cancelCtx).Find(&unmarshalMap)
|
result := pgClient.Table(tableName).WithContext(cancelCtx).Find(&unmarshalMap)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
logger.Error("query component detail info failed", zap.Error(result.Error))
|
logger.Error("query component detail info failed", zap.Error(result.Error))
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Package readltimedata define real time data operation functions
|
// Package subscription define real time data operation functions
|
||||||
package readltimedata
|
package subscription
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue