277 lines
7.3 KiB
Go
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())
|
||
}
|