Files
ttstd-infinite-canvas/backend/internal/repository/canvas_extensions.go
T

277 lines
7.3 KiB
Go

package repository
import (
"errors"
"fmt"
"time"
"yingce/backend/internal/model"
)
// Canvas 数据访问层扩展
// Canvas 获取画布
func (r *Repository) Canvas(userID, canvasID string) (model.Canvas, error) {
var canvas model.Canvas
err := r.db.Where("user_id = ? AND id = ?", userID, canvasID).First(&canvas).Error
if err != nil {
return canvas, fmt.Errorf("get canvas: %w", err)
}
return canvas, nil
}
// GetCanvas is the explicit repository name used by Agent policy builders.
func (r *Repository) GetCanvas(userID, canvasID string) (model.Canvas, error) {
return r.Canvas(userID, canvasID)
}
func (r *Repository) CanvasNodes(userID, canvasID string) ([]model.CanvasNode, error) {
var nodes []model.CanvasNode
err := r.db.Where("canvas_id IN (SELECT id FROM canvases WHERE user_id = ? AND id = ?)", userID, canvasID).
Find(&nodes).Error
if err != nil {
return nil, fmt.Errorf("get canvas nodes: %w", err)
}
return nodes, nil
}
// CanvasNode 获取单个节点
func (r *Repository) CanvasNode(userID, canvasID, nodeID string) (model.CanvasNode, error) {
var node model.CanvasNode
err := r.db.Where("id = ? AND canvas_id IN (SELECT id FROM canvases WHERE user_id = ? AND id = ?)",
nodeID, userID, canvasID).First(&node).Error
if err != nil {
return node, fmt.Errorf("get canvas node: %w", err)
}
return node, nil
}
// CreateCanvasNode 创建节点
func (r *Repository) CreateCanvasNode(userID, canvasID string, node model.CanvasNode) (model.CanvasNode, error) {
// 验证画布存在且属于用户
var canvas model.Canvas
err := r.db.Where("user_id = ? AND id = ?", userID, canvasID).First(&canvas).Error
if err != nil {
return node, fmt.Errorf("canvas not found: %w", err)
}
// 生成节点 ID
if node.ID == "" {
node.ID = generateNodeID()
}
node.CanvasID = canvasID
// 创建节点
err = r.db.Create(&node).Error
if err != nil {
return node, fmt.Errorf("create canvas node: %w", err)
}
return node, nil
}
// UpdateCanvasNode 更新节点
func (r *Repository) UpdateCanvasNode(userID, canvasID, nodeID string, update model.CanvasNodeUpdate) (model.CanvasNode, error) {
// 获取现有节点
node, err := r.CanvasNode(userID, canvasID, nodeID)
if err != nil {
return node, err
}
// 应用更新
if update.Content != nil {
node.Content = *update.Content
}
if update.Position != nil {
node.Position = update.Position
}
if update.Size != nil {
node.Size = update.Size
}
if update.ParentID != nil {
node.ParentID = update.ParentID
}
if update.Metadata != nil {
if node.Metadata == nil {
node.Metadata = make(map[string]interface{})
}
for k, v := range update.Metadata {
node.Metadata[k] = v
}
}
// 保存
err = r.db.Save(&node).Error
if err != nil {
return node, fmt.Errorf("update canvas node: %w", err)
}
return node, nil
}
// DeleteCanvasNode 删除节点,可选递归删除子节点。
func (r *Repository) DeleteCanvasNode(userID, canvasID, nodeID string, recursive ...bool) error {
// 验证节点存在且属于用户
_, err := r.CanvasNode(userID, canvasID, nodeID)
if err != nil {
return err
}
if len(recursive) > 0 && recursive[0] {
var children []model.CanvasNode
if err := r.db.Where("canvas_id = ? AND parent_id = ?", canvasID, nodeID).Find(&children).Error; err != nil {
return fmt.Errorf("list child nodes: %w", err)
}
for _, child := range children {
if err := r.DeleteCanvasNode(userID, canvasID, child.ID, true); err != nil {
return err
}
}
}
// 删除节点
if err := r.db.Where("id = ? AND canvas_id = ?", nodeID, canvasID).Delete(&model.CanvasNode{}).Error; err != nil {
return fmt.Errorf("delete canvas node: %w", err)
}
return nil
}
// GetCanvasNodeChildren 返回指定父节点的直接子节点。
func (r *Repository) GetCanvasNodeChildren(userID, canvasID, parentID string) ([]model.CanvasNode, error) {
if _, err := r.CanvasNode(userID, canvasID, parentID); err != nil {
return nil, err
}
var children []model.CanvasNode
if err := r.db.Where("canvas_id = ? AND parent_id = ?", canvasID, parentID).Find(&children).Error; err != nil {
return nil, fmt.Errorf("get canvas node children: %w", err)
}
return children, nil
}
// CanvasNodes 获取画布所有节点
func (r *Repository) CreateCanvasRelationship(userID, canvasID string, rel model.CanvasRelationship) error {
// 验证节点存在
_, err := r.CanvasNode(userID, canvasID, rel.From)
if err != nil {
return fmt.Errorf("source node not found: %w", err)
}
_, err = r.CanvasNode(userID, canvasID, rel.To)
if err != nil {
return fmt.Errorf("target node not found: %w", err)
}
// 存储关系到 from 节点的 metadata
fromNode, err := r.CanvasNode(userID, canvasID, rel.From)
if err != nil {
return err
}
if fromNode.Metadata == nil {
fromNode.Metadata = make(map[string]interface{})
}
relationshipsKey := "relationships"
relationships, ok := fromNode.Metadata[relationshipsKey].([]interface{})
if !ok {
relationships = []interface{}{}
}
// 检查关系是否已存在
for _, r := range relationships {
if relMap, ok := r.(map[string]interface{}); ok {
if relMap["to"] == rel.To && relMap["type"] == rel.Type {
return nil // 关系已存在
}
}
}
// 添加新关系
relationships = append(relationships, map[string]interface{}{
"to": rel.To,
"type": rel.Type,
})
fromNode.Metadata[relationshipsKey] = relationships
// 保存
err = r.db.Save(&fromNode).Error
if err != nil {
return fmt.Errorf("save relationship: %w", err)
}
return nil
}
// DeleteCanvasRelationship 删除节点关系
func (r *Repository) DeleteCanvasRelationship(userID, canvasID, from, to, relType string) error {
fromNode, err := r.CanvasNode(userID, canvasID, from)
if err != nil {
return err
}
if fromNode.Metadata == nil {
return errors.New("relationship not found")
}
relationshipsKey := "relationships"
relationships, ok := fromNode.Metadata[relationshipsKey].([]interface{})
if !ok {
return errors.New("relationship not found")
}
// 过滤掉要删除的关系
filtered := make([]interface{}, 0)
found := false
for _, r := range relationships {
if relMap, ok := r.(map[string]interface{}); ok {
if relMap["to"] == to && relMap["type"] == relType {
found = true
continue
}
}
filtered = append(filtered, r)
}
if !found {
return errors.New("relationship not found")
}
fromNode.Metadata[relationshipsKey] = filtered
// 保存
err = r.db.Save(&fromNode).Error
if err != nil {
return fmt.Errorf("delete relationship: %w", err)
}
return nil
}
// CreateApproval 创建审批
func (r *Repository) CreateApproval(approval *model.Approval) error {
return r.db.Create(approval).Error
}
// GetApproval 获取审批
func (r *Repository) GetApproval(approvalID string) (*model.Approval, error) {
var approval model.Approval
err := r.db.Where("id = ?", approvalID).First(&approval).Error
if err != nil {
return nil, err
}
return &approval, nil
}
// UpdateApprovalDecision 更新审批决策
func (r *Repository) UpdateApprovalDecision(approvalID, decision string) error {
return r.db.Model(&model.Approval{}).
Where("id = ?", approvalID).
Updates(map[string]interface{}{
"status": "completed",
"decision": decision,
}).Error
}
// generateNodeID 生成节点 ID(简化实现)
func generateNodeID() string {
return fmt.Sprintf("node_%d", time.Now().UnixNano())
}