|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections.ObjectModel;
|
|
|
using System.ComponentModel;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
using AI.Models.Form;
|
|
|
|
|
|
namespace AI.Models.SpecialMessages
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 表单请求特殊消息 - 在聊天流中显示可填写的表单
|
|
|
/// </summary>
|
|
|
public class FormRequestMessage : ISpecialMessage, INotifyPropertyChanged
|
|
|
{
|
|
|
private string _submitLabel = "提交";
|
|
|
|
|
|
/// <summary>消息唯一标识符</summary>
|
|
|
public string Id { get; set; } = Guid.NewGuid().ToString();
|
|
|
|
|
|
/// <summary>类型名称</summary>
|
|
|
public string TypeName => "Form";
|
|
|
|
|
|
/// <summary>不需要实时更新</summary>
|
|
|
public bool IsLive => false;
|
|
|
|
|
|
/// <summary>表单定义(只读)</summary>
|
|
|
public FormDefinition Definition { get; }
|
|
|
|
|
|
/// <summary>带当前值的字段列表,用于绑定与提交</summary>
|
|
|
public ObservableCollection<FormFieldEntry> FieldsWithValues { get; } = new ObservableCollection<FormFieldEntry>();
|
|
|
|
|
|
/// <summary>提交按钮文案(可从 Definition 覆盖)</summary>
|
|
|
public string SubmitLabel
|
|
|
{
|
|
|
get => _submitLabel;
|
|
|
set => SetProperty(ref _submitLabel, value);
|
|
|
}
|
|
|
|
|
|
public FormRequestMessage(FormDefinition definition)
|
|
|
{
|
|
|
Definition = definition ?? throw new ArgumentNullException(nameof(definition));
|
|
|
_submitLabel = definition.SubmitLabel;
|
|
|
|
|
|
foreach (var f in definition.Fields)
|
|
|
{
|
|
|
var entry = new FormFieldEntry
|
|
|
{
|
|
|
Id = f.Id,
|
|
|
Label = f.Label,
|
|
|
Description = f.Description,
|
|
|
Type = f.Type,
|
|
|
Required = f.Required,
|
|
|
DefaultValue = f.DefaultValue,
|
|
|
Options = f.Options,
|
|
|
Min = f.Min,
|
|
|
Max = f.Max,
|
|
|
Step = f.Step,
|
|
|
MaxLength = f.MaxLength,
|
|
|
Placeholder = f.Placeholder,
|
|
|
DefaultValues = f.DefaultValues != null ? new List<string>(f.DefaultValues) : null,
|
|
|
CurrentValue = f.DefaultValue?.ToString() ?? string.Empty,
|
|
|
};
|
|
|
if (f.Type == FormFieldType.MultiSelect)
|
|
|
{
|
|
|
if (f.DefaultValues != null && f.DefaultValues.Count > 0)
|
|
|
{
|
|
|
foreach (var v in f.DefaultValues)
|
|
|
entry.SelectedValues.Add(v);
|
|
|
}
|
|
|
else if (f.DefaultValue is System.Collections.IEnumerable en && f.DefaultValue is not string)
|
|
|
{
|
|
|
foreach (var v in en)
|
|
|
entry.SelectedValues.Add(v?.ToString() ?? string.Empty);
|
|
|
}
|
|
|
else if (f.DefaultValue is string defStr && !string.IsNullOrEmpty(defStr))
|
|
|
{
|
|
|
foreach (var v in defStr.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
|
|
entry.SelectedValues.Add(v);
|
|
|
}
|
|
|
if (f.Options != null)
|
|
|
{
|
|
|
foreach (var opt in f.Options)
|
|
|
entry.MultiSelectOptions.Add(new MultiSelectOptionItem(entry, opt, entry.SelectedValues.Contains(opt)));
|
|
|
}
|
|
|
}
|
|
|
FieldsWithValues.Add(entry);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>收集当前值,用于提交。Key 为字段 Id,Value 为对象(按 Type 转换)</summary>
|
|
|
public Dictionary<string, object> GetValues()
|
|
|
{
|
|
|
var dict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
|
|
foreach (var entry in FieldsWithValues)
|
|
|
{
|
|
|
var raw = entry.CurrentValue?.Trim() ?? string.Empty;
|
|
|
object value = entry.Type switch
|
|
|
{
|
|
|
FormFieldType.Number => double.TryParse(raw, out var n) ? n : 0d,
|
|
|
FormFieldType.Boolean => raw is "1" or "true" or "True" or "yes" or "是",
|
|
|
FormFieldType.Json => raw,
|
|
|
FormFieldType.MultiSelect => entry.SelectedValues.Count > 0
|
|
|
? new List<string>(entry.SelectedValues)
|
|
|
: (object)raw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList(),
|
|
|
_ => raw,
|
|
|
};
|
|
|
dict[entry.Id] = value;
|
|
|
}
|
|
|
return dict;
|
|
|
}
|
|
|
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
|
|
|
|
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
|
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
|
|
|
|
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
|
|
|
{
|
|
|
if (EqualityComparer<T>.Default.Equals(field, value))
|
|
|
return false;
|
|
|
field = value;
|
|
|
OnPropertyChanged(propertyName);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
}
|