This commit is contained in:
Wyle.Gong-巩文昕
2025-04-22 16:42:48 +08:00
commit 67b0ad2723
95 changed files with 10508 additions and 0 deletions
+236
View File
@@ -0,0 +1,236 @@
package graph_link
import (
"app/cfg"
"app/models"
"app/utils"
"encoding/json"
"errors"
"fmt"
"io"
"github.com/google/uuid"
"github.com/veypi/OneBD/rest"
"gorm.io/gorm"
)
var _ = Router.Get("/:id/", getHandle)//TODO
var _ = Router.Get("", getHandle)
func getHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
stageID, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少stage_id")
}
var links []models.GraphLink
if err := cfg.DB().Where("stage_id = ?", stageID).Find(&links).Error; err != nil {
return nil, err
}
return links, nil
}
// 获取单个连接详情
func getOneHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
id, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少id")
}
var link models.GraphLink
if err := cfg.DB().Where("id = ?", id).First(&link).Error; err != nil {
return nil, err
}
sourceNode, _ := link.SourceNode(cfg.DB())
targetNode, _ := link.TargetNode(cfg.DB())
return map[string]interface{}{
"link": link,
"source_node": sourceNode,
"target_node": targetNode,
}, nil
}
var _ = Router.Post("", postHandle)
// 创建图形连接
func postHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
link := &models.GraphLink{}
if err := json.NewDecoder(x.Request.Body).Decode(&link); err != nil {
return nil, err
}
link.ID = uuid.New().String()[0:32]
// 如果没有提供LinkID,则生成一个
if link.LinkID == "" {
link.LinkID = fmt.Sprintf("%s-%s", link.SourceID, link.TargetID)
}
// 验证源节点是否存在
var sourceNode models.GraphNode
if err := cfg.DB().Where("instance_id = ?", link.SourceID).First(&sourceNode).Error; err != nil {
return nil, errors.New("源节点不存在")
}
// 验证目标节点是否存在
var targetNode models.GraphNode
if err := cfg.DB().Where("instance_id = ?", link.TargetID).First(&targetNode).Error; err != nil {
return nil, errors.New("目标节点不存在")
}
// 验证两个节点是否在同一个阶段
if sourceNode.StageID != targetNode.StageID {
return nil, errors.New("源节点和目标节点必须在同一个阶段")
}
// 设置阶段ID
link.StageID = sourceNode.StageID
// 验证是否已存在相同的连接
var count int64
if err := cfg.DB().Model(&models.GraphLink{}).Where("source_id = ? AND target_id = ?", link.SourceID, link.TargetID).Count(&count).Error; err != nil {
return nil, err
}
if count > 0 {
return nil, errors.New("已存在相同的连接")
}
if err := cfg.DB().Create(&link).Error; err != nil {
return nil, err
}
return link, nil
}
var _ = Router.Patch("/:id/", patchHandle)
// 更新图形连接
func patchHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
// 从URL获取ID
body, err := io.ReadAll(x.Request.Body)
if err != nil {
return nil, fmt.Errorf("读取请求体失败: %v", err)
}
id, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少id")
}
var updateMap map[string]interface{}
if err := json.Unmarshal(body, &updateMap); err != nil {
return nil, fmt.Errorf("解析JSON失败: %v", err)
}
// 先检查连接是否存在
var link models.GraphLink
if err := cfg.DB().Where("id = ?", id).First(&link).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("连接不存在")
}
return nil, err
}
// 如果更新包含source_id或target_id,需要验证节点是否存在和是否在同一阶段
sourceID, hasSourceID := updateMap["source_id"]
targetID, hasTargetID := updateMap["target_id"]
if hasSourceID || hasTargetID {
newSourceID := link.SourceID
newTargetID := link.TargetID
if hasSourceID {
var ok bool
newSourceID, ok = sourceID.(string)
if !ok {
return nil, errors.New("source_id 必须是字符串类型")
}
}
if hasTargetID {
var ok bool
newTargetID, ok = targetID.(string)
if !ok {
return nil, errors.New("target_id 必须是字符串类型")
}
}
// 验证源节点是否存在
var sourceNode models.GraphNode
if err := cfg.DB().Where("instance_id = ?", newSourceID).First(&sourceNode).Error; err != nil {
return nil, errors.New("源节点不存在")
}
// 验证目标节点是否存在
var targetNode models.GraphNode
if err := cfg.DB().Where("instance_id = ?", newTargetID).First(&targetNode).Error; err != nil {
return nil, errors.New("目标节点不存在")
}
// 验证两个节点是否在同一个阶段
if sourceNode.StageID != targetNode.StageID {
return nil, errors.New("源节点和目标节点必须在同一个阶段")
}
// 验证是否已存在相同的连接
var count int64
if err := cfg.DB().Model(&models.GraphLink{}).Where("id != ? AND source_id = ? AND target_id = ?", id, newSourceID, newTargetID).Count(&count).Error; err != nil {
return nil, err
}
if count > 0 {
return nil, errors.New("已存在相同的连接")
}
// 更新阶段ID
updateMap["stage_id"] = sourceNode.StageID
// 更新LinkID
updateMap["link_id"] = fmt.Sprintf("%s-%s", newSourceID, newTargetID)
}
// 删除不允许更新的字段
delete(updateMap, "id")
// 只更新提供的字段
if len(updateMap) > 0 {
if err := cfg.DB().Model(&link).Updates(updateMap).Error; err != nil {
return nil, err
}
}
// 重新查询更新后的完整数据
if err := cfg.DB().Where("id = ?", id).First(&link).Error; err != nil {
return nil, err
}
return link, nil
}
var _ = Router.Delete("/:id/", deleteHandle)
// 删除图形连接
func deleteHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
id, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少id")
}
var link models.GraphLink
if err := cfg.DB().Where("id = ?", id).First(&link).Error; err != nil {
return nil, err
}
// 删除连接
if err := cfg.DB().Delete(&link).Error; err != nil {
return nil, err
}
return map[string]interface{}{
"msg": "删除成功",
}, nil
}
var _ = Router.Any("/*", anyHandle)
func anyHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
return nil, nil
}
+7
View File
@@ -0,0 +1,7 @@
package graph_link
import (
"github.com/veypi/OneBD/rest"
)
var Router = rest.NewRouter()