commits列表 30 项
提交内容 14/14
添加测试项目,添加脱敏支持!
example/ExampleApeart.Application/usermodels/RoleInfoAppService.cs
diff --git a/example/ExampleApeart.Application/usermodels/RoleInfoAppService.cs b/example/ExampleApeart.Application/usermodels/RoleInfoAppService.cs
index de8fed6..258238b 100644
--- a/example/ExampleApeart.Application/usermodels/RoleInfoAppService.cs
+++ b/example/ExampleApeart.Application/usermodels/RoleInfoAppService.cs
@@ -9,6 +9,7 @@ using PasteApeart.Handler;
 using PasteApeart.Handler.Extensions;
 using PasteApeart.Handler.Level;
 using PasteApeart.Helper;
+using PasteApeart.Helper.Extensions;
 using System.Linq.Dynamic.Core;
 
 namespace ExampleApeart.usermodels
example/ExampleApeart.Test/ExampleApeart.Test.csproj
diff --git a/example/ExampleApeart.Test/ExampleApeart.Test.csproj b/example/ExampleApeart.Test/ExampleApeart.Test.csproj
new file mode 100644
index 0000000..93d150e
--- /dev/null
+++ b/example/ExampleApeart.Test/ExampleApeart.Test.csproj
@@ -0,0 +1,20 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<OutputType>Exe</OutputType>
+		<TargetFramework>net8.0</TargetFramework>
+		<ImplicitUsings>enable</ImplicitUsings>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.19" />
+		<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
+		<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6" />
+		<PackageReference Include="xunit.v3" Version="4.0.2" />
+	</ItemGroup>
+
+	<ItemGroup>
+	  <ProjectReference Include="..\..\framework\PasteApeart.Helper\PasteApeart.Helper.csproj" />
+	</ItemGroup>
+
+</Project>
example/ExampleApeart.Test/HalfHideTestHelper.cs
diff --git a/example/ExampleApeart.Test/HalfHideTestHelper.cs b/example/ExampleApeart.Test/HalfHideTestHelper.cs
new file mode 100644
index 0000000..2c6957e
--- /dev/null
+++ b/example/ExampleApeart.Test/HalfHideTestHelper.cs
@@ -0,0 +1,189 @@
+using PasteApeart.Helper;
+using System.Text.Json;
+using Xunit;
+
+namespace ExampleApeart.Test
+{
+    /// <summary>
+    /// 测试脱敏处理
+    /// </summary>
+    public class HalfHideTestHelper
+    {
+        private readonly ITestOutputHelper _output;
+        public HalfHideTestHelper(ITestOutputHelper output) { _output = output; }
+
+        /// <summary>
+        /// 标记新对象单个
+        /// </summary>
+        [Fact]
+        public void NewSingle()
+        {
+            var model = new HalfNewModel { Name = "1345678901", Age = 5, Info = new HalfNewIncludeModel { Email = "buijhu@admin.com", Desc = "bhuijk" } };
+            var result = HalfHideHelper.PasteMaskData(model, typeof(HalfNewModel));
+            _output.WriteLine("原对象:" + JsonSerializer.Serialize(model));
+            _output.WriteLine("新对象:" + JsonSerializer.Serialize(result));
+        }
+
+        /// <summary>
+        /// 标记新对象的集合
+        /// </summary>
+        [Fact]
+        public void NewList()
+        {
+            var list = new List<HalfNewModel>();
+            var model = new HalfNewModel { Name = "1345678901", Age = 5 };
+            list.Add(model);
+            var model2 = new HalfNewModel { Name = "40987654567765", Age = 15, Info = new HalfNewIncludeModel { Email = "cvbnkjhgfdty@qq.com", Desc = "list.info" } };
+            list.Add(model2);
+
+            var result = HalfHideHelper.PasteMaskData(list, typeof(HalfNewModel));
+
+            _output.WriteLine("原对象:" + JsonSerializer.Serialize(list));
+            _output.WriteLine("新对象:" + JsonSerializer.Serialize(result));
+
+        }
+
+        /// <summary>
+        /// 标记单个
+        /// </summary>
+        [Fact]
+        public void Single()
+        {
+            var model = new HalfModel { Name = "1345678901", Age = 5, Info = new HalfIncludeModel { Email = "buijhu@admin.com", Desc = "bhuijk" } };
+            var result = HalfHideHelper.PasteMaskData(model, typeof(HalfModel));
+            _output.WriteLine("原对象:" + JsonSerializer.Serialize(model));
+            _output.WriteLine("新对象:" + JsonSerializer.Serialize(result));
+        }
+
+        /// <summary>
+        /// 标记集合
+        /// </summary>
+        [Fact]
+        public void List()
+        {
+            var list = new List<HalfModel>();
+            var model = new HalfModel { Name = "1345678901", Age = 5 };
+            list.Add(model);
+            var model2 = new HalfModel { Name = "40987654567765", Age = 15, Info = new HalfIncludeModel { Email = "cvbnkjhgfdty@qq.com", Desc = "list.info" } };
+            list.Add(model2);
+
+            var result = HalfHideHelper.PasteMaskData(list, typeof(HalfModel));
+
+            _output.WriteLine("原对象:" + JsonSerializer.Serialize(list));
+            _output.WriteLine("新对象:" + JsonSerializer.Serialize(result));
+
+        }
+
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    [PasteHalfHide(4, 4, '*', true)]
+    public class HalfNewModel
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        [PasteHalfHide]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public int Age { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [PasteHalfHide]
+        public HalfNewIncludeModel Info { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public HalfExpendModel Model { get; set; } = new HalfExpendModel();
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class HalfExpendModel
+    {
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public int High { get; set; } = 100;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public int Width { get; set; } = 1920;
+
+    }
+
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class HalfNewIncludeModel
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        [PasteHalfHide(4, 5, '.')]
+        public string Email { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public string Desc { get; set; }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    [PasteHalfHide(3, 4, '*', false)]
+    public class HalfModel
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        [PasteHalfHide]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public int Age { get; set; }
+
+        /// <summary>
+        /// 关键字段要标记,否则不会继续下探
+        /// </summary>
+        [PasteHalfHide]
+        public HalfIncludeModel Info { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public HalfExpendModel Model { get; set; } = new HalfExpendModel();
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class HalfIncludeModel
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        [PasteHalfHide(4, 5, '#')]
+        public string Email { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public string Desc { get; set; }
+    }
+}
example/ExampleApeart.sln
diff --git a/example/ExampleApeart.sln b/example/ExampleApeart.sln
index a44bb56..d031664 100644
--- a/example/ExampleApeart.sln
+++ b/example/ExampleApeart.sln
@@ -33,6 +33,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PasteApeart.Application", "
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PasteApeart.Helper", "..\framework\PasteApeart.Helper\PasteApeart.Helper.csproj", "{93B87C2D-64EF-BBAB-95C4-8C3F5DB477EB}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleApeart.Test", "ExampleApeart.Test\ExampleApeart.Test.csproj", "{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A79658C0-D6FC-43A3-A828-764AC234223D}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -253,6 +257,22 @@ Global
 		{93B87C2D-64EF-BBAB-95C4-8C3F5DB477EB}.Release|x64.Build.0 = Release|x64
 		{93B87C2D-64EF-BBAB-95C4-8C3F5DB477EB}.Release|x86.ActiveCfg = Release|Any CPU
 		{93B87C2D-64EF-BBAB-95C4-8C3F5DB477EB}.Release|x86.Build.0 = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|ARM64.Build.0 = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|x64.Build.0 = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Debug|x86.Build.0 = Debug|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|ARM64.ActiveCfg = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|ARM64.Build.0 = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|x64.ActiveCfg = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|x64.Build.0 = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|x86.ActiveCfg = Release|Any CPU
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -271,6 +291,7 @@ Global
 		{B4E0F5D3-E931-B1F3-62C4-B9D33F59191E} = {A674AE5C-C826-48E0-9DA8-8978FAFEE10A}
 		{FCEDEE51-A9DC-FC42-61C3-78D85EEB35F9} = {A674AE5C-C826-48E0-9DA8-8978FAFEE10A}
 		{93B87C2D-64EF-BBAB-95C4-8C3F5DB477EB} = {A674AE5C-C826-48E0-9DA8-8978FAFEE10A}
+		{1A55630D-C4E6-4FEF-97F0-0706FDD082DB} = {A79658C0-D6FC-43A3-A828-764AC234223D}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {D5B6327E-927F-4D35-9FFE-1EBDA1F97354}
framework/Directory.Build.props
diff --git a/framework/Directory.Build.props b/framework/Directory.Build.props
index 4878e9e..856c9c3 100644
--- a/framework/Directory.Build.props
+++ b/framework/Directory.Build.props
@@ -1,7 +1,7 @@
 <Project>
   <PropertyGroup>
-    <Version>26.10.10</Version>
-    <FileVersion>26.10.10</FileVersion>
-    <AssemblyVersion>26.10.10</AssemblyVersion>
+    <Version>26.10.11</Version>
+    <FileVersion>26.10.11</FileVersion>
+    <AssemblyVersion>26.10.11</AssemblyVersion>
   </PropertyGroup>
 </Project>
\ No newline at end of file
framework/PasteApeart.Application/IPasteDefaultAppService.cs
diff --git a/framework/PasteApeart.Application/IPasteDefaultAppService.cs b/framework/PasteApeart.Application/IPasteDefaultAppService.cs
index 728d112..418ea4f 100644
--- a/framework/PasteApeart.Application/IPasteDefaultAppService.cs
+++ b/framework/PasteApeart.Application/IPasteDefaultAppService.cs
@@ -97,24 +97,35 @@ namespace PasteApeart.Application
         /// <param name="searchObject"></param>
         /// <param name="entityType"></param>
         /// <param name="searchType"></param>
-        /// <param name="input"></param>
+        /// <param name="page">当前页码,第1页要读取totalCount</param>
         /// <param name="listDtoType"></param>
         /// <returns></returns>
-        Task<dynamic> DirectPageAsync(object searchObject, Type entityType, Type searchType, InputSearchBase input, Type listDtoType);
+        Task<dynamic> DirectPageAsync(object searchObject, Type entityType, Type searchType, int page, Type listDtoType);
 
         /// <summary>
-        /// 
+        /// 获取新增 元数据
         /// </summary>
         /// <param name="entityName"></param>
         /// <returns></returns>
         Task<VoloModelInfo> ReadAddModel(string entityName);
+
         /// <summary>
-        /// 
+        /// 获取对象详细的元数据
         /// </summary>
         /// <param name="entityName"></param>
         /// <param name="id"></param>
         /// <returns></returns>
         Task<VoloModelInfo> ReadDetailModel(string entityName, string id);
+
+        /// <summary>
+        /// 获取对象详细
+        /// </summary>
+        /// <param name="entityType"></param>
+        /// <param name="dtoType"></param>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        Task<object> ReadDetailObjectAsync(Type entityType, Type dtoType, string id);
+
         /// <summary>
         /// 
         /// </summary>
framework/PasteApeart.Application/PasteApeart.Application.xml
diff --git a/framework/PasteApeart.Application/PasteApeart.Application.xml b/framework/PasteApeart.Application/PasteApeart.Application.xml
index 3b58755..c71e24f 100644
--- a/framework/PasteApeart.Application/PasteApeart.Application.xml
+++ b/framework/PasteApeart.Application/PasteApeart.Application.xml
@@ -285,32 +285,41 @@
             <param name="searchName"></param>
             <returns></returns>
         </member>
-        <member name="M:PasteApeart.Application.IPasteDefaultAppService.DirectPageAsync(System.Object,System.Type,System.Type,PasteApeart.Application.Contracts.InputSearchBase,System.Type)">
+        <member name="M:PasteApeart.Application.IPasteDefaultAppService.DirectPageAsync(System.Object,System.Type,System.Type,System.Int32,System.Type)">
             <summary>
             复用 按页查询
             </summary>
             <param name="searchObject"></param>
             <param name="entityType"></param>
             <param name="searchType"></param>
-            <param name="input"></param>
+            <param name="page">当前页码,第1页要读取totalCount</param>
             <param name="listDtoType"></param>
             <returns></returns>
         </member>
         <member name="M:PasteApeart.Application.IPasteDefaultAppService.ReadAddModel(System.String)">
             <summary>
-            
+            获取新增 元数据
             </summary>
             <param name="entityName"></param>
             <returns></returns>
         </member>
         <member name="M:PasteApeart.Application.IPasteDefaultAppService.ReadDetailModel(System.String,System.String)">
             <summary>
-            
+            获取对象详细的元数据
             </summary>
             <param name="entityName"></param>
             <param name="id"></param>
             <returns></returns>
         </member>
+        <member name="M:PasteApeart.Application.IPasteDefaultAppService.ReadDetailObjectAsync(System.Type,System.Type,System.String)">
+            <summary>
+            获取对象详细
+            </summary>
+            <param name="entityType"></param>
+            <param name="dtoType"></param>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
         <member name="M:PasteApeart.Application.IPasteDefaultAppService.ReadListModel(System.String,System.String)">
             <summary>
             
@@ -664,7 +673,13 @@
         </member>
         <member name="M:PasteApeart.Application.PasteDefaultAppService.ReadDetailModel(System.String,System.String)">
             <summary>
-            获取详细
+            获取详细 获取详细对应的元数据
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:PasteApeart.Application.PasteDefaultAppService.ReadDetailObjectAsync(System.Type,System.Type,System.String)">
+            <summary>
+            获取详细 获取数据本身
             </summary>
             <returns></returns>
         </member>
@@ -693,14 +708,14 @@
             <returns></returns>
             <exception cref="T:PasteApeart.Application.Contracts.PasteCodeException"></exception>
         </member>
-        <member name="M:PasteApeart.Application.PasteDefaultAppService.DirectPageAsync(System.Object,System.Type,System.Type,PasteApeart.Application.Contracts.InputSearchBase,System.Type)">
+        <member name="M:PasteApeart.Application.PasteDefaultAppService.DirectPageAsync(System.Object,System.Type,System.Type,System.Int32,System.Type)">
             <summary>
             直接获取页面数据 用于快捷开发
             </summary>
             <param name="searchObject"></param>
             <param name="entityType"></param>
             <param name="searchType"></param>
-            <param name="input"></param>
+            <param name="page">第1页要返回totalCount</param>
             <param name="listDtoType"></param>
             <returns></returns>
         </member>
framework/PasteApeart.Application/PasteDefaultAppService.cs
diff --git a/framework/PasteApeart.Application/PasteDefaultAppService.cs b/framework/PasteApeart.Application/PasteDefaultAppService.cs
index 7e8a03e..9346c73 100644
--- a/framework/PasteApeart.Application/PasteDefaultAppService.cs
+++ b/framework/PasteApeart.Application/PasteDefaultAppService.cs
@@ -128,7 +128,7 @@ namespace PasteApeart.Application
         }
 
         /// <summary>
-        /// 获取详细
+        /// 获取详细 获取详细对应的元数据
         /// </summary>
         /// <returns></returns>
         public async Task<VoloModelInfo> ReadDetailModel(string entityName, string id)
@@ -144,6 +144,53 @@ namespace PasteApeart.Application
                 throw new PasteCodeException($"找不到对应的实体或 DTO 类型: {entityName}");
             }
 
+            var dto = await ReadDetailObjectAsync(entityType,dtoType,id);
+
+            //// 2. 动态查询实体
+            //var entity = await _defaultHelper.FindEntityByIdWithIncludeAsync(_dbContext, entityType, id);
+            //if (entity == null)
+            //{
+            //    throw new PasteCodeException("查询的信息不存在,无法执行编辑操作!");
+            //}
+
+            //await DefaultFilterDataAsync(entityType, entity, "detail");
+            //var dto = Activator.CreateInstance(dtoType);
+            //_defaultHelper.MapProperties(entity, dto, entityType, dtoType);
+
+            ////构建外表等 Include的如何搞定???
+            //await _defaultHelper.BuildOuterQuery(_dbContext, dto, dtoType);
+
+            ////进行脱敏处理
+            //var hasHalfHideAttribute = dtoType.GetCustomAttribute<PasteHalfHideAttribute>();
+            //if (hasHalfHideAttribute != null)
+            //{
+            //    HalfHideHelper.PasteMaskData(dto, dtoType);
+            //}
+
+            // 4. 动态读取 DTO 的属性信息
+            return await DefaultBuildPropertyInfo("detail", dto, dtoType);
+
+        }
+
+
+        /// <summary>
+        /// 获取详细 获取数据本身
+        /// </summary>
+        /// <returns></returns>
+        public async Task<object> ReadDetailObjectAsync(Type entityType,Type dtoType, string id)
+        {
+
+            //entityName = DefaultMapperEntityName(entityName);
+
+            //// 1. 根据实体名称查找对应的实体类型和 DTO 类型
+            //var entityType = _defaultHelper.FindEntityType(entityName);
+            //var dtoType = _defaultHelper.FindDtoType(entityName, "Dto");
+
+            //if (entityType == null || dtoType == null)
+            //{
+            //    throw new PasteCodeException($"找不到对应的实体或 DTO 类型: {entityName}");
+            //}
+
             // 2. 动态查询实体
             var entity = await _defaultHelper.FindEntityByIdWithIncludeAsync(_dbContext, entityType, id);
             if (entity == null)
@@ -157,16 +204,26 @@ namespace PasteApeart.Application
             // 3. 动态映射实体到 DTO
             //var dto = DefaultHelper.MapEntityToDto(ObjectMapper, entity, entityType, dtoType);
 
+
+
             //构建外表等 Include的如何搞定???
             await _defaultHelper.BuildOuterQuery(_dbContext, dto, dtoType);
 
+            //进行脱敏处理
+            var hasHalfHideAttribute = dtoType.GetCustomAttribute<PasteHalfHideAttribute>();
+            if (hasHalfHideAttribute != null)
+            {
+                HalfHideHelper.PasteMaskData(dto, dtoType);
+            }
+
             // 4. 动态读取 DTO 的属性信息
             //var dataModel = DefaultHelper.ReadModelProperties(dto, dtoType);
             //return dataModel;
-            return await DefaultBuildPropertyInfo("detail", dto, dtoType);
-
+            //return await DefaultBuildPropertyInfo("detail", dto, dtoType);
+            return dto;
         }
 
+
         /// <summary>
         /// 获取列表格式
         /// </summary>
@@ -280,7 +337,7 @@ namespace PasteApeart.Application
             var input = _defaultHelper.MapperToQueryModel(queryString, searchType, searchObject);
 
 
-            dynamic pagedto = await DirectPageAsync(searchObject, entityType, searchType, input, listDtoType);
+            dynamic pagedto = await DirectPageAsync(searchObject, entityType, searchType, input.page, listDtoType);
             if (input.page == 1)
             {
                 if (queryString.Contains("request=one"))
@@ -349,15 +406,15 @@ namespace PasteApeart.Application
         /// <param name="searchObject"></param>
         /// <param name="entityType"></param>
         /// <param name="searchType"></param>
-        /// <param name="input"></param>
+        /// <param name="page">第1页要返回totalCount</param>
         /// <param name="listDtoType"></param>
         /// <returns></returns>
-        public async Task<dynamic> DirectPageAsync(object searchObject, Type entityType, Type searchType, InputSearchBase input, Type listDtoType)
+        public async Task<dynamic> DirectPageAsync(object searchObject, Type entityType, Type searchType, int page, Type listDtoType)
         {
 
             dynamic pageDto = new ExpandoObject();
             IQueryable query = _defaultHelper.BuildDynamicQuery(_dbContext, entityType, searchType, searchObject);
-            if (input.page == 1)
+            if (page == 1)
             {
                 pageDto.totalCount = await _defaultHelper.ExecuteCountQuery(query, entityType);
             }
@@ -387,6 +444,14 @@ namespace PasteApeart.Application
             }
             //查询外表 并实现 这里是简单的外表ID的查询 如果有更复杂的,还需要实现
             await _defaultHelper.BuildOuterData(_dbContext, listDtoType, dtos);
+
+            //进行脱敏处理
+            var hasHalfHideAttribute = listDtoType.GetCustomAttribute<PasteHalfHideAttribute>();
+            if (hasHalfHideAttribute != null)
+            {
+                HalfHideHelper.PasteMaskData(dtos, listDtoType);
+            }
+
             // 7. 设置结果并返回
             //pagedDto.Items = dtos.Cast<object>().ToList();
             pageDto.items = dtos;
framework/PasteApeart.Handler/common/EventActionHandler.cs
diff --git a/framework/PasteApeart.Handler/common/EventActionHandler.cs b/framework/PasteApeart.Handler/common/EventActionHandler.cs
index 10a9a39..e43a8aa 100644
--- a/framework/PasteApeart.Handler/common/EventActionHandler.cs
+++ b/framework/PasteApeart.Handler/common/EventActionHandler.cs
@@ -8,11 +8,14 @@ using System.Text.Json;
 
 namespace PasteApeart.Handler
 {
+
+
     /// <summary>
     /// 队列处理 可以被RabbitMQ或者Channel的消费者调用
     /// </summary>
     public class EventActionHandler : IEventActionHandler
     {
+        private const string DefaultHandleMethodName = "HandleEventAsync";
 
         private readonly ILogger<EventActionHandler> _logger;
         private readonly IServiceProvider _serviceProvider;
@@ -20,7 +23,18 @@ namespace PasteApeart.Handler
         private readonly Type[] _dtoTypeArray = null;
 
         /// <summary>
-        /// 队列处理 可以被RabbitMQ或者Channel的消费者调用
+        /// 事件名 -> 事件类型。找不到时不写缓存。
+        /// 全系统 types 是同一份,所以 key 只放 eventName。
+        /// </summary>
+        private readonly ConcurrentDictionary<string, Type> _eventTypeCache = new();
+
+        /// <summary>
+        /// (事件类型, 处理方法名) -> (处理器接口类型, 处理方法)。
+        /// methodName 有不同入口,必须进 key。
+        /// </summary>
+        private readonly ConcurrentDictionary<(Type EventType, string MethodName), (Type HandlerType, MethodInfo HandleMethod)> _handlerCache = new();
+        /// <summary>
+        /// 
         /// </summary>
         /// <param name="logger"></param>
         /// <param name="serviceProvider"></param>
@@ -37,13 +51,9 @@ namespace PasteApeart.Handler
             }
         }
 
-
-        private readonly ConcurrentDictionary<string, Type> _eventTypeCache = new();
-
-        private readonly ConcurrentDictionary<Type, (Type HandlerType, MethodInfo HandleMethod)> _handlerCache = new();
-
+        #region 字符串入口
         /// <summary>
-        /// 主要适用于分布式队列 比如RabitMQ等
+        /// 
         /// </summary>
         /// <param name="msg"></param>
         /// <returns></returns>
@@ -62,7 +72,6 @@ namespace PasteApeart.Handler
 
             await ActionReturnResultAsync(msg, _dtoTypeArray);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -77,14 +86,13 @@ namespace PasteApeart.Handler
             }
             await ActionReturnResultAsync(msg, types);
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="msg"></param>
         /// <param name="methodName"></param>
         /// <returns></returns>
-        public async Task<object> ActionResultAsync(string msg, string methodName = "HandleEventAsync")
+        public async Task<object> ActionResultAsync(string msg, string methodName = DefaultHandleMethodName)
         {
             if (string.IsNullOrWhiteSpace(msg))
             {
@@ -100,7 +108,6 @@ namespace PasteApeart.Handler
 
             return await ActionReturnResultAsync(msg, _dtoTypeArray, methodName);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -108,7 +115,7 @@ namespace PasteApeart.Handler
         /// <param name="types"></param>
         /// <param name="methodName"></param>
         /// <returns></returns>
-        public async Task<object> ActionResultAsync(string msg, Type[] types, string methodName = "HandleEventAsync")
+        public async Task<object> ActionResultAsync(string msg, Type[] types, string methodName = DefaultHandleMethodName)
         {
             if (string.IsNullOrWhiteSpace(msg))
             {
@@ -116,121 +123,6 @@ namespace PasteApeart.Handler
             }
             return await ActionReturnResultAsync(msg, types, methodName);
         }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="msg"></param>
-        /// <param name="types"></param>
-        /// <returns></returns>
-        private async Task ActionAsync(string msg, Type[] types)
-        {
-            object input = null;
-            object handler = null;
-            try
-            {
-                // 1. 只反序列化一次,使用 System.Text.Json 性能更好
-                using var jsonDoc = JsonDocument.Parse(msg);
-                var root = jsonDoc.RootElement;
-                JsonElement eventNameProperty;
-                // 使用不区分大小写的匹配,更健壮
-                if (!root.TryGetProperty("eventName", out eventNameProperty))
-                {
-                    root.TryGetProperty("EventName", out eventNameProperty);
-                }
-                // 获取字符串值并验证
-                string eventName = eventNameProperty.GetString();
-                if (string.IsNullOrEmpty(eventName))
-                {
-                    _logger.LogError($"EventName 字段值为空: {msg}");
-                    return;
-                }
-                // 2. 获取事件类型(带缓存)
-                var modelType = _eventTypeCache.GetOrAdd(eventName, name =>
-                {
-                    return types.FirstOrDefault(x => x.Name == name);
-                });
-                if (modelType == null)
-                {
-                    _logger.LogError($"未找到事件类型: {eventName}");
-                    return;
-                }
-                // 3. 反序列化为具体类型
-                input = JsonSerializer.Deserialize(msg, modelType, JsonConfig.Options);
-                if (input == null)
-                {
-                    _logger.LogError($"无法将消息反序列化为类型 {eventName}: {msg}");
-                    return;
-                }
-                using var scope = _serviceProvider.CreateScope();
-                if (input is IEventModel tryModel)
-                {
-                    if (tryModel.ExpireSecond > 0)
-                    {
-                        await _channelHelper.WriteAutoQueueAsync(tryModel);
-                        return;
-                    }
-                }
-                // 4. 获取处理器信息(带缓存)
-                var (handlerType, handleMethod) = _handlerCache.GetOrAdd(modelType, type =>
-                {
-                    var hType = typeof(IEventHandler<>).MakeGenericType(type);
-                    var method = hType.GetMethod("HandleEventAsync");
-                    return (hType, method);
-                });
-                if (handleMethod == null)
-                {
-                    _logger.LogError($"处理器 {handlerType.Name} 没有 HandleEventAsync 方法");
-                    return;
-                }
-                handler = scope.ServiceProvider.GetRequiredService(handlerType);
-                if (handler == null)
-                {
-                    _logger.LogError($"没有找到 {eventName} 的 IEventHandler 实现");
-                    return;
-                }
-                try
-                {
-                    // 5. 执行处理
-                    var task = handleMethod.Invoke(handler, new[] { input }) as Task;
-                    if (task != null)
-                    {
-                        await task;
-                    }
-                    else
-                    {
-                        _logger.LogError($"无法调用 {eventName} 的处理方法");
-                    }
-                }
-                catch (Exception handlerExl)
-                {
-                    _logger.LogException(handlerExl);
-                }
-                finally
-                {
-                    try
-                    {
-                        if (handler is IDisposable disposable)
-                        {
-                            disposable.Dispose();
-                        }
-                        if (handler is IAsyncDisposable disposable1)
-                        {
-                            await disposable1.DisposeAsync();
-                        }
-                    }
-                    catch (Exception exlDisposable)
-                    {
-                        _logger.LogException(exlDisposable);
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                _logger.LogException(ex);
-            }
-        }
-
         /// <summary>
         /// 
         /// </summary>
@@ -238,84 +130,69 @@ namespace PasteApeart.Handler
         /// <param name="types"></param>
         /// <param name="methodName"></param>
         /// <returns></returns>
-        private async Task<object> ActionReturnResultAsync(string msg, Type[] types, string methodName = "HandleEventAsync")
+        public virtual async Task<object> ActionReturnResultAsync(string msg, Type[] types, string methodName = DefaultHandleMethodName)
         {
-            object input = null;
             object handler = null;
             try
             {
-                // 1. 只反序列化一次,使用 System.Text.Json 性能更好
                 using var jsonDoc = JsonDocument.Parse(msg);
                 var root = jsonDoc.RootElement;
+
                 JsonElement eventNameProperty;
-                // 使用不区分大小写的匹配,更健壮
                 if (!root.TryGetProperty("eventName", out eventNameProperty))
                 {
                     root.TryGetProperty("EventName", out eventNameProperty);
                 }
-                // 获取字符串值并验证
+
                 string eventName = eventNameProperty.GetString();
                 if (string.IsNullOrEmpty(eventName))
                 {
                     _logger.LogError($"EventName 字段值为空: {msg}");
                     return null;
                 }
-                // 2. 获取事件类型(带缓存)
-                var modelType = _eventTypeCache.GetOrAdd(eventName, name =>
-                {
-                    return types.FirstOrDefault(x => x.Name == name);
-                });
+
+                var modelType = ResolveEventType(eventName, types);
                 if (modelType == null)
                 {
                     _logger.LogError($"未找到事件类型: {eventName}");
                     return null;
                 }
-                // 3. 反序列化为具体类型
-                input = JsonSerializer.Deserialize(msg, modelType, JsonConfig.Options);
+
+                var input = JsonSerializer.Deserialize(msg, modelType, JsonConfig.Options);
                 if (input == null)
                 {
                     _logger.LogError($"无法将消息反序列化为类型 {eventName}: {msg}");
                     return null;
                 }
+
                 using var scope = _serviceProvider.CreateScope();
-                if (input is IEventModel tryModel)
+
+                if (input is IEventModel tryModel && tryModel.ExpireSecond > 0)
                 {
-                    if (tryModel.ExpireSecond > 0)
-                    {
-                        await _channelHelper.WriteAutoQueueAsync(tryModel);
-                        return null;
-                    }
+                    await _channelHelper.WriteAutoQueueAsync(tryModel);
+                    return null;
                 }
-                // 4. 获取处理器信息(带缓存)
-                var (handlerType, handleMethod) = _handlerCache.GetOrAdd(modelType, type =>
-                {
-                    var hType = typeof(IEventHandler<>).MakeGenericType(type);
-                    var method = hType.GetMethod(methodName);
-                    return (hType, method);
-                });
+
+                var (handlerType, handleMethod) = ResolveHandlerInfo(modelType, methodName);
                 if (handleMethod == null)
                 {
                     _logger.LogError($"处理器 {handlerType.Name} 没有 {methodName} 方法");
                     return null;
                 }
+
                 handler = scope.ServiceProvider.GetRequiredService(handlerType);
                 if (handler == null)
                 {
                     _logger.LogError($"没有找到 {eventName} 的 IEventHandler 实现");
                     return null;
                 }
+
                 try
                 {
-                    // 5. 执行处理
                     var task = handleMethod.Invoke(handler, new[] { input }) as Task;
                     if (task != null)
                     {
                         await task;
-                        //// 从 handler 接口上读 Result 属性(而不是从 Task<T> 里读)
-                        //var resultProp = handlerType.GetProperty("Result");
-                        //return resultProp?.GetValue(handler);
-
-                        // 用具体类型读,而不是接口类型
                         var resultProp = handler.GetType().GetProperty("Result");
                         return resultProp?.GetValue(handler);
                     }
@@ -327,29 +204,10 @@ namespace PasteApeart.Handler
                 catch (Exception handlerExl)
                 {
                     _logger.LogException(handlerExl);
-                    //TODO 是否自动尝试... .. .
-                    if (input is IEventModel inputModel)
-                    {
-                        //if(inputModel.tr)
-                    }
                 }
                 finally
                 {
-                    try
-                    {
-                        if (handler is IDisposable disposable)
-                        {
-                            disposable.Dispose();
-                        }
-                        if (handler is IAsyncDisposable disposable1)
-                        {
-                            await disposable1.DisposeAsync();
-                        }
-                    }
-                    catch (Exception exlDisposable)
-                    {
-                        _logger.LogException(exlDisposable);
-                    }
+                    await DisposeHandlerAsync(handler);
                 }
             }
             catch (Exception ex)
@@ -359,10 +217,9 @@ namespace PasteApeart.Handler
             return null;
         }
 
+        #endregion
 
-        private readonly ConcurrentDictionary<Type, Type> _eventHandlerCache = new();
-        private readonly ConcurrentDictionary<Type, MethodInfo> _handleMethodCache = new();
-
+        #region 对象入口(本地 Channel 模式)
         /// <summary>
         /// 
         /// </summary>
@@ -373,7 +230,6 @@ namespace PasteApeart.Handler
         {
             await ActionMessageAsync(read);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -384,44 +240,48 @@ namespace PasteApeart.Handler
         {
             await ActionMessageAsync(read);
         }
-
         /// <summary>
-        /// 主要适用于本地Chennel模式
+        /// 
         /// </summary>
         /// <param name="read"></param>
         /// <returns></returns>
-        public async Task ActionMessageAsync(IEventModel read)
+        public virtual async Task ActionMessageAsync(IEventModel read)
         {
-            _logger.LogInformation($"Event Msg:{read.EventName}");
-            //read是一个IEventModel
-            var typeName = read.GetType().Name;
-            var eventType = read.GetType();
-            using var _scope = _serviceProvider.CreateScope();
-            var handlerType = _eventHandlerCache.GetOrAdd(eventType, t => typeof(IEventHandler<>).MakeGenericType(t));
-            var handler = _scope.ServiceProvider.GetService(handlerType);
-            // 通过依赖注入获取处理器实例
-            if (handler == null)
+            if (read == null)
             {
-                _logger.LogError($"没有找到 {typeName} 的 IEventHandler 实现!");
-                return;
-            }
-            // 获取处理方法(带缓存)
-            //var handleMethod = _handleMethodCache.GetOrAdd(eventType, t =>
-            //    handlerType.GetMethod("HandleEventAsync"));
-            var handleMethod = _handleMethodCache.GetOrAdd(handlerType, t => t.GetMethod("HandleEventAsync"));
-            if (handleMethod == null)
-            {
-                _logger.LogError($"无法找到 {typeName} 的 HandleEventAsync 方法");
+                _logger.LogError("read 不能为空");
                 return;
             }
+
+            _logger.LogInformation($"Event Msg:{read.EventName}");
+
+            var eventType = read.GetType();
+            var typeName = eventType.Name;
+
+            object handler = null;
             try
             {
+                using var scope = _serviceProvider.CreateScope();
+
+                var (handlerType, handleMethod) = ResolveHandlerInfo(eventType, DefaultHandleMethodName);
+                if (handleMethod == null)
+                {
+                    _logger.LogError($"无法找到 {typeName} 的 {DefaultHandleMethodName} 方法");
+                    return;
+                }
+
+                handler = scope.ServiceProvider.GetService(handlerType);
+                if (handler == null)
+                {
+                    _logger.LogError($"没有找到 {typeName} 的 IEventHandler 实现!");
+                    return;
+                }
+
                 var task = handleMethod.Invoke(handler, new[] { read }) as Task;
                 if (task != null)
                 {
                     await task;
                 }
-                //_logger.LogInformation($"执行了 {typeName} 的 HandleEventAsync 函数");
             }
             catch (Exception ex)
             {
@@ -429,23 +289,532 @@ namespace PasteApeart.Handler
             }
             finally
             {
-                try
+                await DisposeHandlerAsync(handler);
+            }
+        }
+
+        #endregion
+
+        #region 缓存解析 & 公共方法
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="eventName"></param>
+        /// <param name="types"></param>
+        /// <returns></returns>
+        private Type ResolveEventType(string eventName, Type[] types)
+        {
+            if (types == null || types.Length == 0)
+            {
+                return null;
+            }
+
+            if (_eventTypeCache.TryGetValue(eventName, out var cached))
+            {
+                return cached;
+            }
+
+            var modelType = types.FirstOrDefault(x => x.Name == eventName);
+            if (modelType != null)
+            {
+                _eventTypeCache.TryAdd(eventName, modelType);
+            }
+            return modelType;
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="eventType"></param>
+        /// <param name="methodName"></param>
+        /// <returns></returns>
+        private (Type HandlerType, MethodInfo HandleMethod) ResolveHandlerInfo(Type eventType, string methodName)
+        {
+            if (string.IsNullOrEmpty(methodName))
+            {
+                methodName = DefaultHandleMethodName;
+            }
+
+            return _handlerCache.GetOrAdd((eventType, methodName), key =>
+            {
+                var handlerType = typeof(IEventHandler<>).MakeGenericType(key.EventType);
+                var handleMethod = handlerType.GetMethod(key.MethodName);
+                return (handlerType, handleMethod);
+            });
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="handler"></param>
+        /// <returns></returns>
+        private async Task DisposeHandlerAsync(object handler)
+        {
+            if (handler == null)
+            {
+                return;
+            }
+
+            try
+            {
+                if (handler is IAsyncDisposable asyncDisposable)
                 {
-                    if (handler is IDisposable disposable)
-                    {
-                        disposable.Dispose();
-                    }
-                    if (handler is IAsyncDisposable disposable1)
-                    {
-                        await disposable1.DisposeAsync();
-                    }
+                    await asyncDisposable.DisposeAsync();
                 }
-                catch (Exception exl)
+                else if (handler is IDisposable disposable)
                 {
-                    _logger.LogException(exl);
+                    disposable.Dispose();
                 }
             }
+            catch (Exception ex)
+            {
+                _logger.LogException(ex);
+            }
         }
 
+        #endregion
     }
+
+    #region 以下是历史代码
+
+    ///// <summary>
+    ///// 队列处理 可以被RabbitMQ或者Channel的消费者调用
+    ///// </summary>
+    //public class EventActionHandler : IEventActionHandler
+    //{
+
+    //    private readonly ILogger<EventActionHandler> _logger;
+    //    private readonly IServiceProvider _serviceProvider;
+    //    private readonly IChannelHelper _channelHelper;
+    //    private readonly Type[] _dtoTypeArray = null;
+
+    //    /// <summary>
+    //    /// 队列处理 可以被RabbitMQ或者Channel的消费者调用
+    //    /// </summary>
+    //    /// <param name="logger"></param>
+    //    /// <param name="serviceProvider"></param>
+    //    /// <param name="channelHelper"></param>
+    //    /// <param name="dtoTypes"></param>
+    //    public EventActionHandler(ILogger<EventActionHandler> logger, IServiceProvider serviceProvider, IChannelHelper channelHelper, Type[] dtoTypes = null)
+    //    {
+    //        _logger = logger;
+    //        _serviceProvider = serviceProvider;
+    //        _channelHelper = channelHelper;
+    //        if (dtoTypes != null)
+    //        {
+    //            _dtoTypeArray = dtoTypes;
+    //        }
+    //    }
+
+
+    //    private readonly ConcurrentDictionary<string, Type> _eventTypeCache = new();
+
+    //    private readonly ConcurrentDictionary<Type, (Type HandlerType, MethodInfo HandleMethod)> _handlerCache = new();
+
+    //    /// <summary>
+    //    /// 主要适用于分布式队列 比如RabitMQ等
+    //    /// </summary>
+    //    /// <param name="msg"></param>
+    //    /// <returns></returns>
+    //    public async Task ActionMessageAsync(string msg)
+    //    {
+    //        if (string.IsNullOrWhiteSpace(msg))
+    //        {
+    //            return;
+    //        }
+
+    //        if (_dtoTypeArray?.Any() != true)
+    //        {
+    //            _logger.LogError("ActionMessageAsync 的string模式下,构造函数的dtoTypes是必传的,表示EventModel所在程序集的类型集合");
+    //            return;
+    //        }
+
+    //        await ActionReturnResultAsync(msg, _dtoTypeArray);
+    //    }
+
+    //    /// <summary>
+    //    /// 
+    //    /// </summary>
+    //    /// <param name="msg"></param>
+    //    /// <param name="types"></param>
+    //    /// <returns></returns>
+    //    public async Task ActionMessageAsync(string msg, Type[] types)
+    //    {
+    //        if (string.IsNullOrWhiteSpace(msg))
+    //        {
+    //            return;
+    //        }
+    //        await ActionReturnResultAsync(msg, types);
+    //    }
+
+    //    /// <summary>
+    //    /// 
+    //    /// </summary>
+    //    /// <param name="msg"></param>
+    //    /// <param name="methodName"></param>
+    //    /// <returns></returns>
+    //    public async Task<object> ActionResultAsync(string msg, string methodName = "HandleEventAsync")
+    //    {
+    //        if (string.IsNullOrWhiteSpace(msg))
+    //        {
+    //            _logger.LogError("传入的数据不能为空");
+    //            return null;
+    //        }
+
+    //        if (_dtoTypeArray?.Any() != true)
+    //        {
+    //            _logger.LogError("ActionMessageAsync 的string模式下,构造函数的dtoTypes是必传的,表示EventModel所在程序集的类型集合");
+    //            return null;
+    //        }
+
+    //        return await ActionReturnResultAsync(msg, _dtoTypeArray, methodName);
+    //    }
+
+    //    /// <summary>
+    //    /// 
+    //    /// </summary>
+    //    /// <param name="msg"></param>
+    //    /// <param name="types"></param>
+    //    /// <param name="methodName"></param>
+    //    /// <returns></returns>
+    //    public async Task<object> ActionResultAsync(string msg, Type[] types, string methodName = "HandleEventAsync")
+    //    {
+    //        if (string.IsNullOrWhiteSpace(msg))
+    //        {
+    //            return null;
+    //        }
+    //        return await ActionReturnResultAsync(msg, types, methodName);
+    //    }
+
+    //    /// <summary>
+    //    /// 
+    //    /// </summary>
+    //    /// <param name="msg"></param>
+    //    /// <param name="types"></param>
+    //    /// <returns></returns>
+    //    private async Task ActionAsync(string msg, Type[] types)
+    //    {
+    //        object input = null;
+    //        object handler = null;
+    //        try
+    //        {
+    //            // 1. 只反序列化一次,使用 System.Text.Json 性能更好
+    //            using var jsonDoc = JsonDocument.Parse(msg);
+    //            var root = jsonDoc.RootElement;
+    //            JsonElement eventNameProperty;
+    //            // 使用不区分大小写的匹配,更健壮
+    //            if (!root.TryGetProperty("eventName", out eventNameProperty))
+    //            {
+    //                root.TryGetProperty("EventName", out eventNameProperty);
+    //            }
+    //            // 获取字符串值并验证
+    //            string eventName = eventNameProperty.GetString();
+    //            if (string.IsNullOrEmpty(eventName))
+    //            {
+    //                _logger.LogError($"EventName 字段值为空: {msg}");
+    //                return;
+    //            }
+    //            // 2. 获取事件类型(带缓存)
+    //            var modelType = _eventTypeCache.GetOrAdd(eventName, name =>
+    //            {
+    //                return types.FirstOrDefault(x => x.Name == name);
+    //            });
+    //            if (modelType == null)
+    //            {
+    //                _logger.LogError($"未找到事件类型: {eventName}");
+    //                return;
+    //            }
+    //            // 3. 反序列化为具体类型
+    //            input = JsonSerializer.Deserialize(msg, modelType, JsonConfig.Options);
+    //            if (input == null)
+    //            {
+    //                _logger.LogError($"无法将消息反序列化为类型 {eventName}: {msg}");
+    //                return;
+    //            }
+    //            using var scope = _serviceProvider.CreateScope();
+    //            if (input is IEventModel tryModel)
+    //            {
+    //                if (tryModel.ExpireSecond > 0)
+    //                {
+    //                    await _channelHelper.WriteAutoQueueAsync(tryModel);
+    //                    return;
+    //                }
+    //            }
+    //            // 4. 获取处理器信息(带缓存)
+    //            var (handlerType, handleMethod) = _handlerCache.GetOrAdd(modelType, type =>
+    //            {
+    //                var hType = typeof(IEventHandler<>).MakeGenericType(type);
+    //                var method = hType.GetMethod("HandleEventAsync");
+    //                return (hType, method);
+    //            });
+    //            if (handleMethod == null)
+    //            {
+    //                _logger.LogError($"处理器 {handlerType.Name} 没有 HandleEventAsync 方法");
+    //                return;
+    //            }
+    //            handler = scope.ServiceProvider.GetRequiredService(handlerType);
+    //            if (handler == null)
+    //            {
+    //                _logger.LogError($"没有找到 {eventName} 的 IEventHandler 实现");
+    //                return;
+    //            }
+    //            try
+    //            {
+    //                // 5. 执行处理
+    //                var task = handleMethod.Invoke(handler, new[] { input }) as Task;
+    //                if (task != null)
+    //                {
+    //                    await task;
+    //                }
+    //                else
+    //                {
+    //                    _logger.LogError($"无法调用 {eventName} 的处理方法");
+    //                }
+    //            }
+    //            catch (Exception handlerExl)
+    //            {
+    //                _logger.LogException(handlerExl);
+    //            }
+    //            finally
+    //            {
+    //                try
+    //                {
+    //                    if (handler is IDisposable disposable)
+    //                    {
+    //                        disposable.Dispose();
+    //                    }
+    //                    if (handler is IAsyncDisposable disposable1)
+    //                    {
+    //                        await disposable1.DisposeAsync();
+    //                    }
+    //                }
+    //                catch (Exception exlDisposable)
+    //                {
+    //                    _logger.LogException(exlDisposable);
+    //                }
+    //            }
+    //        }
+    //        catch (Exception ex)
+    //        {
+    //            _logger.LogException(ex);
+    //        }
+    //    }
+
+    //    /// <summary>
+    //    /// 
+    //    /// </summary>
+    //    /// <param name="msg"></param>
+    //    /// <param name="types"></param>
+    //    /// <param name="methodName"></param>
+    //    /// <returns></returns>
+    //    public virtual async Task<object> ActionReturnResultAsync(string msg, Type[] types, string methodName = "HandleEventAsync")
+    //    {
+    //        object input = null;
+    //        object handler = null;
+    //        try
+    //        {
+    //            // 1. 只反序列化一次,使用 System.Text.Json 性能更好
+    //            using var jsonDoc = JsonDocument.Parse(msg);
+    //            var root = jsonDoc.RootElement;
+    //            JsonElement eventNameProperty;
+    //            // 使用不区分大小写的匹配,更健壮
+    //            if (!root.TryGetProperty("eventName", out eventNameProperty))
+    //            {
+    //                root.TryGetProperty("EventName", out eventNameProperty);
+    //            }
+    //            // 获取字符串值并验证
+    //            string eventName = eventNameProperty.GetString();
+    //            if (string.IsNullOrEmpty(eventName))
+    //            {
+    //                _logger.LogError($"EventName 字段值为空: {msg}");
+    //                return null;
+    //            }
+    //            // 2. 获取事件类型(带缓存)
+    //            var modelType = _eventTypeCache.GetOrAdd(eventName, name =>
+    //            {
+    //                return types.FirstOrDefault(x => x.Name == name);
+    //            });
+    //            if (modelType == null)
+    //            {
+    //                _logger.LogError($"未找到事件类型: {eventName}");
+    //                return null;
+    //            }
+    //            // 3. 反序列化为具体类型
+    //            input = JsonSerializer.Deserialize(msg, modelType, JsonConfig.Options);
+    //            if (input == null)
+    //            {
+    //                _logger.LogError($"无法将消息反序列化为类型 {eventName}: {msg}");
+    //                return null;
+    //            }
+    //            using var scope = _serviceProvider.CreateScope();
+    //            if (input is IEventModel tryModel)
+    //            {
+    //                if (tryModel.ExpireSecond > 0)
+    //                {
+    //                    await _channelHelper.WriteAutoQueueAsync(tryModel);
+    //                    return null;
+    //                }
+    //            }
+    //            // 4. 获取处理器信息(带缓存)
+    //            var (handlerType, handleMethod) = _handlerCache.GetOrAdd(modelType, type =>
+    //            {
+    //                var hType = typeof(IEventHandler<>).MakeGenericType(type);
+    //                var method = hType.GetMethod(methodName);
+    //                return (hType, method);
+    //            });
+    //            if (handleMethod == null)
+    //            {
+    //                _logger.LogError($"处理器 {handlerType.Name} 没有 {methodName} 方法");
+    //                return null;
+    //            }
+    //            handler = scope.ServiceProvider.GetRequiredService(handlerType);
+    //            if (handler == null)
+    //            {
+    //                _logger.LogError($"没有找到 {eventName} 的 IEventHandler 实现");
+    //                return null;
+    //            }
+    //            try
+    //            {
+    //                // 5. 执行处理
+    //                var task = handleMethod.Invoke(handler, new[] { input }) as Task;
+    //                if (task != null)
+    //                {
+    //                    await task;
+    //                    //// 从 handler 接口上读 Result 属性(而不是从 Task<T> 里读)
+    //                    //var resultProp = handlerType.GetProperty("Result");
+    //                    //return resultProp?.GetValue(handler);
+
+    //                    // 用具体类型读,而不是接口类型
+    //                    var resultProp = handler.GetType().GetProperty("Result");
+    //                    return resultProp?.GetValue(handler);
+    //                }
+    //                else
+    //                {
+    //                    _logger.LogError($"无法调用 {eventName} 的处理方法");
+    //                }
+    //            }
+    //            catch (Exception handlerExl)
+    //            {
+    //                _logger.LogException(handlerExl);
+    //                //TODO 是否自动尝试... .. .
+    //                if (input is IEventModel inputModel)
+    //                {
+    //                    //if(inputModel.tr)
+    //                }
+    //            }
+    //            finally
+    //            {
+    //                try
+    //                {
+    //                    if (handler is IDisposable disposable)
+    //                    {
+    //                        disposable.Dispose();
+    //                    }
+    //                    if (handler is IAsyncDisposable disposable1)
+    //                    {
+    //                        await disposable1.DisposeAsync();
+    //                    }
+    //                }
+    //                catch (Exception exlDisposable)
+    //                {
+    //                    _logger.LogException(exlDisposable);
+    //                }
+    //            }
+    //        }
+    //        catch (Exception ex)
+    //        {
+    //            _logger.LogException(ex);
+    //        }
+    //        return null;
+    //    }
+
+
+    //    private readonly ConcurrentDictionary<Type, Type> _eventHandlerCache = new();
+    //    private readonly ConcurrentDictionary<Type, MethodInfo> _handleMethodCache = new();
+
+    //    /// <summary>
+    //    /// 
+    //    /// </summary>
+    //    /// <param name="read"></param>
+    //    /// <returns></returns>
+    //    [Obsolete("Use ActionMessageAsync")]
+    //    public async Task HanlderEventMessage(IEventModel read)
+    //    {
+    //        await ActionMessageAsync(read);
+    //    }
+
+    //    /// <summary>
+    //    /// 
+    //    /// </summary>
+    //    /// <param name="read"></param>
+    //    /// <returns></returns>
+    //    [Obsolete("Use ActionMessageAsync")]
+    //    public async Task HanlderEventMessage(string read)
+    //    {
+    //        await ActionMessageAsync(read);
+    //    }
+
+    //    /// <summary>
+    //    /// 主要适用于本地Chennel模式
+    //    /// </summary>
+    //    /// <param name="read"></param>
+    //    /// <returns></returns>
+    //    public virtual async Task ActionMessageAsync(IEventModel read)
+    //    {
+    //        _logger.LogInformation($"Event Msg:{read.EventName}");
+    //        //read是一个IEventModel
+    //        var typeName = read.GetType().Name;
+    //        var eventType = read.GetType();
+    //        using var _scope = _serviceProvider.CreateScope();
+    //        var handlerType = _eventHandlerCache.GetOrAdd(eventType, t => typeof(IEventHandler<>).MakeGenericType(t));
+    //        var handler = _scope.ServiceProvider.GetService(handlerType);
+    //        // 通过依赖注入获取处理器实例
+    //        if (handler == null)
+    //        {
+    //            _logger.LogError($"没有找到 {typeName} 的 IEventHandler 实现!");
+    //            return;
+    //        }
+    //        // 获取处理方法(带缓存)
+    //        //var handleMethod = _handleMethodCache.GetOrAdd(eventType, t =>
+    //        //    handlerType.GetMethod("HandleEventAsync"));
+    //        var handleMethod = _handleMethodCache.GetOrAdd(handlerType, t => t.GetMethod("HandleEventAsync"));
+    //        if (handleMethod == null)
+    //        {
+    //            _logger.LogError($"无法找到 {typeName} 的 HandleEventAsync 方法");
+    //            return;
+    //        }
+    //        try
+    //        {
+    //            var task = handleMethod.Invoke(handler, new[] { read }) as Task;
+    //            if (task != null)
+    //            {
+    //                await task;
+    //            }
+    //            //_logger.LogInformation($"执行了 {typeName} 的 HandleEventAsync 函数");
+    //        }
+    //        catch (Exception ex)
+    //        {
+    //            _logger.LogError(ex, $"处理事件 {eventType.Name} 时发生错误");
+    //        }
+    //        finally
+    //        {
+    //            try
+    //            {
+    //                if (handler is IDisposable disposable)
+    //                {
+    //                    disposable.Dispose();
+    //                }
+    //                if (handler is IAsyncDisposable disposable1)
+    //                {
+    //                    await disposable1.DisposeAsync();
+    //                }
+    //            }
+    //            catch (Exception exl)
+    //            {
+    //                _logger.LogException(exl);
+    //            }
+    //        }
+    //    }
+
+    //}
+
+    #endregion
 }
framework/PasteApeart.Helper/BuilderHelper.cs
diff --git a/framework/PasteApeart.Helper/BuilderHelper.cs b/framework/PasteApeart.Helper/BuilderHelper.cs
index 4130690..6f71ef2 100644
--- a/framework/PasteApeart.Helper/BuilderHelper.cs
+++ b/framework/PasteApeart.Helper/BuilderHelper.cs
@@ -2517,179 +2517,17 @@ namespace PasteApeart.Helper
 
         }
 
-
-        #region 脱敏处理
-
-        /// <summary>
-        /// 对数据进行脱敏处理
-        /// </summary>
-        /// <param name="data">要处理的数据(可以是object或List)</param>
-        /// <param name="targetType">目标类型</param>
-        /// <returns>脱敏后的数据</returns>
-        public static object PasteMaskData(object data, Type targetType)
-        {
-            if (data == null || targetType == null)
-            {
-                return data;
-            }
-            // 检查类型是否有 [PasteHalfHide] 特性
-            var classAttribute = targetType.GetCustomAttribute<PasteHalfHideAttribute>();
-
-            // 如果类型没有脱敏特性,直接返回原数据
-            if (classAttribute == null)
-            {
-                return data;
-            }
-            var properties = ReadTypeProperties(targetType);// targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
-            if (classAttribute.CreateNewObj)
-            {
-                if (data is IEnumerable list)
-                {
-                    //var listType = list.GetType().GetGenericArguments()[0];
-                    var resultList = new List<object>();
-                    foreach (var item in list)
-                    {
-                        if (item.GetType() != targetType)
-                        {
-                            resultList.Add(item);
-                            continue;
-                        }
-                        var maskedItem = MaskNewSingleObject(item, targetType, properties);
-                        resultList.Add(maskedItem);
-                    }
-                    return resultList;
-                }
-            }
-            else
-            {
-                if (data is IEnumerable list)
-                {
-                    foreach (var item in list)
-                    {
-                        MaskSingleObject(item, targetType, properties);
-                    }
-                }
-            }
-
-            if (classAttribute.CreateNewObj)
-            {
-                // 处理单个对象
-                return MaskNewSingleObject(data, targetType, properties);
-            }
-            else
-            {
-                MaskSingleObject(data, targetType, properties);
-                return data;
-            }
-        }
-
         /// <summary>
-        /// 原对象上处理
+        /// 脱敏数据 基于特性PasteHalfHide
         /// </summary>
-        /// <param name="obj"></param>
-        /// <param name="type"></param>
-        /// <param name="properties"></param>
+        /// <param name="data"></param>
+        /// <param name="targetType"></param>
         /// <returns></returns>
-        private static void MaskSingleObject(object obj, Type type, PropertyInfo[] properties)
-        {
-            if (obj == null)
-                return;
-
-            foreach (var property in properties)
-            {
-                var attr = property.GetCustomAttribute<PasteHalfHideAttribute>();
-                if (attr == null)
-                    continue;
-
-                var originalValue = property.GetValue(obj)?.ToString();
-                if (string.IsNullOrEmpty(originalValue))
-                    continue;
-
-                var maskedValue = Desensitize(originalValue, attr);
-                property.SetValue(obj, maskedValue);  // 直接修改原对象
-            }
-
-            //return obj;
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="obj"></param>
-        /// <param name="type"></param>
-        /// <param name="properties"></param>
-        /// <returns></returns>
-        private static object MaskNewSingleObject(object obj, Type type, PropertyInfo[] properties)
-        {
-            if (obj == null)
-                return null;
-
-            // 创建对象副本
-            var result = Activator.CreateInstance(type);
-            //var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
-
-            foreach (var property in properties)
-            {
-                // 检查属性是否有 [PasteHalfHide] 特性
-                var attr = property.GetCustomAttribute<PasteHalfHideAttribute>();
-
-                if (attr == null)
-                {
-                    // 没有特性,直接复制值
-                    var value = property.GetValue(obj);
-                    property.SetValue(result, value);
-                    continue;
-                }
-
-                // 获取属性值
-                var originalValue = property.GetValue(obj)?.ToString();
-                if (string.IsNullOrEmpty(originalValue))
-                {
-                    property.SetValue(result, originalValue);
-                    continue;
-                }
-
-                // 进行脱敏处理
-                var maskedValue = Desensitize(originalValue, attr);
-                property.SetValue(result, maskedValue);
-            }
-
-            return result;
-        }
-
-        /// <summary>
-        /// 执行脱敏
-        /// </summary>
-        private static string Desensitize(string value, PasteHalfHideAttribute attr)
-        {
-            if (string.IsNullOrEmpty(value))
-            {
-                return value;
-            }
-
-            return DesensitizeCustom(value, attr.StartLength, attr.EndLength, attr.MaskChar);
-        }
-
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="value"></param>
-        /// <param name="startLength"></param>
-        /// <param name="endLength"></param>
-        /// <param name="maskChar"></param>
-        /// <returns></returns>
-        private static string DesensitizeCustom(string value, int startLength, int endLength, char maskChar)
+        [Obsolete("Use HalfHideHelper.PasteMaskData")]
+        public static object PasteMaskData(object data, Type targetType)
         {
-            if (string.IsNullOrEmpty(value)) return value;
-            if (value.Length <= startLength + endLength) return value;
-
-            return value.Substring(0, startLength) +
-                   new string(maskChar, value.Length - startLength - endLength) +
-                   value.Substring(value.Length - endLength);
+            return HalfHideHelper.PasteMaskData(data, targetType);
         }
 
-        #endregion
-
     }
 }
framework/PasteApeart.Helper/HalfHideHelper.cs
diff --git a/framework/PasteApeart.Helper/HalfHideHelper.cs b/framework/PasteApeart.Helper/HalfHideHelper.cs
new file mode 100644
index 0000000..f9ff8dc
--- /dev/null
+++ b/framework/PasteApeart.Helper/HalfHideHelper.cs
@@ -0,0 +1,307 @@
+using System.Collections;
+using System.Reflection;
+
+namespace PasteApeart.Helper
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public class HalfHideHelper
+    {
+
+        #region 脱敏处理 跟级的Class一定要标记PasteHalfHide特性
+
+        /// <summary>
+        /// 对字段进行脱敏处理,注意[PasteHalfHide]如果没在Class标记,则使用默认值,就近原则!
+        /// </summary>
+        /// <param name="data"></param>
+        /// <param name="targetType"></param>
+        /// <returns></returns>
+        public static object PasteMaskData(object data, Type targetType)
+        {
+            if (data == null || targetType == null)
+            {
+                return data;
+            }
+
+            var classAttribute = targetType.GetCustomAttribute<PasteHalfHideAttribute>();
+            if (classAttribute == null)
+            {
+                //跟级一定要有class的特性,这样可以避免无用扫描
+                return data;
+            }
+
+            var properties = ReadTypeProperties(targetType);
+            bool createNew = classAttribute.CreateNewObj;   // 唯一决策点,向下传
+
+            if (data is IEnumerable list && data is not string)
+            {
+                if (createNew)
+                {
+                    var resultList = new List<object>();
+                    foreach (var item in list)
+                    {
+                        if (item == null || !targetType.IsInstanceOfType(item))
+                        {
+                            resultList.Add(item);
+                            continue;
+                        }
+                        resultList.Add(MaskNewSingleObject(item, targetType, properties, createNew, classAttribute));
+                    }
+                    return resultList;
+                }
+                else
+                {
+                    foreach (var item in list)
+                    {
+                        if (item == null || !targetType.IsInstanceOfType(item))
+                            continue;
+                        MaskSingleObject(item, targetType, properties, createNew, classAttribute);
+                    }
+                    return data;
+                }
+            }
+
+            if (createNew)
+                return MaskNewSingleObject(data, targetType, properties, createNew, classAttribute);
+
+            MaskSingleObject(data, targetType, properties, createNew, classAttribute);
+            return data;
+        }
+
+        /// <summary>
+        /// 原地修改模式(createNew 恒 false)
+        /// 字段特性就近优先;字段没标但类标了 -> 用类级;都没标 -> 跳过
+        /// </summary>
+        private static void MaskSingleObject(object obj, Type type, PropertyInfo[] properties, bool createNew, PasteHalfHideAttribute inputAttribute)
+        {
+            if (obj == null) return;
+
+            var classAttr = type.GetCustomAttribute<PasteHalfHideAttribute>();
+            if (classAttr == null)
+            {
+                classAttr = inputAttribute;
+            }
+
+            foreach (var property in properties)
+            {
+                if (!property.CanRead || !property.CanWrite) continue;
+
+                var propAttr = property.GetCustomAttribute<PasteHalfHideAttribute>();
+                var value = property.GetValue(obj);
+
+                bool shouldMask = propAttr != null || classAttr != null;
+                if (!shouldMask) continue;
+
+                // string
+                if (property.PropertyType == typeof(string))
+                {
+                    var s = value as string;
+                    if (string.IsNullOrEmpty(s)) continue;
+                    var attr = propAttr ?? classAttr;   // 就近优先
+                    property.SetValue(obj, Desensitize(s, attr));
+                    continue;
+                }
+
+                // 值类型
+                if (property.PropertyType.IsValueType || property.PropertyType == typeof(DateTime))
+                    continue;
+
+                // 集合
+                if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
+                {
+                    if (value is not IEnumerable srcList) continue;
+                    var elementType = GetEnumerableElementType(property.PropertyType);
+                    if (elementType == null) continue;
+                    var elementProps = ReadTypeProperties(elementType);
+                    foreach (var item in srcList)
+                    {
+                        if (item == null || !elementType.IsInstanceOfType(item)) continue;
+                        MaskSingleObject(item, elementType, elementProps, createNew, classAttr);
+                    }
+                    continue;
+                }
+
+                // 复杂对象
+                if (value == null) continue;
+                var childType = property.PropertyType;
+                var childProps = ReadTypeProperties(childType);
+                MaskSingleObject(value, childType, childProps, createNew, classAttr);
+            }
+        }
+
+        /// <summary>
+        /// 副本模式(createNew 恒 true)
+        /// 不吞值:字段没标 -> 原样复制原值;字段标了 -> 处理
+        /// 类没标不再提前 return 空对象
+        /// </summary>
+        private static object MaskNewSingleObject(object obj, Type type, PropertyInfo[] properties, bool createNew, PasteHalfHideAttribute inputAttribute)
+        {
+            if (obj == null) return null;
+
+            var classAttr = type.GetCustomAttribute<PasteHalfHideAttribute>();
+            if (classAttr == null)
+            {
+                classAttr = inputAttribute;
+            }
+            var result = Activator.CreateInstance(type);
+
+            foreach (var property in properties)
+            {
+                if (!property.CanRead || !property.CanWrite) continue;
+
+                var propAttr = property.GetCustomAttribute<PasteHalfHideAttribute>();
+                var value = property.GetValue(obj);
+
+                bool shouldMask = propAttr != null || classAttr != null;
+
+                // string
+                if (property.PropertyType == typeof(string))
+                {
+                    var s = value as string;
+                    if (!shouldMask || string.IsNullOrEmpty(s))
+                    {
+                        property.SetValue(result, s);   // 没标/空值:原样复制,不吞
+                        continue;
+                    }
+                    var attr = propAttr ?? classAttr;
+                    property.SetValue(result, Desensitize(s, attr));
+                    continue;
+                }
+
+                // 值类型
+                if (property.PropertyType.IsValueType || property.PropertyType == typeof(DateTime))
+                {
+                    property.SetValue(result, value);
+                    continue;
+                }
+
+                // 集合
+                if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
+                {
+                    if (value is not IEnumerable srcList)
+                    {
+                        property.SetValue(result, value);
+                        continue;
+                    }
+                    var elementType = GetEnumerableElementType(property.PropertyType);
+                    if (elementType == null)
+                    {
+                        property.SetValue(result, value);
+                        continue;
+                    }
+                    if (!shouldMask)
+                    {
+                        // 没标:原样复制集合引用
+                        property.SetValue(result, value);
+                        continue;
+                    }
+                    var elementProps = ReadTypeProperties(elementType);
+                    var newList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(elementType));
+                    foreach (var item in srcList)
+                    {
+                        if (item == null || !elementType.IsInstanceOfType(item))
+                        {
+                            newList.Add(item);
+                            continue;
+                        }
+                        newList.Add(MaskNewSingleObject(item, elementType, elementProps, createNew, classAttr));
+                    }
+                    property.SetValue(result, newList);
+                    continue;
+                }
+
+                // 复杂对象
+                if (!shouldMask || value == null)
+                {
+                    property.SetValue(result, value);   // 没标/空值:原样复制,不吞
+                    continue;
+                }
+
+                var childType = property.PropertyType;
+                var childProps = ReadTypeProperties(childType);
+                property.SetValue(result, MaskNewSingleObject(value, childType, childProps, createNew, classAttr));
+            }
+
+            return result;
+        }
+
+        private static Type GetEnumerableElementType(Type t)
+        {
+            if (t.IsArray) return t.GetElementType();
+            if (t.IsGenericType && t.GetGenericArguments().Length == 1)
+                return t.GetGenericArguments()[0];
+            var iface = t.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>));
+            return iface?.GetGenericArguments()[0];
+        }
+
+        private static string Desensitize(string value, PasteHalfHideAttribute attr)
+        {
+            if (string.IsNullOrEmpty(value)) return value;
+            return DesensitizeCustom(value, attr.StartLength, attr.EndLength, attr.MaskChar);
+        }
+
+        private static string DesensitizeCustom(string value, int startLength, int endLength, char maskChar)
+        {
+            if (string.IsNullOrEmpty(value)) return value;
+            if (startLength < 0) startLength = 0;
+            if (endLength < 0) endLength = 0;
+            if (value.Length <= startLength + endLength) return value;
+
+            return value.Substring(0, startLength) +
+                   new string(maskChar, value.Length - startLength - endLength) +
+                   value.Substring(value.Length - endLength);
+        }
+
+        #endregion
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="searchType"></param>
+        /// <returns></returns>
+        private static PropertyInfo[] ReadTypeProperties(Type searchType)
+        {
+
+            var typeName = searchType.FullName;
+
+            var allProperties = searchType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
+
+            // 辅助方法:计算类型的继承深度
+            int GetInheritanceDepth(Type type)
+            {
+                int depth = 0;
+                while (type.BaseType != null && type.BaseType != typeof(object))
+                {
+                    depth++;
+                    type = type.BaseType;
+                }
+                return depth;
+            }
+
+            // 按继承深度从远到近排序
+            var sortedProperties = allProperties
+                .OrderBy(p => GetInheritanceDepth(p.DeclaringType))
+                .ToArray();
+
+            var hasDuplicates = sortedProperties.Length != sortedProperties.Select(p => p.Name).Distinct().Count();
+            if (!hasDuplicates)
+            {
+                return sortedProperties;
+            }
+
+            // 去重:保留最近的(后面的覆盖前面的)
+            var propertyDict = new Dictionary<string, PropertyInfo>();
+            foreach (var prop in sortedProperties)
+            {
+                propertyDict[prop.Name] = prop;
+            }
+
+            return propertyDict.Values
+                .OrderBy(p => GetInheritanceDepth(p.DeclaringType))
+                .ToArray();
+
+        }
+
+    }
+}
framework/PasteApeart.Helper/PasteApeartAttribute.cs
diff --git a/framework/PasteApeart.Helper/PasteApeartAttribute.cs b/framework/PasteApeart.Helper/PasteApeartAttribute.cs
index 083989f..4dac959 100644
--- a/framework/PasteApeart.Helper/PasteApeartAttribute.cs
+++ b/framework/PasteApeart.Helper/PasteApeartAttribute.cs
@@ -1074,16 +1074,16 @@ namespace PasteApeart.Helper
         public char MaskChar { get; set; } = '*';
 
         /// <summary>
-        /// 
+        /// 创建新对象,还是在原值上修改,顶级Class上有效,字段上无效
         /// </summary>
         public bool CreateNewObj { get; set; } = false;
 
         /// <summary>
         /// 服务端特性 脱敏处理 需要Class先标记,表示这个对象有字段要脱敏 然后字段标记
         /// </summary>
-        /// <param name="startLen"></param>
-        /// <param name="endLen"></param>
-        /// <param name="hideChar"></param>
+        /// <param name="startLen">开头保持位数</param>
+        /// <param name="endLen">尾巴保持位数</param>
+        /// <param name="hideChar">默认字段的脱敏字符</param>
         /// <param name="newObj">新对象上处理,否则为原对象上变更</param>
         public PasteHalfHideAttribute(int startLen = 3, int endLen = 4, char hideChar = '*', bool newObj = false)
         {
manage/page/pasteform/form.js
diff --git a/manage/page/pasteform/form.js b/manage/page/pasteform/form.js
index 8dca2c5..3d0c85f 100644
--- a/manage/page/pasteform/form.js
+++ b/manage/page/pasteform/form.js
@@ -2949,7 +2949,7 @@ function InitMarkDownEditor(item) {
 
     BtnExpend = editormd.BtnMenu;
 
-    _mdEditor = editormd(_editor, {
+    var _mdEditor = editormd(_editor, {
         height: _high,
         saveHTMLToTextarea: true,
         imageUpload: true,
manage/page/pasteform/view.html
diff --git a/manage/page/pasteform/view.html b/manage/page/pasteform/view.html
index e4e6efc..6e811d1 100644
--- a/manage/page/pasteform/view.html
+++ b/manage/page/pasteform/view.html
@@ -121,7 +121,7 @@
                                 <%}%>
                             <% break; 
                             case "password": %>
-                                <input name="<%:=item.name%>" autocomplete="off" class="input-text" <% if(item.required){%>required<%}%> type="password" onblur="handlerBlur(this)" <% if(item.readonly){ %>readonly<% } %> value="<%:=item.value || ''%>" <%if(item.maxlength!=0){%> maxlength="<%:=item.maxlength%>"<%}%> placeholder="<%:=item.placeholder%>" />
+                                <input name="<%:=item.name%>" autocomplete="new-password" class="input-text" <% if(item.required){%>required<%}%> type="password" onblur="handlerBlur(this)" <% if(item.readonly){ %>readonly<% } %> value="<%:=item.value || ''%>" <%if(item.maxlength!=0){%> maxlength="<%:=item.maxlength%>"<%}%> placeholder="<%:=item.placeholder%>" />
                                 <span class="Hui-iconfont Hui-iconfont-del spanclean" onclick="handlerClean(this)"></span>
                             <% break; 
                             case "html": %>
​ ​