Cube/NewLife.CubeNC/ViewModels/FieldCollection.cs

331 lines
9.7 KiB
C#
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.

using System.Reflection;
using NewLife.Cube.ViewModels;
using XCode;
using XCode.Configuration;
namespace NewLife.Cube;
/// <summary>分组可见委托</summary>
/// <param name="entity"></param>
/// <param name="group"></param>
/// <returns></returns>
public delegate Boolean GroupVisibleDelegate(IEntity entity, String group);
/// <summary>字段集合</summary>
public class FieldCollection : List<DataField>
{
#region
/// <summary>类型</summary>
public ViewKinds Kind { get; set; }
/// <summary>工厂</summary>
public IEntityFactory Factory { get; set; }
/// <summary>需要隐藏的分组名</summary>
public ICollection<String> HiddenGroups { get; } = new HashSet<String>();
/// <summary>是否显示分组</summary>
public GroupVisibleDelegate GroupVisible { get; set; }
#endregion
#region
/// <summary>实例化一个字段集合</summary>
/// <param name="kind"></param>
public FieldCollection(ViewKinds kind) => Kind = kind;
/// <summary>使用工厂实例化一个字段集合</summary>
/// <param name="factory"></param>
/// <param name="kind"></param>
public FieldCollection(IEntityFactory factory, ViewKinds kind)
{
Kind = kind;
Factory = factory;
//AddRange(Factory.Fields);
if (factory != null)
{
foreach (var item in factory.Fields)
{
Add(item);
}
switch (kind)
{
case ViewKinds.List:
SetRelation(false);
break;
case ViewKinds.Detail:
SetRelation(true);
break;
case ViewKinds.AddForm:
SetRelation(true);
//RemoveCreateField();
RemoveUpdateField();
break;
case ViewKinds.EditForm:
SetRelation(true);
break;
case ViewKinds.Search:
break;
default:
SetRelation(false);
break;
}
}
}
#endregion
#region
/// <summary>为指定字段创建数据字段,可以为空</summary>
/// <param name="field"></param>
/// <returns></returns>
public DataField Create(FieldItem field)
{
DataField df = Kind switch
{
ViewKinds.List => new ListField(),
ViewKinds.Detail or ViewKinds.AddForm or ViewKinds.EditForm => new FormField(),
_ => throw new NotImplementedException(),
};
//df.Sort = Count + 1;
//df.Sort = Count == 0 ? 1 : (this[Count - 1].Sort + 1);
if (field != null) df.Fill(field);
return df;
}
/// <summary>为指定字段创建数据字段</summary>
/// <param name="field"></param>
/// <returns></returns>
public DataField Add(FieldItem field)
{
var df = Create(field);
Add(df);
return df;
}
/// <summary>设置扩展关系</summary>
/// <param name="isForm">是否表单使用</param>
/// <returns></returns>
public FieldCollection SetRelation(Boolean isForm)
{
var type = Factory.EntityType;
// 扩展属性
foreach (var pi in type.GetProperties())
{
// 处理带有Map特性的扩展属性
var map = pi.GetCustomAttribute<MapAttribute>();
if (map != null) Replace(map.Name, pi.Name);
}
if (!isForm)
{
// 长字段和密码字段不显示
NoPass();
}
return this;
}
private void NoPass()
{
for (var i = Count - 1; i >= 0; i--)
{
var fi = this[i];
if (fi.Type == typeof(String) && fi.MapField.IsNullOrEmpty())
{
if (fi.Length <= 0 || fi.Length > 1000 ||
fi.Name.EqualIgnoreCase("password", "pass", "pwd", "Secret"))
{
RemoveAt(i);
}
}
}
}
#endregion
#region
/// <summary>查找指定字段</summary>
/// <param name="name"></param>
/// <returns></returns>
public Int32 FindIndex(String name) => FindIndex(e => e.Name.EqualIgnoreCase(name));
/// <summary>从AllFields中添加字段可以是扩展属性</summary>
/// <param name="name"></param>
/// <returns></returns>
public FieldCollection AddField(String name)
{
var fi = Factory.AllFields.FirstOrDefault(e => e.Name.EqualIgnoreCase(name));
if (fi != null) Add(fi);
return this;
}
/// <summary>删除字段</summary>
/// <param name="names"></param>
/// <returns></returns>
public FieldCollection RemoveField(params String[] names)
{
foreach (var item in names)
{
if (!item.IsNullOrEmpty())
{
// 模糊匹配
if (item.Contains("*"))
RemoveAll(e => item.IsMatch(e.Name));
else
RemoveAll(e => e.Name.EqualIgnoreCase(item));
}
}
return this;
}
/// <summary>操作字段列表,把旧项换成新项</summary>
/// <param name="oriName"></param>
/// <param name="newName"></param>
/// <returns></returns>
public FieldCollection Replace(String oriName, String newName)
{
var idx = FindIndex(e => e.Name.EqualIgnoreCase(oriName));
if (idx < 0) return this;
var fi = Factory.AllFields.FirstOrDefault(e => e.Name.EqualIgnoreCase(newName));
if (fi == null) return this;
// 如果本身就存在目标项,则删除
var idx2 = FindIndex(e => e.Name.EqualIgnoreCase(fi.Name));
if (idx2 >= 0) RemoveAt(idx2);
this[idx] = Create(fi);
return this;
}
#endregion
#region /
/// <summary>设置是否显示创建信息</summary>
/// <returns></returns>
public FieldCollection RemoveCreateField()
{
RemoveAll(e => e.Name.EqualIgnoreCase("CreateUserID", "CreateUser", "CreateTime", "CreateIP"));
return this;
}
/// <summary>设置是否显示更新信息</summary>
/// <returns></returns>
public FieldCollection RemoveUpdateField()
{
RemoveAll(e => e.Name.EqualIgnoreCase("UpdateUserID", "UpdateUser", "UpdateTime", "UpdateIP"));
return this;
}
/// <summary>设置是否显示备注信息</summary>
/// <returns></returns>
public FieldCollection RemoveRemarkField()
{
RemoveAll(e => e.Name.EqualIgnoreCase("Remark", "Description"));
return this;
}
#endregion
#region
/// <summary>添加定制字段,插入指定列前后</summary>
/// <param name="name"></param>
/// <param name="beforeName"></param>
/// <param name="afterName"></param>
/// <returns></returns>
public DataField AddDataField(String name, String beforeName = null, String afterName = null)
{
if (name.IsNullOrEmpty()) throw new ArgumentNullException(nameof(name));
var fi = Factory.AllFields.FirstOrDefault(e => e.Name.EqualIgnoreCase(name));
// 有可能fi为空创建一个所有字段都为空的field
var field = Create(fi);
if (field.Name.IsNullOrEmpty()) field.Name = name;
if (!beforeName.IsNullOrEmpty())
{
var idx = FindIndex(beforeName);
if (idx >= 0)
Insert(idx, field);
else
Add(field);
}
else if (!afterName.IsNullOrEmpty())
{
var idx = FindIndex(afterName);
if (idx >= 0)
Insert(idx + 1, field);
else
Add(field);
}
else
Add(field);
return field;
}
/// <summary>添加定制字段,插入指定列前后</summary>
/// <param name="name"></param>
/// <param name="beforeName"></param>
/// <param name="afterName"></param>
/// <returns></returns>
public ListField AddListField(String name, String beforeName = null, String afterName = null) => AddDataField(name, beforeName, afterName) as ListField;
/// <summary>获取指定名称的定制字段</summary>
/// <param name="name"></param>
/// <returns></returns>
public DataField GetField(String name) => this.FirstOrDefault(e => name.EqualIgnoreCase(e.Name, e.MapField));
#endregion
#region
/// <summary>按类别分组获取字段列表</summary>
/// <param name="entity">实体对象</param>
/// <returns></returns>
public IDictionary<String, IList<DataField>> GroupByCategory(IEntity entity)
{
var dic = new Dictionary<String, IList<DataField>>();
var groupFields = this.GroupBy(e => e.Category + "").ToList();
foreach (var item in groupFields)
{
var key = item.Key.IsNullOrEmpty() ? "默认" : item.Key;
if (HiddenGroups.Contains(key)) continue;
if (GroupVisible != null && !GroupVisible(entity, key)) continue;
if (!dic.TryGetValue(key, out var list))
dic[key] = list = new List<DataField>();
//(list as List<DataField>).AddRange(item);
foreach (var elm in item)
{
list.Add(elm);
}
}
return dic;
}
#endregion
#region
/// <summary>克隆集合</summary>
/// <returns></returns>
public FieldCollection Clone()
{
var fs = new FieldCollection(Kind);
foreach (var item in this)
{
fs.Add(item.Clone());
}
return fs;
}
#endregion
}