using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using YamlDotNet.Serialization;
namespace AI.Models.SpecialMessages
{
///
/// 参数集单条字段的控件类型(用于可编辑参数卡片)
///
public enum ParameterSetFieldType
{
/// 单行文本
Text,
/// 数值
Number,
/// 下拉选择(如成图算法)
Choice,
/// 文件路径,带“选择文件”按钮
FilePath,
}
///
/// 单条参数项:名称、当前值(可编辑)、描述、控件类型及选项。
///
public class ParameterSetItem : INotifyPropertyChanged
{
private string _name = string.Empty;
private string _valueText = string.Empty;
private string _description = string.Empty;
private ParameterSetFieldType _fieldType = ParameterSetFieldType.Text;
public string Name
{
get => _name;
set => SetProperty(ref _name, value ?? string.Empty);
}
/// 当前值的展示/编辑文本
public string ValueText
{
get => _valueText;
set
{
if (SetProperty(ref _valueText, value ?? string.Empty))
{
OnPropertyChanged(nameof(NumericValue));
}
}
}
///
/// 数字值(仅 Number 类型控件绑定使用)。
/// 写回时仅在 FieldType == Number 时才更新 ValueText,
/// 防止不可见 NumericUpDown 的双向绑定覆盖 FilePath / Text 等字段的值。
///
public double NumericValue
{
get => double.TryParse(
_valueText?.Trim(),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture,
out var n) ? n : 0d;
set
{
if (_fieldType == ParameterSetFieldType.Number)
{
var s = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
if (SetProperty(ref _valueText, s, nameof(ValueText)))
{
OnPropertyChanged(nameof(NumericValue));
}
}
}
}
public string Description
{
get => _description;
set => SetProperty(ref _description, value ?? string.Empty);
}
/// 控件类型(Text / Number / Choice / FilePath)
public ParameterSetFieldType FieldType
{
get => _fieldType;
set => SetProperty(ref _fieldType, value);
}
/// 下拉选项(Choice 类型时使用)
public List Options { get; set; } = new List();
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
///
/// 参数集特殊消息 - 用于在聊天流中展示一组「名称 / 值 / 描述」参数(如网格化参数等),由基本消息样式组合而成。
///
public class ParameterSetMessage : ISpecialMessage, INotifyPropertyChanged
{
private string _title = "参数";
public string Id { get; set; } = Guid.NewGuid().ToString();
public string TypeName => "ParameterSet";
public bool IsLive => false;
public string Title
{
get => _title;
set => SetProperty(ref _title, value ?? string.Empty);
}
/// 参数项列表(名称、值、描述)
public ObservableCollection Items { get; } = new ObservableCollection();
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
///
/// 从 YAML 文本填充参数集。格式示例:
/// Input:
/// Value: ...
/// Description: 散点数据文件路径
/// Type: FilePath
/// 支持 PascalCase / camelCase 键(Value/value, Type/type 等)。
///
public void LoadFromJson(string text)
{
Items.Clear();
if (string.IsNullOrWhiteSpace(text)) return;
LoadFromYamlInternal(text.Trim());
}
///
/// 从 YAML 解析参数集。根级为参数名(如 Input, Faultage),每项含 Value/Description/Type/Options。
/// 支持根级单键包装(如 parameters: 下再挂 Input/Faultage/...),会自动解包一层。
///
private void LoadFromYamlInternal(string yaml)
{
try
{
var deserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.Build();
var root = deserializer.Deserialize>(yaml);
if (root == null || root.Count == 0) return;
// 若根级只有一键且其值为映射,认为是 parameters: { input: ..., faultage: ... },用内层作为参数表
IEnumerable> paramsIter = root;
if (root.Count == 1)
{
var singleValue = root.Values.First();
if (singleValue is Dictionary