diff --git a/database/query_project_manager.go b/database/query_project_manager.go new file mode 100644 index 0000000..6b0cd3d --- /dev/null +++ b/database/query_project_manager.go @@ -0,0 +1,29 @@ +// Package database define database operation functions +package database + +import ( + "context" + "time" + + "modelRT/logger" + "modelRT/orm" + + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +// QueryArrtibuteRecordByUUID return the attribute table record info of the component attribute by uuid +func QueryArrtibuteRecordByUUID(ctx context.Context, tx *gorm.DB, gridID, zoneID, stationID int64) ([]orm.Page, error) { + var pages []orm.Page + // ctx timeout judgment + cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + result := tx.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) + + if result.Error != nil { + logger.Error(ctx, "query circuit diagram pages by gridID and zoneID and stationID failed", "grid_id", gridID, "zone_id", zoneID, "station_id", stationID, "error", result.Error) + return nil, result.Error + } + return pages, nil +} diff --git a/diagram/redis_hash.go b/diagram/redis_hash.go index e0724f0..9ef0f22 100644 --- a/diagram/redis_hash.go +++ b/diagram/redis_hash.go @@ -12,82 +12,85 @@ import ( // RedisHash defines the encapsulation struct of redis hash type type RedisHash struct { ctx context.Context + hashKey string rwLocker *locker.RedissionRWLocker storageClient *redis.Client } // NewRedisHash define func of new redis hash instance -func NewRedisHash(ctx context.Context, hashKey string, token string, lockLeaseTime uint64, needRefresh bool) *RedisHash { +func NewRedisHash(ctx context.Context, hashKey string, lockLeaseTime uint64, needRefresh bool) *RedisHash { + token := ctx.Value("client_token").(string) return &RedisHash{ ctx: ctx, + hashKey: hashKey, rwLocker: locker.InitRWLocker(hashKey, token, lockLeaseTime, needRefresh), storageClient: GetRedisClientInstance(), } } // SetRedisHashByMap define func of set redis hash by map struct -func (rh *RedisHash) SetRedisHashByMap(hashKey string, fields map[string]interface{}) error { +func (rh *RedisHash) SetRedisHashByMap(fields map[string]interface{}) error { err := rh.rwLocker.WLock(rh.ctx) if err != nil { - logger.Error(rh.ctx, "lock wLock by hash_key failed", "hash_key", hashKey, "error", err) + logger.Error(rh.ctx, "lock wLock by hash_key failed", "hash_key", rh.hashKey, "error", err) return err } defer rh.rwLocker.UnWLock(rh.ctx) - err = rh.storageClient.HSet(rh.ctx, hashKey, fields).Err() + err = rh.storageClient.HSet(rh.ctx, rh.hashKey, fields).Err() if err != nil { - logger.Error(rh.ctx, "set hash by map failed", "hash_key", hashKey, "fields", fields, "error", err) + logger.Error(rh.ctx, "set hash by map failed", "hash_key", rh.hashKey, "fields", fields, "error", err) return err } return nil } // SetRedisHashByKV define func of set redis hash by kv struct -func (rh *RedisHash) SetRedisHashByKV(hashKey string, field string, value interface{}) error { +func (rh *RedisHash) SetRedisHashByKV(field string, value interface{}) error { err := rh.rwLocker.WLock(rh.ctx) if err != nil { - logger.Error(rh.ctx, "lock wLock by hash_key failed", "hash_key", hashKey, "error", err) + logger.Error(rh.ctx, "lock wLock by hash_key failed", "hash_key", rh.hashKey, "error", err) return err } defer rh.rwLocker.UnWLock(rh.ctx) - err = rh.storageClient.HSet(rh.ctx, hashKey, field, value).Err() + err = rh.storageClient.HSet(rh.ctx, rh.hashKey, field, value).Err() if err != nil { - logger.Error(rh.ctx, "set hash by kv failed", "hash_key", hashKey, "field", field, "value", value, "error", err) + logger.Error(rh.ctx, "set hash by kv failed", "hash_key", rh.hashKey, "field", field, "value", value, "error", err) return err } return nil } // HGet define func of get specified field value from redis hash by key and field name -func (rh *RedisHash) HGet(hashKey string, field string) (string, error) { +func (rh *RedisHash) HGet(field string) (string, error) { err := rh.rwLocker.RLock(rh.ctx) if err != nil { - logger.Error(rh.ctx, "lock rLock by hash_key failed", "hash_key", hashKey, "error", err) + logger.Error(rh.ctx, "lock rLock by hash_key failed", "hash_key", rh.hashKey, "error", err) return "", err } defer rh.rwLocker.UnRLock(rh.ctx) - result, err := rh.storageClient.HGet(rh.ctx, hashKey, field).Result() + result, err := rh.storageClient.HGet(rh.ctx, rh.hashKey, field).Result() if err != nil { - logger.Error(rh.ctx, "set hash by kv failed", "hash_key", hashKey, "field", field, "error", err) + logger.Error(rh.ctx, "set hash by kv failed", "hash_key", rh.hashKey, "field", field, "error", err) return "", err } return result, nil } // HGetAll define func of get all filelds from redis hash by key -func (rh *RedisHash) HGetAll(hashKey string) (map[string]string, error) { +func (rh *RedisHash) HGetAll() (map[string]string, error) { err := rh.rwLocker.RLock(rh.ctx) if err != nil { - logger.Error(rh.ctx, "lock rLock by hash_key failed", "hash_key", hashKey, "error", err) + logger.Error(rh.ctx, "lock rLock by hash_key failed", "hash_key", rh.hashKey, "error", err) return nil, err } defer rh.rwLocker.UnRLock(rh.ctx) - result, err := rh.storageClient.HGetAll(rh.ctx, hashKey).Result() + result, err := rh.storageClient.HGetAll(rh.ctx, rh.hashKey).Result() if err != nil { - logger.Error(rh.ctx, "get all hash field by hash key failed", "hash_key", hashKey, "error", err) + logger.Error(rh.ctx, "get all hash field by hash key failed", "hash_key", rh.hashKey, "error", err) return nil, err } return result, nil diff --git a/handler/component_attribute_update.go b/handler/component_attribute_update.go new file mode 100644 index 0000000..e33139d --- /dev/null +++ b/handler/component_attribute_update.go @@ -0,0 +1,82 @@ +// Package handler provides HTTP handlers for various endpoints. +package handler + +import ( + "fmt" + "net/http" + + "modelRT/database" + "modelRT/diagram" + "modelRT/logger" + "modelRT/network" + + "github.com/gin-gonic/gin" + "github.com/gofrs/uuid" +) + +// ComponentAttributeUpdateHandler define circuit diagram component attribute value update process API +func ComponentAttributeUpdateHandler(c *gin.Context) { + pgClient := database.GetPostgresDBClient() + + var request network.ComponentAttributeUpdateInfo + if err := c.ShouldBindJSON(&request); err != nil { + logger.Error(c, "unmarshal circuit diagram component attribute update info failed", "error", err) + + resp := network.FailureResponse{ + Code: http.StatusBadRequest, + Msg: err.Error(), + } + c.JSON(http.StatusOK, resp) + return + } + + componentUUID := uuid.FromStringOrNil(request.UUIDStr) + if componentUUID == uuid.Nil { + err := fmt.Errorf("convert component uuid failed") + logger.Error(c, "convert component uuid type from string to uuid failed", "error", err) + + resp := network.FailureResponse{ + Code: http.StatusBadRequest, + Msg: err.Error(), + } + c.JSON(http.StatusOK, resp) + return + } + + // open transaction + tx := pgClient.Begin() + + componentInfo, err := database.QueryComponentByUUID(c, tx, componentUUID) + if err != nil { + logger.Error(c, "query component info by uuid from postgres failed failed", "error", err) + + tx.Rollback() + + resp := network.FailureResponse{ + Code: http.StatusBadRequest, + Msg: err.Error(), + } + c.JSON(http.StatusOK, resp) + return + } + + // TODO 从 project_manager 表进行查询,然后更新对应表的数据的值 + + // TODO 更新 redis 中的缓存的数值 + componentAttributeKey := fmt.Sprintf("%s_%s", componentInfo.Tag, request.AttributeConfigs[0].AttributeExtendType) + // attributeSet.CompTag, colParams.AttributeType + attributeHSet := diagram.NewRedisHash(c, componentAttributeKey, 5000, false) + attributeHSet.SetRedisHashByKV("", nil) + + // commit transaction + tx.Commit() + + resp := network.SuccessResponse{ + Code: http.StatusOK, + Msg: "success", + Payload: map[string]interface{}{ + "uuid": request.UUIDStr, + }, + } + c.JSON(http.StatusOK, resp) +} diff --git a/model/attribute_group_recommend_model.go b/model/attribute_group_recommend_model.go index cc36e0d..2db4baa 100644 --- a/model/attribute_group_recommend_model.go +++ b/model/attribute_group_recommend_model.go @@ -141,7 +141,6 @@ func storeAttributeGroup(ctx context.Context, attributeSet orm.AttributeSet, ful // add redis fuzzy search suggestion for token4-token7 type configTerm = fmt.Sprintf("%s.%s", isLocalFullPath, colParams.AttributeType) - fmt.Printf("is local full path attribute configTerm:%v\n", configTerm) sug = append(sug, redisearch.Suggestion{ Term: configTerm, Score: constants.DefaultScore, diff --git a/network/component_attribute_update_request.go b/network/component_attribute_update_request.go new file mode 100644 index 0000000..03bf5b3 --- /dev/null +++ b/network/component_attribute_update_request.go @@ -0,0 +1,16 @@ +// Package network define struct of network operation +package network + +// ComponentAttributeUpdateInfo defines circuit diagram component attribute params info +type ComponentAttributeUpdateInfo struct { + UUIDStr string `json:"uuid"` + AttributeConfigs []ComponentAttributeConfig `json:"attributes"` +} + +// ComponentAttributeConfig defines request params of circuit diagram component attribute update config +type ComponentAttributeConfig struct { + AttributeExtendType string `json:"attribute_extend_type"` + AttributeName string `json:"attribute_name"` + AttributeVal string `json:"attribute_val"` + AttributeFieldType string `json:"attribute_field_type"` +}