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

277 lines
7.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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())
}