using System.Text.Json;
using System.Text.Json.Serialization;
using Workflow.Domain.Enums;
namespace Workflow.Domain.Engine;
///
/// X6 graph 的强类型模型,与 X6 toJSON/fromJSON 原生格式兼容。
/// 替代裸 JsonDocument,供 ProcessEngine / 校验器 / 迁移脚本统一读写。
/// 顶层结构为 { nodes: [], edges: [] }(X6 fromJSON 支持的两种等价格式之一)。
///
public sealed class WorkflowGraph
{
[JsonPropertyName("nodes")]
public List Nodes { get; set; } = new();
[JsonPropertyName("edges")]
public List Edges { get; set; } = new();
/// 空图工厂(容错用)。
public static WorkflowGraph Empty() => new();
}
///
/// X6 节点。shape 决定渲染器并反推 NodeType(见 );
/// 业务配置统一进 data;x/y/width/height/ports 为几何与渲染信息。
///
public sealed class GraphNode
{
[JsonPropertyName("id")]
public string Id { get; set; } = string.Empty;
[JsonPropertyName("shape")]
public string Shape { get; set; } = string.Empty;
[JsonPropertyName("x")]
public double X { get; set; }
[JsonPropertyName("y")]
public double Y { get; set; }
[JsonPropertyName("width")]
public double? Width { get; set; }
[JsonPropertyName("height")]
public double? Height { get; set; }
[JsonPropertyName("angle")]
public double? Angle { get; set; }
[JsonPropertyName("visible")]
public bool? Visible { get; set; }
/// 业务数据(节点配置)。替代旧 WorkflowNode.Config 字符串字段。
[JsonPropertyName("data")]
public JsonElement? Data { get; set; }
/// 显示名(对应旧 WorkflowNode.Name)。
public string? GetTitle() => Data.TryGetString("title");
[JsonPropertyName("ports")]
public JsonElement? Ports { get; set; }
}
///
/// X6 边。source/target 用 { cell, port } 结构;几何信息(vertices/router/connector)放顶层;
/// 业务字段(edgeType/condition/order)放 data。
///
public sealed class GraphEdge
{
[JsonPropertyName("id")]
public string Id { get; set; } = string.Empty;
[JsonPropertyName("shape")]
public string? Shape { get; set; }
[JsonPropertyName("source")]
public GraphEndpoint Source { get; set; } = new();
[JsonPropertyName("target")]
public GraphEndpoint Target { get; set; } = new();
/// 业务数据:edgeType / condition / order。
[JsonPropertyName("data")]
public JsonElement? Data { get; set; }
[JsonPropertyName("label")]
public JsonElement? Label { get; set; }
[JsonPropertyName("vertices")]
public List? Vertices { get; set; }
[JsonPropertyName("router")]
public JsonElement? Router { get; set; }
[JsonPropertyName("connector")]
public JsonElement? Connector { get; set; }
/// 边类型(Normal=0/Approved=1/Rejected=2)。缺省为 Normal。
public EdgeType GetEdgeType() => Data.TryGetInt32("edgeType") is { } v ? (EdgeType)v : EdgeType.Normal;
/// 条件表达式(Condition/ExclusiveGateway 出边)。
public string? GetCondition() => Data.TryGetString("condition");
/// 分支评估顺序(值小优先)。
public int GetOrder() => Data.TryGetInt32("order") ?? 0;
}
public sealed class GraphEndpoint
{
/// 节点 id(对应 GraphNode.Id)。
[JsonPropertyName("cell")]
public string? Cell { get; set; }
/// 端口 id(top/right/bottom/left)。
[JsonPropertyName("port")]
public string? Port { get; set; }
}
public sealed class GraphPoint
{
[JsonPropertyName("x")]
public double X { get; set; }
[JsonPropertyName("y")]
public double Y { get; set; }
}
///
/// JsonElement? 安全取值扩展:统一处理 Nullable 解构与 ValueKind 校验,
/// 避免 WorkflowGraph 各 getter 重复 null 检查。
///
internal static class GraphJsonExtensions
{
public static string? TryGetString(this JsonElement? element, string name) =>
element is { ValueKind: JsonValueKind.Object } el
&& el.TryGetProperty(name, out var p)
&& p.ValueKind == JsonValueKind.String
? p.GetString()
: null;
public static int? TryGetInt32(this JsonElement? element, string name) =>
element is { ValueKind: JsonValueKind.Object } el
&& el.TryGetProperty(name, out var p)
&& (p.ValueKind == JsonValueKind.Number || p.ValueKind == JsonValueKind.String)
&& p.TryGetInt32(out var n)
? n
: null;
}