commits列表 30 项
提交内容 28/28
脱敏处理!
abp_example/ExampleForm.Application.Contracts/eventmodels/EventDemoModel.cs
diff --git a/abp_example/ExampleForm.Application.Contracts/eventmodels/EventDemoModel.cs b/abp_example/ExampleForm.Application.Contracts/eventmodels/EventDemoModel.cs
index 53de19a..8537d87 100644
--- a/abp_example/ExampleForm.Application.Contracts/eventmodels/EventDemoModel.cs
+++ b/abp_example/ExampleForm.Application.Contracts/eventmodels/EventDemoModel.cs
@@ -13,5 +13,10 @@ namespace ExampleForm.Application.Contracts.eventmodels
         /// </summary>
         [PasteOuter("userInfo", "extendUser", "id", "userName")]
         public int UserId { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public override string MutexKey => $"mutex:{nameof(EventDemoModel)}:{UserId}";
     }
 }
abp_example/ExampleForm.Application.Contracts/usermodels/UserInfoDto.cs
diff --git a/abp_example/ExampleForm.Application.Contracts/usermodels/UserInfoDto.cs b/abp_example/ExampleForm.Application.Contracts/usermodels/UserInfoDto.cs
index a5b5a1a..04c1820 100644
--- a/abp_example/ExampleForm.Application.Contracts/usermodels/UserInfoDto.cs
+++ b/abp_example/ExampleForm.Application.Contracts/usermodels/UserInfoDto.cs
@@ -138,6 +138,7 @@ namespace ExampleForm.usermodels
     ///</summary>
     [Description("用户信息")]
     [PasteEnable(0, 1, 1, 0)]
+    [PasteHalfHide]
     public class UserInfoListDto : EntityDto<int>
     {
         ///<summary>
@@ -171,6 +172,7 @@ namespace ExampleForm.usermodels
         ///邮箱
         ///</summary>
         [PasteSearch]
+        [PasteHalfHide]
         [Description("邮箱")]
         public string Email { get; set; }
 
abp_example/ExampleForm.Application/usermodels/RoleInfoAppService.cs
diff --git a/abp_example/ExampleForm.Application/usermodels/RoleInfoAppService.cs b/abp_example/ExampleForm.Application/usermodels/RoleInfoAppService.cs
index 500ce1e..44bafc4 100644
--- a/abp_example/ExampleForm.Application/usermodels/RoleInfoAppService.cs
+++ b/abp_example/ExampleForm.Application/usermodels/RoleInfoAppService.cs
@@ -468,29 +468,29 @@ namespace ExampleForm.usermodels
             return "删除成功";
         }
 
-        /// <summary>
-        /// 备份数据
-        /// </summary>
-        /// <param name="save"></param>
-        /// <returns></returns>
-        /// <exception cref="PasteCodeException"></exception>
-        [HttpPost]
-        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]
-        public async Task<dynamic> Backup(bool save = true)
-        {
-            return await RoleBackLoadHandler.BackupAsync(_dbContext, save);
-        }
+        ///// <summary>
+        ///// 备份数据
+        ///// </summary>
+        ///// <param name="save"></param>
+        ///// <returns></returns>
+        ///// <exception cref="PasteCodeException"></exception>
+        //[HttpPost]
+        //[TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]
+        //public async Task<dynamic> Backup(bool save = true)
+        //{
+        //    return await RoleBackLoadHandler.BackupAsync(_dbContext, save);
+        //}
 
-        /// <summary>
-        /// 载入数据
-        /// </summary>
-        /// <returns></returns>
-        [HttpPost]
-        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]
-        public async Task<string> Load()
-        {
-            return await RoleBackLoadHandler.LoadAsync(_dbContext);
-        }
+        ///// <summary>
+        ///// 载入数据
+        ///// </summary>
+        ///// <returns></returns>
+        //[HttpPost]
+        //[TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]
+        //public async Task<string> Load()
+        //{
+        //    return await RoleBackLoadHandler.LoadAsync(_dbContext);
+        //}
 
     }
 }
abp_example/ExampleForm.Domain/basicmodels/IUserIdEntiry.cs
diff --git a/abp_example/ExampleForm.Domain/basicmodels/IUserIdEntiry.cs b/abp_example/ExampleForm.Domain/basicmodels/IUserIdEntiry.cs
deleted file mode 100644
index 352ba04..0000000
--- a/abp_example/ExampleForm.Domain/basicmodels/IUserIdEntiry.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//using System;
-//using System.Collections.Generic;
-//using System.Linq;
-//using System.Text;
-//using System.Threading.Tasks;
-
-//namespace ExampleForm
-//{
-//    /// <summary>
-//    /// 
-//    /// </summary>
-//    public interface IUserIdEntiry
-//    {
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        int UserId { get; set; }
-//    }
-//}
abp_example/ExampleForm.Domain/enummodels/ILevelEntity.cs
diff --git a/abp_example/ExampleForm.Domain/enummodels/ILevelEntity.cs b/abp_example/ExampleForm.Domain/enummodels/ILevelEntity.cs
deleted file mode 100644
index 223cd9f..0000000
--- a/abp_example/ExampleForm.Domain/enummodels/ILevelEntity.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//using System;
-//using System.Collections.Generic;
-//using System.Linq;
-//using System.Text;
-//using System.Threading.Tasks;
-
-//namespace ExampleForm
-//{
-//    /// <summary>
-//    /// 支持 非递归多级查询,支持多级排序
-//    /// </summary>
-//    public interface ILevelEntity
-//    {
-//        /// <summary>
-//        /// 标识
-//        /// </summary>
-//        int Id { get; set; }
-
-//        /// <summary>
-//        /// 排序串
-//        /// </summary>
-//        string SortStr { get; set; }
-
-//        /// <summary>
-//        /// 层级
-//        /// </summary>
-//        int Level { get; set; }
-
-//        /// <summary>
-//        /// 排序 层级内排序
-//        /// </summary>
-//        int Sort { get; set; }
-
-//        /// <summary>
-//        /// 父级
-//        /// </summary>
-//        int FatherId { get; set; }
-
-//        /// <summary>
-//        /// 父级串 替换递归查询用
-//        /// </summary>
-//        string FatherStr { get; set; }
-
-//        /// <summary>
-//        /// 根级 大块
-//        /// </summary>
-//        int RootId { get; set; }
-//    }
-
-//}
abp_example/ExampleForm.Handler/common/ArticleHandler.cs
diff --git a/abp_example/ExampleForm.Handler/common/ArticleHandler.cs b/abp_example/ExampleForm.Handler/common/ArticleHandler.cs
deleted file mode 100644
index 7f97a94..0000000
--- a/abp_example/ExampleForm.Handler/common/ArticleHandler.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace ExampleForm.Handler
-{
-    public class ArticleHandler
-    {
-
-        private IHttpClientFactory _httpClientFactory;
-        public ArticleHandler(IHttpClientFactory httpClientFactory)
-        {
-            _httpClientFactory = httpClientFactory;
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="url"></param>
-        public void Read(string url)
-        {
-
-        }
-
-    }
-}
abp_example/ExampleForm.Handler/common/CacheHandler.cs
diff --git a/abp_example/ExampleForm.Handler/common/CacheHandler.cs b/abp_example/ExampleForm.Handler/common/CacheHandler.cs
index 62be47b..b655c25 100644
--- a/abp_example/ExampleForm.Handler/common/CacheHandler.cs
+++ b/abp_example/ExampleForm.Handler/common/CacheHandler.cs
@@ -1,13 +1,8 @@
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
-using ExampleForm.Application.Contracts;
-using ExampleForm.Handler;
 using ExampleForm.usermodels;
+using PasteApeart.Application.Contracts;
+using PasteApeart.Handler.redis;
 using Volo.Abp.DependencyInjection;
 using Volo.Abp.Domain.Entities;
-using Volo.Abp.ObjectMapping;
-using PasteApeart.Handler.redis;
-using PasteApeart.Application.Contracts;
 
 namespace ExampleForm
 {
@@ -53,7 +48,7 @@ namespace ExampleForm
             if (entity != null)
             {
                 //var dto = _objectMapper.Map<TEntity, TDto>(entity);
-                var dto = Mapster.TypeAdapter.Adapt<TEntity,TDto>(entity);
+                var dto = Mapster.TypeAdapter.Adapt<TEntity, TDto>(entity);
                 await _appCache.SetObjectAsync<TDto>(cacheKey, dto, expireSeconds);
                 return dto;
             }
abp_example/ExampleForm.Handler/common/ChannelHelper.cs
diff --git a/abp_example/ExampleForm.Handler/common/ChannelHelper.cs b/abp_example/ExampleForm.Handler/common/ChannelHelper.cs
deleted file mode 100644
index d95986b..0000000
--- a/abp_example/ExampleForm.Handler/common/ChannelHelper.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//using System.Threading.Channels;
-//using Volo.Abp.DependencyInjection;
-
-//namespace ExampleForm
-//{
-//    /// <summary>
-//    /// 
-//    /// </summary>
-//    public class ChannelHelper : ISingletonDependency
-//    {
-
-//        private Channel<ChannelNoticeModel> _channelnotice;
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        public ChannelHelper()
-//        {
-//            _channelnotice = Channel.CreateUnbounded<ChannelNoticeModel>();
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="input"></param>
-//        public async void Write(ChannelNoticeModel input)
-//        {
-//            await _channelnotice.Writer.WriteAsync(input);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        public Channel<ChannelNoticeModel> Notice { get { return _channelnotice; } }
-
-//    }
-
-//    /// <summary>
-//    /// 
-//    /// </summary>
-//    public class ChannelNoticeModel
-//    {
-//        /// <summary>
-//        /// 内容
-//        /// </summary>
-//        public string body { get; set; }
-
-//        /// <summary>
-//        /// 动作名称 waitrevice:任务待领取 finish:任务完成 cannel:任务取消 waithand:待处理 waitreply:待反馈
-//        /// </summary>
-//        public string action { get; set; }
-
-//        /// <summary>
-//        /// 用户id
-//        /// </summary>
-//        public int userid { get; set; }
-
-//        /// <summary>
-//        /// 部门ID
-//        /// </summary>
-//        public int partid { get; set; }
-
-//        /// <summary>
-//        /// 整个项目组
-//        /// </summary>
-//        public int projectid { get; set; }
-
-//        /// <summary>
-//        /// 排除谁
-//        /// </summary>
-//        public int exceptuid { get; set; }
-//    }
-//}
abp_example/ExampleForm.Handler/common/ImageHelper.cs
diff --git a/abp_example/ExampleForm.Handler/common/ImageHelper.cs b/abp_example/ExampleForm.Handler/common/ImageHelper.cs
index fade384..9dc7dcd 100644
--- a/abp_example/ExampleForm.Handler/common/ImageHelper.cs
+++ b/abp_example/ExampleForm.Handler/common/ImageHelper.cs
@@ -1,17 +1,16 @@
-using SixLabors.Fonts;
+using SixLabors.Fonts;
 using SixLabors.ImageSharp;
 using SixLabors.ImageSharp.Drawing.Processing;
 using SixLabors.ImageSharp.Formats.Jpeg;
 using SixLabors.ImageSharp.PixelFormats;
 using SixLabors.ImageSharp.Processing;
-using Volo.Abp.DependencyInjection;
 
 namespace ExampleForm
 {
     /// <summary>
     /// 
     /// </summary>
-    public sealed class ImageHelper : ISingletonDependency
+    public sealed class ImageHelper
     {
 
         #region 生产验证码
abp_example/ExampleForm.Handler/common/PublicHelper.cs
diff --git a/abp_example/ExampleForm.Handler/common/PublicHelper.cs b/abp_example/ExampleForm.Handler/common/PublicHelper.cs
index 3e99544..0f7ec0d 100644
--- a/abp_example/ExampleForm.Handler/common/PublicHelper.cs
+++ b/abp_example/ExampleForm.Handler/common/PublicHelper.cs
@@ -1,4 +1,4 @@
-using System.Text;
+using System.Text;
 
 namespace ExampleForm
 {
@@ -33,7 +33,7 @@ namespace ExampleForm
         /// <summary>
         /// user.token密钥 这个在使用模板创建的时候会随机掉
         /// </summary>
-        public const string TokenKey = "b118f5eb-596d-4ed7-bfc4-21618327142e";
+        public const string TokenKey = "11223344-596d-4ed7-bfc4-21618327142e";
 
         /// <summary>
         /// 密钥名称
abp_example/ExampleForm.Handler/eventmodels/EventDemoModelHandler.cs
diff --git a/abp_example/ExampleForm.Handler/eventmodels/EventDemoModelHandler.cs b/abp_example/ExampleForm.Handler/eventmodels/EventDemoModelHandler.cs
new file mode 100644
index 0000000..0774c59
--- /dev/null
+++ b/abp_example/ExampleForm.Handler/eventmodels/EventDemoModelHandler.cs
@@ -0,0 +1,94 @@
+using ExampleForm.Application.Contracts.eventmodels;
+using Microsoft.Extensions.Logging;
+using PasteApeart.Handler;
+using PasteApeart.Handler.Extensions;
+using PasteApeart.Handler.redis;
+using Volo.Abp.DependencyInjection;
+
+namespace ExampleForm.Handler.eventmodels
+{
+    /// <summary>
+    /// 案例 EventDemoModel对应的业务执行案例,管好自己的一亩三分地的哲学就在这里体现了
+    /// </summary>
+    public class EventDemoModelHandler : IEventHandler<EventDemoModel>, ITransientDependency
+    {
+        private readonly IAppCache _appCache;
+
+        private readonly ILogger<EventDemoModelHandler> _logger;
+
+        private readonly IChannelHelper _channelHelper;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="appCache"></param>
+        /// <param name="logger"></param>
+        /// <param name="channelHelper"></param>
+        public EventDemoModelHandler(IAppCache appCache, ILogger<EventDemoModelHandler> logger, IChannelHelper channelHelper)
+        {
+            _appCache = appCache;
+            _logger = logger;
+            _channelHelper = channelHelper;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public object Result { get; protected set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task HandleEventAsync(EventDemoModel input)
+        {
+            //按需调用 是否排重,比如统计某一个信息,有时候只要统计一次,最后一次得执行即可,前面得都可以抛弃
+            if (!await input.ToMatchTaskMutexAsync(_appCache))
+            {
+                _logger.LogWarning($"{nameof(EventDemoModelHandler)} 任务被重置了,当前任务不需要处理 ");
+                return;
+            }
+
+            //按需使用并发锁
+            var lockKey = $"lock:{nameof(EventDemoModel)}:{input.UserId}";
+            if (!await _appCache.LockAsync(lockKey, 10))
+            {
+                //设置重试 
+                await input.ToAutoExpireAndSendAsync(_channelHelper);
+                return;
+            }
+
+            try
+            {
+
+                //业务代码
+                Console.WriteLine("自定义 实现 业务代码");
+
+            }
+            catch (Exception exl)
+            {
+                _logger.LogException(exl);
+            }
+            finally
+            {
+                await _appCache.UnLockAsync(lockKey);
+            }
+
+            ////启动一个其他的任务,并带上延迟,下面例子标识过10分钟后启动EventDemoModel对应的业务任务
+            //var newTaskModel = new EventDemoModel { };
+            ////选填 任务是否延迟触发,否则立马触发(当然这个立马中间还是需要消耗一些时效的,比如MQ的中间通讯,比如Channel的排队等)
+            //newTaskModel.ExpireSecond = 600;
+            ////业务代码的其他赋值
+            ////选填 表示启动任务标记,一般用于任务排重,比如git提交后1个小时后执行gc,你这样操作后,那么只有最后一个任务会被执行
+            //await newTaskModel.ToStartTaskMutexAsync(_appCache,"3");
+            ////消息压入到队列,基于配置走Channel或者比如RabbitMQ
+            //await _channelHelper.WriteAutoQueueAsync(newTaskModel);
+
+            ////基于对AbsEventModel的扩展,你还可以实现重试机制,比如异常后5s 10s 30s 5m等非等时重试
+
+            //是否包裹异常处理,看业务需求,反正队列消费者那边会有异常处理
+
+        }
+    }
+}
abp_example/ExampleForm.Handler/extendmodel/QueryableExtensions.cs
diff --git a/abp_example/ExampleForm.Handler/extendmodel/QueryableExtensions.cs b/abp_example/ExampleForm.Handler/extendmodel/QueryableExtensions.cs
deleted file mode 100644
index a869c6b..0000000
--- a/abp_example/ExampleForm.Handler/extendmodel/QueryableExtensions.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-//using System;
-//using System.Collections.Generic;
-//using System.Linq;
-//using System.Linq.Expressions;
-//using System.Reflection;
-//using System.Text;
-//using System.Threading.Tasks;
-
-//namespace ExampleForm.Handler
-//{
-//    public static class QueryableExtensions
-//    {
-//        /// <summary>
-//        /// 取代System.Linq.XXX的OrderBy慢的问题
-//        /// </summary>
-//        /// <typeparam name="T"></typeparam>
-//        /// <param name="query"></param>
-//        /// <param name="ordering"></param>
-//        /// <returns></returns>
-//        [Obsolete("迁移到ExampleFormHelper的包中")]
-//        public static IOrderedQueryable<T> PasteOrderBy<T>(this IQueryable<T> query, string ordering)
-//        {
-//            if (string.IsNullOrWhiteSpace(ordering))
-//                return query.OrderBy(x => 1);
-
-//            // 分割多个排序字段
-//            var orderClauses = ordering.Split(',', StringSplitOptions.RemoveEmptyEntries);
-//            IOrderedQueryable<T> orderedQuery = null;
-//            var eType = typeof(T);
-//            foreach (var clause in orderClauses)
-//            {
-//                var parts = clause.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
-//                if (parts.Length == 0) continue;
-
-//                var fieldName = parts[0];
-//                var descending = false;
-//                if (parts.Length > 1)
-//                {
-//                    descending = parts.Length > 1 &&
-//                                   (parts[1].Equals("desc", StringComparison.OrdinalIgnoreCase) ||
-//                                    parts[1].Equals("descending", StringComparison.OrdinalIgnoreCase));
-//                }
-//                //// 构建表达式
-//                //var parameter = Expression.Parameter(typeof(T), "x");
-//                //var property = Expression.Property(parameter, fieldName);
-//                //var lambda = Expression.Lambda(property, parameter);
-
-//                // 使用 GetProperty 而不是 Expression.Property
-//                var propertyInfo = eType.GetProperty(fieldName,
-//                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
-
-//                if (propertyInfo == null)
-//                {
-//                    // 如果当前类型没有,查找基类的属性
-//                    propertyInfo = eType.GetProperty(fieldName,
-//                        BindingFlags.Public | BindingFlags.Instance);
-//                }
-
-//                if (propertyInfo == null)
-//                {
-//                    throw new ArgumentException($"类型 '{eType.Name}' 中不存在属性 '{fieldName}'");
-//                }
-
-//                // 构建表达式
-//                var parameter = Expression.Parameter(eType, "x");
-//                var property = Expression.Property(parameter, propertyInfo);
-//                var lambda = Expression.Lambda(property, parameter);
-
-//                if (orderedQuery == null)
-//                {
-//                    // 第一个排序字段
-//                    var methodName = descending ? "OrderByDescending" : "OrderBy";
-//                    var methodCall = Expression.Call(
-//                        typeof(Queryable), methodName,
-//                        new Type[] { typeof(T), property.Type },
-//                        query.Expression, Expression.Quote(lambda));
-
-//                    orderedQuery = (IOrderedQueryable<T>)query.Provider.CreateQuery<T>(methodCall);
-//                }
-//                else
-//                {
-//                    // 后续排序字段
-//                    var methodName = descending ? "ThenByDescending" : "ThenBy";
-//                    var methodCall = Expression.Call(
-//                        typeof(Queryable), methodName,
-//                        new Type[] { typeof(T), property.Type },
-//                        orderedQuery.Expression, Expression.Quote(lambda));
-
-//                    orderedQuery = (IOrderedQueryable<T>)orderedQuery.Provider.CreateQuery<T>(methodCall);
-//                }
-//            }
-
-//            return orderedQuery ?? (IOrderedQueryable<T>)query;
-//        }
-
-//        /// <summary>
-//        /// 测试可用 DefaultAppService的默认
-//        /// </summary>
-//        /// <param name="query"></param>
-//        /// <param name="ordering"></param>
-//        /// <returns></returns>
-//        [Obsolete("迁移到ExampleFormHelper的包中")]
-//        public static IOrderedQueryable PasteOrder(this IQueryable query, string ordering)
-//        {
-//            //if (string.IsNullOrWhiteSpace(ordering))
-//            //return query.OrderBy(x => 1);
-//            if (String.IsNullOrEmpty(ordering))
-//            {
-//                return (IOrderedQueryable)query;
-//            }
-
-//            // 分割多个排序字段
-//            var orderClauses = ordering.Split(',', StringSplitOptions.RemoveEmptyEntries);
-//            IOrderedQueryable orderedQuery = null;
-
-//            var eType = query.ElementType;
-
-//            foreach (var clause in orderClauses)
-//            {
-//                var parts = clause.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
-//                if (parts.Length == 0) continue;
-
-//                var fieldName = parts[0];
-//                var descending = false;
-//                if (parts.Length > 1)
-//                {
-//                   descending = parts.Length > 1 &&
-//                                   (parts[1].Equals("desc", StringComparison.OrdinalIgnoreCase) ||
-//                                    parts[1].Equals("descending", StringComparison.OrdinalIgnoreCase));
-//                }
-//                //// 构建表达式
-//                //var parameter = Expression.Parameter(eType, "x");
-//                //var property = Expression.Property(parameter, fieldName);
-//                //var lambda = Expression.Lambda(property, parameter);
-
-//                // 使用 GetProperty 而不是 Expression.Property
-//                var propertyInfo = eType.GetProperty(fieldName,
-//                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
-
-//                if (propertyInfo == null)
-//                {
-//                    // 如果当前类型没有,查找基类的属性
-//                    propertyInfo = eType.GetProperty(fieldName,
-//                        BindingFlags.Public | BindingFlags.Instance);
-//                }
-
-//                if (propertyInfo == null)
-//                {
-//                    throw new ArgumentException($"类型 '{eType.Name}' 中不存在属性 '{fieldName}'");
-//                }
-
-//                // 构建表达式
-//                var parameter = Expression.Parameter(eType, "x");
-//                var property = Expression.Property(parameter, propertyInfo);
-//                var lambda = Expression.Lambda(property, parameter);
-
-//                if (orderedQuery == null)
-//                {
-//                    // 第一个排序字段
-//                    var methodName = descending ? "OrderByDescending" : "OrderBy";
-//                    var methodCall = Expression.Call(
-//                        typeof(Queryable), methodName,
-//                        new Type[] { eType, property.Type },
-//                        query.Expression, Expression.Quote(lambda));
-
-//                    orderedQuery = (IOrderedQueryable)query.Provider.CreateQuery(methodCall);
-//                }
-//                else
-//                {
-//                    // 后续排序字段
-//                    var methodName = descending ? "ThenByDescending" : "ThenBy";
-//                    var methodCall = Expression.Call(
-//                        typeof(Queryable), methodName,
-//                        new Type[] { eType, property.Type },
-//                        orderedQuery.Expression, Expression.Quote(lambda));
-
-//                    orderedQuery = (IOrderedQueryable)orderedQuery.Provider.CreateQuery(methodCall);
-//                }
-//            }
-
-//            return orderedQuery ?? (IOrderedQueryable)query;
-//        }
-//    }
-//}
abp_example/ExampleForm.Handler/modelhandler/LevelHandler.cs
diff --git a/abp_example/ExampleForm.Handler/modelhandler/LevelHandler.cs b/abp_example/ExampleForm.Handler/modelhandler/LevelHandler.cs
deleted file mode 100644
index b331c73..0000000
--- a/abp_example/ExampleForm.Handler/modelhandler/LevelHandler.cs
+++ /dev/null
@@ -1,321 +0,0 @@
-//using Mapster;
-//using Microsoft.EntityFrameworkCore;
-//using ExampleForm.Application.Contracts;
-//using ExampleForm.usermodels;
-//using Volo.Abp.ObjectMapping;
-//using Z.EntityFramework.Plus;
-//using PasteApeart.Domain.Entity;
-
-//namespace ExampleForm.Handler
-//{
-//    /// <summary>
-//    /// 多层级 非递归多层级新增和更新
-//    /// </summary>
-//    public class LevelHandler
-//    {
-//        /// <summary>
-//        /// 这是一个新增案例
-//        ///</summary>
-//        /// <param name="input"></param>
-//        /// <returns></returns>
-//        public static async Task<RoleInfoDto> RoleAdd(IExampleFormDbContext _dbContext, IObjectMapper ObjectMapper, RoleInfoAddDto input)
-//        {
-//            if (input.Sort == 0)
-//            {
-//                var _max = await _dbContext.RoleInfo.Where(x => x.FatherId == input.FatherId)
-//                    .OrderByDescending(x => x.Sort)
-//                    .Select(x => x.Sort)
-//                    .FirstOrDefaultAsync();
-//                input.Sort = _max + 10;
-//            }
-
-//            if (input.RoleType == 0)
-//            {
-//                if (String.IsNullOrEmpty(input.Model) || String.IsNullOrEmpty(input.Role))
-//                {
-//                    throw new PasteCodeException("新增权限的时候,模块和权限必填,请重新填写!");
-//                }
-//                var find = await _dbContext.RoleInfo.Where(x => x.RoleType == 0 && x.Model == input.Model && x.Role == input.Role).Select(x => x.Id).FirstOrDefaultAsync();
-//                if (find > 0)
-//                {
-//                    throw new PasteCodeException("已经有这个菜单项了,请勿重复添加!");
-//                }
-//            }
-//            if (input.RoleType == EnumRoleType.Menu)
-//            {
-//                if (!string.IsNullOrEmpty(input.Path))
-//                {
-//                    if (input.FatherId == 0)
-//                    {
-//                        throw new PasteCodeException("非一级菜单,父级必选,请重新选择!");
-//                    }
-//                    var find = await _dbContext.RoleInfo.Where(x => x.RoleType == EnumRoleType.Menu && x.Path == input.Path).Select(x => x.Id).FirstOrDefaultAsync();
-//                    if (find > 0)
-//                    {
-//                        throw new PasteCodeException("已经有这个菜单项了,请勿重复添加!");
-//                    }
-//                }
-//            }
-
-//            //这里最好用事务包裹下
-//            //var info = ObjectMapper.Map<RoleInfoAddDto, RoleInfo>(input);
-//            var info = input.Adapt<RoleInfo>();
-//            info.IsEnable = true;//添加自定义
-//            _dbContext.Add(info);
-//            await _dbContext.SaveChangesAsync();
-//            await AfterAdd(_dbContext, nameof(RoleInfo), info);
-//            await _dbContext.SaveChangesAsync();
-
-//            //var backinfo = ObjectMapper.Map<RoleInfo, RoleInfoDto>(info);
-//            var backinfo = info.Adapt<RoleInfoDto>();
-//            return backinfo;
-//        }
-
-//        /// <summary>
-//        /// 这是一个更新案例
-//        ///</summary>
-//        /// <param name="input"></param>
-//        /// <returns></returns>
-//        public static async Task<RoleInfoDto> RoleUpdate(IExampleFormDbContext _dbContext, IObjectMapper ObjectMapper, RoleInfoUpdateDto input)
-//        {
-//            if (input.Sort == 0)
-//            {
-//                var _max = await _dbContext.RoleInfo.Where(x => x.FatherId == input.FatherId)
-//                    .OrderByDescending(x => x.Sort)
-//                    .Select(x => x.Sort)
-//                    .FirstOrDefaultAsync();
-//                input.Sort = _max + 10;
-//            }
-
-//            if (input.RoleType == 0)
-//            {
-//                if (String.IsNullOrEmpty(input.Model) || String.IsNullOrEmpty(input.Role))
-//                {
-//                    throw new PasteCodeException("新增权限的时候,模块和权限必填,请重新填写!");
-//                }
-//                var find = await _dbContext.RoleInfo.Where(x => x.RoleType == 0 && x.Model == input.Model && x.Role == input.Role && x.Id != input.Id).Select(x => x.Id).FirstOrDefaultAsync();
-//                if (find > 0)
-//                {
-//                    throw new PasteCodeException("已经有这个菜单项了,请勿重复添加!");
-//                }
-//            }
-//            if (input.RoleType == EnumRoleType.Menu)
-//            {
-//                if (!string.IsNullOrEmpty(input.Path))
-//                {
-//                    if (input.FatherId == 0)
-//                    {
-//                        throw new PasteCodeException("非一级菜单,父级必选,请重新选择!");
-//                    }
-//                    var find = await _dbContext.RoleInfo.Where(x => x.RoleType == EnumRoleType.Menu && x.Path == input.Path && x.Id != input.Id).Select(x => x.Id).FirstOrDefaultAsync();
-//                    if (find > 0)
-//                    {
-//                        throw new PasteCodeException("已经有这个菜单项了,请勿重复添加!");
-//                    }
-//                }
-//            }
-
-//            var info = await _dbContext.RoleInfo.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
-//            if (info == null || info == default)
-//            {
-//                throw new PasteCodeException("需要查询的信息不存在");
-//            }
-//            //ObjectMapper.Map<RoleInfoUpdateDto, RoleInfo>(input, info);
-//            input.Adapt(info);
-//            await AfterUpdate(_dbContext, nameof(RoleInfo), info);
-//            //var backinfo = ObjectMapper.Map<RoleInfo, RoleInfoDto>(info);?
-//            var backinfo = info.Adapt<RoleInfoDto>();
-//            await _dbContext.SaveChangesAsync();
-//            return backinfo;
-//        }
-
-//        /// <summary>
-//        /// 新增后 注意外部要保存下
-//        /// </summary>
-//        /// <param name="_dbContext"></param>
-//        /// <param name="TableName">应该是PropertyName</param>
-//        /// <param name="info"></param>
-//        public static async Task AfterAdd(IExampleFormDbContext _dbContext, string TableName, ILevelEntity info)
-//        {
-//            info.SortStr = info.Sort.ToString().PadLeft(_persize, '0') + "0".PadLeft((_maxlevel - 1) * _persize, '0');
-//            if (info.FatherId <= 0)
-//            {
-//                info.FatherStr = $"{info.Id},";
-//                info.RootId = info.Id;
-//                return;
-//            }
-
-//            var dbType = _dbContext.GetType();
-//            var dbProperty = dbType.GetProperty(TableName);
-//            if (dbProperty != null)
-//            {
-//                var dbSet = dbProperty.GetValue(_dbContext) as IQueryable<ILevelEntity>;
-//                if (dbSet != null)
-//                {
-
-//                    var father = await dbSet.Where(x => x.Id == info.FatherId).AsNoTracking().FirstOrDefaultAsync();
-//                    if (father != null && father != default)
-//                    {
-//                        info.FatherStr = $"{father.FatherStr}{info.Id},";
-//                        info.Level = (father.Level + 1);
-//                        info.FatherId = father.Id;
-//                        info.RootId = father.RootId != 0 ? father.RootId : father.Id;
-//                        BuildSortStr(info, father);
-//                    }
-//                    else
-//                    {
-//                        info.FatherId = 0;
-//                    }
-
-//                }
-//            }
-//        }
-
-//        /// <summary>
-//        /// 更新后 注意外部要保存下
-//        /// </summary>
-//        /// <param name="_dbContext"></param>
-//        /// <param name="TableName">应该是PropertyName</param>
-//        /// <param name="info"></param>
-//        /// <returns></returns>
-//        public static async Task AfterUpdate(IExampleFormDbContext _dbContext, string TableName, ILevelEntity info)
-//        {
-//            IQueryable<ILevelEntity> dbSet = null;
-//            var dbType = _dbContext.GetType();
-//            var dbProperty = dbType.GetProperty(TableName);
-//            if (dbProperty != null)
-//            {
-//                dbSet = dbProperty.GetValue(_dbContext) as IQueryable<ILevelEntity>;
-//            }
-//            if (dbSet == null)
-//            {
-//                return;
-//            }
-//            var old_father_str = info.FatherStr;
-//            var _chat_level = info.Level;
-
-//            if (info.FatherId != 0)
-//            {
-//                var father = await dbSet.Where(x => x.Id == info.FatherId).AsNoTracking().FirstOrDefaultAsync();
-//                if (father != null && father != default)
-//                {
-//                    info.Level = father.Level + 1;
-//                    info.FatherStr = $"{father.FatherStr}{info.Id},";
-//                    info.RootId = father.RootId;
-//                    BuildSortStr(info, father);
-//                }
-//                else
-//                {
-//                    info.FatherId = 0;
-//                    info.FatherStr = $"{info.Id},";
-//                    info.Level = 0;
-//                    info.RootId = info.Id;
-//                    BuildSortStr(info, null);
-//                }
-//            }
-//            else
-//            {
-//                info.FatherId = 0;
-//                info.FatherStr = $"{info.Id},";
-//                info.Level = 0;
-//                info.RootId = info.Id;
-//                BuildSortStr(info, null);
-//            }
-//            _chat_level = _chat_level - (info.Level);
-//            if (!String.IsNullOrEmpty(old_father_str))
-//            {
-//                var suns = await dbSet.Where(x => x.Id != info.Id && x.FatherStr.StartsWith(old_father_str)).ToListAsync();
-//                if (suns != null && suns.Count > 0)
-//                {
-//                    foreach (var item in suns)
-//                    {
-//                        item.FatherStr = item.FatherStr.Replace(old_father_str, info.FatherStr);
-//                        item.Level = item.Level + _chat_level;
-//                        item.RootId = info.RootId;
-//                        BuildFootSortStr(item, info);
-//                    }
-//                }
-//            }
-//        }
-
-//        /// <summary>
-//        /// 自动排序 基于同层级排序到后面,只有当当前是0的时候生效
-//        /// </summary>
-//        /// <param name="_dbContext"></param>
-//        /// <param name="TableName">应该是PropertyName</param>
-//        /// <param name="input"></param>
-//        /// <param name="step"></param>
-//        /// <returns></returns>
-//        public static async Task AutoSort(IExampleFormDbContext _dbContext, string TableName, ILevelEntity input,int step=10)
-//        {
-//            if (input.Sort == 0)
-//            {
-//                var dbType = _dbContext.GetType();
-//                var dbProperty = dbType.GetProperty(TableName);
-//                if (dbProperty != null)
-//                {
-//                    var dbSet = dbProperty.GetValue(_dbContext) as IQueryable<ILevelEntity>;
-//                    if (dbSet != null)
-//                    {
-
-//                        var _max = await dbSet.Where(x => x.FatherId == input.FatherId)
-//                            .OrderByDescending(x => x.Sort)
-//                            .Select(x => x.Sort)
-//                            .FirstOrDefaultAsync();
-//                        input.Sort = _max + 10;
-//                    }
-//                }
-//            }
-//        }
-
-//        /// <summary>
-//        /// 每层最大支持的排序位数 5表示00000
-//        /// </summary>
-//        private const int _persize = 5;
-//        /// <summary>
-//        /// 最大层级个数,从0开始 比如4就是 0 1 2 3
-//        /// </summary>
-//        private const int _maxlevel = 4;
-
-//        /// <summary>
-//        /// 基于父级和当前自己的排序信息,构建对应的排序字符串
-//        /// </summary>
-//        /// <param name="_info"></param>
-//        /// <param name="_father"></param>
-//        private static void BuildSortStr(ILevelEntity _info, ILevelEntity _father)
-//        {
-//            if (_info.Level < _maxlevel)
-//            {
-//                if (_father == null)
-//                {
-//                    _info.SortStr = _info.Sort.ToString().PadLeft(_persize, '0') + "0".PadLeft(_persize * (_maxlevel - 1), '0');
-//                }
-//                else
-//                {
-//                    if (!string.IsNullOrEmpty(_father.SortStr))
-//                    {
-//                        _info.SortStr = _father.SortStr.Substring(0, (_father.Level + 1) * _persize) + _info.Sort.ToString().PadLeft(_persize, '0');
-//                        //补充尾巴
-//                        if (_info.Level < (_maxlevel - 1))
-//                        {
-//                            _info.SortStr += "0".PadLeft(_persize * (_maxlevel - 1 - _info.Level), '0');
-//                        }
-//                    }
-//                }
-//            }
-//        }
-
-//        /// <summary>
-//        /// 上级或者祖籍变更的替换,自己之后的不变,中间层级也不变 
-//        /// </summary>
-//        /// <param name="_info"></param>
-//        /// <param name="_father">是自己的上级或者祖级</param>
-//        private static void BuildFootSortStr(ILevelEntity _info, ILevelEntity _father)
-//        {
-//            var _old_sort_str = _info.SortStr;
-//            _info.SortStr = _father.SortStr.Substring(0, (_father.Level + 1) * _persize);
-//            _info.SortStr += _old_sort_str.Substring((_father.Level + 1) * _persize);
-//        }
-
-//    }
-//}
abp_example/ExampleForm.Handler/modelhandler/RoleBackLoadHandler.cs
diff --git a/abp_example/ExampleForm.Handler/modelhandler/RoleBackLoadHandler.cs b/abp_example/ExampleForm.Handler/modelhandler/RoleBackLoadHandler.cs
index cb907bc..108c9ee 100644
--- a/abp_example/ExampleForm.Handler/modelhandler/RoleBackLoadHandler.cs
+++ b/abp_example/ExampleForm.Handler/modelhandler/RoleBackLoadHandler.cs
@@ -127,6 +127,8 @@ namespace ExampleForm.Handler
                         {
                             await _dbContext.Database.CommitTransactionAsync();
                         }
+
+                        //需要更新最大ID
                     }
                     catch (Exception exl)
                     {
abp_example/ExampleForm.Handler/redismodel/HashKeyValue.cs
diff --git a/abp_example/ExampleForm.Handler/redismodel/HashKeyValue.cs b/abp_example/ExampleForm.Handler/redismodel/HashKeyValue.cs
deleted file mode 100644
index b28de76..0000000
--- a/abp_example/ExampleForm.Handler/redismodel/HashKeyValue.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-//namespace ExampleForm.Handler
-//{
-//    public class HashKeyValue
-//    {
-//        public string Key { get; set; }
-//        public string Value { get; set; }
-//    }
-//}
abp_example/ExampleForm.Handler/redismodel/IAppCache.cs
diff --git a/abp_example/ExampleForm.Handler/redismodel/IAppCache.cs b/abp_example/ExampleForm.Handler/redismodel/IAppCache.cs
deleted file mode 100644
index 96d2396..0000000
--- a/abp_example/ExampleForm.Handler/redismodel/IAppCache.cs
+++ /dev/null
@@ -1,290 +0,0 @@
-//using StackExchange.Redis;
-
-//namespace ExampleForm.Handler
-//{
-//    /// <summary>
-//    /// 缓存通用接口
-//    /// </summary>
-//    public interface IAppCache
-//    {
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        bool IsRedis { get; }
-
-//        /// <summary>
-//        /// 添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        bool Set(string key, string value, TimeSpan? expiry = null);
-
-//        /// <summary>
-//        /// 添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        bool Set(string key, string value, int seconds);
-
-//        /// <summary>
-//        /// 添加一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <typeparam name="T">对象的类型。</typeparam>
-//        /// <param name="value">值。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        bool SetObject<T>(string key, T value, TimeSpan? expiry = null);
-
-//        /// <summary>
-//        /// 添加一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <typeparam name="T">对象的类型。</typeparam>
-//        /// <param name="value">值。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        bool SetObject<T>(string key, T value, int seconds);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="val"></param>
-//        /// <param name="second"></param>
-//        /// <returns></returns>
-//        bool SetValue(string key, string val, int second);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="val"></param>
-//        /// <returns></returns>
-//        bool SetValue(string key, string val);
-
-//        /// <summary>
-//        /// 获取一个对象。
-//        /// </summary>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        T GetObject<T>(string key);
-
-//        /// <summary>
-//        /// 获取一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        [Obsolete]
-//        string Get(string key);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        string GetStringValue(string key);
-
-//        /// <summary>
-//        /// 删除一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        [Obsolete]
-//        bool Delete(string key);
-
-//        /// <summary>
-//        /// 返回键是否存在。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <returns>返回键是否存在。</returns>
-//        [Obsolete]
-//        bool Exists(string key);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        Task<bool> ExistsAsync(string key);
-
-//        /// <summary>
-//        /// 设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        [Obsolete]
-//        bool SetExpire(string key, TimeSpan? expiry);
-
-//        /// <summary>
-//        /// 设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        [Obsolete]
-//        bool SetExpire(string key, int seconds);
-
-//        /// <summary>
-//        /// 异步添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        Task<bool> SetAsync(string key, string value, TimeSpan? expiry = null);
-
-//        /// <summary>
-//        /// 异步添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        Task<bool> SetAsync(string key, string value, int seconds);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <typeparam name="T"></typeparam>
-//        /// <param name="key"></param>
-//        /// <param name="value"></param>
-//        /// <param name="seconds"></param>
-//        /// <returns></returns>
-//        Task<bool> SetObjectAsync<T>(string key, T value, int seconds = 300);
-
-//        /// <summary>
-//        /// 异步获取一个对象。
-//        /// </summary>
-//        /// <typeparam name="T">对象的类型。</typeparam>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        Task<T> GetObjectAsync<T>(string key);
-
-//        /// <summary>
-//        /// 异步获取一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        Task<string> GetAsync(string key);
-
-//        /// <summary>
-//        /// 异步删除一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        Task<bool> DeleteAsync(string key);
-
-//        /// <summary>
-//        /// 异步设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        Task<bool> SetExpireAsync(string key, int seconds);
-
-//        /// <summary>
-//        /// 异步设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        Task<bool> SetExpireAsync(string key, TimeSpan? expiry);
-
-//        #region 分布式锁...
-
-//        /// <summary>
-//        /// 获取锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>是否已锁。</returns>
-//        bool Lock(string key, int seconds);
-
-//        /// <summary>
-//        /// 释放锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <returns>是否成功。</returns>
-//        bool UnLock(string key);
-
-//        /// <summary>
-//        /// 异步获取锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>是否成功。</returns>
-//        Task<bool> LockAsync(string key, int seconds);
-
-//        /// <summary>
-//        /// 异步释放锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <returns>是否成功。</returns>
-//        Task<bool> UnLockAsync(string key);
-
-//        #endregion
-
-
-//        #region hashtable
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        List<HashKeyValue> HashGetAll(string key);
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        Task<List<HashKeyValue>> HashGetAllAsync(string key);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="vals"></param>
-//        void HashSet(string key, HashEntry[] vals);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="vals"></param>
-//        Task HashSetAsync(string key, HashEntry[] vals);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="vals"></param>
-//        void HashSet(string key, System.Collections.Generic.List<HashKeyValue> vals);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="vals"></param>
-//        Task HashSetAsync(string key, System.Collections.Generic.List<HashKeyValue> vals);
-
-
-
-//        string HashGet(string key, string sunkey);
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="sunkey"></param>
-//        /// <returns></returns>
-//        Task<string> HashGetAsync(string key, string sunkey);
-//        #endregion
-//    }
-
-//}
abp_example/ExampleForm.Handler/redismodel/MemoryClient.cs
diff --git a/abp_example/ExampleForm.Handler/redismodel/MemoryClient.cs b/abp_example/ExampleForm.Handler/redismodel/MemoryClient.cs
deleted file mode 100644
index 3b7e1e1..0000000
--- a/abp_example/ExampleForm.Handler/redismodel/MemoryClient.cs
+++ /dev/null
@@ -1,308 +0,0 @@
-//using Microsoft.Extensions.Caching.Memory;
-//using Newtonsoft.Json;
-//using StackExchange.Redis;
-
-//namespace ExampleForm.Handler
-//{
-//    /// <summary>
-//    /// 本地缓存
-//    /// </summary>
-//    public class MemoryClient : IAppCache
-//    {
-//        private readonly IMemoryCache _memoryCache;
-//        public MemoryClient(IMemoryCache memoryCache)
-//        {
-//            _memoryCache = memoryCache;
-//        }
-
-//        public bool IsRedis { get => false; }
-
-//        public bool Delete(string key)
-//        {
-//            _memoryCache.Remove(key);
-//            return true;
-//        }
-
-//        /// <summary>
-//        /// error
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public Task<bool> DeleteAsync(string key)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return Delete(key);
-//            });
-//        }
-
-//        public bool Exists(string key)
-//        {
-//            return _memoryCache.TryGetValue(key, out var val);
-//            //throw new NotImplementedException();
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public async Task<bool> ExistsAsync(string key)
-//        {
-//            var read = _memoryCache.TryGetValue(key, out var val);
-//            //throw new NotImplementedException();
-//            return await Task.FromResult(read);
-//        }
-
-//        public T GetObject<T>(string key)
-//        {
-//            if (_memoryCache.TryGetValue(key, out string val))
-//            {
-//                return JsonConvert.DeserializeObject<T>(val);
-//            }
-//            return default(T);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public string Get(string key)
-//        {
-//            if (_memoryCache.TryGetValue(key, out string val))
-//            {
-//                return val;
-//            }
-//            return "";
-//            // throw new NotImplementedException();
-//        }
-
-//        public Task<T> GetObjectAsync<T>(string key)
-//        {
-//            return Task.Run<T>(() =>
-//            {
-//                return GetObject<T>(key);
-//            });
-//        }
-
-//        public Task<string> GetAsync(string key)
-//        {
-//            return Task.Run<string>(() =>
-//            {
-//                return Get(key);
-//            });
-//        }
-
-//        public string GetStringValue(string key)
-//        {
-//            return Get(key);
-//        }
-
-//        public string HashGet(string key, string sunkey)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        public HashEntry[] HashGetAll(string key)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        public Task<HashEntry[]> HashGetAllAsync(string key)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        public Task<string> HashGetAsync(string key, string sunkey)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        public void HashSet(string key, HashEntry[] vals)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        //public void HashSetAsync(string key, HashEntry[] vals)
-//        //{
-//        //    throw new NotImplementedException();
-//        //}
-
-//        public bool Lock(string key, int seconds)
-//        {
-//            return false;
-//        }
-
-//        public Task<bool> LockAsync(string key, int seconds)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return Lock(key, seconds);
-//            });
-//        }
-
-//        public bool Set(string key, string value, TimeSpan? expiry = null)
-//        {
-//            using (var wcache = _memoryCache.CreateEntry(key))
-//            {
-//                wcache.Value = value;
-//                if (expiry == null)
-//                {
-//                    wcache.AbsoluteExpiration = System.DateTimeOffset.Now.AddSeconds(30);
-//                }
-//                else
-//                {
-//                    wcache.AbsoluteExpiration = DateTimeOffset.Now.Add((TimeSpan)expiry);
-//                }
-//            }
-
-//            return true;
-//        }
-
-//        public bool Set(string key, string value, int seconds)
-//        {
-//            using (var wcache = _memoryCache.CreateEntry(key))
-//            {
-//                wcache.Value = value;
-
-//                wcache.AbsoluteExpiration = System.DateTimeOffset.Now.AddSeconds(seconds);
-
-//            }
-
-//            return true;
-//        }
-
-//        public bool Set(string key, string value)
-//        {
-//            using (var wcache = _memoryCache.CreateEntry(key))
-//            {
-//                wcache.Value = value;
-//            }
-//            return true;
-//        }
-
-//        public bool SetObject<T>(string key, T value, TimeSpan? expiry = null)
-//        {
-
-//            return Set(key, JsonConvert.SerializeObject(value), expiry);
-//        }
-
-//        public bool SetObject<T>(string key, T value, int seconds)
-//        {
-//            return Set(key, JsonConvert.SerializeObject(value), seconds);
-//        }
-
-//        public Task<bool> SetAsync(string key, string value, TimeSpan? expiry = null)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return Set(key, value, expiry);
-//            });
-//        }
-
-//        public Task<bool> SetAsync(string key, string value, int seconds)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return Set(key, value, seconds);
-//            });
-//        }
-
-//        public Task<bool> SetObjectAsync<T>(string key, T value, int second)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return SetObject(key, value, second);
-//            });
-//        }
-
-//        public bool SetExpire(string key, TimeSpan? expiry)
-//        {
-//            if (_memoryCache.TryGetValue(key, out string sval))
-//            {
-
-//                return Set(key, sval, expiry);
-//            }
-//            return false;
-//        }
-
-//        public bool SetExpire(string key, int seconds)
-//        {
-//            if (_memoryCache.TryGetValue(key, out string sval))
-//            {
-
-//                return Set(key, sval, seconds);
-//            }
-//            return false;
-//        }
-
-//        public Task<bool> SetExpireAsync(string key, int seconds)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return SetExpire(key, seconds);
-//            });
-//        }
-
-//        public Task<bool> SetExpireAsync(string key, TimeSpan? expiry)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return SetExpire(key, expiry);
-//            });
-//        }
-
-//        public bool SetValue(string key, string val, int second)
-//        {
-//            return Set(key, val, second);
-//        }
-
-//        public bool SetValue(string key, string val)
-//        {
-//            return Set(key, val);
-//        }
-
-//        public bool UnLock(string key)
-//        {
-//            return false;
-//        }
-
-//        public Task<bool> UnLockAsync(string key)
-//        {
-//            return Task.Run<bool>(() =>
-//            {
-//                return UnLock(key);
-//            });
-//        }
-
-//        public async Task HashSetAsync(string key, HashEntry[] vals)
-//        {
-//            await Task.Run(() =>
-//            {
-//                throw new NotImplementedException();
-//            });
-
-//        }
-
-//        List<HashKeyValue> IAppCache.HashGetAll(string key)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        Task<List<HashKeyValue>> IAppCache.HashGetAllAsync(string key)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        public void HashSet(string key, List<HashKeyValue> vals)
-//        {
-//            throw new NotImplementedException();
-//        }
-
-//        public Task HashSetAsync(string key, List<HashKeyValue> vals)
-//        {
-//            throw new NotImplementedException();
-//        }
-//    }
-//}
abp_example/ExampleForm.Handler/redismodel/RedisClient.cs
diff --git a/abp_example/ExampleForm.Handler/redismodel/RedisClient.cs b/abp_example/ExampleForm.Handler/redismodel/RedisClient.cs
deleted file mode 100644
index 6c44888..0000000
--- a/abp_example/ExampleForm.Handler/redismodel/RedisClient.cs
+++ /dev/null
@@ -1,733 +0,0 @@
-//using Microsoft.Extensions.Options;
-//using Newtonsoft.Json;
-//using StackExchange.Redis;
-
-//namespace ExampleForm.Handler
-//{
-//    /// <summary>
-//    /// 封装 Redis 相关操作的方法类。
-//    /// </summary>
-//    public class RedisClient : IAppCache
-//    {
-
-//        //private readonly RedisConfig _redisconfig;
-//        //private IDatabase _database { get { return _mainconnect.Value.GetDatabase(); } }
-//        //private Lazy<ConnectionMultiplexer> _mainconnect;
-//        //private string PrefixHead = String.Empty;
-//        //public RedisClient(IOptions<RedisConfig> options)
-//        //{
-//        //    _redisconfig = options.Value;
-//        //    var oaconfig = ConfigurationOptions.Parse(_redisconfig.MainConnection);
-//        //    PrefixHead = _redisconfig.Prefix;
-//        //    oaconfig.ClientName = _redisconfig.ClientName;
-//        //    _mainconnect = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(oaconfig));
-//        //}
-
-
-//        private readonly RedisConfig _redisconfig;
-//        private readonly Lazy<ConnectionMultiplexer>[] _connectionPool;
-//        private int _currentConnectionIndex = 0;
-//        private readonly object _lock = new object();
-
-//        /// <summary>
-//        /// Key的前缀
-//        /// </summary>
-//        private string PrefixHead = string.Empty;
-
-//        public RedisClient(IOptions<RedisConfig> options)
-//        {
-//            _redisconfig = options.Value;
-//            PrefixHead = _redisconfig.Prefix;
-
-//            // 创建4个连接的池
-//            _connectionPool = new Lazy<ConnectionMultiplexer>[4];
-
-//            for (int i = 0; i < _connectionPool.Length; i++)
-//            {
-//                var config = ConfigurationOptions.Parse(_redisconfig.MainConnection);
-//                config.ClientName = $"{_redisconfig.ClientName}_{i}"; // 为每个连接添加序号
-
-//                _connectionPool[i] = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(config));
-//            }
-//        }
-
-//        // 使用轮询方式获取连接
-//        private IDatabase GetDatabase()
-//        {
-//            lock (_lock)
-//            {
-//                // 轮询选择连接
-//                var connection = _connectionPool[_currentConnectionIndex];
-//                _currentConnectionIndex = (_currentConnectionIndex + 1) % _connectionPool.Length;
-
-//                return connection.Value.GetDatabase();
-//            }
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        private IDatabase _database { get { return GetDatabase(); } }
-
-
-//        private string setKey(string key)
-//        {
-//            return PrefixHead + key;
-//        }
-
-
-
-//        #region 同步方法...
-
-//        /// <summary>
-//        /// 添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public bool Set(string key, string value, TimeSpan? expiry = null)
-//        {
-//            return _database.StringSet(setKey(key), value, expiry);
-//        }
-
-//        /// <summary>
-//        /// 设置值
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="val"></param>
-//        /// <param name="second"></param>
-//        /// <returns></returns>
-//        public bool SetValue(string key, string val, int second)
-//        {
-//            return _database.StringSet(setKey(key), val, TimeSpan.FromSeconds(second));
-//        }
-
-//        /// <summary>
-//        /// 添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public bool Set(string key, string value, int seconds)
-//        {
-//            TimeSpan expiry = TimeSpan.FromSeconds(seconds);
-//            return _database.StringSet(setKey(key), value, expiry);
-//        }
-
-//        /// <summary>
-//        /// 添加一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <typeparam name="T">对象的类型。</typeparam>
-//        /// <param name="value">值。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public bool SetObject<T>(string key, T value, TimeSpan? expiry = null)
-//        {
-//            var data = JsonConvert.SerializeObject(value);
-//            return _database.StringSet(setKey(key), data, expiry);
-//        }
-
-//        /// <summary>
-//        /// 添加一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <typeparam name="T">对象的类型。</typeparam>
-//        /// <param name="value">值。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public bool SetObject<T>(string key, T value, int seconds)
-//        {
-//            TimeSpan expiry = TimeSpan.FromSeconds(seconds);
-//            var data = JsonConvert.SerializeObject(value);
-//            return _database.StringSet(setKey(key), data, expiry);
-//        }
-
-//        /// <summary>
-//        /// 获取一个对象。
-//        /// </summary>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        public T GetObject<T>(string key)
-//        {
-//            string json = _database.StringGet(setKey(key));
-//            if (string.IsNullOrWhiteSpace(json))
-//            {
-//                return default(T);
-//            }
-//            T entity = JsonConvert.DeserializeObject<T>(json);
-//            return entity;
-//        }
-
-//        /// <summary>
-//        /// 获取一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        public string Get(string key)
-//        {
-//            return _database.StringGet(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public string GetStringValue(string key)
-//        {
-//            return _database.StringGet(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 删除一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public bool Delete(string key)
-//        {
-//            return _database.KeyDelete(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 返回键是否存在。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <returns>返回键是否存在。</returns>
-//        public bool Exists(string key)
-//        {
-//            return _database.KeyExists(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public async Task<bool> ExistsAsync(string key)
-//        {
-//            return await _database.KeyExistsAsync(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public bool SetExpire(string key, TimeSpan? expiry)
-//        {
-//            return _database.KeyExpire(setKey(key), expiry);
-//        }
-
-//        /// <summary>
-//        /// 设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public bool SetExpire(string key, int seconds)
-//        {
-
-//            TimeSpan expiry = TimeSpan.FromSeconds(seconds);
-//            return _database.KeyExpire(setKey(key), expiry);
-//        }
-
-//        #endregion
-
-//        #region 异步方法...
-
-//        /// <summary>
-//        /// 异步添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public async Task<bool> SetAsync(string key, string value, TimeSpan? expiry = null)
-//        {
-//            return await _database.StringSetAsync(setKey(key), value, expiry);
-//        }
-
-//        /// <summary>
-//        /// 异步添加一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="value">值。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public async Task<bool> SetAsync(string key, string value, int seconds)
-//        {
-//            TimeSpan expiry = TimeSpan.FromSeconds(seconds);
-//            return await _database.StringSetAsync(setKey(key), value, expiry);
-//        }
-
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <typeparam name="T"></typeparam>
-//        /// <param name="key"></param>
-//        /// <param name="value"></param>
-//        /// <param name="second"></param>
-//        /// <returns></returns>
-//        public async Task<bool> SetObjectAsync<T>(string key, T value, int second)
-//        {
-//            var data = JsonConvert.SerializeObject(value);
-//            return await _database.StringSetAsync(setKey(key), data, TimeSpan.FromSeconds(second));
-//        }
-
-//        /// <summary>
-//        /// 异步获取一个对象。
-//        /// </summary>
-//        /// <typeparam name="T">对象的类型。</typeparam>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        public async Task<T> GetObjectAsync<T>(string key)
-//        {
-//            string json = await _database.StringGetAsync(setKey(key));
-//            if (string.IsNullOrWhiteSpace(json))
-//            {
-//                return default(T);
-//            }
-//            T entity = JsonConvert.DeserializeObject<T>(json);
-//            return entity;
-//        }
-
-//        /// <summary>
-//        /// 异步获取一个字符串对象。
-//        /// </summary>
-//        /// <param name="key">值。</param>
-//        /// <returns>返回对象的值。</returns>
-//        public async Task<string> GetAsync(string key)
-//        {
-//            return await _database.StringGetAsync(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 异步删除一个对象。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public async Task<bool> DeleteAsync(string key)
-//        {
-//            return await _database.KeyDeleteAsync(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 异步设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public async Task<bool> SetExpireAsync(string key, int seconds)
-//        {
-//            TimeSpan expiry = TimeSpan.FromSeconds(seconds);
-//            return await _database.KeyExpireAsync(setKey(key), expiry);
-//        }
-
-//        /// <summary>
-//        /// 异步设置一个键的过期时间。
-//        /// </summary>
-//        /// <param name="key">键。</param>
-//        /// <param name="expiry">过期时间(时间间隔)。</param>
-//        /// <returns>返回是否执行成功。</returns>
-//        public async Task<bool> SetExpireAsync(string key, TimeSpan? expiry)
-//        {
-//            return await _database.KeyExpireAsync(setKey(key), expiry);
-//        }
-
-//        #endregion
-
-//        #region 分布式锁...
-
-//        /// <summary>
-//        /// 分布式锁 Token。
-//        /// </summary>
-//        private static readonly RedisValue LockToken = Environment.MachineName;
-
-//        /// <summary>
-//        /// 是redis缓存
-//        /// </summary>
-//        public bool IsRedis => true;
-
-//        /// <summary>
-//        /// 获取锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>是否已锁。</returns>
-//        public bool Lock(string key, int seconds)
-//        {
-//            return _database.LockTake(setKey(key), LockToken, TimeSpan.FromSeconds(seconds));
-//        }
-
-//        /// <summary>
-//        /// 释放锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <returns>是否成功。</returns>
-//        public bool UnLock(string key)
-//        {
-//            return _database.LockRelease(setKey(key), LockToken);
-//        }
-
-//        /// <summary>
-//        /// 异步获取锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <param name="seconds">过期时间(秒)。</param>
-//        /// <returns>是否成功。</returns>
-//        public async Task<bool> LockAsync(string key, int seconds)
-//        {
-//            return await _database.LockTakeAsync(setKey(key), LockToken, TimeSpan.FromSeconds(seconds));
-//        }
-
-//        /// <summary>
-//        /// 异步释放锁。
-//        /// </summary>
-//        /// <param name="key">锁名称。</param>
-//        /// <returns>是否成功。</returns>
-//        public async Task<bool> UnLockAsync(string key)
-//        {
-//            return await _database.LockReleaseAsync(setKey(key), LockToken);
-//        }
-
-//        #endregion
-
-//        #region Hash
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public List<HashKeyValue> HashGetAll(string key)
-//        {
-
-//            //return  _database.HashGetAll(setKey(key));
-
-//            var hentry = _database.HashGetAll(setKey(key));
-//            var result = new List<HashKeyValue>();
-//            foreach (var h in hentry)
-//            {
-//                result.Add(new HashKeyValue()
-//                {
-//                    Key = h.Name,
-//                    Value = h.Value
-//                });
-//            }
-//            return result;
-
-//        }
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public async Task<List<HashKeyValue>> HashGetAllAsync(string key)
-//        {
-//            var hentry = await _database.HashGetAllAsync(setKey(key));
-//            var result = new List<HashKeyValue>();
-//            foreach (var h in hentry)
-//            {
-//                result.Add(new HashKeyValue()
-//                {
-//                    Key = h.Name,
-//                    Value = h.Value
-//                });
-//            }
-//            return result;
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public async Task<HashEntry[]> HashReadAllAsync(string key)
-//        {
-//            return await _database.HashGetAllAsync(setKey(key));
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="vals"></param>
-//        public void HashSet(string key, HashEntry[] vals)
-//        {
-//            _database.HashSet(setKey(key), vals);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="vals"></param>
-//        public async Task HashSetAsync(string key, HashEntry[] vals)
-//        {
-//            await _database.HashSetAsync(setKey(key), vals);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="field"></param>
-//        /// <param name="num"></param>
-//        /// <returns></returns>
-//        public async Task HashIncrementAsync(string key, RedisValue field, int num = 1)
-//        {
-//            await _database.HashIncrementAsync(setKey(key), field, num);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="field"></param>
-//        /// <param name="num"></param>
-//        /// <returns></returns>
-//        public async Task HashDecrementAsync(string key, RedisValue field, int num = 1)
-//        {
-//            await _database.HashDecrementAsync(setKey(key), field, num);
-//        }
-
-//        public string HashGet(string key, string sunkey)
-//        {
-//            return _database.HashGet(setKey(key), sunkey);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="sunkey"></param>
-//        /// <returns></returns>
-//        public async Task<string> HashGetAsync(string key, string sunkey)
-//        {
-//            return await _database.HashGetAsync(setKey(key), sunkey);
-//        }
-
-//        #endregion
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="start"></param>
-//        /// <param name="end"></param>
-//        /// <param name="bit"></param>   
-//        /// <returns></returns>
-//        public long StringBitPosition(string key, int start, int end, bool bit)
-//        {
-//            return _database.StringBitPosition(setKey(key), bit, start, end);
-//        }
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="start"></param>
-//        /// <param name="end"></param>
-//        /// <param name="bit"></param>
-//        /// <returns></returns>
-//        public async Task<long> StringBitPositionAsync(string key, int start, int end, bool bit)
-//        {
-//            return await _database.StringBitPositionAsync(setKey(key), bit, start, end);
-//        }
-
-
-//        /// <summary>
-//        /// 获取个数?
-//        /// </summary>
-//        /// <param name="deskey"></param>
-//        /// <param name="key"></param>
-//        /// <returns></returns>
-//        public long StringBitOperation(string deskey, string key)
-//        {
-//            return _database.StringBitOperation(Bitwise.And, setKey(deskey), setKey(key));
-//        }
-
-
-//        /// <summary>
-//        /// 设置值
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="offset"></param>
-//        /// <param name="bit"></param>
-//        /// <returns></returns>
-//        public bool StringSetBit(string key, long offset, bool bit)
-//        {
-//            return _database.StringSetBit(setKey(key), offset, bit);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="start"></param>
-//        /// <param name="end"></param>
-//        /// <returns></returns>
-//        public long StringBitCount(string key, long start = 0, long end = -1)
-//        {
-//            return _database.StringBitCount(setKey(key), start, end);
-//        }
-
-//        /// <summary>
-//        /// 
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="start"></param>
-//        /// <param name="end"></param>
-//        /// <returns></returns>
-//        public async Task<long> StringBitCountAsync(string key, long start = 0, long end = -1)
-//        {
-//            return await _database.StringBitCountAsync(setKey(key), start, end);
-//        }
-
-//        /// <summary>
-//        /// 获取第一次出现的位置
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="offset"></param>
-//        /// <param name="bit"></param>
-//        /// <returns></returns>
-//        public async Task<bool> StringSetBitAsync(string key, long offset, bool bit)
-//        {
-//            return await _database.StringSetBitAsync(setKey(key), offset, bit);
-//        }
-
-//        public void HashSet(string key, List<HashKeyValue> vals)
-//        {
-//            var list = new List<HashEntry>();
-//            foreach (var item in vals)
-//            {
-//                list.Add(new HashEntry(item.Key, item.Value) { });
-//            }
-
-//            _database.HashSet(setKey(key), list.ToArray());
-//        }
-
-//        public async Task HashSetAsync(string key, List<HashKeyValue> vals)
-//        {
-//            var list = new List<HashEntry>();
-//            foreach (var item in vals)
-//            {
-//                list.Add(new HashEntry(item.Key, item.Value) { });
-//            }
-
-//            await _database.HashSetAsync(setKey(key), list.ToArray());
-//        }
-
-//        public bool SetValue(string key, string val)
-//        {
-//            return Set(key, val);
-//        }
-
-//        /// <summary>
-//        /// 写入有序排序
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="field"></param>
-//        /// <param name="score"></param>
-//        public async Task SortedSetAddAsync(string key, RedisValue field, int score)
-//        {
-//            await _database.SortedSetAddAsync(setKey(key), field, score);
-//        }
-
-//        /// <summary>
-//        /// 批量写入有序排序
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="fields"></param>
-//        public async Task SortedSetAddAsync(string key, SortedSetEntry[] fields)
-//        {
-//            await _database.SortedSetAddAsync(setKey(key), fields);
-//        }
-
-
-//        /// <summary>
-//        /// 按照分数升序,获取第一个分数 >= 指定分数的数据并删除
-//        /// </summary>
-//        /// <param name="key"></param>
-//        /// <param name="minScore">最低分数</param>
-//        /// <returns></returns>
-//        public async Task<SortedSetEntry?> SortedSetStartPopScoreAsync(string key, int minScore)
-//        {
-//            var luaScript = @"
-//                    local members = redis.call('ZRANGEBYSCORE', KEYS[1], ARGV[1], '+inf', 'WITHSCORES', 'LIMIT', 0, 1)
-//                    if #members == 0 then
-//                        return nil
-//                    end
-//                    redis.call('ZREM', KEYS[1], members[1])
-//                    return {members[1], members[2]}
-//                ";
-
-//            var result =await _database.ScriptEvaluateAsync(luaScript,
-//                new RedisKey[] { setKey(key) },
-//                new RedisValue[] { minScore });
-
-//            if (result.IsNull)
-//            {
-//                return null;
-//            }
-
-//            var resultArray = (RedisResult[])result;
-//            if (resultArray.Length >= 2)
-//            {
-//                string element = (string)resultArray[0];
-//                double redisScore = (double)resultArray[1];
-
-//                // 将double转换为int(根据您的需求)
-//                int scoreValue = (int)redisScore;
-
-//                return new SortedSetEntry(element, scoreValue);
-//            }
-
-//            return null;
-//        }
-
-//        /// <summary>
-//        /// 返回分数符合的第一个元素,返回并删除这个元素
-//        /// </summary>
-//        public async Task<SortedSetEntry?> SortedSetPopExactScoreAsync(string key, int targetScore)
-//        {
-//            var luaScript = @"
-//                    local members = redis.call('ZRANGEBYSCORE', KEYS[1], ARGV[1], ARGV[1], 'WITHSCORES', 'LIMIT', 0, 1)
-//                    if #members == 0 then
-//                        return nil
-//                    end
-//                    redis.call('ZREM', KEYS[1], members[1])
-//                    return {members[1], members[2]}
-//                ";
-
-//            var result = await _database.ScriptEvaluateAsync(luaScript,
-//                new RedisKey[] { setKey(key) },
-//                new RedisValue[] { targetScore });
-
-//            if (result.IsNull)
-//            {
-//                return null;
-//            }
-
-//            var resultArray = (RedisResult[])result;
-//            if (resultArray.Length >= 2)
-//            {
-//                string element = (string)resultArray[0];
-//                double redisScore = (double)resultArray[1];
-//                int scoreValue = (int)redisScore;
-
-//                return new SortedSetEntry(element, scoreValue);
-//            }
-
-//            return null;
-//        }
-
-
-//    }
-
-
-
-//}
abp_example/ExampleForm.Handler/redismodel/RedisConfig.cs
diff --git a/abp_example/ExampleForm.Handler/redismodel/RedisConfig.cs b/abp_example/ExampleForm.Handler/redismodel/RedisConfig.cs
deleted file mode 100644
index ddc0ce5..0000000
--- a/abp_example/ExampleForm.Handler/redismodel/RedisConfig.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//namespace ExampleForm.Handler
-//{
-//    public class RedisConfig
-//    {
-//        public bool Enable { get; set; } = false;
-
-//        /// <summary>
-//        /// 主链接
-//        /// </summary>
-//        public string MainConnection { get; set; } = "127.0.0.1:6379";
-
-//        /// <summary>
-//        /// 前缀 xxx:
-//        /// </summary>
-//        public string Prefix { get; set; } = "pt:";
-
-//        /// <summary>
-//        /// 链接名称
-//        /// </summary>
-//        public string ClientName { get; set; } = "paste";
-
-//    }
-//}
abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.Contracts.xml
diff --git a/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.Contracts.xml b/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.Contracts.xml
index 7aa050b..b680482 100644
--- a/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.Contracts.xml
+++ b/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.Contracts.xml
@@ -29,6 +29,11 @@
             用户 这里是测试,表示输入一个用户UserId信息
             </summary>
         </member>
+        <member name="P:ExampleForm.Application.Contracts.eventmodels.EventDemoModel.MutexKey">
+            <summary>
+            
+            </summary>
+        </member>
         <member name="T:ExampleForm.Application.Contracts.QuickHandlerModelDto">
             <summary>
             
abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.xml
diff --git a/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.xml b/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.xml
index 98522fc..664bbab 100644
--- a/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.xml
+++ b/abp_example/ExampleForm.HttpApi.Host/ExampleForm.Application.xml
@@ -578,20 +578,6 @@
             <param name="id"></param>
             <returns></returns>
         </member>
-        <member name="M:ExampleForm.usermodels.RoleInfoAppService.Backup(System.Boolean)">
-            <summary>
-            备份数据
-            </summary>
-            <param name="save"></param>
-            <returns></returns>
-            <exception cref="T:PasteApeart.Application.Contracts.PasteCodeException"></exception>
-        </member>
-        <member name="M:ExampleForm.usermodels.RoleInfoAppService.Load">
-            <summary>
-            载入数据
-            </summary>
-            <returns></returns>
-        </member>
         <member name="T:ExampleForm.usermodels.SingleAppService">
              <summary>
             用于动态渲染 什么时候最合适? 比如多格式的图标模式
example/ExampleApeart.Handler/eventmodels/AbsEventModelExtensions.cs
diff --git a/example/ExampleApeart.Handler/eventmodels/AbsEventModelExtensions.cs b/example/ExampleApeart.Handler/eventmodels/AbsEventModelExtensions.cs
index 12f461a..fc2214d 100644
--- a/example/ExampleApeart.Handler/eventmodels/AbsEventModelExtensions.cs
+++ b/example/ExampleApeart.Handler/eventmodels/AbsEventModelExtensions.cs
@@ -1,153 +1,153 @@
-using PasteApeart;
-using PasteApeart.Application.Contracts;
-using PasteApeart.Handler;
-using ExampleApeart.Application.Contracts;
-using ExampleApeart.Handler;
-using Serilog;
+//using PasteApeart;
+//using PasteApeart.Application.Contracts;
+//using PasteApeart.Handler;
+//using ExampleApeart.Application.Contracts;
+//using ExampleApeart.Handler;
+//using Serilog;
 
-namespace ExampleApeart
-{
-    /// <summary>
-    /// 事件模型的扩展
-    /// </summary>
-    public static class AbsEventModelExtensions
-    {
+//namespace ExampleApeart
+//{
+//    /// <summary>
+//    /// 事件模型的扩展
+//    /// </summary>
+//    public static class AbsEventModelExtensions
+//    {
 
-        ///// <summary>
-        ///// 启动 任务排重标记,修改MutexVal
-        ///// </summary>
-        ///// <param name="info"></param>
-        ///// <param name="appCache"></param>
-        ///// <param name="id"></param>
-        ///// <param name="expireSecond"></param>
-        ///// <returns></returns>
-        //public static async Task ToStartTaskMutexAsync(this AbsEventModel info, IAppCache appCache, object id = null, int expireSecond = 300)
-        //{
-        //    if (string.IsNullOrEmpty(info.MutexKey))
-        //    {
-        //        info.MutexKey = $"mutex:{info.GetType().Name}:{(id?.ToString() ?? "0")}";
-        //    }
-        //    else
-        //    {
-        //        info.MutexKey = info.MutexKey.Replace(":id", $":{(id?.ToString() ?? "0")}");
-        //    }
-        //    info.MutexVal = Guid.NewGuid().ToString("N");
-        //    await appCache.SetAsync(info.MutexKey, info.MutexVal, expireSecond);
-        //}
+//        ///// <summary>
+//        ///// 启动 任务排重标记,修改MutexVal
+//        ///// </summary>
+//        ///// <param name="info"></param>
+//        ///// <param name="appCache"></param>
+//        ///// <param name="id"></param>
+//        ///// <param name="expireSecond"></param>
+//        ///// <returns></returns>
+//        //public static async Task ToStartTaskMutexAsync(this AbsEventModel info, IAppCache appCache, object id = null, int expireSecond = 300)
+//        //{
+//        //    if (string.IsNullOrEmpty(info.MutexKey))
+//        //    {
+//        //        info.MutexKey = $"mutex:{info.GetType().Name}:{(id?.ToString() ?? "0")}";
+//        //    }
+//        //    else
+//        //    {
+//        //        info.MutexKey = info.MutexKey.Replace(":id", $":{(id?.ToString() ?? "0")}");
+//        //    }
+//        //    info.MutexVal = Guid.NewGuid().ToString("N");
+//        //    await appCache.SetAsync(info.MutexKey, info.MutexVal, expireSecond);
+//        //}
 
-        ///// <summary>
-        ///// 判断是否有同样的任务,如果有则返回false表示不能启动
-        ///// </summary>
-        ///// <param name="info"></param>
-        ///// <param name="appCache"></param>
-        ///// <param name="id"></param>
-        ///// <param name="expireSecond"></param>
-        ///// <returns>是否可以启动 false表示正在执行中</returns>
-        //public static async Task<bool> ToAutoStartTaskMutexAsync(this AbsEventModel info, IAppCache appCache, object id = null, int expireSecond = 300)
-        //{
-        //    if (string.IsNullOrEmpty(info.MutexKey))
-        //    {
-        //        info.MutexKey = $"mutex:{info.GetType().Name}:{(id?.ToString() ?? "0")}";
-        //    }
-        //    else
-        //    {
-        //        info.MutexKey = info.MutexKey.Replace(":id", $":{(id?.ToString() ?? "0")}");
-        //    }
-        //    if (!await appCache.ExistsAsync(info.MutexKey))
-        //    {
-        //        info.MutexVal = Guid.NewGuid().ToString("N");
-        //        await appCache.SetAsync(info.MutexKey, info.MutexVal, expireSecond);
-        //        return true;
-        //    }
-        //    else
-        //    {
-        //        return false;
-        //    }
-        //}
+//        ///// <summary>
+//        ///// 判断是否有同样的任务,如果有则返回false表示不能启动
+//        ///// </summary>
+//        ///// <param name="info"></param>
+//        ///// <param name="appCache"></param>
+//        ///// <param name="id"></param>
+//        ///// <param name="expireSecond"></param>
+//        ///// <returns>是否可以启动 false表示正在执行中</returns>
+//        //public static async Task<bool> ToAutoStartTaskMutexAsync(this AbsEventModel info, IAppCache appCache, object id = null, int expireSecond = 300)
+//        //{
+//        //    if (string.IsNullOrEmpty(info.MutexKey))
+//        //    {
+//        //        info.MutexKey = $"mutex:{info.GetType().Name}:{(id?.ToString() ?? "0")}";
+//        //    }
+//        //    else
+//        //    {
+//        //        info.MutexKey = info.MutexKey.Replace(":id", $":{(id?.ToString() ?? "0")}");
+//        //    }
+//        //    if (!await appCache.ExistsAsync(info.MutexKey))
+//        //    {
+//        //        info.MutexVal = Guid.NewGuid().ToString("N");
+//        //        await appCache.SetAsync(info.MutexKey, info.MutexVal, expireSecond);
+//        //        return true;
+//        //    }
+//        //    else
+//        //    {
+//        //        return false;
+//        //    }
+//        //}
 
-        ///// <summary>
-        ///// 检查任务是否被重置 返回true表示可以执行 返回false表示不能执行
-        ///// </summary>
-        ///// <param name="info"></param>
-        ///// <param name="appCache"></param>
-        ///// <returns>true:可以执行,匹配 false:任务被重置,不能执行</returns>
-        //public static async Task<bool> ToMatchTaskMutexAsync(this AbsEventModel info, IAppCache appCache)
-        //{
-        //    if (!string.IsNullOrEmpty(info.MutexKey))
-        //    {
-        //        var readVal = await appCache.GetAsync(info.MutexKey);
-        //        if (string.IsNullOrEmpty(readVal))
-        //        {
-        //            return true;
-        //        }
-        //        if (readVal != info.MutexVal)
-        //        {
-        //            Log.Logger.Warning($"任务互斥 Model:{info.GetType().Name} Key:{info.MutexKey} Val:{info.MutexVal} != Read:{readVal}");
-        //            return false;
-        //        }
-        //    }
-        //    return true;
-        //}
+//        ///// <summary>
+//        ///// 检查任务是否被重置 返回true表示可以执行 返回false表示不能执行
+//        ///// </summary>
+//        ///// <param name="info"></param>
+//        ///// <param name="appCache"></param>
+//        ///// <returns>true:可以执行,匹配 false:任务被重置,不能执行</returns>
+//        //public static async Task<bool> ToMatchTaskMutexAsync(this AbsEventModel info, IAppCache appCache)
+//        //{
+//        //    if (!string.IsNullOrEmpty(info.MutexKey))
+//        //    {
+//        //        var readVal = await appCache.GetAsync(info.MutexKey);
+//        //        if (string.IsNullOrEmpty(readVal))
+//        //        {
+//        //            return true;
+//        //        }
+//        //        if (readVal != info.MutexVal)
+//        //        {
+//        //            Log.Logger.Warning($"任务互斥 Model:{info.GetType().Name} Key:{info.MutexKey} Val:{info.MutexVal} != Read:{readVal}");
+//        //            return false;
+//        //        }
+//        //    }
+//        //    return true;
+//        //}
 
-        ///// <summary>
-        ///// 删除标记
-        ///// </summary>
-        ///// <param name="info"></param>
-        ///// <param name="appCache"></param>
-        ///// <returns></returns>
-        //public static async Task ToCleanTaskMutexAsync(this AbsEventModel info, IAppCache appCache)
-        //{
-        //    if (!string.IsNullOrEmpty(info.MutexKey))
-        //    {
-        //        await appCache.DeleteAsync(info.MutexKey);
-        //    }
-        //}
+//        ///// <summary>
+//        ///// 删除标记
+//        ///// </summary>
+//        ///// <param name="info"></param>
+//        ///// <param name="appCache"></param>
+//        ///// <returns></returns>
+//        //public static async Task ToCleanTaskMutexAsync(this AbsEventModel info, IAppCache appCache)
+//        //{
+//        //    if (!string.IsNullOrEmpty(info.MutexKey))
+//        //    {
+//        //        await appCache.DeleteAsync(info.MutexKey);
+//        //    }
+//        //}
 
-        ///// <summary>
-        ///// 任务是否标记 注意要使用这个的时候,任务结束的时候需要调用 ToCleanTaskMutexAsync
-        ///// 需要之前有对MutexKey进行赋值 也就是ToAutoStartTaskMutexAsync/ToStartTaskMutexAsync
-        ///// </summary>
-        ///// <param name="info"></param>
-        ///// <param name="appCache"></param>
-        ///// <returns>true 任务在进行 false:没有任务 或者任务已经结束</returns>
-        //public static async Task<bool> ToExistsTaskMutexAsync(this AbsEventModel info, IAppCache appCache)
-        //{
-        //    if (!string.IsNullOrEmpty(info.MutexKey))
-        //    {
-        //        return await appCache.ExistsAsync(info.MutexKey);
-        //    }
-        //    return false;
-        //}
+//        ///// <summary>
+//        ///// 任务是否标记 注意要使用这个的时候,任务结束的时候需要调用 ToCleanTaskMutexAsync
+//        ///// 需要之前有对MutexKey进行赋值 也就是ToAutoStartTaskMutexAsync/ToStartTaskMutexAsync
+//        ///// </summary>
+//        ///// <param name="info"></param>
+//        ///// <param name="appCache"></param>
+//        ///// <returns>true 任务在进行 false:没有任务 或者任务已经结束</returns>
+//        //public static async Task<bool> ToExistsTaskMutexAsync(this AbsEventModel info, IAppCache appCache)
+//        //{
+//        //    if (!string.IsNullOrEmpty(info.MutexKey))
+//        //    {
+//        //        return await appCache.ExistsAsync(info.MutexKey);
+//        //    }
+//        //    return false;
+//        //}
 
-        ///// <summary>
-        ///// 设置下一次执行时间 并压入到队列
-        ///// </summary>
-        ///// <param name="input"></param>
-        ///// <returns></returns>
-        //public static async Task<bool> ToAutoExpireAndSendAsync(this AbsEventModel input, ChannelHelper _channelHelper)
-        //{
-        //    input.RetryTime++;
-        //    if (input.MaxRetryTime <= 0)
-        //    {
-        //        return false;
-        //    }
-        //    if (input.RetryTime > input.MaxRetryTime)
-        //    {
-        //        return false;
-        //    }
-        //    //计算下一次时间 默认基于5秒的倍率延迟
-        //    var baseRate = 5;
-        //    if (!string.IsNullOrEmpty(input.RetryModel))
-        //    {
-        //        //基于业务自定义模型
-        //    }
-        //    input.ExpireSecond = baseRate * input.RetryTime;
-        //    //可以设定最大时间等
-        //    await _channelHelper.WriteAutoQueueAsync(input);
-        //    return true;
-        //}
+//        ///// <summary>
+//        ///// 设置下一次执行时间 并压入到队列
+//        ///// </summary>
+//        ///// <param name="input"></param>
+//        ///// <returns></returns>
+//        //public static async Task<bool> ToAutoExpireAndSendAsync(this AbsEventModel input, ChannelHelper _channelHelper)
+//        //{
+//        //    input.RetryTime++;
+//        //    if (input.MaxRetryTime <= 0)
+//        //    {
+//        //        return false;
+//        //    }
+//        //    if (input.RetryTime > input.MaxRetryTime)
+//        //    {
+//        //        return false;
+//        //    }
+//        //    //计算下一次时间 默认基于5秒的倍率延迟
+//        //    var baseRate = 5;
+//        //    if (!string.IsNullOrEmpty(input.RetryModel))
+//        //    {
+//        //        //基于业务自定义模型
+//        //    }
+//        //    input.ExpireSecond = baseRate * input.RetryTime;
+//        //    //可以设定最大时间等
+//        //    await _channelHelper.WriteAutoQueueAsync(input);
+//        //    return true;
+//        //}
 
 
 
-    }
-}
+//    }
+//}
example/ExampleApeart.Test/HalfHideTestHelper.cs
diff --git a/example/ExampleApeart.Test/HalfHideTestHelper.cs b/example/ExampleApeart.Test/HalfHideTestHelper.cs
index 2c6957e..7090b94 100644
--- a/example/ExampleApeart.Test/HalfHideTestHelper.cs
+++ b/example/ExampleApeart.Test/HalfHideTestHelper.cs
@@ -102,6 +102,11 @@ namespace ExampleApeart.Test
         /// <summary>
         /// 
         /// </summary>
+        public string FullName { get; set; } = "vuijbjioklmnjkop";
+
+        /// <summary>
+        /// 
+        /// </summary>
         public HalfExpendModel Model { get; set; } = new HalfExpendModel();
     }
 
@@ -121,6 +126,11 @@ namespace ExampleApeart.Test
         /// </summary>
         public int Width { get; set; } = 1920;
 
+        /// <summary>
+        /// 
+        /// </summary>
+        public string FullName { get; set; } = "vuijbjioklmnjkop";
+
     }
 
 
@@ -138,7 +148,7 @@ namespace ExampleApeart.Test
         /// <summary>
         /// 
         /// </summary>
-        public string Desc { get; set; }
+        public string Desc { get; set; } = "2345678987654356";
     }
 
     /// <summary>
@@ -167,6 +177,11 @@ namespace ExampleApeart.Test
         /// <summary>
         /// 
         /// </summary>
+        public string FullName { get; set; } = "vuijbjioklmnjkop";
+
+        /// <summary>
+        /// 
+        /// </summary>
         public HalfExpendModel Model { get; set; } = new HalfExpendModel();
     }
 
@@ -184,6 +199,6 @@ namespace ExampleApeart.Test
         /// <summary>
         /// 
         /// </summary>
-        public string Desc { get; set; }
+        public string Desc { get; set; } = "23456789098323456";
     }
 }
framework/Directory.Build.props
diff --git a/framework/Directory.Build.props b/framework/Directory.Build.props
index 856c9c3..71ff48f 100644
--- a/framework/Directory.Build.props
+++ b/framework/Directory.Build.props
@@ -1,7 +1,7 @@
 <Project>
   <PropertyGroup>
-    <Version>26.10.11</Version>
-    <FileVersion>26.10.11</FileVersion>
-    <AssemblyVersion>26.10.11</AssemblyVersion>
+    <Version>26.10.12</Version>
+    <FileVersion>26.10.12</FileVersion>
+    <AssemblyVersion>26.10.12</AssemblyVersion>
   </PropertyGroup>
 </Project>
\ No newline at end of file
framework/PasteApeart.Helper/HalfHideHelper.cs
diff --git a/framework/PasteApeart.Helper/HalfHideHelper.cs b/framework/PasteApeart.Helper/HalfHideHelper.cs
index f9ff8dc..df4c687 100644
--- a/framework/PasteApeart.Helper/HalfHideHelper.cs
+++ b/framework/PasteApeart.Helper/HalfHideHelper.cs
@@ -55,7 +55,9 @@ namespace PasteApeart.Helper
                     foreach (var item in list)
                     {
                         if (item == null || !targetType.IsInstanceOfType(item))
+                        {
                             continue;
+                        }
                         MaskSingleObject(item, targetType, properties, createNew, classAttribute);
                     }
                     return data;
@@ -63,8 +65,9 @@ namespace PasteApeart.Helper
             }
 
             if (createNew)
+            {
                 return MaskNewSingleObject(data, targetType, properties, createNew, classAttribute);
-
+            }
             MaskSingleObject(data, targetType, properties, createNew, classAttribute);
             return data;
         }
@@ -90,8 +93,8 @@ namespace PasteApeart.Helper
                 var propAttr = property.GetCustomAttribute<PasteHalfHideAttribute>();
                 var value = property.GetValue(obj);
 
-                bool shouldMask = propAttr != null || classAttr != null;
-                if (!shouldMask) continue;
+                //bool shouldMask = propAttr != null || classAttr != null;
+                if (propAttr==null) continue;
 
                 // string
                 if (property.PropertyType == typeof(string))
@@ -153,7 +156,7 @@ namespace PasteApeart.Helper
                 var propAttr = property.GetCustomAttribute<PasteHalfHideAttribute>();
                 var value = property.GetValue(obj);
 
-                bool shouldMask = propAttr != null || classAttr != null;
+                bool shouldMask = propAttr != null;
 
                 // string
                 if (property.PropertyType == typeof(string))
@@ -226,6 +229,11 @@ namespace PasteApeart.Helper
             return result;
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="t"></param>
+        /// <returns></returns>
         private static Type GetEnumerableElementType(Type t)
         {
             if (t.IsArray) return t.GetElementType();
@@ -235,12 +243,26 @@ namespace PasteApeart.Helper
             return iface?.GetGenericArguments()[0];
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="attr"></param>
+        /// <returns></returns>
         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)
         {
             if (string.IsNullOrEmpty(value)) return value;
framework/PasteApeart.Helper/PasteApeartAttribute.cs
diff --git a/framework/PasteApeart.Helper/PasteApeartAttribute.cs b/framework/PasteApeart.Helper/PasteApeartAttribute.cs
index 4dac959..2e9caf6 100644
--- a/framework/PasteApeart.Helper/PasteApeartAttribute.cs
+++ b/framework/PasteApeart.Helper/PasteApeartAttribute.cs
@@ -1776,7 +1776,7 @@ namespace PasteApeart.Helper
         /// <summary>
         /// outer 链接外表显示和输入用
         /// </summary>
-        /// <param name="path"><![CDATA[外表名称,示例serviceInfo,也可以是路径(路径注意model=select表示选择模式),示例:./pasteform/index.html?path=xxxx&model=select&is_top=1,支持宏模式]]></param>
+        /// <param name="path"><![CDATA[外表名称,示例:serviceInfo,示例:userInfo&age=13示例:gradeInfo&user_id={{:=item.id}}示例:./pasteform/index.html?path=xxxx&model=select&is_top=1,支持宏模式]]></param>
         /// <param name="extendName">显示的时候的表达式,示例extendService,这个时候一般用于UpdateDto的时候,因为一个字段表示数据userId,一个字段表示数据extendUser</param>
         /// <param name="_keyColumn">回传的列的名称,示例id,多个支持用,隔开,第一个是主要的,后面的会寻找对应字段进行赋值</param>
         /// <param name="_showColumn">显示的列表的名称,示例name,新版本应该支持+拼接,如果中间的不是有效属性则原样输出</param>
manage/page/pasteform/index.html
diff --git a/manage/page/pasteform/index.html b/manage/page/pasteform/index.html
index 53ade3a..059a281 100644
--- a/manage/page/pasteform/index.html
+++ b/manage/page/pasteform/index.html
@@ -529,7 +529,7 @@
     <script type="text/javascript" src="../lib/layer/3.1.1/layer.js"></script>
     <script type="text/javascript" src="./lib/template.js"></script>
     <script type="text/javascript" src="./lib/My97DatePicker/4.8/WdatePicker.js"></script>
-    <script type="text/javascript" src="../lib/api.js?v=251002"></script>
+    <script type="text/javascript" src="../lib/api.js?v=261003"></script>
 
     <!-- <script type="text/javascript" src="../lib/page.min.js"></script> -->
 
manage/page/pasteform/view.html
diff --git a/manage/page/pasteform/view.html b/manage/page/pasteform/view.html
index 6e811d1..0028b91 100644
--- a/manage/page/pasteform/view.html
+++ b/manage/page/pasteform/view.html
@@ -358,7 +358,7 @@
 
     <!--/_footer /作为公共模版分离出去-->
     <!--请在下方写此页面业务相关的脚本-->
-    <script type="text/javascript" src="../lib/api.js"></script>
+    <script type="text/javascript" src="../lib/api.js?guid=261003"></script>
 
     <link rel="stylesheet" href="./lib/pickerdaterange/dateRange.css">
     <script type="text/javascript" src="./lib/template.js"></script>
​ ​