diff --git a/ReactCubeDemo/appsettings.Development.json b/CubeDemo/appsettings.Development.json
similarity index 100%
rename from ReactCubeDemo/appsettings.Development.json
rename to CubeDemo/appsettings.Development.json
diff --git a/ReactCubeDemo/appsettings.json b/CubeDemo/appsettings.json
similarity index 100%
rename from ReactCubeDemo/appsettings.json
rename to CubeDemo/appsettings.json
diff --git a/ReactCubeDemo/Areas/School/Controllers/AbcController.cs b/CubeDemo/Areas/School/Controllers/AbcController.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Controllers/AbcController.cs
rename to CubeDemo/Areas/School/Controllers/AbcController.cs
diff --git a/ReactCubeDemo/Areas/School/Controllers/ClassController.cs b/CubeDemo/Areas/School/Controllers/ClassController.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Controllers/ClassController.cs
rename to CubeDemo/Areas/School/Controllers/ClassController.cs
diff --git a/ReactCubeDemo/Areas/School/Controllers/StudentController.cs b/CubeDemo/Areas/School/Controllers/StudentController.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Controllers/StudentController.cs
rename to CubeDemo/Areas/School/Controllers/StudentController.cs
diff --git a/ReactCubeDemo/Areas/School/Controllers/TestConfigController.cs b/CubeDemo/Areas/School/Controllers/TestConfigController.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Controllers/TestConfigController.cs
rename to CubeDemo/Areas/School/Controllers/TestConfigController.cs
diff --git a/ReactCubeDemo/Areas/School/Models/Entity/Interfaces/IClass.cs b/CubeDemo/Areas/School/Models/Entity/Interfaces/IClass.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/Entity/Interfaces/IClass.cs
rename to CubeDemo/Areas/School/Models/Entity/Interfaces/IClass.cs
diff --git a/ReactCubeDemo/Areas/School/Models/Entity/Interfaces/IStudent.cs b/CubeDemo/Areas/School/Models/Entity/Interfaces/IStudent.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/Entity/Interfaces/IStudent.cs
rename to CubeDemo/Areas/School/Models/Entity/Interfaces/IStudent.cs
diff --git a/ReactCubeDemo/Areas/School/Models/Entity/Interfaces/ITrade.cs b/CubeDemo/Areas/School/Models/Entity/Interfaces/ITrade.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/Entity/Interfaces/ITrade.cs
rename to CubeDemo/Areas/School/Models/Entity/Interfaces/ITrade.cs
diff --git a/ReactCubeDemo/Areas/School/Models/Entity/Models/ClassModel.cs b/CubeDemo/Areas/School/Models/Entity/Models/ClassModel.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/Entity/Models/ClassModel.cs
rename to CubeDemo/Areas/School/Models/Entity/Models/ClassModel.cs
diff --git a/ReactCubeDemo/Areas/School/Models/Entity/Models/StudentModel.cs b/CubeDemo/Areas/School/Models/Entity/Models/StudentModel.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/Entity/Models/StudentModel.cs
rename to CubeDemo/Areas/School/Models/Entity/Models/StudentModel.cs
diff --git a/ReactCubeDemo/Areas/School/Models/Entity/Models/TradeModel.cs b/CubeDemo/Areas/School/Models/Entity/Models/TradeModel.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/Entity/Models/TradeModel.cs
rename to CubeDemo/Areas/School/Models/Entity/Models/TradeModel.cs
diff --git "a/ReactCubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.Biz.cs" "b/CubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.Biz.cs"
similarity index 100%
rename from "ReactCubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.Biz.cs"
rename to "CubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.Biz.cs"
diff --git "a/ReactCubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.cs" "b/CubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.cs"
similarity index 100%
rename from "ReactCubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.cs"
rename to "CubeDemo/Areas/School/Models/Entity/\344\272\244\346\230\223.cs"
diff --git "a/ReactCubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.Biz.cs" "b/CubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.Biz.cs"
similarity index 100%
rename from "ReactCubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.Biz.cs"
rename to "CubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.Biz.cs"
diff --git "a/ReactCubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.cs" "b/CubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.cs"
similarity index 100%
rename from "ReactCubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.cs"
rename to "CubeDemo/Areas/School/Models/Entity/\345\255\246\347\224\237.cs"
diff --git "a/ReactCubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.Biz.cs" "b/CubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.Biz.cs"
similarity index 100%
rename from "ReactCubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.Biz.cs"
rename to "CubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.Biz.cs"
diff --git "a/ReactCubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.cs" "b/CubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.cs"
similarity index 100%
rename from "ReactCubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.cs"
rename to "CubeDemo/Areas/School/Models/Entity/\347\217\255\347\272\247.cs"
diff --git a/ReactCubeDemo/Areas/School/Models/Model.xml b/CubeDemo/Areas/School/Models/Model.xml
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/Model.xml
rename to CubeDemo/Areas/School/Models/Model.xml
diff --git a/ReactCubeDemo/Areas/School/Models/School.htm b/CubeDemo/Areas/School/Models/School.htm
similarity index 100%
rename from ReactCubeDemo/Areas/School/Models/School.htm
rename to CubeDemo/Areas/School/Models/School.htm
diff --git a/ReactCubeDemo/Areas/School/SchoolArea.cs b/CubeDemo/Areas/School/SchoolArea.cs
similarity index 100%
rename from ReactCubeDemo/Areas/School/SchoolArea.cs
rename to CubeDemo/Areas/School/SchoolArea.cs
diff --git a/CubeDemo/Areas/Test/Controllers/TestFieldController.cs b/CubeDemo/Areas/Test/Controllers/TestFieldController.cs
new file mode 100644
index 0000000..098ca0b
--- /dev/null
+++ b/CubeDemo/Areas/Test/Controllers/TestFieldController.cs
@@ -0,0 +1,124 @@
+using System.ComponentModel;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using NewLife;
+using NewLife.Cube;
+using NewLife.Log;
+using NewLife.Web;
+using XCode;
+using XCode.Configuration;
+using XCode.Membership;
+
+namespace CubeDemo.Areas.Test.Controllers;
+
+/// <summary>字段类型全覆盖测试控制器。配合 测试字段 实体,向前端默认模板下发覆盖全部控件类型的字段元数据。</summary>
+[TestArea]
+[DisplayName("字段类型测试")]
+[Menu(0, true, Mode = MenuModes.Admin | MenuModes.Tenant)]
+public class TestFieldController : EntityController<测试字段, 测试字段Model>
+{
+ static TestFieldController()
+ {
+ // 统一为 枚举 / 单选 / 多选 三类值集字段下发 lovCode。
+ // 值集由 LovAutoRegisterService 自动注册为 Enum.CubeDemo.Areas.Test.测试枚举。
+ var lovCode = $"Enum.{typeof(测试枚举).FullName}";
+
+ SetLov(ListFields, 测试字段._.Kind, lovCode);
+ SetLov(AddFormFields, 测试字段._.Kind, lovCode);
+ SetLov(EditFormFields, 测试字段._.Kind, lovCode);
+ SetLov(SearchFields, 测试字段._.Kind, lovCode);
+
+ SetLov(ListFields, 测试字段._.SingleVal, lovCode);
+ SetLov(AddFormFields, 测试字段._.SingleVal, lovCode);
+ SetLov(EditFormFields, 测试字段._.SingleVal, lovCode);
+ SetLov(SearchFields, 测试字段._.SingleVal, lovCode);
+
+ SetLov(ListFields, 测试字段._.MultiVal, lovCode);
+ SetLov(AddFormFields, 测试字段._.MultiVal, lovCode);
+ SetLov(EditFormFields, 测试字段._.MultiVal, lovCode);
+ SetLov(SearchFields, 测试字段._.MultiVal, lovCode);
+
+ // 下拉表格字段:使用列表型值集 List.CubeDemo.Role(由本控制器 RoleList 方法上的 [LovList] 自动注册)。
+ // 该值集 ProxyRequest=false,前端直接请求同应用接口 /Test/TestField/RoleList(不代理)。
+ const String roleLovCode = "List.CubeDemo.Role";
+ SetLov(ListFields, 测试字段._.ListVal, roleLovCode);
+ SetLov(AddFormFields, 测试字段._.ListVal, roleLovCode);
+ SetLov(EditFormFields, 测试字段._.ListVal, roleLovCode);
+ SetLov(SearchFields, 测试字段._.ListVal, roleLovCode);
+
+ // 下拉表格·多选字段:复用同一个列表型值集 List.CubeDemo.Role,前端以多选弹窗表格呈现。
+ SetLov(ListFields, 测试字段._.ListMVal, roleLovCode);
+ SetLov(AddFormFields, 测试字段._.ListMVal, roleLovCode);
+ SetLov(EditFormFields, 测试字段._.ListMVal, roleLovCode);
+ SetLov(SearchFields, 测试字段._.ListMVal, roleLovCode);
+ }
+
+ /// <summary>为字段集合中的指定字段设置 LOV 值集编码</summary>
+ /// <param name="fields">字段集合</param>
+ /// <param name="field">目标字段(FieldItem)</param>
+ /// <param name="lovCode">值集编码</param>
+ private static void SetLov(FieldCollection fields, Field field, String lovCode)
+ {
+ var df = fields.GetField(field);
+ if (df != null) df.LovCode = lovCode;
+ }
+
+ /// <summary>角色列表数据源。返回角色列表 JSON,供 List.CubeDemo.Role 值集(前端直连,不代理)使用。
+ /// 同时用 [LovList] 声明该列表型值集,由 LovAutoRegisterService 在初始化时自动注册。</summary>
+ /// <returns>角色列表与总数</returns>
+ [LovList(
+ LovCode = "List.CubeDemo.Role",
+ Name = "角色",
+ RequestUrl = "/Test/TestField/RoleList",
+ Method = "GET",
+ Pageable = true,
+ ValueField = "id",
+ LabelField = "name",
+ DataPath = "data",
+ TotalPath = "total",
+ ProxyRequest = false,
+ Columns = new[] { "id:编号:80:left", "name:角色名:200:left" },
+ SearchFields = new[] { "name:角色名:input:BODY:false" }
+ )]
+ [HttpGet]
+ public Object RoleList(Int32 pageIndex = 1, Int32 pageSize = 10, String name = null)
+ {
+ // 真实角色(来自 Membership)
+ var real = Role.FindAll().Select(r => new Dictionary<String, Object>
+ {
+ ["id"] = r.ID,
+ ["name"] = r.Name,
+ }).ToList();
+
+ // 演示用扩展角色:凑足分页数据,便于演示翻页(id 从 1001 起,避免与真实角色冲突)
+ var list = new List<Dictionary<String, Object>>(real);
+ for (var i = 1; i <= 21; i++)
+ {
+ list.Add(new Dictionary<String, Object>
+ {
+ ["id"] = 1000 + i,
+ ["name"] = $"演示角色 {i:D2}",
+ });
+ }
+
+ // 名称过滤:支持搜索栏按角色名模糊查询(不区分大小写)
+ if (!name.IsNullOrEmpty())
+ {
+ var kw = name.Trim();
+ list = list.Where(d => d["name"].ToString().Contains(kw, StringComparison.OrdinalIgnoreCase)).ToList();
+ }
+
+ var total = list.Count;
+ var paged = list
+ .Skip((pageIndex - 1) * pageSize)
+ .Take(pageSize)
+ .ToList();
+
+ // 显式字典投影,确保序列化键为小驼峰 id/name,与 ValueField/LabelField 对齐
+ return new
+ {
+ Data = (Object)paged,
+ Total = total,
+ };
+ }
+}
diff --git a/CubeDemo/Areas/Test/Models/Cube.htm b/CubeDemo/Areas/Test/Models/Cube.htm
new file mode 100644
index 0000000..85ad2b8
--- /dev/null
+++ b/CubeDemo/Areas/Test/Models/Cube.htm
@@ -0,0 +1,350 @@
+<style>
+ table {
+ border-collapse: collapse;
+ border: 1px solid;
+ border-color: rgb(211, 202, 221);
+ }
+
+ table thead,
+ table tr {
+ border-top-width: 1px;
+ border-top-style: solid;
+ border-top-color: rgb(211, 202, 221);
+ }
+
+ table {
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ border-bottom-color: rgb(211, 202, 221);
+ }
+
+ table td,
+ table th {
+ padding: 5px 10px;
+ font-size: 14px;
+ font-family: Verdana;
+ color: rgb(95, 74, 121);
+ }
+
+ table tr:nth-child(even) {
+ background: rgb(223, 216, 232)
+ }
+
+ table tr:nth-child(odd) {
+ background: #FFF
+ }
+</style>
+<h3>字段类型全覆盖测试实体(测试字段)</h3>
+<table>
+ <thead>
+ <tr>
+ <th>名称</th>
+ <th>显示名</th>
+ <th>类型</th>
+ <th>长度</th>
+ <th>精度</th>
+ <th>主键</th>
+ <th>允许空</th>
+ <th>备注</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Id</td>
+ <td>编号</td>
+ <td>Int32</td>
+ <td></td>
+ <td></td>
+ <td title="自增">AI</td>
+ <td>N</td>
+ <td></td>
+ </tr>
+
+ <tr>
+ <td>ShortText</td>
+ <td>短文本</td>
+ <td>String</td>
+ <td>50</td>
+ <td></td>
+ <td></td>
+ <td>N</td>
+ <td>必填的短文本示例</td>
+ </tr>
+
+ <tr>
+ <td>LongText</td>
+ <td>长文本</td>
+ <td>String</td>
+ <td>500</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>大文本(Length>=300)渲染为多行文本域</td>
+ </tr>
+
+ <tr>
+ <td>Int32Val</td>
+ <td>整数</td>
+ <td>Int32</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>Int32 数值</td>
+ </tr>
+
+ <tr>
+ <td>Int64Val</td>
+ <td>长整数</td>
+ <td>Int64</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>Int64 数值</td>
+ </tr>
+
+ <tr>
+ <td>DecimalVal</td>
+ <td>金额</td>
+ <td>Decimal</td>
+ <td></td>
+ <td>(18, 2)</td>
+ <td></td>
+ <td></td>
+ <td>Decimal 数值,带精度</td>
+ </tr>
+
+ <tr>
+ <td>DoubleVal</td>
+ <td>双精度</td>
+ <td>Double</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>Double 数值</td>
+ </tr>
+
+ <tr>
+ <td>FloatVal</td>
+ <td>单精度</td>
+ <td>Single</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>Single 数值</td>
+ </tr>
+
+ <tr>
+ <td>Enable</td>
+ <td>启用</td>
+ <td>Boolean</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>N</td>
+ <td>布尔开关</td>
+ </tr>
+
+ <tr>
+ <td>CreateTime</td>
+ <td>创建时间</td>
+ <td>DateTime</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>日期时间</td>
+ </tr>
+
+ <tr>
+ <td>Kind</td>
+ <td>种类</td>
+ <td>Int32</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>枚举类型,后端下发 lovCode 走 LOV 单选</td>
+ </tr>
+
+ <tr>
+ <td>GuidVal</td>
+ <td>唯一标识</td>
+ <td>Guid</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>Guid,非主键,渲染为只读文本</td>
+ </tr>
+
+ <tr>
+ <td>FileUrl</td>
+ <td>附件</td>
+ <td>String</td>
+ <td>200</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>文件上传,存储上传后返回的 URL</td>
+ </tr>
+
+ <tr>
+ <td>Avatar</td>
+ <td>头像</td>
+ <td>String</td>
+ <td>200</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>图片上传,带预览,存储 URL</td>
+ </tr>
+
+ <tr>
+ <td>JsonVal</td>
+ <td>Json</td>
+ <td>String</td>
+ <td>2000</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>Json 编辑器,存储 Json 字符串</td>
+ </tr>
+
+ <tr>
+ <td>HtmlVal</td>
+ <td>富文本</td>
+ <td>String</td>
+ <td>2000</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>html 富文本编辑器,存储 html 字符串</td>
+ </tr>
+
+ <tr>
+ <td>MarkdownVal</td>
+ <td>Markdown</td>
+ <td>String</td>
+ <td>2000</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>Markdown 富文本编辑器,存储 md 字符串</td>
+ </tr>
+
+ <tr>
+ <td>ColorVal</td>
+ <td>颜色</td>
+ <td>String</td>
+ <td>50</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>颜色选择器,存储色值字符串</td>
+ </tr>
+
+ <tr>
+ <td>IconVal</td>
+ <td>图标</td>
+ <td>String</td>
+ <td>50</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>图标选择器,存储图标名字符串</td>
+ </tr>
+
+ <tr>
+ <td>MailVal</td>
+ <td>邮箱</td>
+ <td>String</td>
+ <td>50</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>邮箱输入,带格式校验</td>
+ </tr>
+
+ <tr>
+ <td>MobileVal</td>
+ <td>手机</td>
+ <td>String</td>
+ <td>50</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>手机输入,带格式校验</td>
+ </tr>
+
+ <tr>
+ <td>UrlVal</td>
+ <td>网址</td>
+ <td>String</td>
+ <td>200</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>网址输入,带格式校验</td>
+ </tr>
+
+ <tr>
+ <td>SingleVal</td>
+ <td>单选</td>
+ <td>Int32</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>singleSelect,后端下发 lovCode 走 LOV 单选</td>
+ </tr>
+
+ <tr>
+ <td>MultiVal</td>
+ <td>多选</td>
+ <td>String</td>
+ <td>200</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值</td>
+ </tr>
+
+ <tr>
+ <td>UserId</td>
+ <td>用户</td>
+ <td>String</td>
+ <td>200</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>singleSelect,后端下发 lovCode 走 LOV 单选</td>
+ </tr>
+
+ <tr>
+ <td>ListVal</td>
+ <td>下拉表格</td>
+ <td>Int32</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择</td>
+ </tr>
+
+ <tr>
+ <td>ListMVal</td>
+ <td>下拉表格(多选)</td>
+ <td>String</td>
+ <td>200</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id</td>
+ </tr>
+ </tbody>
+</table>
+<br></br>
diff --git "a/CubeDemo/Areas/Test/Models/Entity/Interfaces/I\346\265\213\350\257\225\345\255\227\346\256\265.cs" "b/CubeDemo/Areas/Test/Models/Entity/Interfaces/I\346\265\213\350\257\225\345\255\227\346\256\265.cs"
new file mode 100644
index 0000000..afd4572
--- /dev/null
+++ "b/CubeDemo/Areas/Test/Models/Entity/Interfaces/I\346\265\213\350\257\225\345\255\227\346\256\265.cs"
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.Serialization;
+using System.Web.Script.Serialization;
+using System.Xml.Serialization;
+
+namespace CubeDemo.Areas.Test;
+
+/// <summary>字段类型全覆盖测试实体</summary>
+public partial interface I测试字段
+{
+ #region 属性
+ /// <summary>编号</summary>
+ Int32 Id { get; set; }
+
+ /// <summary>短文本。必填的短文本示例</summary>
+ String ShortText { get; set; }
+
+ /// <summary>长文本。大文本(Length>=300)渲染为多行文本域</summary>
+ String LongText { get; set; }
+
+ /// <summary>整数。Int32 数值</summary>
+ Int32 Int32Val { get; set; }
+
+ /// <summary>长整数。Int64 数值</summary>
+ Int64 Int64Val { get; set; }
+
+ /// <summary>金额。Decimal 数值,带精度</summary>
+ Decimal DecimalVal { get; set; }
+
+ /// <summary>双精度。Double 数值</summary>
+ Double DoubleVal { get; set; }
+
+ /// <summary>单精度。Single 数值</summary>
+ Single FloatVal { get; set; }
+
+ /// <summary>启用。布尔开关</summary>
+ Boolean Enable { get; set; }
+
+ /// <summary>创建时间。日期时间</summary>
+ DateTime CreateTime { get; set; }
+
+ /// <summary>种类。枚举类型,后端下发 lovCode 走 LOV 单选</summary>
+ CubeDemo.Areas.Test.测试枚举 Kind { get; set; }
+
+ /// <summary>唯一标识。Guid,非主键,渲染为只读文本</summary>
+ Guid GuidVal { get; set; }
+
+ /// <summary>附件。文件上传,存储上传后返回的 URL</summary>
+ String FileUrl { get; set; }
+
+ /// <summary>头像。图片上传,带预览,存储 URL</summary>
+ String Avatar { get; set; }
+
+ /// <summary>Json。Json 编辑器,存储 Json 字符串</summary>
+ String JsonVal { get; set; }
+
+ /// <summary>富文本。html 富文本编辑器,存储 html 字符串</summary>
+ String HtmlVal { get; set; }
+
+ /// <summary>Markdown。Markdown 富文本编辑器,存储 md 字符串</summary>
+ String MarkdownVal { get; set; }
+
+ /// <summary>颜色。颜色选择器,存储色值字符串</summary>
+ String ColorVal { get; set; }
+
+ /// <summary>图标。图标选择器,存储图标名字符串</summary>
+ String IconVal { get; set; }
+
+ /// <summary>邮箱。邮箱输入,带格式校验</summary>
+ String MailVal { get; set; }
+
+ /// <summary>手机。手机输入,带格式校验</summary>
+ String MobileVal { get; set; }
+
+ /// <summary>网址。网址输入,带格式校验</summary>
+ String UrlVal { get; set; }
+
+ /// <summary>单选。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ Int32 SingleVal { get; set; }
+
+ /// <summary>多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值</summary>
+ String MultiVal { get; set; }
+
+ /// <summary>用户。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ String UserId { get; set; }
+
+ /// <summary>下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择</summary>
+ Int32 ListVal { get; set; }
+
+ /// <summary>下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id</summary>
+ String ListMVal { get; set; }
+ #endregion
+}
diff --git "a/CubeDemo/Areas/Test/Models/Entity/Models/\346\265\213\350\257\225\345\255\227\346\256\265Model.cs" "b/CubeDemo/Areas/Test/Models/Entity/Models/\346\265\213\350\257\225\345\255\227\346\256\265Model.cs"
new file mode 100644
index 0000000..fce0e95
--- /dev/null
+++ "b/CubeDemo/Areas/Test/Models/Entity/Models/\346\265\213\350\257\225\345\255\227\346\256\265Model.cs"
@@ -0,0 +1,210 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.Serialization;
+using System.Web.Script.Serialization;
+using System.Xml.Serialization;
+using NewLife;
+using NewLife.Data;
+using NewLife.Reflection;
+
+namespace CubeDemo.Areas.Test;
+
+/// <summary>字段类型全覆盖测试实体</summary>
+public partial class 测试字段Model : IModel
+{
+ #region 属性
+ /// <summary>编号</summary>
+ public Int32 Id { get; set; }
+
+ /// <summary>短文本。必填的短文本示例</summary>
+ public String ShortText { get; set; }
+
+ /// <summary>长文本。大文本(Length>=300)渲染为多行文本域</summary>
+ public String LongText { get; set; }
+
+ /// <summary>整数。Int32 数值</summary>
+ public Int32 Int32Val { get; set; }
+
+ /// <summary>长整数。Int64 数值</summary>
+ public Int64 Int64Val { get; set; }
+
+ /// <summary>金额。Decimal 数值,带精度</summary>
+ public Decimal DecimalVal { get; set; }
+
+ /// <summary>双精度。Double 数值</summary>
+ public Double DoubleVal { get; set; }
+
+ /// <summary>单精度。Single 数值</summary>
+ public Single FloatVal { get; set; }
+
+ /// <summary>启用。布尔开关</summary>
+ public Boolean Enable { get; set; }
+
+ /// <summary>创建时间。日期时间</summary>
+ public DateTime CreateTime { get; set; }
+
+ /// <summary>种类。枚举类型,后端下发 lovCode 走 LOV 单选</summary>
+ public CubeDemo.Areas.Test.测试枚举 Kind { get; set; }
+
+ /// <summary>唯一标识。Guid,非主键,渲染为只读文本</summary>
+ public Guid GuidVal { get; set; }
+
+ /// <summary>附件。文件上传,存储上传后返回的 URL</summary>
+ public String FileUrl { get; set; }
+
+ /// <summary>头像。图片上传,带预览,存储 URL</summary>
+ public String Avatar { get; set; }
+
+ /// <summary>Json。Json 编辑器,存储 Json 字符串</summary>
+ public String JsonVal { get; set; }
+
+ /// <summary>富文本。html 富文本编辑器,存储 html 字符串</summary>
+ public String HtmlVal { get; set; }
+
+ /// <summary>Markdown。Markdown 富文本编辑器,存储 md 字符串</summary>
+ public String MarkdownVal { get; set; }
+
+ /// <summary>颜色。颜色选择器,存储色值字符串</summary>
+ public String ColorVal { get; set; }
+
+ /// <summary>图标。图标选择器,存储图标名字符串</summary>
+ public String IconVal { get; set; }
+
+ /// <summary>邮箱。邮箱输入,带格式校验</summary>
+ public String MailVal { get; set; }
+
+ /// <summary>手机。手机输入,带格式校验</summary>
+ public String MobileVal { get; set; }
+
+ /// <summary>网址。网址输入,带格式校验</summary>
+ public String UrlVal { get; set; }
+
+ /// <summary>单选。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ public Int32 SingleVal { get; set; }
+
+ /// <summary>多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值</summary>
+ public String MultiVal { get; set; }
+
+ /// <summary>用户。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ public String UserId { get; set; }
+
+ /// <summary>下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择</summary>
+ public Int32 ListVal { get; set; }
+
+ /// <summary>下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id</summary>
+ public String ListMVal { get; set; }
+ #endregion
+
+ #region 获取/设置 字段值
+ /// <summary>获取/设置 字段值</summary>
+ /// <param name="name">字段名</param>
+ /// <returns></returns>
+ public virtual Object this[String name]
+ {
+ get
+ {
+ return name switch
+ {
+ "Id" => Id,
+ "ShortText" => ShortText,
+ "LongText" => LongText,
+ "Int32Val" => Int32Val,
+ "Int64Val" => Int64Val,
+ "DecimalVal" => DecimalVal,
+ "DoubleVal" => DoubleVal,
+ "FloatVal" => FloatVal,
+ "Enable" => Enable,
+ "CreateTime" => CreateTime,
+ "Kind" => Kind,
+ "GuidVal" => GuidVal,
+ "FileUrl" => FileUrl,
+ "Avatar" => Avatar,
+ "JsonVal" => JsonVal,
+ "HtmlVal" => HtmlVal,
+ "MarkdownVal" => MarkdownVal,
+ "ColorVal" => ColorVal,
+ "IconVal" => IconVal,
+ "MailVal" => MailVal,
+ "MobileVal" => MobileVal,
+ "UrlVal" => UrlVal,
+ "SingleVal" => SingleVal,
+ "MultiVal" => MultiVal,
+ "UserId" => UserId,
+ "ListVal" => ListVal,
+ "ListMVal" => ListMVal,
+ _ => this.GetValue(name, false),
+ };
+ }
+ set
+ {
+ switch (name)
+ {
+ case "Id": Id = value.ToInt(); break;
+ case "ShortText": ShortText = Convert.ToString(value); break;
+ case "LongText": LongText = Convert.ToString(value); break;
+ case "Int32Val": Int32Val = value.ToInt(); break;
+ case "Int64Val": Int64Val = value.ToLong(); break;
+ case "DecimalVal": DecimalVal = Convert.ToDecimal(value); break;
+ case "DoubleVal": DoubleVal = value.ToDouble(); break;
+ case "FloatVal": FloatVal = Convert.ToSingle(value); break;
+ case "Enable": Enable = value.ToBoolean(); break;
+ case "CreateTime": CreateTime = value.ToDateTime(); break;
+ case "Kind": Kind = (CubeDemo.Areas.Test.测试枚举)value; break;
+ case "GuidVal": GuidVal = (Guid)value; break;
+ case "FileUrl": FileUrl = Convert.ToString(value); break;
+ case "Avatar": Avatar = Convert.ToString(value); break;
+ case "JsonVal": JsonVal = Convert.ToString(value); break;
+ case "HtmlVal": HtmlVal = Convert.ToString(value); break;
+ case "MarkdownVal": MarkdownVal = Convert.ToString(value); break;
+ case "ColorVal": ColorVal = Convert.ToString(value); break;
+ case "IconVal": IconVal = Convert.ToString(value); break;
+ case "MailVal": MailVal = Convert.ToString(value); break;
+ case "MobileVal": MobileVal = Convert.ToString(value); break;
+ case "UrlVal": UrlVal = Convert.ToString(value); break;
+ case "SingleVal": SingleVal = value.ToInt(); break;
+ case "MultiVal": MultiVal = Convert.ToString(value); break;
+ case "UserId": UserId = Convert.ToString(value); break;
+ case "ListVal": ListVal = value.ToInt(); break;
+ case "ListMVal": ListMVal = Convert.ToString(value); break;
+ default: this.SetValue(name, value); break;
+ }
+ }
+ }
+ #endregion
+
+ #region 拷贝
+ /// <summary>拷贝模型对象</summary>
+ /// <param name="model">模型</param>
+ public void Copy(I测试字段 model)
+ {
+ Id = model.Id;
+ ShortText = model.ShortText;
+ LongText = model.LongText;
+ Int32Val = model.Int32Val;
+ Int64Val = model.Int64Val;
+ DecimalVal = model.DecimalVal;
+ DoubleVal = model.DoubleVal;
+ FloatVal = model.FloatVal;
+ Enable = model.Enable;
+ CreateTime = model.CreateTime;
+ Kind = model.Kind;
+ GuidVal = model.GuidVal;
+ FileUrl = model.FileUrl;
+ Avatar = model.Avatar;
+ JsonVal = model.JsonVal;
+ HtmlVal = model.HtmlVal;
+ MarkdownVal = model.MarkdownVal;
+ ColorVal = model.ColorVal;
+ IconVal = model.IconVal;
+ MailVal = model.MailVal;
+ MobileVal = model.MobileVal;
+ UrlVal = model.UrlVal;
+ SingleVal = model.SingleVal;
+ MultiVal = model.MultiVal;
+ UserId = model.UserId;
+ ListVal = model.ListVal;
+ ListMVal = model.ListMVal;
+ }
+ #endregion
+}
diff --git "a/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\345\255\227\346\256\265.Biz.cs" "b/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\345\255\227\346\256\265.Biz.cs"
new file mode 100644
index 0000000..34158ed
--- /dev/null
+++ "b/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\345\255\227\346\256\265.Biz.cs"
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using NewLife;
+using NewLife.Data;
+using NewLife.Log;
+using NewLife.Web;
+using XCode;
+using XCode.Membership;
+
+namespace CubeDemo.Areas.Test;
+
+public partial class 测试字段 : Entity<测试字段>
+{
+ #region 对象操作
+ static 测试字段()
+ {
+ // 过滤器 UserModule、TimeModule、IPModule
+ Meta.Modules.Add<UserModule>();
+ Meta.Modules.Add<TimeModule>();
+ Meta.Modules.Add<IPModule>();
+ }
+
+ /// <summary>验证并修补数据,通过抛出异常的方式提示验证失败。</summary>
+ /// <param name="isNew">是否插入</param>
+ public override void Valid(Boolean isNew)
+ {
+ // 如果没有脏数据,则不需要进行任何处理
+ if (!HasDirty) return;
+
+ // 建议先调用基类方法,基类方法会做一些统一处理
+ base.Valid(isNew);
+ }
+ #endregion
+
+ #region 扩展查询
+ /// <summary>根据编号查找</summary>
+ /// <param name="id">编号</param>
+ /// <returns>实体对象</returns>
+ public static 测试字段 FindById(Int32 id)
+ {
+ if (id <= 0) return null;
+
+ // 实体缓存
+ if (Meta.Session.Count < 1000) return Meta.Cache.Find(e => e.Id == id);
+
+ // 单对象缓存
+ return Meta.SingleCache[id];
+ }
+ #endregion
+
+ #region 高级查询
+ /// <summary>高级查询</summary>
+ /// <param name="key">关键字</param>
+ /// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
+ /// <returns>实体列表</returns>
+ public static IList<测试字段> Search(String key, PageParameter page)
+ {
+ var exp = new WhereExpression();
+
+ if (!key.IsNullOrEmpty())
+ exp &= _.ShortText.Contains(key) | _.LongText.Contains(key) | _.MailVal.Contains(key) | _.MobileVal.Contains(key) | _.UrlVal.Contains(key);
+
+ return FindAll(exp, page);
+ }
+ #endregion
+
+ #region 业务操作
+ /// <summary>转为模型对象</summary>
+ /// <returns></returns>
+ public 测试字段Model ToModel()
+ {
+ var model = new 测试字段Model();
+ model.Copy(this);
+
+ return model;
+ }
+ #endregion
+}
diff --git "a/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\345\255\227\346\256\265.cs" "b/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\345\255\227\346\256\265.cs"
new file mode 100644
index 0000000..81cd662
--- /dev/null
+++ "b/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\345\255\227\346\256\265.cs"
@@ -0,0 +1,577 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.Serialization;
+using System.Web.Script.Serialization;
+using System.Xml.Serialization;
+using NewLife;
+using NewLife.Data;
+using XCode;
+using XCode.Cache;
+using XCode.Configuration;
+using XCode.DataAccessLayer;
+
+namespace CubeDemo.Areas.Test;
+
+/// <summary>字段类型全覆盖测试实体</summary>
+[Serializable]
+[DataObject]
+[Description("字段类型全覆盖测试实体")]
+[BindTable("测试字段", Description = "字段类型全覆盖测试实体", ConnName = "Cube", DbType = DatabaseType.SQLite)]
+public partial class 测试字段 : I测试字段, IEntity<I测试字段>
+{
+ #region 属性
+ private Int32 _Id;
+ /// <summary>编号</summary>
+ [DisplayName("编号")]
+ [Description("编号")]
+ [DataObjectField(true, true, false, 0)]
+ [BindColumn("Id", "编号", "")]
+ public Int32 Id { get => _Id; set { if (OnPropertyChanging("Id", value)) { _Id = value; OnPropertyChanged("Id"); } } }
+
+ private String _ShortText;
+ /// <summary>短文本。必填的短文本示例</summary>
+ [Category("基本信息")]
+ [DisplayName("短文本")]
+ [Description("短文本。必填的短文本示例")]
+ [DataObjectField(false, false, false, 50)]
+ [BindColumn("ShortText", "短文本。必填的短文本示例", "")]
+ public String ShortText { get => _ShortText; set { if (OnPropertyChanging("ShortText", value)) { _ShortText = value; OnPropertyChanged("ShortText"); } } }
+
+ private String _LongText;
+ /// <summary>长文本。大文本(Length>=300)渲染为多行文本域</summary>
+ [Category("基本信息")]
+ [DisplayName("长文本")]
+ [Description("长文本。大文本(Length>=300)渲染为多行文本域")]
+ [DataObjectField(false, false, true, 500)]
+ [BindColumn("LongText", "长文本。大文本(Length>=300)渲染为多行文本域", "")]
+ public String LongText { get => _LongText; set { if (OnPropertyChanging("LongText", value)) { _LongText = value; OnPropertyChanged("LongText"); } } }
+
+ private Int32 _Int32Val;
+ /// <summary>整数。Int32 数值</summary>
+ [Category("基本信息")]
+ [DisplayName("整数")]
+ [Description("整数。Int32 数值")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("Int32Val", "整数。Int32 数值", "")]
+ public Int32 Int32Val { get => _Int32Val; set { if (OnPropertyChanging("Int32Val", value)) { _Int32Val = value; OnPropertyChanged("Int32Val"); } } }
+
+ private Int64 _Int64Val;
+ /// <summary>长整数。Int64 数值</summary>
+ [Category("基本信息")]
+ [DisplayName("长整数")]
+ [Description("长整数。Int64 数值")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("Int64Val", "长整数。Int64 数值", "")]
+ public Int64 Int64Val { get => _Int64Val; set { if (OnPropertyChanging("Int64Val", value)) { _Int64Val = value; OnPropertyChanged("Int64Val"); } } }
+
+ private Decimal _DecimalVal;
+ /// <summary>金额。Decimal 数值,带精度</summary>
+ [Category("基本信息")]
+ [DisplayName("金额")]
+ [Description("金额。Decimal 数值,带精度")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("DecimalVal", "金额。Decimal 数值,带精度", "", Precision = 18, Scale = 2)]
+ public Decimal DecimalVal { get => _DecimalVal; set { if (OnPropertyChanging("DecimalVal", value)) { _DecimalVal = value; OnPropertyChanged("DecimalVal"); } } }
+
+ private Double _DoubleVal;
+ /// <summary>双精度。Double 数值</summary>
+ [Category("基本信息")]
+ [DisplayName("双精度")]
+ [Description("双精度。Double 数值")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("DoubleVal", "双精度。Double 数值", "")]
+ public Double DoubleVal { get => _DoubleVal; set { if (OnPropertyChanging("DoubleVal", value)) { _DoubleVal = value; OnPropertyChanged("DoubleVal"); } } }
+
+ private Single _FloatVal;
+ /// <summary>单精度。Single 数值</summary>
+ [Category("基本信息")]
+ [DisplayName("单精度")]
+ [Description("单精度。Single 数值")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("FloatVal", "单精度。Single 数值", "")]
+ public Single FloatVal { get => _FloatVal; set { if (OnPropertyChanging("FloatVal", value)) { _FloatVal = value; OnPropertyChanged("FloatVal"); } } }
+
+ private Boolean _Enable;
+ /// <summary>启用。布尔开关</summary>
+ [Category("基本信息")]
+ [DisplayName("启用")]
+ [Description("启用。布尔开关")]
+ [DataObjectField(false, false, false, 0)]
+ [BindColumn("Enable", "启用。布尔开关", "")]
+ public Boolean Enable { get => _Enable; set { if (OnPropertyChanging("Enable", value)) { _Enable = value; OnPropertyChanged("Enable"); } } }
+
+ private DateTime _CreateTime;
+ /// <summary>创建时间。日期时间</summary>
+ [Category("基本信息")]
+ [DisplayName("创建时间")]
+ [Description("创建时间。日期时间")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("CreateTime", "创建时间。日期时间", "")]
+ public DateTime CreateTime { get => _CreateTime; set { if (OnPropertyChanging("CreateTime", value)) { _CreateTime = value; OnPropertyChanged("CreateTime"); } } }
+
+ private CubeDemo.Areas.Test.测试枚举 _Kind;
+ /// <summary>种类。枚举类型,后端下发 lovCode 走 LOV 单选</summary>
+ [Category("值集")]
+ [DisplayName("种类")]
+ [Description("种类。枚举类型,后端下发 lovCode 走 LOV 单选")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("Kind", "种类。枚举类型,后端下发 lovCode 走 LOV 单选", "")]
+ public CubeDemo.Areas.Test.测试枚举 Kind { get => _Kind; set { if (OnPropertyChanging("Kind", value)) { _Kind = value; OnPropertyChanged("Kind"); } } }
+
+ private Guid _GuidVal;
+ /// <summary>唯一标识。Guid,非主键,渲染为只读文本</summary>
+ [Category("高级控件")]
+ [DisplayName("唯一标识")]
+ [Description("唯一标识。Guid,非主键,渲染为只读文本")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("GuidVal", "唯一标识。Guid,非主键,渲染为只读文本", "")]
+ public Guid GuidVal { get => _GuidVal; set { if (OnPropertyChanging("GuidVal", value)) { _GuidVal = value; OnPropertyChanged("GuidVal"); } } }
+
+ private String _FileUrl;
+ /// <summary>附件。文件上传,存储上传后返回的 URL</summary>
+ [Category("高级控件")]
+ [DisplayName("附件")]
+ [Description("附件。文件上传,存储上传后返回的 URL")]
+ [DataObjectField(false, false, true, 200)]
+ [BindColumn("FileUrl", "附件。文件上传,存储上传后返回的 URL", "", ItemType = "file")]
+ public String FileUrl { get => _FileUrl; set { if (OnPropertyChanging("FileUrl", value)) { _FileUrl = value; OnPropertyChanged("FileUrl"); } } }
+
+ private String _Avatar;
+ /// <summary>头像。图片上传,带预览,存储 URL</summary>
+ [Category("高级控件")]
+ [DisplayName("头像")]
+ [Description("头像。图片上传,带预览,存储 URL")]
+ [DataObjectField(false, false, true, 200)]
+ [BindColumn("Avatar", "头像。图片上传,带预览,存储 URL", "", ItemType = "image")]
+ public String Avatar { get => _Avatar; set { if (OnPropertyChanging("Avatar", value)) { _Avatar = value; OnPropertyChanged("Avatar"); } } }
+
+ private String _JsonVal;
+ /// <summary>Json。Json 编辑器,存储 Json 字符串</summary>
+ [Category("高级控件")]
+ [DisplayName("Json")]
+ [Description("Json。Json 编辑器,存储 Json 字符串")]
+ [DataObjectField(false, false, true, 2000)]
+ [BindColumn("JsonVal", "Json。Json 编辑器,存储 Json 字符串", "", ItemType = "json")]
+ public String JsonVal { get => _JsonVal; set { if (OnPropertyChanging("JsonVal", value)) { _JsonVal = value; OnPropertyChanged("JsonVal"); } } }
+
+ private String _HtmlVal;
+ /// <summary>富文本。html 富文本编辑器,存储 html 字符串</summary>
+ [Category("高级控件")]
+ [DisplayName("富文本")]
+ [Description("富文本。html 富文本编辑器,存储 html 字符串")]
+ [DataObjectField(false, false, true, 2000)]
+ [BindColumn("HtmlVal", "富文本。html 富文本编辑器,存储 html 字符串", "", ItemType = "html")]
+ public String HtmlVal { get => _HtmlVal; set { if (OnPropertyChanging("HtmlVal", value)) { _HtmlVal = value; OnPropertyChanged("HtmlVal"); } } }
+
+ private String _MarkdownVal;
+ /// <summary>Markdown。Markdown 富文本编辑器,存储 md 字符串</summary>
+ [Category("高级控件")]
+ [DisplayName("Markdown")]
+ [Description("Markdown。Markdown 富文本编辑器,存储 md 字符串")]
+ [DataObjectField(false, false, true, 2000)]
+ [BindColumn("MarkdownVal", "Markdown。Markdown 富文本编辑器,存储 md 字符串", "", ItemType = "markdown")]
+ public String MarkdownVal { get => _MarkdownVal; set { if (OnPropertyChanging("MarkdownVal", value)) { _MarkdownVal = value; OnPropertyChanged("MarkdownVal"); } } }
+
+ private String _ColorVal;
+ /// <summary>颜色。颜色选择器,存储色值字符串</summary>
+ [Category("高级控件")]
+ [DisplayName("颜色")]
+ [Description("颜色。颜色选择器,存储色值字符串")]
+ [DataObjectField(false, false, true, 50)]
+ [BindColumn("ColorVal", "颜色。颜色选择器,存储色值字符串", "", ItemType = "color")]
+ public String ColorVal { get => _ColorVal; set { if (OnPropertyChanging("ColorVal", value)) { _ColorVal = value; OnPropertyChanged("ColorVal"); } } }
+
+ private String _IconVal;
+ /// <summary>图标。图标选择器,存储图标名字符串</summary>
+ [Category("高级控件")]
+ [DisplayName("图标")]
+ [Description("图标。图标选择器,存储图标名字符串")]
+ [DataObjectField(false, false, true, 50)]
+ [BindColumn("IconVal", "图标。图标选择器,存储图标名字符串", "", ItemType = "icon")]
+ public String IconVal { get => _IconVal; set { if (OnPropertyChanging("IconVal", value)) { _IconVal = value; OnPropertyChanged("IconVal"); } } }
+
+ private String _MailVal;
+ /// <summary>邮箱。邮箱输入,带格式校验</summary>
+ [Category("高级控件")]
+ [DisplayName("邮箱")]
+ [Description("邮箱。邮箱输入,带格式校验")]
+ [DataObjectField(false, false, true, 50)]
+ [BindColumn("MailVal", "邮箱。邮箱输入,带格式校验", "", ItemType = "mail")]
+ public String MailVal { get => _MailVal; set { if (OnPropertyChanging("MailVal", value)) { _MailVal = value; OnPropertyChanged("MailVal"); } } }
+
+ private String _MobileVal;
+ /// <summary>手机。手机输入,带格式校验</summary>
+ [Category("高级控件")]
+ [DisplayName("手机")]
+ [Description("手机。手机输入,带格式校验")]
+ [DataObjectField(false, false, true, 50)]
+ [BindColumn("MobileVal", "手机。手机输入,带格式校验", "", ItemType = "mobile")]
+ public String MobileVal { get => _MobileVal; set { if (OnPropertyChanging("MobileVal", value)) { _MobileVal = value; OnPropertyChanged("MobileVal"); } } }
+
+ private String _UrlVal;
+ /// <summary>网址。网址输入,带格式校验</summary>
+ [Category("高级控件")]
+ [DisplayName("网址")]
+ [Description("网址。网址输入,带格式校验")]
+ [DataObjectField(false, false, true, 200)]
+ [BindColumn("UrlVal", "网址。网址输入,带格式校验", "", ItemType = "url")]
+ public String UrlVal { get => _UrlVal; set { if (OnPropertyChanging("UrlVal", value)) { _UrlVal = value; OnPropertyChanged("UrlVal"); } } }
+
+ private Int32 _SingleVal;
+ /// <summary>单选。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ [Category("值集")]
+ [DisplayName("单选")]
+ [Description("单选。singleSelect,后端下发 lovCode 走 LOV 单选")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("SingleVal", "单选。singleSelect,后端下发 lovCode 走 LOV 单选", "", ItemType = "singleSelect")]
+ public Int32 SingleVal { get => _SingleVal; set { if (OnPropertyChanging("SingleVal", value)) { _SingleVal = value; OnPropertyChanged("SingleVal"); } } }
+
+ private String _MultiVal;
+ /// <summary>多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值</summary>
+ [Category("值集")]
+ [DisplayName("多选")]
+ [Description("多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值")]
+ [DataObjectField(false, false, true, 200)]
+ [BindColumn("MultiVal", "多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值", "", ItemType = "multipleSelect")]
+ public String MultiVal { get => _MultiVal; set { if (OnPropertyChanging("MultiVal", value)) { _MultiVal = value; OnPropertyChanged("MultiVal"); } } }
+
+ private String _UserId;
+ /// <summary>用户。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ [Category("值集")]
+ [DisplayName("用户")]
+ [Description("用户。singleSelect,后端下发 lovCode 走 LOV 单选")]
+ [DataObjectField(false, false, true, 200)]
+ [BindColumn("UserId", "用户。singleSelect,后端下发 lovCode 走 LOV 单选", "", ItemType = "singleSelect")]
+ public String UserId { get => _UserId; set { if (OnPropertyChanging("UserId", value)) { _UserId = value; OnPropertyChanged("UserId"); } } }
+
+ private Int32 _ListVal;
+ /// <summary>下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择</summary>
+ [Category("值集")]
+ [DisplayName("下拉表格")]
+ [Description("下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择")]
+ [DataObjectField(false, false, true, 0)]
+ [BindColumn("ListVal", "下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择", "", ItemType = "lovTable")]
+ public Int32 ListVal { get => _ListVal; set { if (OnPropertyChanging("ListVal", value)) { _ListVal = value; OnPropertyChanged("ListVal"); } } }
+
+ private String _ListMVal;
+ /// <summary>下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id</summary>
+ [Category("值集")]
+ [DisplayName("下拉表格(多选)")]
+ [Description("下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id")]
+ [DataObjectField(false, false, true, 200)]
+ [BindColumn("ListMVal", "下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id", "", ItemType = "lovTableMulti")]
+ public String ListMVal { get => _ListMVal; set { if (OnPropertyChanging("ListMVal", value)) { _ListMVal = value; OnPropertyChanged("ListMVal"); } } }
+ #endregion
+
+ #region 拷贝
+ /// <summary>拷贝模型对象</summary>
+ /// <param name="model">模型</param>
+ public void Copy(I测试字段 model)
+ {
+ Id = model.Id;
+ ShortText = model.ShortText;
+ LongText = model.LongText;
+ Int32Val = model.Int32Val;
+ Int64Val = model.Int64Val;
+ DecimalVal = model.DecimalVal;
+ DoubleVal = model.DoubleVal;
+ FloatVal = model.FloatVal;
+ Enable = model.Enable;
+ CreateTime = model.CreateTime;
+ Kind = model.Kind;
+ GuidVal = model.GuidVal;
+ FileUrl = model.FileUrl;
+ Avatar = model.Avatar;
+ JsonVal = model.JsonVal;
+ HtmlVal = model.HtmlVal;
+ MarkdownVal = model.MarkdownVal;
+ ColorVal = model.ColorVal;
+ IconVal = model.IconVal;
+ MailVal = model.MailVal;
+ MobileVal = model.MobileVal;
+ UrlVal = model.UrlVal;
+ SingleVal = model.SingleVal;
+ MultiVal = model.MultiVal;
+ UserId = model.UserId;
+ ListVal = model.ListVal;
+ ListMVal = model.ListMVal;
+ }
+ #endregion
+
+ #region 获取/设置 字段值
+ /// <summary>获取/设置 字段值</summary>
+ /// <param name="name">字段名</param>
+ /// <returns></returns>
+ public override Object this[String name]
+ {
+ get => name switch
+ {
+ "Id" => _Id,
+ "ShortText" => _ShortText,
+ "LongText" => _LongText,
+ "Int32Val" => _Int32Val,
+ "Int64Val" => _Int64Val,
+ "DecimalVal" => _DecimalVal,
+ "DoubleVal" => _DoubleVal,
+ "FloatVal" => _FloatVal,
+ "Enable" => _Enable,
+ "CreateTime" => _CreateTime,
+ "Kind" => _Kind,
+ "GuidVal" => _GuidVal,
+ "FileUrl" => _FileUrl,
+ "Avatar" => _Avatar,
+ "JsonVal" => _JsonVal,
+ "HtmlVal" => _HtmlVal,
+ "MarkdownVal" => _MarkdownVal,
+ "ColorVal" => _ColorVal,
+ "IconVal" => _IconVal,
+ "MailVal" => _MailVal,
+ "MobileVal" => _MobileVal,
+ "UrlVal" => _UrlVal,
+ "SingleVal" => _SingleVal,
+ "MultiVal" => _MultiVal,
+ "UserId" => _UserId,
+ "ListVal" => _ListVal,
+ "ListMVal" => _ListMVal,
+ _ => base[name]
+ };
+ set
+ {
+ switch (name)
+ {
+ case "Id": _Id = value.ToInt(); break;
+ case "ShortText": _ShortText = Convert.ToString(value); break;
+ case "LongText": _LongText = Convert.ToString(value); break;
+ case "Int32Val": _Int32Val = value.ToInt(); break;
+ case "Int64Val": _Int64Val = value.ToLong(); break;
+ case "DecimalVal": _DecimalVal = Convert.ToDecimal(value); break;
+ case "DoubleVal": _DoubleVal = value.ToDouble(); break;
+ case "FloatVal": _FloatVal = Convert.ToSingle(value); break;
+ case "Enable": _Enable = value.ToBoolean(); break;
+ case "CreateTime": _CreateTime = value.ToDateTime(); break;
+ case "Kind": _Kind = (CubeDemo.Areas.Test.测试枚举)value.ToInt(); break;
+ case "GuidVal": _GuidVal = (Guid)value; break;
+ case "FileUrl": _FileUrl = Convert.ToString(value); break;
+ case "Avatar": _Avatar = Convert.ToString(value); break;
+ case "JsonVal": _JsonVal = Convert.ToString(value); break;
+ case "HtmlVal": _HtmlVal = Convert.ToString(value); break;
+ case "MarkdownVal": _MarkdownVal = Convert.ToString(value); break;
+ case "ColorVal": _ColorVal = Convert.ToString(value); break;
+ case "IconVal": _IconVal = Convert.ToString(value); break;
+ case "MailVal": _MailVal = Convert.ToString(value); break;
+ case "MobileVal": _MobileVal = Convert.ToString(value); break;
+ case "UrlVal": _UrlVal = Convert.ToString(value); break;
+ case "SingleVal": _SingleVal = value.ToInt(); break;
+ case "MultiVal": _MultiVal = Convert.ToString(value); break;
+ case "UserId": _UserId = Convert.ToString(value); break;
+ case "ListVal": _ListVal = value.ToInt(); break;
+ case "ListMVal": _ListMVal = Convert.ToString(value); break;
+ default: base[name] = value; break;
+ }
+ }
+ }
+ #endregion
+
+ #region 关联映射
+ #endregion
+
+ #region 扩展查询
+ #endregion
+
+ #region 高级查询
+ /// <summary>高级查询</summary>
+ /// <param name="kind">种类。枚举类型,后端下发 lovCode 走 LOV 单选</param>
+ /// <param name="enable">启用。布尔开关</param>
+ /// <param name="start">创建时间开始</param>
+ /// <param name="end">创建时间结束</param>
+ /// <param name="key">关键字</param>
+ /// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
+ /// <returns>实体列表</returns>
+ public static IList<测试字段> Search(CubeDemo.Areas.Test.测试枚举 kind, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
+ {
+ var exp = new WhereExpression();
+
+ if (kind >= 0) exp &= _.Kind == kind;
+ if (enable != null) exp &= _.Enable == enable;
+ exp &= _.CreateTime.Between(start, end);
+ if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);
+
+ return FindAll(exp, page);
+ }
+ #endregion
+
+ #region 字段名
+ /// <summary>取得字段类型全覆盖测试实体字段信息的快捷方式</summary>
+ public partial class _
+ {
+ /// <summary>编号</summary>
+ public static readonly Field Id = FindByName("Id");
+
+ /// <summary>短文本。必填的短文本示例</summary>
+ public static readonly Field ShortText = FindByName("ShortText");
+
+ /// <summary>长文本。大文本(Length>=300)渲染为多行文本域</summary>
+ public static readonly Field LongText = FindByName("LongText");
+
+ /// <summary>整数。Int32 数值</summary>
+ public static readonly Field Int32Val = FindByName("Int32Val");
+
+ /// <summary>长整数。Int64 数值</summary>
+ public static readonly Field Int64Val = FindByName("Int64Val");
+
+ /// <summary>金额。Decimal 数值,带精度</summary>
+ public static readonly Field DecimalVal = FindByName("DecimalVal");
+
+ /// <summary>双精度。Double 数值</summary>
+ public static readonly Field DoubleVal = FindByName("DoubleVal");
+
+ /// <summary>单精度。Single 数值</summary>
+ public static readonly Field FloatVal = FindByName("FloatVal");
+
+ /// <summary>启用。布尔开关</summary>
+ public static readonly Field Enable = FindByName("Enable");
+
+ /// <summary>创建时间。日期时间</summary>
+ public static readonly Field CreateTime = FindByName("CreateTime");
+
+ /// <summary>种类。枚举类型,后端下发 lovCode 走 LOV 单选</summary>
+ public static readonly Field Kind = FindByName("Kind");
+
+ /// <summary>唯一标识。Guid,非主键,渲染为只读文本</summary>
+ public static readonly Field GuidVal = FindByName("GuidVal");
+
+ /// <summary>附件。文件上传,存储上传后返回的 URL</summary>
+ public static readonly Field FileUrl = FindByName("FileUrl");
+
+ /// <summary>头像。图片上传,带预览,存储 URL</summary>
+ public static readonly Field Avatar = FindByName("Avatar");
+
+ /// <summary>Json。Json 编辑器,存储 Json 字符串</summary>
+ public static readonly Field JsonVal = FindByName("JsonVal");
+
+ /// <summary>富文本。html 富文本编辑器,存储 html 字符串</summary>
+ public static readonly Field HtmlVal = FindByName("HtmlVal");
+
+ /// <summary>Markdown。Markdown 富文本编辑器,存储 md 字符串</summary>
+ public static readonly Field MarkdownVal = FindByName("MarkdownVal");
+
+ /// <summary>颜色。颜色选择器,存储色值字符串</summary>
+ public static readonly Field ColorVal = FindByName("ColorVal");
+
+ /// <summary>图标。图标选择器,存储图标名字符串</summary>
+ public static readonly Field IconVal = FindByName("IconVal");
+
+ /// <summary>邮箱。邮箱输入,带格式校验</summary>
+ public static readonly Field MailVal = FindByName("MailVal");
+
+ /// <summary>手机。手机输入,带格式校验</summary>
+ public static readonly Field MobileVal = FindByName("MobileVal");
+
+ /// <summary>网址。网址输入,带格式校验</summary>
+ public static readonly Field UrlVal = FindByName("UrlVal");
+
+ /// <summary>单选。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ public static readonly Field SingleVal = FindByName("SingleVal");
+
+ /// <summary>多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值</summary>
+ public static readonly Field MultiVal = FindByName("MultiVal");
+
+ /// <summary>用户。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ public static readonly Field UserId = FindByName("UserId");
+
+ /// <summary>下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择</summary>
+ public static readonly Field ListVal = FindByName("ListVal");
+
+ /// <summary>下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id</summary>
+ public static readonly Field ListMVal = FindByName("ListMVal");
+
+ static Field FindByName(String name) => Meta.Table.FindByName(name);
+ }
+
+ /// <summary>取得字段类型全覆盖测试实体字段名称的快捷方式</summary>
+ public partial class __
+ {
+ /// <summary>编号</summary>
+ public const String Id = "Id";
+
+ /// <summary>短文本。必填的短文本示例</summary>
+ public const String ShortText = "ShortText";
+
+ /// <summary>长文本。大文本(Length>=300)渲染为多行文本域</summary>
+ public const String LongText = "LongText";
+
+ /// <summary>整数。Int32 数值</summary>
+ public const String Int32Val = "Int32Val";
+
+ /// <summary>长整数。Int64 数值</summary>
+ public const String Int64Val = "Int64Val";
+
+ /// <summary>金额。Decimal 数值,带精度</summary>
+ public const String DecimalVal = "DecimalVal";
+
+ /// <summary>双精度。Double 数值</summary>
+ public const String DoubleVal = "DoubleVal";
+
+ /// <summary>单精度。Single 数值</summary>
+ public const String FloatVal = "FloatVal";
+
+ /// <summary>启用。布尔开关</summary>
+ public const String Enable = "Enable";
+
+ /// <summary>创建时间。日期时间</summary>
+ public const String CreateTime = "CreateTime";
+
+ /// <summary>种类。枚举类型,后端下发 lovCode 走 LOV 单选</summary>
+ public const String Kind = "Kind";
+
+ /// <summary>唯一标识。Guid,非主键,渲染为只读文本</summary>
+ public const String GuidVal = "GuidVal";
+
+ /// <summary>附件。文件上传,存储上传后返回的 URL</summary>
+ public const String FileUrl = "FileUrl";
+
+ /// <summary>头像。图片上传,带预览,存储 URL</summary>
+ public const String Avatar = "Avatar";
+
+ /// <summary>Json。Json 编辑器,存储 Json 字符串</summary>
+ public const String JsonVal = "JsonVal";
+
+ /// <summary>富文本。html 富文本编辑器,存储 html 字符串</summary>
+ public const String HtmlVal = "HtmlVal";
+
+ /// <summary>Markdown。Markdown 富文本编辑器,存储 md 字符串</summary>
+ public const String MarkdownVal = "MarkdownVal";
+
+ /// <summary>颜色。颜色选择器,存储色值字符串</summary>
+ public const String ColorVal = "ColorVal";
+
+ /// <summary>图标。图标选择器,存储图标名字符串</summary>
+ public const String IconVal = "IconVal";
+
+ /// <summary>邮箱。邮箱输入,带格式校验</summary>
+ public const String MailVal = "MailVal";
+
+ /// <summary>手机。手机输入,带格式校验</summary>
+ public const String MobileVal = "MobileVal";
+
+ /// <summary>网址。网址输入,带格式校验</summary>
+ public const String UrlVal = "UrlVal";
+
+ /// <summary>单选。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ public const String SingleVal = "SingleVal";
+
+ /// <summary>多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值</summary>
+ public const String MultiVal = "MultiVal";
+
+ /// <summary>用户。singleSelect,后端下发 lovCode 走 LOV 单选</summary>
+ public const String UserId = "UserId";
+
+ /// <summary>下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择</summary>
+ public const String ListVal = "ListVal";
+
+ /// <summary>下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id</summary>
+ public const String ListMVal = "ListMVal";
+ }
+ #endregion
+}
diff --git "a/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\346\236\232\344\270\276.cs" "b/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\346\236\232\344\270\276.cs"
new file mode 100644
index 0000000..abb0416
--- /dev/null
+++ "b/CubeDemo/Areas/Test/Models/Entity/\346\265\213\350\257\225\346\236\232\344\270\276.cs"
@@ -0,0 +1,30 @@
+using System.ComponentModel;
+
+namespace CubeDemo.Areas.Test;
+
+/// <summary>
+/// 测试枚举。用于验证 枚举 / 单选(singleSelect) / 多选(multipleSelect) 三种 LOV 场景。
+/// <para>
+/// <see cref="NewLife.Cube.Services.LovAutoRegisterService"/> 会在启动时扫描
+/// <c>CubeDemo.Areas.Test</c> 命名空间下的枚举,自动将其注册为
+/// <c>Enum.CubeDemo.Areas.Test.测试枚举</c> 值集,无需手工维护 <c>LovDefinition</c> 记录。
+/// </para>
+/// </summary>
+public enum 测试枚举
+{
+ /// <summary>未知</summary>
+ [Description("未知")]
+ 未知 = 0,
+
+ /// <summary>选项一</summary>
+ [Description("选项一")]
+ 选项一 = 1,
+
+ /// <summary>选项二</summary>
+ [Description("选项二")]
+ 选项二 = 2,
+
+ /// <summary>选项三</summary>
+ [Description("选项三")]
+ 选项三 = 3,
+}
diff --git a/CubeDemo/Areas/Test/Models/Model.xml b/CubeDemo/Areas/Test/Models/Model.xml
new file mode 100644
index 0000000..4b737c0
--- /dev/null
+++ b/CubeDemo/Areas/Test/Models/Model.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<EntityModel xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="https://newlifex.com https://newlifex.com/Model202509.xsd" Version="11.7.2023.0327" Document="https://newlifex.com/xcode/model" ModelVersion="2.0.2026.130" xmlns="https://newlifex.com/Model202509.xsd">
+ <Option>
+ <!--类名模板。其中{name}替换为Table.Name,如{name}Model/I{name}Dto等-->
+ <ClassNameTemplate />
+ <!--显示名模板。其中{displayName}替换为Table.DisplayName-->
+ <DisplayNameTemplate />
+ <!--基类。可能包含基类和接口,其中{name}替换为Table.Name-->
+ <BaseClass>Entity</BaseClass>
+ <!--命名空间-->
+ <Namespace>CubeDemo.Areas.Test</Namespace>
+ <!--引用命名空间-->
+ <ExtendNameSpace />
+ <!--输出目录-->
+ <Output>.\Entity\</Output>
+ <!--是否使用中文文件名。默认false-->
+ <ChineseFileName>False</ChineseFileName>
+ <!--用于生成Copy函数的参数类型。例如{name}或I{name}-->
+ <ModelNameForCopy />
+ <!--带有索引器。实现IModel接口-->
+ <HasIModel>True</HasIModel>
+ <!--可为null上下文。生成String?等-->
+ <Nullable>False</Nullable>
+ <!--数据库连接名-->
+ <ConnName>Cube</ConnName>
+ <!--模型类模版。设置后生成模型类,用于接口数据传输,例如{name}Model-->
+ <ModelClass>{name}Model</ModelClass>
+ <!--模型类输出目录。默认当前目录的Models子目录-->
+ <ModelsOutput>.\Models\</ModelsOutput>
+ <!--模型接口模版。设置后生成模型接口,用于约束模型类和实体类,例如I{name}-->
+ <ModelInterface>I{name}</ModelInterface>
+ <!--模型接口输出目录。默认当前目录的Interfaces子目录-->
+ <InterfacesOutput>.\Interfaces\</InterfacesOutput>
+ <!--用户实体转为模型类的模型类。例如{name}或{name}DTO-->
+ <ModelNameForToModel />
+ <!--命名格式。Default/Upper/Lower/Underline-->
+ <NameFormat>Default</NameFormat>
+ <!--魔方区域显示名-->
+ <DisplayName />
+ <!--魔方控制器输出目录-->
+ <CubeOutput />
+ </Option>
+ <Tables>
+ <Table Name="测试字段" Description="字段类型全覆盖测试实体" ConnName="Cube" DbType="SQLite">
+ <Columns>
+ <Column Name="Id" DataType="Int32" Identity="True" PrimaryKey="True" Description="编号" />
+ <Column Name="ShortText" DataType="String" Nullable="False" Description="短文本。必填的短文本示例" Category="基本信息" />
+ <Column Name="LongText" DataType="String" Length="500" Description="长文本。大文本(Length>=300)渲染为多行文本域" Category="基本信息" />
+ <Column Name="Int32Val" DataType="Int32" Nullable="True" Description="整数。Int32 数值" Category="基本信息" />
+ <Column Name="Int64Val" DataType="Int64" Nullable="True" Description="长整数。Int64 数值" Category="基本信息" />
+ <Column Name="DecimalVal" DataType="Decimal" Precision="18" Scale="2" Nullable="True" Description="金额。Decimal 数值,带精度" Category="基本信息" />
+ <Column Name="DoubleVal" DataType="Double" Nullable="True" Description="双精度。Double 数值" Category="基本信息" />
+ <Column Name="FloatVal" DataType="Single" Nullable="True" Description="单精度。Single 数值" Category="基本信息" />
+ <Column Name="Enable" DataType="Boolean" Description="启用。布尔开关" Category="基本信息" />
+ <Column Name="CreateTime" DataType="DateTime" Description="创建时间。日期时间" Category="基本信息" />
+ <Column Name="Kind" DataType="Int32" Nullable="True" Description="种类。枚举类型,后端下发 lovCode 走 LOV 单选" Type="CubeDemo.Areas.Test.测试枚举" Category="值集" />
+ <Column Name="GuidVal" DataType="Guid" Nullable="True" Description="唯一标识。Guid,非主键,渲染为只读文本" Category="高级控件" />
+ <Column Name="FileUrl" DataType="String" ItemType="file" Length="200" Description="附件。文件上传,存储上传后返回的 URL" Category="高级控件" />
+ <Column Name="Avatar" DataType="String" ItemType="image" Length="200" Description="头像。图片上传,带预览,存储 URL" Category="高级控件" />
+ <Column Name="JsonVal" DataType="String" ItemType="json" Length="2000" Description="Json。Json 编辑器,存储 Json 字符串" Category="高级控件" />
+ <Column Name="HtmlVal" DataType="String" ItemType="html" Length="2000" Description="富文本。html 富文本编辑器,存储 html 字符串" Category="高级控件" />
+ <Column Name="MarkdownVal" DataType="String" ItemType="markdown" Length="2000" Description="Markdown。Markdown 富文本编辑器,存储 md 字符串" Category="高级控件" />
+ <Column Name="ColorVal" DataType="String" ItemType="color" Description="颜色。颜色选择器,存储色值字符串" Category="高级控件" />
+ <Column Name="IconVal" DataType="String" ItemType="icon" Description="图标。图标选择器,存储图标名字符串" Category="高级控件" />
+ <Column Name="MailVal" DataType="String" ItemType="mail" Description="邮箱。邮箱输入,带格式校验" Category="高级控件" />
+ <Column Name="MobileVal" DataType="String" ItemType="mobile" Description="手机。手机输入,带格式校验" Category="高级控件" />
+ <Column Name="UrlVal" DataType="String" ItemType="url" Length="200" Description="网址。网址输入,带格式校验" Category="高级控件" />
+ <Column Name="SingleVal" DataType="Int32" ItemType="singleSelect" Nullable="True" Description="单选。singleSelect,后端下发 lovCode 走 LOV 单选" Category="值集" />
+ <Column Name="MultiVal" DataType="String" ItemType="multipleSelect" Length="200" Description="多选。multipleSelect,后端下发 lovCode 走 LOV 多选,存储逗号分隔的值" Category="值集" />
+ <Column Name="UserId" DataType="String" ItemType="singleSelect" Length="200" Description="用户。singleSelect,后端下发 lovCode 走 LOV 单选" Category="值集" />
+ <Column Name="ListVal" DataType="Int32" ItemType="lovTable" Nullable="True" Description="下拉表格。lovTable,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格选择" Category="值集" />
+ <Column Name="ListMVal" DataType="String" ItemType="lovTableMulti" Length="200" Description="下拉表格(多选)。lovTableMulti,后端下发 List.* 类型 lovCode,走 LOV 弹窗表格多选,存储逗号分隔的 id" Category="值集" />
+ </Columns>
+ </Table>
+ </Tables>
+</EntityModel>
\ No newline at end of file
diff --git a/CubeDemo/Areas/Test/TestArea.cs b/CubeDemo/Areas/Test/TestArea.cs
new file mode 100644
index 0000000..df67a1a
--- /dev/null
+++ b/CubeDemo/Areas/Test/TestArea.cs
@@ -0,0 +1,13 @@
+using System.ComponentModel;
+using NewLife;
+using NewLife.Cube;
+
+namespace CubeDemo.Areas.Test;
+
+/// <summary>测试中心区域。承载「字段类型全覆盖」测试台,用于验证前端默认模板对所有字段类型的渲染与提交。</summary>
+[DisplayName("测试中心")]
+[Menu(200)]
+public class TestArea : AreaBase
+{
+ public TestArea() : base(nameof(TestArea).TrimEnd("Area")) { }
+}
diff --git a/CubeDemo/Controllers/TestController.cs b/CubeDemo/Controllers/TestController.cs
new file mode 100644
index 0000000..6d91384
--- /dev/null
+++ b/CubeDemo/Controllers/TestController.cs
@@ -0,0 +1,71 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using NewLife.Cube;
+using NewLife.Cube.Extensions;
+using NewLife.Web;
+using XCode.Statistics;
+
+namespace CubeDemo.Controllers;
+
+//[ApiExplorerSettings(GroupName = "vTest1")]
+[AreaBase("vTest1"),]
+[Route("[controller]/[action]")]
+
+public class TestController : ControllerBaseX
+{
+ [HttpGet]
+ [HttpPost]
+ [AllowAnonymous]
+ public ApiResponse<TestClass> HelloList()
+ {
+ var enity = new TestClass { Name = "测试", Id = 100 };
+ var aa = enity.ToOkApiResponse();
+ return aa;
+ }
+
+ [HttpGet]
+ [HttpPost]
+ [AllowAnonymous]
+ public ApiListResponse<TestClass> HelloList1([FromQuery] Pager pager, [FromBody] TestClass para)
+ {
+ var p = new Pager(WebHelper.Params) { RetrieveTotalCount = true };
+
+ var list = SearchData1(p);
+ return list.ToOkApiResponse().WithPager(p);
+ }
+
+ [HttpGet]
+ [HttpPost]
+ [AllowAnonymous]
+ public ApiListResponse<TestClass> HelloList2([FromQuery] Pager pager, [FromBody] TestClass para)
+ {
+ var p = new Pager(WebHelper.Params) { RetrieveTotalCount = true };
+ var list = SearchData1(p);
+ var ss = list.ToFailApiResponse("");
+ return ss.WithPager(p);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ private IEnumerable<TestClass> SearchData1(Pager pager)
+ {
+ pager.PageSize = 11;
+
+ var list = new List<TestClass>();
+ for (int i = 0; i < 10; i++)
+ list.Add(new TestClass { Name = "测试" + i, Id = i });
+ return list;
+
+ }
+}
\ No newline at end of file
diff --git a/ReactCubeDemo/ReactCubeDemo.csproj b/CubeDemo/CubeDemo.csproj
similarity index 95%
rename from ReactCubeDemo/ReactCubeDemo.csproj
rename to CubeDemo/CubeDemo.csproj
index ef817db..1a13537 100644
--- a/ReactCubeDemo/ReactCubeDemo.csproj
+++ b/CubeDemo/CubeDemo.csproj
@@ -27,6 +27,10 @@
</ItemGroup>
<ItemGroup>
+ <Folder Include="Controllers\" />
+ </ItemGroup>
+
+ <ItemGroup>
<PackageReference Include="NewLife.MySql" Version="1.4.2026.801" />
</ItemGroup>
diff --git a/ReactCubeDemo/IoTSetting.cs b/CubeDemo/IoTSetting.cs
similarity index 100%
rename from ReactCubeDemo/IoTSetting.cs
rename to CubeDemo/IoTSetting.cs
diff --git a/ReactCubeDemo/Program.cs b/CubeDemo/Program.cs
similarity index 96%
rename from ReactCubeDemo/Program.cs
rename to CubeDemo/Program.cs
index 85c3329..badc453 100644
--- a/ReactCubeDemo/Program.cs
+++ b/CubeDemo/Program.cs
@@ -37,9 +37,7 @@ app.MapControllerRoute(name: "default", pattern: "{controller=Index}/{action=Ind
app.MapControllers();
// UseVue 必须在 MapControllers 之后,确保 API endpoint 优先匹配,SPA 回退兜底
-//app.UseVue(builder.Environment);
app.UseReact(builder.Environment);
-// app.UseArcoVue(builder.Environment);
app.RegisterService("CubeDemo", null, builder.Environment.EnvironmentName, "/cube/info");
diff --git a/ReactCubeDemo/Properties/launchSettings.json b/CubeDemo/Properties/launchSettings.json
similarity index 100%
rename from ReactCubeDemo/Properties/launchSettings.json
rename to CubeDemo/Properties/launchSettings.json
diff --git a/CubeDemo/TestClass.cs b/CubeDemo/TestClass.cs
new file mode 100644
index 0000000..84c1527
--- /dev/null
+++ b/CubeDemo/TestClass.cs
@@ -0,0 +1,17 @@
+namespace CubeDemo;
+
+/// <summary>测试类Model</summary>
+public class TestClass
+{
+ /// <summary></summary>
+ public Int32 Id { get; set; }
+
+ /// <summary></summary>
+ public String Name { get; set; } = null!;
+}
+/// <summary>测试</summary>
+public class MyClass
+{
+ public int Id { get; set; }
+ public Int32 Age { get; set; }
+}
\ No newline at end of file
diff --git "a/\351\255\224\346\226\271React.slnx" "b/\351\255\224\346\226\271React.slnx"
index f989960..3bf5f9c 100644
--- "a/\351\255\224\346\226\271React.slnx"
+++ "b/\351\255\224\346\226\271React.slnx"
@@ -1,4 +1,4 @@
<Solution>
+ <Project Path="CubeDemo/CubeDemo.csproj" />
<Project Path="NewLife.Cube.React/NewLife.Cube.React.csproj" />
- <Project Path="ReactCubeDemo/ReactCubeDemo.csproj" />
</Solution>