新增底部工具栏标签<util-footer-toolbar>, 封装 Ng-Alain 底部工具栏 <footer-toolbar> 组件.

新增查询表单标签 <util-search-form>,自动设置内部栅格列 span.
<util-table> 标签新增 enable-custom-column 属性,开启自定义列设置.
<util-a> 标签新增 show-table-settings 属性,点击弹出表格自定义列设置界面.
<util-a> 标签新增 is-search 属性, 创建具有展开和收起效果的查询按钮.
修复 Util.Data.EntityFrameworkCore.StoreBase 更新实体验证并发导致的 bug
This commit is contained in:
utilcore
2024-02-18 15:07:54 +08:00
parent 87b5e6b9fe
commit ec00e69ce6
46 changed files with 2116 additions and 817 deletions
@@ -3,7 +3,7 @@ using Util.Data.Stores;
using Util.Exceptions;
using Util.Validation;
namespace Util.Data.EntityFrameworkCore;
namespace Util.Data.EntityFrameworkCore;
/// <summary>
/// 存储器
@@ -133,7 +133,7 @@ public abstract class StoreBase<TEntity, TKey> : IStore<TEntity, TKey>, IFilterS
if ( id.SafeString().IsEmpty() )
return null;
var key = GetKey( id );
if( IsTracking )
if ( IsTracking )
return Set.Find( key );
return Single( t => t.Id.Equals( key ) );
}
@@ -142,7 +142,7 @@ public abstract class StoreBase<TEntity, TKey> : IStore<TEntity, TKey>, IFilterS
/// 获取标识
/// </summary>
protected object GetKey( object id ) {
if( id is TKey )
if ( id is TKey )
return id;
return Util.Helpers.Convert.To<TKey>( id );
}
@@ -158,7 +158,7 @@ public abstract class StoreBase<TEntity, TKey> : IStore<TEntity, TKey>, IFilterS
if ( id.SafeString().IsEmpty() )
return null;
var key = GetKey( id );
if( IsTracking )
if ( IsTracking )
return await Set.FindAsync( new[] { key }, cancellationToken );
return await SingleAsync( t => t.Id.Equals( key ), cancellationToken );
}
@@ -212,7 +212,7 @@ public abstract class StoreBase<TEntity, TKey> : IStore<TEntity, TKey>, IFilterS
}
/// <inheritdoc />
public virtual TEntity Single( Expression<Func<TEntity, bool>> condition,Func<IQueryable<TEntity>, IQueryable<TEntity>> action ) {
public virtual TEntity Single( Expression<Func<TEntity, bool>> condition, Func<IQueryable<TEntity>, IQueryable<TEntity>> action ) {
if ( action == null )
return Single( condition );
return action( Find() ).FirstOrDefault( condition );
@@ -328,7 +328,7 @@ public abstract class StoreBase<TEntity, TKey> : IStore<TEntity, TKey>, IFilterS
/// </summary>
protected virtual void Validate( IEnumerable<TEntity> entities ) {
entities.CheckNull( nameof( entities ) );
foreach ( var entity in entities )
foreach ( var entity in entities )
Validate( entity );
}
@@ -337,7 +337,7 @@ public abstract class StoreBase<TEntity, TKey> : IStore<TEntity, TKey>, IFilterS
/// </summary>
protected virtual void Validate( TEntity entity ) {
entity.CheckNull( nameof( entity ) );
if ( entity is IValidation validation )
if ( entity is IValidation validation )
validation.Validate();
}
@@ -382,6 +382,8 @@ public abstract class StoreBase<TEntity, TKey> : IStore<TEntity, TKey>, IFilterS
protected virtual void ValidateVersion( EntityEntry<TEntity> entry, TEntity entity ) {
if ( entity is not IVersion current )
return;
if ( entry.State == EntityState.Added )
return;
if ( current.Version == null || current.Version.Length == 0 ) {
ThrowConcurrencyException( entity );
return;
@@ -1700,4 +1700,8 @@ public static class AngularConst {
/// 自动换行
/// </summary>
public const string BindWrap = "bind-wrap";
/// <summary>
/// 单元格控件
/// </summary>
public const string BindCellControl = "bind-cell-control";
}
@@ -0,0 +1,47 @@
using Util.Ui.Angular.Builders;
using Util.Ui.Angular.Configs;
using Util.Ui.Configs;
namespace Util.Ui.NgAlain.Components.FooterToolbars.Builders;
/// <summary>
/// 底部工具栏生成器
/// </summary>
public class FooterToolbarBuilder : AngularTagBuilder {
/// <summary>
/// 配置
/// </summary>
private readonly Config _config;
/// <summary>
/// 初始化底部工具栏生成器
/// </summary>
/// <param name="config">配置</param>
public FooterToolbarBuilder( Config config ) : base( config, "footer-toolbar" ) {
_config = config;
}
/// <summary>
/// 配置错误收集
/// </summary>
public FooterToolbarBuilder ErrorCollect() {
AttributeIfNotEmpty( "[errorCollect]", _config.GetValue( UiConst.ErrorCollect ) );
return this;
}
/// <summary>
/// 配置额外信息
/// </summary>
public FooterToolbarBuilder Extra() {
AttributeIfNotEmpty( "extra", _config.GetValue( UiConst.Extra ) );
AttributeIfNotEmpty( "[extra]", _config.GetValue( AngularConst.BindExtra ) );
return this;
}
/// <summary>
/// 配置
/// </summary>
public override void Config() {
base.Config();
ErrorCollect().Extra();
}
}
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Util.Ui.Angular.TagHelpers;
using Util.Ui.Configs;
using Util.Ui.NgAlain.Components.FooterToolbars.Renders;
using Util.Ui.Renders;
namespace Util.Ui.NgAlain.Components.FooterToolbars;
/// <summary>
/// ng-alain 底部工具栏,生成的标签为&lt;footer-toolbar&gt;&lt;/footer-toolbar&gt;
/// </summary>
[HtmlTargetElement( "util-footer-toolbar" )]
public class FooterToolbarTagHelper : AngularTagHelperBase {
/// <summary>
/// [errorCollect],是否收集表单错误,需要放入 form 标签内, 默认值: false
/// </summary>
public string ErrorCollect { get; set; }
/// <summary>
/// extra,额外信息,显示在左边
/// </summary>
public string Extra { get; set; }
/// <summary>
/// [extra],额外信息,显示在左边
/// </summary>
public string BindExtra { get; set; }
/// <inheritdoc />
protected override IRender GetRender( TagHelperContext context, TagHelperOutput output, TagHelperContent content ) {
var config = new Config( context, output, content );
return new FooterToolbarRender( config );
}
}
@@ -0,0 +1,39 @@
using Util.Ui.Angular.Extensions;
using Util.Ui.Builders;
using Util.Ui.Configs;
using Util.Ui.NgAlain.Components.FooterToolbars.Builders;
using Util.Ui.Renders;
namespace Util.Ui.NgAlain.Components.FooterToolbars.Renders;
/// <summary>
/// 底部工具栏渲染器
/// </summary>
public class FooterToolbarRender : RenderBase {
/// <summary>
/// 配置
/// </summary>
private readonly Config _config;
/// <summary>
/// 初始化底部工具栏渲染器
/// </summary>
/// <param name="config">配置</param>
public FooterToolbarRender( Config config ) {
_config = config;
}
/// <summary>
/// 获取标签生成器
/// </summary>
protected override TagBuilder GetTagBuilder() {
var builder = new FooterToolbarBuilder( _config );
builder.Config();
return builder;
}
/// <inheritdoc />
public override IHtmlContent Clone() {
return new FooterToolbarRender( _config.CopyRemoveAttributes() );
}
}
@@ -43,6 +43,10 @@ public class ATagHelper : ButtonTagHelperBase {
/// 扩展属性,是否查询表单链接,折叠时显示展开文本,展开时显示收起文本
/// </summary>
public bool IsSearch { get; set; }
/// <summary>
/// 扩展属性,显示表格设置,参数值为表格标识
/// </summary>
public string ShowTableSettings { get; set; }
/// <inheritdoc />
protected override IRender GetRender( TagHelperContext context, TagHelperOutput output, TagHelperContent content ) {
@@ -4,6 +4,8 @@ using Util.Ui.Enums;
using Util.Ui.NgZorro.Components.Base;
using Util.Ui.NgZorro.Components.Icons.Builders;
using Util.Ui.NgZorro.Configs;
using Util.Ui.NgZorro.Directives.Tooltips;
using Util.Ui.NgZorro.Enums;
namespace Util.Ui.NgZorro.Components.Links.Builders;
@@ -70,8 +72,8 @@ public class ABuilder : ButtonBuilderBase<ABuilder> {
return this;
this.OnClick( "expand=!expand" );
var options = NgZorroOptionsService.GetOptions();
if (options.EnableI18n)
AppendContent("{{" + $"expand?('{I18nKeys.Collapse}'|i18n):('{I18nKeys.Expand}'|i18n)" + "}}");
if ( options.EnableI18n )
AppendContent( "{{" + $"expand?('{I18nKeys.Collapse}'|i18n):('{I18nKeys.Expand}'|i18n)" + "}}" );
else
AppendContent( "{{expand?'收起':'展开'}}" );
var icon = new IconBuilder( _config );
@@ -80,11 +82,29 @@ public class ABuilder : ButtonBuilderBase<ABuilder> {
return this;
}
/// <summary>
/// 配置显示表格设置
/// </summary>
public ABuilder ShowTableSettings() {
var tableId = _config.GetValue( UiConst.ShowTableSettings );
if ( tableId.IsEmpty() )
return this;
this.OnClick( $"ts_{tableId}.show()" );
Class( "btn-table-settings" );
var options = NgZorroOptionsService.GetOptions();
this.TooltipTitle( options.EnableI18n ? "util.tableSettings" : "表格设置" );
var icon = new IconBuilder( _config );
icon.Type( AntDesignIcon.Setting );
AppendContent( icon );
return this;
}
/// <summary>
/// 配置
/// </summary>
public override void Config() {
base.Config();
ConfigButton().Href().Target().Rel().RouterLink().DropdownMenu().DropdownMenuPlacement().IsSearch();
ConfigButton().Href().Target().Rel().RouterLink().DropdownMenu()
.DropdownMenuPlacement().IsSearch().ShowTableSettings();
}
}
@@ -1,7 +1,6 @@
using Util.Ui.Angular.Builders;
using Util.Ui.Angular.Configs;
using Util.Ui.Angular.Extensions;
using Util.Ui.Configs;
using Util.Ui.Extensions;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Components.Tables.Helpers;
@@ -499,6 +498,32 @@ public class TableBuilder : AngularTagBuilder {
return this;
}
/// <summary>
/// 配置自定义列
/// </summary>
public TableBuilder CustomColumn() {
CustomColumn( _config.GetValue( UiConst.CustomColumn ) );
return this;
}
/// <summary>
/// 配置自定义列
/// </summary>
public TableBuilder CustomColumn( string value ) {
AttributeIfNotEmpty( "[nzCustomColumn]", value );
return this;
}
/// <summary>
/// 配置启用自定义列
/// </summary>
public TableBuilder EnableCustomColumn() {
if (_shareConfig.IsEnableCustomColumn == false)
return this;
CustomColumn( $"{_shareConfig.TableSettingsId}.columns" );
return this;
}
/// <summary>
/// 配置事件
/// </summary>
@@ -566,6 +591,7 @@ public class TableBuilder : AngularTagBuilder {
.Layout()
.QueryParam().Url().DeleteUrl()
.Sort().AutoLoad().ConfigKeys()
.CustomColumn().EnableCustomColumn()
.Events();
ConfigAutoCreate();
if ( _shareConfig.IsEnableExtend )
@@ -1,7 +1,6 @@
using Util.Ui.Angular.Builders;
using Util.Ui.Angular.Configs;
using Util.Ui.Builders;
using Util.Ui.Configs;
using Util.Ui.NgZorro.Components.Tables.Builders.Contents;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Enums;
@@ -160,6 +159,34 @@ public class TableColumnBuilder : AngularTagBuilder {
return this;
}
/// <summary>
/// 配置单元格控件
/// </summary>
public virtual TableColumnBuilder CellControl() {
CellControl( _config.GetValue( UiConst.CellControl ) );
AttributeIfNotEmpty( "[nzCellControl]", _config.GetValue( AngularConst.BindCellControl ) );
return this;
}
/// <summary>
/// 配置单元格控件
/// </summary>
/// <param name="value">值</param>
public virtual TableColumnBuilder CellControl( string value ) {
AttributeIfNotEmpty( "nzCellControl", value );
return this;
}
/// <summary>
/// 配置启用自定义列
/// </summary>
public TableColumnBuilder EnableCustomColumn() {
if ( _shareConfig.IsEnableCustomColumn == false )
return this;
CellControl( _shareConfig.CellControl );
return this;
}
/// <summary>
/// 配置事件
/// </summary>
@@ -177,7 +204,7 @@ public class TableColumnBuilder : AngularTagBuilder {
ShowCheckbox().Disabled().Indeterminate().Checked()
.ShowExpand().Expand()
.Left().Right().Align().BreakWord().Ellipsis()
.IndentSize()
.IndentSize().CellControl().EnableCustomColumn()
.Events();
ConfigContent();
}
@@ -1,14 +1,13 @@
using Util.Ui.Angular.Builders;
using Util.Ui.Angular.Configs;
using Util.Ui.Angular.Extensions;
using Util.Ui.Configs;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Components.Tables.Helpers;
using Util.Ui.NgZorro.Configs;
using Util.Ui.NgZorro.Enums;
using Util.Ui.NgZorro.Extensions;
namespace Util.Ui.NgZorro.Components.Tables.Builders;
namespace Util.Ui.NgZorro.Components.Tables.Builders;
/// <summary>
/// 表头单元格标签生成器
@@ -28,7 +27,7 @@ public class TableHeadColumnBuilder : AngularTagBuilder {
/// </summary>
/// <param name="config">配置</param>
/// <param name="shareConfig">表头列共享配置</param>
public TableHeadColumnBuilder( Config config, TableHeadColumnShareConfig shareConfig ) : base( config,"th" ) {
public TableHeadColumnBuilder( Config config, TableHeadColumnShareConfig shareConfig ) : base( config, "th" ) {
_config = config;
_shareConfig = shareConfig;
}
@@ -194,6 +193,8 @@ public class TableHeadColumnBuilder : AngularTagBuilder {
/// 配置列宽
/// </summary>
public TableHeadColumnBuilder Width() {
if ( _shareConfig.IsEnableCustomColumn )
return this;
this.Width( _config.GetValue( UiConst.Width ) );
BindWidth( _config.GetValue( AngularConst.BindWidth ) );
return this;
@@ -352,6 +353,41 @@ public class TableHeadColumnBuilder : AngularTagBuilder {
AppendContent( title );
}
/// <summary>
/// 配置单元格控件
/// </summary>
public virtual TableHeadColumnBuilder CellControl() {
CellControl( _config.GetValue( UiConst.CellControl ) );
AttributeIfNotEmpty( "[nzCellControl]", _config.GetValue( AngularConst.BindCellControl ) );
return this;
}
/// <summary>
/// 配置单元格控件
/// </summary>
/// <param name="value">值</param>
public virtual TableHeadColumnBuilder CellControl( string value ) {
AttributeIfNotEmpty( "nzCellControl", value );
return this;
}
/// <summary>
/// 配置启用自定义列
/// </summary>
public TableHeadColumnBuilder EnableCustomColumn() {
return EnableCustomColumn( _shareConfig.CellControl );
}
/// <summary>
/// 配置启用自定义列
/// </summary>
public TableHeadColumnBuilder EnableCustomColumn( string cellControl ) {
if ( _shareConfig.IsEnableCustomColumn == false )
return this;
CellControl( cellControl );
return this;
}
/// <summary>
/// 配置事件
/// </summary>
@@ -382,6 +418,7 @@ public class TableHeadColumnBuilder : AngularTagBuilder {
.Width().Left().Right().Align().BreakWord().Ellipsis()
.Colspan().Rowspan().ColumnKey()
.TitleOperation().Title()
.CellControl().EnableCustomColumn()
.Events()
.CheckBox().Radio().LineNumber();
}
@@ -498,16 +535,18 @@ public class TableHeadColumnBuilder : AngularTagBuilder {
if ( column.IsSort )
Sort( column.Column );
Title( column.Title );
this.Width( column.Width );
if ( _shareConfig.IsEnableCustomColumn == false )
this.Width( column.Width );
Left( column.IsLeft );
Right( column.IsRight );
SetAcl( column.Acl, column.AclElseTemplateId );
EnableCustomColumn( column.GetCellControl() );
}
/// <summary>
/// 配置访问控制列表
/// </summary>
public TableHeadColumnBuilder SetAcl( string acl,string aclElseTemplateId ) {
public TableHeadColumnBuilder SetAcl( string acl, string aclElseTemplateId ) {
_config.SetAttribute( UiConst.Acl, acl );
_config.SetAttribute( UiConst.AclElseTemplateId, aclElseTemplateId );
this.Acl( _config );
@@ -0,0 +1,61 @@
using Util.Ui.Angular.Builders;
using Util.Ui.NgZorro.Components.Tables.Configs;
namespace Util.Ui.NgZorro.Components.Tables.Builders;
/// <summary>
/// 表格设置标签生成器
/// </summary>
public class TableSettingsBuilder : AngularTagBuilder {
/// <summary>
/// 配置
/// </summary>
private readonly Config _config;
/// <summary>
/// 表格共享配置
/// </summary>
private TableShareConfig _tableShareConfig;
/// <summary>
/// 初始化表格设置标签生成器
/// </summary>
/// <param name="config">配置</param>
public TableSettingsBuilder( Config config ) : base( config, "x-table-settings" ) {
_config = config;
_tableShareConfig = GetTableShareConfig();
}
/// <summary>
/// 获取表格共享配置
/// </summary>
public TableShareConfig GetTableShareConfig() {
return _tableShareConfig ??= _config.GetValueFromItems<TableShareConfig>() ?? new TableShareConfig();
}
/// <summary>
/// 配置初始设置的列集合
/// </summary>
public TableSettingsBuilder InitColumns() {
if ( _tableShareConfig.ColumnNumber == 0 )
return this;
Attribute( "[initColumns]", GetColumnsJson() );
return this;
}
/// <summary>
/// 获取自定义列Json
/// </summary>
private string GetColumnsJson() {
var customColumns = _tableShareConfig.Columns.Select( column => column.ToCustomColumn() );
return Util.Helpers.Json.ToJson( customColumns, new JsonOptions { ToSingleQuotes = true, IgnoreNullValues = true } );
}
/// <summary>
/// 配置
/// </summary>
public override void Config() {
Attribute( $"#{_tableShareConfig.TableSettingsId}" );
Attribute( "customColumnKey", _tableShareConfig.CustomColumnKey );
InitColumns();
}
}
@@ -1,5 +1,4 @@
using Util.Ui.Configs;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Components.Templates.Builders;
namespace Util.Ui.NgZorro.Components.Tables.Builders;
@@ -1,7 +1,7 @@
using Util.Helpers;
using Util.Ui.NgZorro.Components.Tables.Helpers;
namespace Util.Ui.NgZorro.Components.Tables.Configs;
namespace Util.Ui.NgZorro.Components.Tables.Configs;
/// <summary>
/// 表格列共享配置
@@ -23,6 +23,8 @@ public class TableColumnShareConfig {
public TableColumnShareConfig( TableShareConfig tableShareConfig ) {
_tableShareConfig = tableShareConfig;
IsAutoCreateControl = true;
Index = _tableShareConfig.ColumnNumber;
_tableShareConfig.ColumnNumber++;
Column = Id.Create();
}
@@ -41,6 +43,11 @@ public class TableColumnShareConfig {
/// </summary>
public bool IsEnableEdit => _tableShareConfig.IsEnableEdit;
/// <summary>
/// 是否启用自定义列
/// </summary>
public bool IsEnableCustomColumn => _tableShareConfig.IsEnableCustomColumn;
/// <summary>
/// 表格扩展标识
/// </summary>
@@ -61,6 +68,21 @@ public class TableColumnShareConfig {
/// </summary>
public string Column { get; set; }
/// <summary>
/// 索引
/// </summary>
public int Index { get; set; }
/// <summary>
/// 自定义列标识
/// </summary>
public string CellControl {
get {
var column = _tableShareConfig.GetColumn( Index );
return column.GetCellControl();
}
}
/// <summary>
/// 编辑控件模板标识
/// </summary>
@@ -134,7 +156,17 @@ public class TableColumnShareConfig {
public void AddColumn( ColumnInfo column ) {
if ( column == null )
return;
column.Index = Index;
Column = column.Column;
var headColumn = _tableShareConfig.GetHeadColumn( Index );
if ( headColumn != null ) {
if ( headColumn.Title.IsEmpty() == false )
column.Title = headColumn.Title;
if ( headColumn.CellControl.IsEmpty() == false )
column.CellControl = headColumn.CellControl;
if ( headColumn.Width.IsEmpty() == false )
column.Width = headColumn.Width;
}
_tableShareConfig.Columns.Add( column );
}
@@ -1,4 +1,6 @@
namespace Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Components.Tables.Helpers;
namespace Util.Ui.NgZorro.Components.Tables.Configs;
/// <summary>
/// 表头列共享配置
@@ -15,6 +17,8 @@ public class TableHeadColumnShareConfig {
/// <param name="tableShareConfig">表格共享配置</param>
public TableHeadColumnShareConfig( TableShareConfig tableShareConfig ) {
_tableShareConfig = tableShareConfig;
Index = _tableShareConfig.HeadColumnNumber;
_tableShareConfig.HeadColumnNumber++;
}
/// <summary>
@@ -32,6 +36,11 @@ public class TableHeadColumnShareConfig {
/// </summary>
public string TableEditId => _tableShareConfig.TableEditId;
/// <summary>
/// 是否启用自定义列
/// </summary>
public bool IsEnableCustomColumn => _tableShareConfig.IsEnableCustomColumn;
/// <summary>
/// 是否显示复选框
/// </summary>
@@ -75,12 +84,39 @@ public class TableHeadColumnShareConfig {
/// </summary>
public bool IsFirst { get; set; }
/// <summary>
/// 索引
/// </summary>
public int Index { get; set; }
/// <summary>
/// 自定义列标识
/// </summary>
public string CellControl {
get {
var column = _tableShareConfig.GetColumn( Index );
if (column == null)
return null;
return column.GetCellControl();
}
}
/// <summary>
/// 设置第一列
/// </summary>
public void SetIsFirst() {
if ( _tableShareConfig.HeadColumnNumber == 0 )
if ( Index == 0 )
IsFirst = true;
_tableShareConfig.HeadColumnNumber++;
}
/// <summary>
/// 添加列
/// </summary>
/// <param name="column">列信息</param>
public void AddColumn( HeadColumnInfo column ) {
if ( column == null )
return;
column.Index = Index;
_tableShareConfig.HeadColumns.Add( column );
}
}
@@ -1,6 +1,6 @@
using Util.Ui.NgZorro.Components.Tables.Helpers;
namespace Util.Ui.NgZorro.Components.Tables.Configs;
namespace Util.Ui.NgZorro.Components.Tables.Configs;
/// <summary>
/// 表格共享配置
@@ -17,6 +17,7 @@ public class TableShareConfig {
/// <param name="id">表格标识</param>
public TableShareConfig( string id = null ) {
Id = id.IsEmpty() ? Util.Helpers.Id.Create() : id;
HeadColumns = new List<HeadColumnInfo>();
Columns = new List<ColumnInfo>();
IsAutoCreateHead = true;
IsAutoCreateHeadRow = true;
@@ -45,6 +46,11 @@ public class TableShareConfig {
/// </summary>
public string RowId => _rowId.IsEmpty() ? $"{Id}_row" : _rowId;
/// <summary>
/// 表格设置组件标识
/// </summary>
public string TableSettingsId => $"ts_{Id}";
/// <summary>
/// 设置表格主体行标识
/// </summary>
@@ -58,6 +64,11 @@ public class TableShareConfig {
/// </summary>
public string TotalTemplateId => $"total_{Id}";
/// <summary>
/// 表头列信息集合
/// </summary>
public List<HeadColumnInfo> HeadColumns { get; }
/// <summary>
/// 列信息集合
/// </summary>
@@ -68,6 +79,11 @@ public class TableShareConfig {
/// </summary>
public int HeadColumnNumber { get; set; }
/// <summary>
/// 列数
/// </summary>
public int ColumnNumber { get; set; }
/// <summary>
/// 是否自动创建表头thead
/// </summary>
@@ -133,6 +149,11 @@ public class TableShareConfig {
/// </summary>
public bool IsEnableEdit { get; set; }
/// <summary>
/// 是否启用自定义列
/// </summary>
public bool IsEnableCustomColumn { get; set; }
/// <summary>
/// 是否显示复选框
/// </summary>
@@ -187,4 +208,25 @@ public class TableShareConfig {
/// 点击是否仅选中该行
/// </summary>
public bool SelectOnlyOnClickRow { get; set; }
/// <summary>
/// 自定义列标识
/// </summary>
public string CustomColumnKey { get; set; }
/// <summary>
/// 获取列信息
/// </summary>
/// <param name="index">列索引</param>
public ColumnInfo GetColumn( int index ) {
return Columns.Find( t => t.Index == index );
}
/// <summary>
/// 获取表头列信息
/// </summary>
/// <param name="index">列索引</param>
public HeadColumnInfo GetHeadColumn( int index ) {
return HeadColumns.Find( t => t.Index == index );
}
}
@@ -1,9 +1,13 @@
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
/// <summary>
/// 列配置信息
/// </summary>
public class ColumnInfo {
/// <summary>
/// 索引
/// </summary>
public int Index { get; set; }
/// <summary>
/// 标题
/// </summary>
@@ -13,6 +17,10 @@ public class ColumnInfo {
/// </summary>
public string Column { get; set; }
/// <summary>
/// 自定义列标识
/// </summary>
public string CellControl { get; set; }
/// <summary>
/// 是否排序
/// </summary>
public bool IsSort { get; set; }
@@ -40,4 +48,18 @@ public class ColumnInfo {
/// 访问控制列表模板标识
/// </summary>
public string AclElseTemplateId { get; set; }
/// <summary>
/// 转换为自定义列
/// </summary>
public CustomColumn ToCustomColumn() {
return new CustomColumn( GetCellControl(), Width, Acl );
}
/// <summary>
/// 获取自定义列标识
/// </summary>
public string GetCellControl() {
return CellControl.IsEmpty() ? Title : CellControl;
}
}
@@ -0,0 +1,62 @@
using Util.Ui.NgZorro.Configs;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
/// <summary>
/// 自定义列信息
/// </summary>
public class CustomColumn {
/// <summary>
/// 初始化自定义列信息
/// </summary>
/// <param name="value">值</param>
/// <param name="width">宽度</param>
/// <param name="acl">访问控制</param>
public CustomColumn( string value, string width, string acl ) {
Value = value;
Default = true;
Width = GetWidth( width );
if ( acl.IsEmpty() == false )
Acl = acl;
}
/// <summary>
/// 获取宽度
/// </summary>
private double GetWidth( string value ) {
var defaultWidth = NgZorroOptionsService.GetOptions().TableColumnDefaultWidth;
if ( value.IsEmpty() )
return defaultWidth;
if ( Util.Helpers.Validation.IsNumber( value ) )
return Util.Helpers.Convert.ToDouble( value );
if ( value.EndsWith( "px" ) )
return Util.Helpers.Convert.ToDouble( value.RemoveEnd( "px" ) );
if ( value.EndsWith( "%" ) )
return 10 * Util.Helpers.Convert.ToDouble( value.RemoveEnd( "%" ) );
return defaultWidth;
}
/// <summary>
/// 值
/// </summary>
[JsonPropertyName( "value" )]
public string Value { get; }
/// <summary>
/// 默认
/// </summary>
[JsonPropertyName( "default" )]
public bool Default { get; }
/// <summary>
/// 宽度
/// </summary>
[JsonPropertyName( "width" )]
public double Width { get; }
/// <summary>
/// 访问控制
/// </summary>
[JsonPropertyName( "acl" )]
public string Acl { get; }
}
@@ -0,0 +1,30 @@
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
/// <summary>
/// 表头列配置信息
/// </summary>
public class HeadColumnInfo {
/// <summary>
/// 索引
/// </summary>
public int Index { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 宽度
/// </summary>
public string Width { get; set; }
/// <summary>
/// 自定义列标识
/// </summary>
public string CellControl { get; set; }
/// <summary>
/// 获取自定义列标识
/// </summary>
public string GetCellControl() {
return CellControl.IsEmpty() ? Title : CellControl;
}
}
@@ -1,8 +1,7 @@
using Util.Ui.Configs;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.NgZorro.Configs;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
/// <summary>
/// 表格列服务
@@ -64,7 +63,7 @@ public class TableColumnService {
/// </summary>
private void EnableEdit() {
var result = _config.GetValue<bool>( UiConst.IsEdit );
if( result )
if ( result )
_shareConfig.EnableEdit();
}
@@ -99,6 +98,7 @@ public class TableColumnService {
var result = new ColumnInfo {
Title = GetTitle(),
Column = _config.GetValue( UiConst.Column ),
CellControl = _config.GetValue( UiConst.CellControl ),
Width = _config.GetValue( UiConst.Width ),
IsSort = _config.GetValue<bool>( UiConst.Sort ),
IsFirst = _shareConfig.IsFirst,
@@ -1,8 +1,7 @@
using Util.Ui.Configs;
using Util.Ui.Expressions;
using Util.Ui.Expressions;
using Util.Ui.NgZorro.Components.Tables.Configs;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
/// <summary>
/// 表头单元格服务
@@ -32,6 +31,7 @@ public class TableHeadColumnService {
CreateTableHeadColumnShareConfig();
CancelAutoCreateHeadColumn();
SetIsFirst();
SetColumn();
LoadExpression();
}
@@ -39,7 +39,7 @@ public class TableHeadColumnService {
/// 创建表头列共享配置
/// </summary>
private void CreateTableHeadColumnShareConfig() {
_shareConfig = new TableHeadColumnShareConfig( GetTableShareConfig());
_shareConfig = new TableHeadColumnShareConfig( GetTableShareConfig() );
_config.SetValueToItems( _shareConfig );
}
@@ -64,6 +64,16 @@ public class TableHeadColumnService {
_shareConfig.SetIsFirst();
}
/// <summary>
/// 设置表头列
/// </summary>
public void SetColumn() {
var title = _config.GetValue( UiConst.Title );
var width = _config.GetValue( UiConst.Width );
var cellControl = _config.GetValue( UiConst.CellControl );
_shareConfig.AddColumn( new HeadColumnInfo { Title = title, Width = width, CellControl = cellControl } );
}
/// <summary>
/// 加载表达式
/// </summary>
@@ -2,7 +2,7 @@
using Util.Ui.Configs;
using Util.Ui.NgZorro.Components.Tables.Configs;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
namespace Util.Ui.NgZorro.Components.Tables.Helpers;
/// <summary>
/// 表格服务
@@ -44,6 +44,7 @@ public class TableService {
/// </summary>
public void Init() {
CreateShareConfig();
SetEnableCustomColumn();
SetIsShowCheckbox();
SetIsShowRadio();
SetIsCheckLeafOnly();
@@ -67,6 +68,17 @@ public class TableService {
return _config.GetValue( UiConst.Id );
}
/// <summary>
/// 设置启用自定义列
/// </summary>
private void SetEnableCustomColumn() {
var key = _config.GetValue( UiConst.EnableCustomColumn );
if ( key.IsEmpty() || key.ToLower() == "true" )
return;
_shareConfig.IsEnableCustomColumn = true;
_shareConfig.CustomColumnKey = key;
}
/// <summary>
/// 设置是否显示复选框
/// </summary>
@@ -115,7 +127,7 @@ public class TableService {
_shareConfig.IsEnableExtend = false;
return;
}
if ( GetEnableExtend() == true ||
if ( GetEnableExtend() == true ||
GetUrl().IsEmpty() == false ||
GetBindUrl().IsEmpty() == false ||
GetLoadUrl().IsEmpty() == false ||
@@ -125,7 +137,7 @@ public class TableService {
GetLoadChildrenUrl().IsEmpty() == false ||
GetBindLoadChildrenUrl().IsEmpty() == false ||
_shareConfig.IsShowCheckbox ||
_shareConfig.IsShowRadio ||
_shareConfig.IsShowRadio ||
_shareConfig.IsShowLineNumber ) {
_shareConfig.IsEnableExtend = true;
}
@@ -1,5 +1,5 @@
using Util.Ui.Builders;
using Util.Ui.Configs;
using Util.Ui.Angular.Extensions;
using Util.Ui.Builders;
using Util.Ui.NgZorro.Components.Tables.Builders;
using Util.Ui.NgZorro.Components.Tables.Configs;
using Util.Ui.Renders;
@@ -40,6 +40,7 @@ public class TableRender : RenderBase {
public override void WriteTo( TextWriter writer, HtmlEncoder encoder ) {
base.WriteTo( writer, encoder );
RenderTotalTemplate( writer, encoder );
RenderTableSettings( writer, encoder );
}
/// <summary>
@@ -62,8 +63,21 @@ public class TableRender : RenderBase {
builder.WriteTo( writer, encoder );
}
/// <summary>
/// 渲染表格设置组件
/// </summary>
protected void RenderTableSettings( TextWriter writer, HtmlEncoder encoder ) {
if ( _shareConfig.IsEnableCustomColumn == false )
return;
if ( _shareConfig.ColumnNumber == 0 )
return;
var builder = new TableSettingsBuilder( _config );
builder.Config();
builder.WriteTo( writer, encoder );
}
/// <inheritdoc />
public override IHtmlContent Clone() {
return new TableRender( _config.Copy(), _shareConfig.MapTo<TableShareConfig>() );
return new TableRender( _config.CopyRemoveAttributes(), _shareConfig.MapTo<TableShareConfig>() );
}
}
@@ -166,6 +166,14 @@ public class TableColumnTagHelper : AngularTagHelperBase {
/// </summary>
public string BindIndentSize { get; set; }
/// <summary>
/// nzCellControl,设置列的位置,该值为 NzCustomColumn 类型中 value 字段的值
/// </summary>
public string CellControl { get; set; }
/// <summary>
/// [nzCellControl],设置列的位置,该值为 NzCustomColumn 类型中 value 字段的值
/// </summary>
public string BindCellControl { get; set; }
/// <summary>
/// (nzCheckedChange),复选框选中状态变化事件,类型: EventEmitter&lt;boolean>
/// </summary>
public string OnCheckedChange { get; set; }
@@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Util.Ui.Angular.TagHelpers;
using Util.Ui.Configs;
using Util.Ui.NgZorro.Components.Tables.Helpers;
using Util.Ui.NgZorro.Components.Tables.Renders;
using Util.Ui.NgZorro.Enums;
@@ -203,6 +202,14 @@ public class TableHeadColumnTagHelper : AngularTagHelperBase {
/// </summary>
public string BindColumnKey { get; set; }
/// <summary>
/// nzCellControl,设置列的位置,该值为 NzCustomColumn 类型中 value 字段的值
/// </summary>
public string CellControl { get; set; }
/// <summary>
/// [nzCellControl],设置列的位置,该值为 NzCustomColumn 类型中 value 字段的值
/// </summary>
public string BindCellControl { get; set; }
/// <summary>
/// (nzCheckedChange),复选框选中状态变化事件,类型: EventEmitter&lt;boolean>
/// </summary>
public string OnCheckedChange { get; set; }
@@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Util.Ui.Angular.TagHelpers;
using Util.Ui.Configs;
using Util.Ui.NgZorro.Components.Tables.Helpers;
using Util.Ui.NgZorro.Components.Tables.Renders;
using Util.Ui.NgZorro.Enums;
@@ -326,6 +325,14 @@ public class TableTagHelper : AngularTagHelperBase {
/// </summary>
public string BindLayout { get; set; }
/// <summary>
/// [nzCustomColumn],自定义列, 控制表格列的展示与排序, 类型: NzCustomColumn[], 注意: 开启后 nzWidthConfig 和 th 的 nzWidth 将不生效
/// </summary>
public string CustomColumn { get; set; }
/// <summary>
/// 扩展属性,启用自定义列, 参数值为自定义列标识 Key,用于将自定义列数据存储到浏览器本地, 必须全局唯一
/// </summary>
public string EnableCustomColumn { get; set; }
/// <summary>
/// (nzPageIndexChange),页码变化事件,类型: EventEmitter&lt;number>
/// </summary>
public string OnPageIndexChange { get; set; }
@@ -1,5 +1,4 @@
using Util.Ui.Angular.Builders;
using Util.Ui.Configs;
namespace Util.Ui.NgZorro.Components.Templates.Builders;
+4
View File
@@ -44,4 +44,8 @@ public class NgZorroOptions {
/// 获取表格布尔列内容操作
/// </summary>
public Func<string, string> GetTableColumnBoolContentAction { get; set; }
/// <summary>
/// 表格列默认宽度,单位: px, 默认值:180, 自定义列使用
/// </summary>
public double TableColumnDefaultWidth { get; set; } = 180;
}
+20
View File
@@ -25,6 +25,14 @@ public static class UiConst {
/// </summary>
public const string Color = "color";
/// <summary>
/// 单元格控件
/// </summary>
public const string CellControl = "cell-control";
/// <summary>
/// 是否启用自定义列
/// </summary>
public const string EnableCustomColumn = "enable-custom-column";
/// <summary>
/// 背景色
/// </summary>
public const string BackgroundColor = "background-color";
@@ -273,6 +281,10 @@ public static class UiConst {
/// </summary>
public const string IsSearch = "is-search";
/// <summary>
/// 显示表格设置
/// </summary>
public const string ShowTableSettings = "show-table-settings";
/// <summary>
/// 显示数量
/// </summary>
public const string ShowNumber = "show-number";
@@ -705,6 +717,10 @@ public static class UiConst {
/// </summary>
public const string Title = "title";
/// <summary>
/// 错误收集
/// </summary>
public const string ErrorCollect = "error-collect";
/// <summary>
/// operation标题
/// </summary>
public const string TitleOperation = "title-operation";
@@ -1281,6 +1297,10 @@ public static class UiConst {
/// </summary>
public const string Layout = "layout";
/// <summary>
/// 自定义列
/// </summary>
public const string CustomColumn = "custom-column";
/// <summary>
/// 显示冒号
/// </summary>
public const string ShowColon = "show-colon";