升级XCode和NewLife.Core,使用全新的IModel来拷贝接口入参
This commit is contained in:
parent
922229e780
commit
1519c0774a
|
@ -1,39 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NewLife.Cube;
|
||||
using NewLife.School.Entity;
|
||||
using NewLife.Web;
|
||||
|
||||
namespace CubeDemo.Areas.School.Controllers
|
||||
namespace CubeDemo.Areas.School.Controllers;
|
||||
|
||||
[SchoolArea]
|
||||
[DisplayName("学生")]
|
||||
public class StudentController : EntityController<Student>
|
||||
{
|
||||
[SchoolArea]
|
||||
[DisplayName("学生")]
|
||||
public class StudentController : EntityController<Student>
|
||||
static StudentController()
|
||||
{
|
||||
static StudentController()
|
||||
{
|
||||
ListFields.RemoveField("CreateUserID");
|
||||
ListFields.RemoveField("UpdateUserID");
|
||||
//FormFields
|
||||
}
|
||||
ListFields.RemoveField("CreateUserID");
|
||||
ListFields.RemoveField("UpdateUserID");
|
||||
//FormFields
|
||||
}
|
||||
|
||||
protected override Student Find(Object key)
|
||||
{
|
||||
return base.Find(key);
|
||||
}
|
||||
protected override Student Find(Object key)
|
||||
{
|
||||
return base.Find(key);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Student> Search(Pager p)
|
||||
{
|
||||
return base.Search(p);
|
||||
var classid = p["classid"].ToInt();
|
||||
return Student.Search(null,p);
|
||||
}
|
||||
protected override IEnumerable<Student> Search(Pager p)
|
||||
{
|
||||
return base.Search(p);
|
||||
//var classid = p["classid"].ToInt();
|
||||
//return Student.Search(null,p);
|
||||
}
|
||||
|
||||
public override ActionResult Index(Pager p = null)
|
||||
{
|
||||
return base.Index(p);
|
||||
}
|
||||
public override ActionResult Index(Pager p = null)
|
||||
{
|
||||
return base.Index(p);
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NewLife.Core" Version="10.2.2023.322-beta0150" />
|
||||
<PackageReference Include="NewLife.Core" Version="10.2.2023.323-beta1548" />
|
||||
<PackageReference Include="NewLife.Stardust.Extensions" Version="2.8.2023.318-beta0213" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
@*
|
||||
用户信息
|
||||
*@
|
||||
@model ChangePasswordModel
|
||||
@model ChangePasswordModel
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using NewLife;
|
||||
@using NewLife.Cube
|
||||
|
@ -10,21 +7,12 @@
|
|||
@using XCode;
|
||||
@using XCode.Configuration
|
||||
@using XCode.Membership;
|
||||
@using System.Linq;
|
||||
@using System.Reflection;
|
||||
@{
|
||||
var requireOldPass = Model.SsoName.IsNullOrEmpty();
|
||||
var user = ManageProvider.User;
|
||||
}
|
||||
|
||||
@using System.Linq;
|
||||
@using System.Reflection;
|
||||
@using NewLife.Cube
|
||||
@using NewLife.Cube.Areas.Admin.Models
|
||||
@using XCode;
|
||||
@using XCode.Configuration
|
||||
@using NewLife.Cube.Entity;
|
||||
@using XCode.Membership;
|
||||
@using NewLife;
|
||||
|
||||
<div class="">
|
||||
<div class="card">
|
||||
<div class="card-body pt-9 pb-0">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NewLife.Cube.Entity;
|
||||
using NewLife.Data;
|
||||
|
@ -118,11 +117,16 @@ public class EntityController<TEntity, TModel> : ReadOnlyEntityController<TEntit
|
|||
if (model is not TEntity entity)
|
||||
{
|
||||
entity = Factory.Create(false) as TEntity;
|
||||
entity.Copy(model);
|
||||
|
||||
if (model is TEntity src)
|
||||
entity.CopyFrom(src, true);
|
||||
else
|
||||
entity.Copy(model);
|
||||
}
|
||||
|
||||
// 检测避免乱用Add/id
|
||||
if (Factory.Unique.IsIdentity && entity[Factory.Unique.Name].ToInt() != 0) throw new Exception("我们约定添加数据时路由id部分默认没有数据,以免模型绑定器错误识别!");
|
||||
if (Factory.Unique.IsIdentity && entity[Factory.Unique.Name].ToInt() != 0)
|
||||
throw new Exception("我们约定添加数据时路由id部分默认没有数据,以免模型绑定器错误识别!");
|
||||
|
||||
var rs = false;
|
||||
var err = "";
|
||||
|
@ -212,11 +216,15 @@ public class EntityController<TEntity, TModel> : ReadOnlyEntityController<TEntit
|
|||
if (model is not TEntity entity)
|
||||
{
|
||||
var uk = Factory.Unique;
|
||||
var key = model is IExtend ext ? ext[uk.Name] : model.GetValue(uk.Name);
|
||||
var key = model is IModel ext ? ext[uk.Name] : model.GetValue(uk.Name);
|
||||
|
||||
// 先查出来,再拷贝。这里没有考虑脏数据的问题,有可能拷贝后并没有脏数据
|
||||
entity = FindData(key);
|
||||
entity.Copy(model, false, uk.Name);
|
||||
|
||||
if (model is TEntity src)
|
||||
entity.CopyFrom(src, true);
|
||||
else
|
||||
entity.Copy(model, false, uk.Name);
|
||||
}
|
||||
|
||||
var rs = false;
|
||||
|
|
|
@ -148,7 +148,7 @@ public class ReadOnlyEntityController<TEntity> : ControllerBaseX where TEntity :
|
|||
var builder = CreateWhere();
|
||||
if (builder != null)
|
||||
{
|
||||
builder.Data2 ??= p;
|
||||
builder.Data2 ??= p.Items;
|
||||
p.State = builder;
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,8 @@ public class ReadOnlyEntityController<TEntity> : ControllerBaseX where TEntity :
|
|||
//Data = Session,
|
||||
};
|
||||
builder.SetData(Session);
|
||||
builder.Data2 = new ItemsExtend { Items = HttpContext.Items };
|
||||
//builder.Data2 = new ItemsExtend { Items = HttpContext.Items };
|
||||
builder.Data2 = HttpContext.Items.ToDictionary(e => e.Key + "", e => e.Value);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ using NewLife.Data;
|
|||
namespace NewLife.Web;
|
||||
|
||||
/// <summary>分页器。包含分页排序参数,支持构造Url的功能</summary>
|
||||
public class Pager : PageParameter, IExtend3
|
||||
public class Pager : PageParameter, IExtend
|
||||
{
|
||||
#region 名称
|
||||
/// <summary>名称类。用户可根据需要修改Url参数名</summary>
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Extensions\ItemsExtend.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\NewLife.CubeNC\Modules\IModule.cs" Link="Modules\IModule.cs" />
|
||||
<Compile Include="..\NewLife.CubeNC\Modules\ModuleAttribute.cs" Link="Modules\ModuleAttribute.cs" />
|
||||
|
@ -70,10 +74,10 @@
|
|||
<Compile Include="..\NewLife.CubeNC\ViewModels\SelectUserModel.cs" Link="ViewModels\SelectUserModel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NewLife.Core" Version="10.2.2023.322-beta0150" />
|
||||
<PackageReference Include="NewLife.Core" Version="10.2.2023.323-beta1548" />
|
||||
<PackageReference Include="NewLife.IP" Version="2.0.2023.203" />
|
||||
<PackageReference Include="NewLife.Stardust" Version="2.8.2023.318-beta0213" />
|
||||
<PackageReference Include="NewLife.XCode" Version="11.7.2023.322-beta1520" />
|
||||
<PackageReference Include="NewLife.XCode" Version="11.7.2023.324-beta1635" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -187,7 +187,7 @@ namespace NewLife.Cube.Web
|
|||
if (user is IEntity entity) entity.Update();
|
||||
|
||||
// 用户角色可能有更新,需要清空扩展属性,避免Roles保留脏数据,导致用户首次访问显示无权限
|
||||
(user as EntityBase).Extends = null;
|
||||
(user as IEntity).Extends.Clear();
|
||||
|
||||
// 写日志
|
||||
var log = LogProvider.Provider;
|
||||
|
|
|
@ -1,116 +1,113 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Web.Script.Serialization;
|
||||
using NewLife.Collections;
|
||||
using NewLife.Data;
|
||||
|
||||
namespace NewLife.Cube.Charts
|
||||
namespace NewLife.Cube.Charts;
|
||||
|
||||
/// <summary>标题,主副标题</summary>
|
||||
public class ChartTitle : IExtend
|
||||
{
|
||||
/// <summary>标题,主副标题</summary>
|
||||
public class ChartTitle : IExtend3
|
||||
{
|
||||
#region 属性
|
||||
/// <summary>显示</summary>
|
||||
public Boolean Show { get; set; }
|
||||
#region 属性
|
||||
/// <summary>显示</summary>
|
||||
public Boolean Show { get; set; }
|
||||
|
||||
/// <summary>一级层叠控制</summary>
|
||||
/// <remarks>
|
||||
/// 每一个不同的zlevel将产生一个独立的canvas,相同zlevel的组件或图标将在同一个canvas上渲染。
|
||||
/// zlevel越高越靠顶层,canvas对象增多会消耗更多的内存和性能,并不建议设置过多的zlevel,大部分情况可以通过二级层叠控制z实现层叠控制。
|
||||
/// </remarks>
|
||||
public Int32 ZLevel { get; set; }
|
||||
/// <summary>一级层叠控制</summary>
|
||||
/// <remarks>
|
||||
/// 每一个不同的zlevel将产生一个独立的canvas,相同zlevel的组件或图标将在同一个canvas上渲染。
|
||||
/// zlevel越高越靠顶层,canvas对象增多会消耗更多的内存和性能,并不建议设置过多的zlevel,大部分情况可以通过二级层叠控制z实现层叠控制。
|
||||
/// </remarks>
|
||||
public Int32 ZLevel { get; set; }
|
||||
|
||||
/// <summary>二级层叠控制</summary>
|
||||
/// <remarks>同一个canvas(相同zlevel)上z越高约靠顶层。</remarks>
|
||||
public Int32 Z { get; set; }
|
||||
/// <summary>二级层叠控制</summary>
|
||||
/// <remarks>同一个canvas(相同zlevel)上z越高约靠顶层。</remarks>
|
||||
public Int32 Z { get; set; }
|
||||
|
||||
/// <summary>主标题文本,'\n'指定换行</summary>
|
||||
public String Text { get; set; }
|
||||
/// <summary>主标题文本,'\n'指定换行</summary>
|
||||
public String Text { get; set; }
|
||||
|
||||
/// <summary>主标题文本超链接</summary>
|
||||
public String Link { get; set; }
|
||||
/// <summary>主标题文本超链接</summary>
|
||||
public String Link { get; set; }
|
||||
|
||||
/// <summary>主标题超链接,'blank' | 'self'</summary>
|
||||
public String Target { get; set; }
|
||||
/// <summary>主标题超链接,'blank' | 'self'</summary>
|
||||
public String Target { get; set; }
|
||||
|
||||
/// <summary>副标题文本,'\n'指定换行</summary>
|
||||
public String SubText { get; set; }
|
||||
/// <summary>副标题文本,'\n'指定换行</summary>
|
||||
public String SubText { get; set; }
|
||||
|
||||
/// <summary>副标题文本超链接</summary>
|
||||
public String SubLink { get; set; }
|
||||
/// <summary>副标题文本超链接</summary>
|
||||
public String SubLink { get; set; }
|
||||
|
||||
/// <summary>副标题超链接,'blank' | 'self'</summary>
|
||||
public String SubTarget { get; set; }
|
||||
/// <summary>副标题超链接,'blank' | 'self'</summary>
|
||||
public String SubTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:'left'
|
||||
/// 水平安放位置,默认为左侧,可选为:'center' | 'left' | 'right' | {number}(x坐标,单位px)
|
||||
/// </summary>
|
||||
public String X { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:'left'
|
||||
/// 水平安放位置,默认为左侧,可选为:'center' | 'left' | 'right' | {number}(x坐标,单位px)
|
||||
/// </summary>
|
||||
public String X { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:'top'
|
||||
/// 垂直安放位置,默认为全图顶端,可选为:'top' | 'bottom' | 'center' | {number}(y坐标,单位px)
|
||||
/// </summary>
|
||||
public String Y { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:'top'
|
||||
/// 垂直安放位置,默认为全图顶端,可选为:'top' | 'bottom' | 'center' | {number}(y坐标,单位px)
|
||||
/// </summary>
|
||||
public String Y { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 水平对齐方式,默认根据x设置自动调整,可选为: left' | 'right' | 'center
|
||||
/// </summary>
|
||||
public String TextAlign { get; set; }
|
||||
/// <summary>
|
||||
/// 水平对齐方式,默认根据x设置自动调整,可选为: left' | 'right' | 'center
|
||||
/// </summary>
|
||||
public String TextAlign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:'rgba(0,0,0,0)'
|
||||
/// 标题背景颜色,默认透明
|
||||
/// </summary>
|
||||
public String BackgroundColor { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:'rgba(0,0,0,0)'
|
||||
/// 标题背景颜色,默认透明
|
||||
/// </summary>
|
||||
public String BackgroundColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:'#ccc'
|
||||
/// 标题边框颜色
|
||||
/// </summary>
|
||||
public String BorderColor { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:'#ccc'
|
||||
/// 标题边框颜色
|
||||
/// </summary>
|
||||
public String BorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题边框线宽,单位px,默认为0(无边框)
|
||||
/// </summary>
|
||||
public Int32 BorderWidth { get; set; }
|
||||
/// <summary>
|
||||
/// 标题边框线宽,单位px,默认为0(无边框)
|
||||
/// </summary>
|
||||
public Int32 BorderWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:5
|
||||
/// 标题内边距,单位px,默认各方向内边距为5,接受数组分别设定上右下左边距,同css,见下图
|
||||
/// </summary>
|
||||
public Int32 Padding { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:5
|
||||
/// 标题内边距,单位px,默认各方向内边距为5,接受数组分别设定上右下左边距,同css,见下图
|
||||
/// </summary>
|
||||
public Int32 Padding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:5
|
||||
/// 主副标题纵向间隔,单位px,默认为5
|
||||
/// </summary>
|
||||
public Int32 ItemGap { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:5
|
||||
/// 主副标题纵向间隔,单位px,默认为5
|
||||
/// </summary>
|
||||
public Int32 ItemGap { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主标题文本样式
|
||||
/// </summary>
|
||||
public TextStyle TextStyle { get; set; }
|
||||
/// <summary>
|
||||
/// 主标题文本样式
|
||||
/// </summary>
|
||||
public TextStyle TextStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 副标题文本样式
|
||||
/// </summary>
|
||||
public TextStyle SubTextStyle { get; set; }
|
||||
/// <summary>
|
||||
/// 副标题文本样式
|
||||
/// </summary>
|
||||
public TextStyle SubTextStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用于标题定位,数组为横纵相对仪表盘圆心坐标偏移,支持百分比(相对外半径)
|
||||
/// </summary>
|
||||
public Object OffsetCenter { get; set; }
|
||||
/// <summary>
|
||||
/// 用于标题定位,数组为横纵相对仪表盘圆心坐标偏移,支持百分比(相对外半径)
|
||||
/// </summary>
|
||||
public Object OffsetCenter { get; set; }
|
||||
|
||||
/// <summary>扩展字典</summary>
|
||||
[ScriptIgnore]
|
||||
public IDictionary<String, Object> Items { get; set; } = new NullableDictionary<String, Object>(StringComparer.OrdinalIgnoreCase);
|
||||
/// <summary>扩展字典</summary>
|
||||
[ScriptIgnore]
|
||||
public IDictionary<String, Object> Items { get; set; } = new NullableDictionary<String, Object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>扩展数据</summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public Object this[String key] { get => Items[key]; set => Items[key] = value; }
|
||||
#endregion
|
||||
}
|
||||
/// <summary>扩展数据</summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public Object this[String key] { get => Items[key]; set => Items[key] = value; }
|
||||
#endregion
|
||||
}
|
|
@ -6,314 +6,313 @@ using NewLife.Serialization;
|
|||
using XCode;
|
||||
using XCode.Configuration;
|
||||
|
||||
namespace NewLife.Cube.Charts
|
||||
namespace NewLife.Cube.Charts;
|
||||
|
||||
/// <summary>ECharts实例</summary>
|
||||
public class ECharts : IExtend
|
||||
{
|
||||
/// <summary>ECharts实例</summary>
|
||||
public class ECharts : IExtend3
|
||||
#region 属性
|
||||
/// <summary>名称</summary>
|
||||
public String Name { get; set; } = Rand.NextString(8);
|
||||
|
||||
/// <summary>宽度。单位px,负数表示百分比,默认-100</summary>
|
||||
public Int32 Width { get; set; } = -100;
|
||||
|
||||
/// <summary>高度。单位px,负数表示百分比,默认300px</summary>
|
||||
public Int32 Height { get; set; } = 300;
|
||||
|
||||
/// <summary>CSS样式</summary>
|
||||
public String Style { get; set; }
|
||||
|
||||
/// <summary>CSS类</summary>
|
||||
public String Class { get; set; }
|
||||
|
||||
/// <summary>标题。字符串或匿名对象</summary>
|
||||
public ChartTitle Title { get; set; }
|
||||
|
||||
/// <summary>提示</summary>
|
||||
public Object Tooltip { get; set; } = new Object();
|
||||
|
||||
/// <summary>提示</summary>
|
||||
public Object Legend { get; set; }
|
||||
|
||||
/// <summary>X轴</summary>
|
||||
public Object XAxis { get; set; }
|
||||
|
||||
/// <summary>Y轴</summary>
|
||||
public Object YAxis { get; set; }
|
||||
|
||||
/// <summary>数据缩放</summary>
|
||||
public DataZoom[] DataZoom { get; set; }
|
||||
|
||||
/// <summary>系列数据</summary>
|
||||
public IList<Series> Series { get; set; }
|
||||
|
||||
/// <summary>标记的图形。设置后添加的图形都使用该值</summary>
|
||||
[ScriptIgnore]
|
||||
public String Symbol { get; set; }
|
||||
|
||||
/// <summary>扩展字典</summary>
|
||||
[ScriptIgnore]
|
||||
public IDictionary<String, Object> Items { get; set; } = new NullableDictionary<String, Object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>扩展数据</summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public Object this[String key] { get => Items[key]; set => Items[key] = value; }
|
||||
|
||||
FieldItem _timeX;
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
/// <summary>添加系列数据</summary>
|
||||
/// <param name="series"></param>
|
||||
public void Add(Series series)
|
||||
{
|
||||
#region 属性
|
||||
/// <summary>名称</summary>
|
||||
public String Name { get; set; } = Rand.NextString(8);
|
||||
Series ??= new List<Series>();
|
||||
|
||||
/// <summary>宽度。单位px,负数表示百分比,默认-100</summary>
|
||||
public Int32 Width { get; set; } = -100;
|
||||
|
||||
/// <summary>高度。单位px,负数表示百分比,默认300px</summary>
|
||||
public Int32 Height { get; set; } = 300;
|
||||
|
||||
/// <summary>CSS样式</summary>
|
||||
public String Style { get; set; }
|
||||
|
||||
/// <summary>CSS类</summary>
|
||||
public String Class { get; set; }
|
||||
|
||||
/// <summary>标题。字符串或匿名对象</summary>
|
||||
public ChartTitle Title { get; set; }
|
||||
|
||||
/// <summary>提示</summary>
|
||||
public Object Tooltip { get; set; } = new Object();
|
||||
|
||||
/// <summary>提示</summary>
|
||||
public Object Legend { get; set; }
|
||||
|
||||
/// <summary>X轴</summary>
|
||||
public Object XAxis { get; set; }
|
||||
|
||||
/// <summary>Y轴</summary>
|
||||
public Object YAxis { get; set; }
|
||||
|
||||
/// <summary>数据缩放</summary>
|
||||
public DataZoom[] DataZoom { get; set; }
|
||||
|
||||
/// <summary>系列数据</summary>
|
||||
public IList<Series> Series { get; set; }
|
||||
|
||||
/// <summary>标记的图形。设置后添加的图形都使用该值</summary>
|
||||
[ScriptIgnore]
|
||||
public String Symbol { get; set; }
|
||||
|
||||
/// <summary>扩展字典</summary>
|
||||
[ScriptIgnore]
|
||||
public IDictionary<String, Object> Items { get; set; } = new NullableDictionary<String, Object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>扩展数据</summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public Object this[String key] { get => Items[key]; set => Items[key] = value; }
|
||||
|
||||
FieldItem _timeX;
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
/// <summary>添加系列数据</summary>
|
||||
/// <param name="series"></param>
|
||||
public void Add(Series series)
|
||||
{
|
||||
Series ??= new List<Series>();
|
||||
|
||||
Series.Add(series);
|
||||
}
|
||||
|
||||
/// <summary>添加系列数据</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="type">图表类型,默认折线图line</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <returns></returns>
|
||||
public Series Add<T>(IList<T> list, FieldItem field, String type = "line", Func<T, Object> selector = null) where T : IEntity
|
||||
{
|
||||
if (type.IsNullOrEmpty()) type = "line";
|
||||
|
||||
var data = _timeX != null ?
|
||||
list.Select(e => new Object[] { e[_timeX.Name], selector == null ? e[field.Name] : selector(e) }).ToArray() :
|
||||
list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray();
|
||||
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = type,
|
||||
Data = data,
|
||||
};
|
||||
if (!Symbol.IsNullOrEmpty()) sr.Symbol = Symbol;
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>添加曲线系列数据</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <param name="smooth">折线光滑</param>
|
||||
/// <returns></returns>
|
||||
public Series AddLine<T>(IList<T> list, FieldItem field, Func<T, Object> selector = null, Boolean smooth = false) where T : IEntity
|
||||
{
|
||||
var data = _timeX != null ?
|
||||
list.Select(e => new Object[] { e[_timeX.Name], selector == null ? e[field.Name] : selector(e) }).ToArray() :
|
||||
list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray();
|
||||
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = "line",
|
||||
Data = data,
|
||||
Smooth = smooth,
|
||||
};
|
||||
if (!Symbol.IsNullOrEmpty()) sr.Symbol = Symbol;
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>添加饼图</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <returns></returns>
|
||||
public Series AddBar<T>(IList<T> list, FieldItem field, Func<T, Object> selector = null) where T : IEntity
|
||||
{
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = "bar",
|
||||
Data = list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray(),
|
||||
};
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>添加曲线系列数据</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <returns></returns>
|
||||
public Series AddPie<T>(IList<T> list, FieldItem field, Func<T, NameValue> selector = null) where T : IEntity
|
||||
{
|
||||
var nameKey = field.Table.Master?.Name ?? field.Table.PrimaryKeys.FirstOrDefault()?.Name;
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = "pie",
|
||||
Data = list.Select(e => selector == null ? new NameValue(e[nameKey] + "", e[field.Name]) : selector(e)).ToArray(),
|
||||
};
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>设置X轴</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">数据列表,从中选择数据构建X轴</param>
|
||||
/// <param name="field">作为X轴的字段,支持time时间轴</param>
|
||||
/// <param name="selector">构建X轴的委托,使用时间轴时该参数无效</param>
|
||||
public void SetX<T>(IList<T> list, FieldItem field, Func<T, String> selector = null) where T : IEntity
|
||||
{
|
||||
if (field != null && field.Type == typeof(DateTime))
|
||||
{
|
||||
XAxis = new
|
||||
{
|
||||
type = "time",
|
||||
};
|
||||
_timeX = field;
|
||||
|
||||
if (Symbol.IsNullOrEmpty() && list.Count > 100) Symbol = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
XAxis = new
|
||||
{
|
||||
data = list.Select(e => selector == null ? e[field.Name] + "" : selector(e)).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>设置Y轴</summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="type">
|
||||
/// 坐标轴类型。
|
||||
/// value 数值轴,适用于连续数据。
|
||||
/// category 类目轴,适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
|
||||
/// time 时间轴,适用于连续的时序数据,与数值轴相比时间轴带有时间的格式化,在刻度计算上也有所不同,例如会根据跨度的范围来决定使用月,星期,日还是小时范围的刻度。
|
||||
/// log 对数轴。适用于对数数据。
|
||||
/// </param>
|
||||
public void SetY(String name, String type = "value") => YAxis = new { name, type };
|
||||
|
||||
/// <summary>设置工具栏</summary>
|
||||
/// <param name="trigger">
|
||||
/// 触发类型。
|
||||
/// item, 数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
|
||||
/// axis, 坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
|
||||
/// none, 什么都不触发。
|
||||
/// </param>
|
||||
/// <param name="axisPointerType">坐标轴指示器配置项。cross,坐标系会自动选择显示哪个轴的 axisPointer</param>
|
||||
/// <param name="backgroundColor"></param>
|
||||
public void SetTooltip(String trigger = "axis", String axisPointerType = "cross", String backgroundColor = "#6a7985")
|
||||
{
|
||||
Tooltip = new
|
||||
{
|
||||
trigger = trigger,
|
||||
axisPointer = new
|
||||
{
|
||||
type = axisPointerType,
|
||||
label = new
|
||||
{
|
||||
backgroundColor = backgroundColor
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>设置提示</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="field"></param>
|
||||
/// <param name="selector"></param>
|
||||
public void SetLegend<T>(IList<T> list, FieldItem field, Func<T, String> selector = null) where T : IEntity => Legend = list.Select(e => selector == null ? e[field.Name] + "" : selector(e)).ToArray();
|
||||
|
||||
/// <summary>添加缩放。默认X0轴,其它设置可直接修改返回对象</summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <returns></returns>
|
||||
public DataZoom AddDataZoom(Int32 start = 0, Int32 end = 100)
|
||||
{
|
||||
var dz = new DataZoom
|
||||
{
|
||||
XAxiaIndex = new[] { 0 },
|
||||
Start = start,
|
||||
End = end,
|
||||
};
|
||||
|
||||
var list = DataZoom?.ToList() ?? new List<DataZoom>();
|
||||
list.Add(dz);
|
||||
|
||||
DataZoom = list.ToArray();
|
||||
|
||||
return dz;
|
||||
}
|
||||
|
||||
/// <summary>构建选项Json</summary>
|
||||
/// <returns></returns>
|
||||
public String Build()
|
||||
{
|
||||
var dic = new Dictionary<String, Object>();
|
||||
|
||||
// 标题
|
||||
var title = Title;
|
||||
if (title != null) dic[nameof(title)] = title;
|
||||
|
||||
// 提示
|
||||
var tooltip = Tooltip;
|
||||
if (tooltip != null) dic[nameof(tooltip)] = tooltip;
|
||||
|
||||
// 提示
|
||||
var legend = Legend;
|
||||
legend ??= Series.Select(e => e.Name).ToArray();
|
||||
if (legend != null)
|
||||
{
|
||||
if (legend is String str)
|
||||
legend = new { data = new[] { str } };
|
||||
else if (legend is String[] ss)
|
||||
legend = new { data = ss };
|
||||
|
||||
dic[nameof(legend)] = legend;
|
||||
}
|
||||
|
||||
// X轴
|
||||
var xAxis = XAxis;
|
||||
if (xAxis != null)
|
||||
{
|
||||
if (xAxis is String str)
|
||||
xAxis = new { data = new[] { str } };
|
||||
else if (xAxis is String[] ss)
|
||||
xAxis = new { data = ss };
|
||||
|
||||
dic[nameof(xAxis)] = xAxis;
|
||||
}
|
||||
|
||||
// Y轴
|
||||
var yAxis = YAxis;
|
||||
if (yAxis != null) dic[nameof(yAxis)] = yAxis;
|
||||
|
||||
var dataZoom = DataZoom;
|
||||
if (dataZoom != null) dic[nameof(dataZoom)] = dataZoom;
|
||||
|
||||
// 系列数据
|
||||
var series = Series;
|
||||
if (series != null) dic[nameof(series)] = series;
|
||||
|
||||
// 合并Items
|
||||
foreach (var item in Items)
|
||||
{
|
||||
dic[item.Key] = item.Value;
|
||||
}
|
||||
|
||||
return dic.ToJson(true, false, true);
|
||||
}
|
||||
#endregion
|
||||
Series.Add(series);
|
||||
}
|
||||
|
||||
/// <summary>添加系列数据</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="type">图表类型,默认折线图line</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <returns></returns>
|
||||
public Series Add<T>(IList<T> list, FieldItem field, String type = "line", Func<T, Object> selector = null) where T : IEntity
|
||||
{
|
||||
if (type.IsNullOrEmpty()) type = "line";
|
||||
|
||||
var data = _timeX != null ?
|
||||
list.Select(e => new Object[] { e[_timeX.Name], selector == null ? e[field.Name] : selector(e) }).ToArray() :
|
||||
list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray();
|
||||
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = type,
|
||||
Data = data,
|
||||
};
|
||||
if (!Symbol.IsNullOrEmpty()) sr.Symbol = Symbol;
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>添加曲线系列数据</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <param name="smooth">折线光滑</param>
|
||||
/// <returns></returns>
|
||||
public Series AddLine<T>(IList<T> list, FieldItem field, Func<T, Object> selector = null, Boolean smooth = false) where T : IEntity
|
||||
{
|
||||
var data = _timeX != null ?
|
||||
list.Select(e => new Object[] { e[_timeX.Name], selector == null ? e[field.Name] : selector(e) }).ToArray() :
|
||||
list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray();
|
||||
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = "line",
|
||||
Data = data,
|
||||
Smooth = smooth,
|
||||
};
|
||||
if (!Symbol.IsNullOrEmpty()) sr.Symbol = Symbol;
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>添加饼图</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <returns></returns>
|
||||
public Series AddBar<T>(IList<T> list, FieldItem field, Func<T, Object> selector = null) where T : IEntity
|
||||
{
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = "bar",
|
||||
Data = list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray(),
|
||||
};
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>添加曲线系列数据</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">实体列表</param>
|
||||
/// <param name="field">要使用数据的字段</param>
|
||||
/// <param name="selector">数据选择器,默认null时直接使用字段数据</param>
|
||||
/// <returns></returns>
|
||||
public Series AddPie<T>(IList<T> list, FieldItem field, Func<T, NameValue> selector = null) where T : IEntity
|
||||
{
|
||||
var nameKey = field.Table.Master?.Name ?? field.Table.PrimaryKeys.FirstOrDefault()?.Name;
|
||||
var sr = new Series
|
||||
{
|
||||
Name = field?.DisplayName ?? field.Name,
|
||||
Type = "pie",
|
||||
Data = list.Select(e => selector == null ? new NameValue(e[nameKey] + "", e[field.Name]) : selector(e)).ToArray(),
|
||||
};
|
||||
|
||||
Add(sr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
/// <summary>设置X轴</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list">数据列表,从中选择数据构建X轴</param>
|
||||
/// <param name="field">作为X轴的字段,支持time时间轴</param>
|
||||
/// <param name="selector">构建X轴的委托,使用时间轴时该参数无效</param>
|
||||
public void SetX<T>(IList<T> list, FieldItem field, Func<T, String> selector = null) where T : IEntity
|
||||
{
|
||||
if (field != null && field.Type == typeof(DateTime))
|
||||
{
|
||||
XAxis = new
|
||||
{
|
||||
type = "time",
|
||||
};
|
||||
_timeX = field;
|
||||
|
||||
if (Symbol.IsNullOrEmpty() && list.Count > 100) Symbol = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
XAxis = new
|
||||
{
|
||||
data = list.Select(e => selector == null ? e[field.Name] + "" : selector(e)).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>设置Y轴</summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="type">
|
||||
/// 坐标轴类型。
|
||||
/// value 数值轴,适用于连续数据。
|
||||
/// category 类目轴,适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
|
||||
/// time 时间轴,适用于连续的时序数据,与数值轴相比时间轴带有时间的格式化,在刻度计算上也有所不同,例如会根据跨度的范围来决定使用月,星期,日还是小时范围的刻度。
|
||||
/// log 对数轴。适用于对数数据。
|
||||
/// </param>
|
||||
public void SetY(String name, String type = "value") => YAxis = new { name, type };
|
||||
|
||||
/// <summary>设置工具栏</summary>
|
||||
/// <param name="trigger">
|
||||
/// 触发类型。
|
||||
/// item, 数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
|
||||
/// axis, 坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
|
||||
/// none, 什么都不触发。
|
||||
/// </param>
|
||||
/// <param name="axisPointerType">坐标轴指示器配置项。cross,坐标系会自动选择显示哪个轴的 axisPointer</param>
|
||||
/// <param name="backgroundColor"></param>
|
||||
public void SetTooltip(String trigger = "axis", String axisPointerType = "cross", String backgroundColor = "#6a7985")
|
||||
{
|
||||
Tooltip = new
|
||||
{
|
||||
trigger = trigger,
|
||||
axisPointer = new
|
||||
{
|
||||
type = axisPointerType,
|
||||
label = new
|
||||
{
|
||||
backgroundColor = backgroundColor
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>设置提示</summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="field"></param>
|
||||
/// <param name="selector"></param>
|
||||
public void SetLegend<T>(IList<T> list, FieldItem field, Func<T, String> selector = null) where T : IEntity => Legend = list.Select(e => selector == null ? e[field.Name] + "" : selector(e)).ToArray();
|
||||
|
||||
/// <summary>添加缩放。默认X0轴,其它设置可直接修改返回对象</summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <returns></returns>
|
||||
public DataZoom AddDataZoom(Int32 start = 0, Int32 end = 100)
|
||||
{
|
||||
var dz = new DataZoom
|
||||
{
|
||||
XAxiaIndex = new[] { 0 },
|
||||
Start = start,
|
||||
End = end,
|
||||
};
|
||||
|
||||
var list = DataZoom?.ToList() ?? new List<DataZoom>();
|
||||
list.Add(dz);
|
||||
|
||||
DataZoom = list.ToArray();
|
||||
|
||||
return dz;
|
||||
}
|
||||
|
||||
/// <summary>构建选项Json</summary>
|
||||
/// <returns></returns>
|
||||
public String Build()
|
||||
{
|
||||
var dic = new Dictionary<String, Object>();
|
||||
|
||||
// 标题
|
||||
var title = Title;
|
||||
if (title != null) dic[nameof(title)] = title;
|
||||
|
||||
// 提示
|
||||
var tooltip = Tooltip;
|
||||
if (tooltip != null) dic[nameof(tooltip)] = tooltip;
|
||||
|
||||
// 提示
|
||||
var legend = Legend;
|
||||
legend ??= Series.Select(e => e.Name).ToArray();
|
||||
if (legend != null)
|
||||
{
|
||||
if (legend is String str)
|
||||
legend = new { data = new[] { str } };
|
||||
else if (legend is String[] ss)
|
||||
legend = new { data = ss };
|
||||
|
||||
dic[nameof(legend)] = legend;
|
||||
}
|
||||
|
||||
// X轴
|
||||
var xAxis = XAxis;
|
||||
if (xAxis != null)
|
||||
{
|
||||
if (xAxis is String str)
|
||||
xAxis = new { data = new[] { str } };
|
||||
else if (xAxis is String[] ss)
|
||||
xAxis = new { data = ss };
|
||||
|
||||
dic[nameof(xAxis)] = xAxis;
|
||||
}
|
||||
|
||||
// Y轴
|
||||
var yAxis = YAxis;
|
||||
if (yAxis != null) dic[nameof(yAxis)] = yAxis;
|
||||
|
||||
var dataZoom = DataZoom;
|
||||
if (dataZoom != null) dic[nameof(dataZoom)] = dataZoom;
|
||||
|
||||
// 系列数据
|
||||
var series = Series;
|
||||
if (series != null) dic[nameof(series)] = series;
|
||||
|
||||
// 合并Items
|
||||
foreach (var item in Items)
|
||||
{
|
||||
dic[item.Key] = item.Value;
|
||||
}
|
||||
|
||||
return dic.ToJson(true, false, true);
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -5,7 +5,7 @@ using NewLife.Data;
|
|||
namespace NewLife.Cube.Charts;
|
||||
|
||||
/// <summary>系列。一组数值以及他们映射成的图</summary>
|
||||
public class Series : IExtend3
|
||||
public class Series : IExtend
|
||||
{
|
||||
#region 属性
|
||||
/// <summary>图表类型</summary>
|
||||
|
|
|
@ -1,66 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Web.Script.Serialization;
|
||||
using NewLife.Collections;
|
||||
using NewLife.Data;
|
||||
|
||||
namespace NewLife.Cube.Charts
|
||||
namespace NewLife.Cube.Charts;
|
||||
|
||||
/// <summary>文字样式</summary>
|
||||
public class TextStyle : IExtend
|
||||
{
|
||||
/// <summary>文字样式</summary>
|
||||
public class TextStyle : IExtend3
|
||||
{
|
||||
/// <summary>
|
||||
/// 颜色
|
||||
/// </summary>
|
||||
public String Color { get; set; }
|
||||
/// <summary>
|
||||
/// 颜色
|
||||
/// </summary>
|
||||
public String Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:'none'
|
||||
/// 修饰,仅对tooltip.textStyle生效
|
||||
/// </summary>
|
||||
public String Decoration { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:'none'
|
||||
/// 修饰,仅对tooltip.textStyle生效
|
||||
/// </summary>
|
||||
public String Decoration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:各异
|
||||
/// 水平对齐方式,可选为:'left' | 'right' | 'center'
|
||||
/// </summary>
|
||||
public String Align { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:各异
|
||||
/// 水平对齐方式,可选为:'left' | 'right' | 'center'
|
||||
/// </summary>
|
||||
public String Align { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:各异
|
||||
/// 垂直对齐方式,可选为:'top' | 'bottom' | 'middle'
|
||||
/// </summary>
|
||||
public String Baseline { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:各异
|
||||
/// 垂直对齐方式,可选为:'top' | 'bottom' | 'middle'
|
||||
/// </summary>
|
||||
public String Baseline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:'Arial, Verdana, sans-serif'
|
||||
/// 字体系列
|
||||
/// </summary>
|
||||
public String FontFamily { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:'Arial, Verdana, sans-serif'
|
||||
/// 字体系列
|
||||
/// </summary>
|
||||
public String FontFamily { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值:12
|
||||
/// 字号,单位px
|
||||
/// </summary>
|
||||
public Int32 FontSize { get; set; }
|
||||
/// <summary>
|
||||
/// 默认值:12
|
||||
/// 字号,单位px
|
||||
/// </summary>
|
||||
public Int32 FontSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字体系列
|
||||
/// </summary>
|
||||
public String FontStyle { get; set; }
|
||||
/// <summary>
|
||||
/// 字体系列
|
||||
/// </summary>
|
||||
public String FontStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 粗细,可选为:'normal' | 'bold' | 'bolder' | 'lighter' | 100 | 200 |... | 900
|
||||
/// </summary>
|
||||
public String FontWeight { get; set; }
|
||||
/// <summary>
|
||||
/// 粗细,可选为:'normal' | 'bold' | 'bolder' | 'lighter' | 100 | 200 |... | 900
|
||||
/// </summary>
|
||||
public String FontWeight { get; set; }
|
||||
|
||||
/// <summary>扩展字典</summary>
|
||||
[ScriptIgnore]
|
||||
public IDictionary<String, Object> Items { get; set; } = new NullableDictionary<String, Object>(StringComparer.OrdinalIgnoreCase);
|
||||
/// <summary>扩展字典</summary>
|
||||
[ScriptIgnore]
|
||||
public IDictionary<String, Object> Items { get; set; } = new NullableDictionary<String, Object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>扩展数据</summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public Object this[String key] { get => Items[key]; set => Items[key] = value; }
|
||||
}
|
||||
/// <summary>扩展数据</summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public Object this[String key] { get => Items[key]; set => Items[key] = value; }
|
||||
}
|
|
@ -127,11 +127,16 @@ public class EntityController<TEntity, TModel> : ReadOnlyEntityController<TEntit
|
|||
if (model is not TEntity entity)
|
||||
{
|
||||
entity = Factory.Create(true) as TEntity;
|
||||
entity.Copy(model);
|
||||
|
||||
if (model is TEntity src)
|
||||
entity.CopyFrom(src, true);
|
||||
else
|
||||
entity.Copy(model);
|
||||
}
|
||||
|
||||
// 检测避免乱用Add/id
|
||||
if (Factory.Unique.IsIdentity && entity[Factory.Unique.Name].ToInt() != 0) throw new Exception("我们约定添加数据时路由id部分默认没有数据,以免模型绑定器错误识别!");
|
||||
if (Factory.Unique.IsIdentity && entity[Factory.Unique.Name].ToInt() != 0)
|
||||
throw new Exception("我们约定添加数据时路由id部分默认没有数据,以免模型绑定器错误识别!");
|
||||
|
||||
var rs = false;
|
||||
var err = "";
|
||||
|
@ -181,11 +186,10 @@ public class EntityController<TEntity, TModel> : ReadOnlyEntityController<TEntit
|
|||
|
||||
var key = $"Cube_Add_{typeof(TEntity).FullName}";
|
||||
var url = Session[key] as String;
|
||||
if (!url.IsNullOrEmpty())
|
||||
return Redirect(url);
|
||||
else
|
||||
// 新增完成跳到列表页,更新完成保持本页
|
||||
return RedirectToAction("Index");
|
||||
if (!url.IsNullOrEmpty()) return Redirect(url);
|
||||
|
||||
// 新增完成跳到列表页,更新完成保持本页
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
/// <summary>表单,添加/修改</summary>
|
||||
|
@ -233,11 +237,15 @@ public class EntityController<TEntity, TModel> : ReadOnlyEntityController<TEntit
|
|||
if (model is not TEntity entity)
|
||||
{
|
||||
var uk = Factory.Unique;
|
||||
var key = model is IExtend ext ? ext[uk.Name] : model.GetValue(uk.Name);
|
||||
var key = model is IModel ext ? ext[uk.Name] : model.GetValue(uk.Name);
|
||||
|
||||
// 先查出来,再拷贝。这里没有考虑脏数据的问题,有可能拷贝后并没有脏数据
|
||||
entity = FindData(key);
|
||||
entity.Copy(model, false, uk.Name);
|
||||
|
||||
if (model is TEntity src)
|
||||
entity.CopyFrom(src, true);
|
||||
else
|
||||
entity.Copy(model, false, uk.Name);
|
||||
}
|
||||
|
||||
var rs = false;
|
||||
|
|
|
@ -13,7 +13,6 @@ using NewLife.Cube.Common;
|
|||
using NewLife.Cube.Entity;
|
||||
using NewLife.Cube.Extensions;
|
||||
using NewLife.Cube.ViewModels;
|
||||
using NewLife.Data;
|
||||
using NewLife.IO;
|
||||
using NewLife.Log;
|
||||
using NewLife.Reflection;
|
||||
|
@ -164,7 +163,7 @@ public class ReadOnlyEntityController<TEntity> : ControllerBaseX where TEntity :
|
|||
var builder = CreateWhere();
|
||||
if (builder != null)
|
||||
{
|
||||
builder.Data2 ??= p;
|
||||
builder.Data2 ??= p.Items;
|
||||
p.State = builder;
|
||||
}
|
||||
|
||||
|
@ -240,7 +239,8 @@ public class ReadOnlyEntityController<TEntity> : ControllerBaseX where TEntity :
|
|||
//Data = Session,
|
||||
};
|
||||
builder.SetData(Session);
|
||||
builder.Data2 = new ItemsExtend { Items = HttpContext.Items };
|
||||
//builder.Data2 = new ItemsExtend { Items = HttpContext.Items };
|
||||
builder.Data2 = HttpContext.Items.ToDictionary(e => e.Key + "", e => e.Value);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,6 @@ public static class StarHelper
|
|||
/// <param name="field"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public String Resolve(DataField field, IExtend data) => BuildUrl(data[field.Name] as String);
|
||||
public String Resolve(DataField field, IModel data) => BuildUrl(data[field.Name] as String);
|
||||
}
|
||||
}
|
|
@ -49,10 +49,10 @@
|
|||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NewLife.Core" Version="10.2.2023.322-beta0150" />
|
||||
<PackageReference Include="NewLife.Core" Version="10.2.2023.323-beta1548" />
|
||||
<PackageReference Include="NewLife.IP" Version="2.0.2023.203" />
|
||||
<PackageReference Include="NewLife.Stardust" Version="2.8.2023.318-beta0213" />
|
||||
<PackageReference Include="NewLife.XCode" Version="11.7.2023.322-beta1520" />
|
||||
<PackageReference Include="NewLife.XCode" Version="11.7.2023.324-beta1635" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -129,6 +129,10 @@
|
|||
<EmbeddedResource Include="wwwroot\**\*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Extensions\ItemsExtend.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\Doc\leaf.png" Link="leaf.png" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
using System;
|
||||
using NewLife.Data;
|
||||
|
||||
namespace NewLife.Cube.ViewModels
|
||||
namespace NewLife.Cube.ViewModels;
|
||||
|
||||
/// <summary>Url扩展</summary>
|
||||
public interface IUrlExtend
|
||||
{
|
||||
/// <summary>Url扩展</summary>
|
||||
public interface IUrlExtend
|
||||
{
|
||||
/// <summary>解析Url地址</summary>
|
||||
/// <param name="field"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
String Resolve(DataField field, IExtend data);
|
||||
}
|
||||
/// <summary>解析Url地址</summary>
|
||||
/// <param name="field"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
String Resolve(DataField field, IModel data);
|
||||
}
|
|
@ -82,7 +82,7 @@ public class ListField : DataField
|
|||
#region 数据格式化
|
||||
private static readonly Regex _reg = new(@"{(\w+)}", RegexOptions.Compiled);
|
||||
|
||||
private static String Replace(String input, IExtend data)
|
||||
private static String Replace(String input, IModel data)
|
||||
{
|
||||
return _reg.Replace(input, m =>
|
||||
{
|
||||
|
@ -98,7 +98,7 @@ public class ListField : DataField
|
|||
/// <summary>针对指定实体对象计算DisplayName,替换其中变量</summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public virtual String GetDisplayName(IExtend data)
|
||||
public virtual String GetDisplayName(IModel data)
|
||||
{
|
||||
if (DisplayName.IsNullOrEmpty()) return null;
|
||||
|
||||
|
@ -108,7 +108,7 @@ public class ListField : DataField
|
|||
/// <summary>针对指定实体对象计算链接名,替换其中变量</summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public virtual String GetLinkName(IExtend data)
|
||||
public virtual String GetLinkName(IModel data)
|
||||
{
|
||||
// 如果设置了单元格文字,则优先使用。Text>Entity[name]>DisplayName
|
||||
var txt = Text;
|
||||
|
@ -129,7 +129,7 @@ public class ListField : DataField
|
|||
/// <summary>针对指定实体对象计算url,替换其中变量</summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public virtual String GetUrl(IExtend data)
|
||||
public virtual String GetUrl(IModel data)
|
||||
{
|
||||
var svc = GetService<IUrlExtend>();
|
||||
if (svc != null) return svc.Resolve(this, data);
|
||||
|
@ -143,7 +143,7 @@ public class ListField : DataField
|
|||
/// <summary>针对指定实体对象计算title,替换其中变量</summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public virtual String GetTitle(IExtend data)
|
||||
public virtual String GetTitle(IModel data)
|
||||
{
|
||||
if (Title.IsNullOrEmpty()) return null;
|
||||
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
<None Remove="Entity\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NewLife.XCode" Version="11.7.2023.322-beta1520" />
|
||||
<PackageReference Include="NewLife.XCode" Version="11.7.2023.324-beta1635" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue