From e49c42ad641fa7ddaa4250ffd408666b087d1d48 Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期五, 29 八月 2025 13:25:26 +0800
Subject: [PATCH] feat:开发

---
 FlexJobApi.Core/Utils/DbUtils/DbUtils.cs |  269 ++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 170 insertions(+), 99 deletions(-)

diff --git a/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs b/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs
index 03c260d..e8e12e3 100644
--- a/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs
+++ b/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs
@@ -148,12 +148,39 @@
             var q = rep.AsQueryable().AsNoTracking();
             if (query != null) q = query(q);
             else q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime);
-            q = q.OrderBy(page.OrderInput);
+            if (page.OrderInput.IsNotNull())
+                q = q.CustomOrderBy(page.OrderInput);
             var s = selector == null
                 ? q.ProjectToType<TItem>()
                 : q.Select(selector);
             var pagedList = await s.ToPagedListAsync(page.Page, page.Rows, cancellationToken);
             var result = new PagedListQueryResult<TItem>();
+            result.PageModel = page.Adapt<PagedListQueryResultPageModel>();
+            result.PageModel.TotalCount = pagedList.TotalCount;
+            result.PageModel.TotalPage = pagedList.TotalPages;
+            result.Data = pagedList.Items.ToList();
+            return result;
+        }
+        /// <summary>
+        /// 鏌ヨ鍒嗛〉鍒楄〃鏁版嵁
+        /// </summary>
+        /// <typeparam name="TResult"></typeparam>
+        /// <typeparam name="TItem"></typeparam>
+        /// <param name="page"></param>
+        /// <param name="q"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public static async Task<TResult> GetPagedListAsync<TResult, TItem>(
+            this PagedListQueryPageModel page,
+            IQueryable<TItem> q,
+            CancellationToken cancellationToken = default)
+            where TItem : class, new()
+            where TResult : PagedListQueryResult<TItem>, new()
+        {
+            if (page.OrderInput.IsNotNull())
+                q = q.CustomOrderBy(page.OrderInput);
+            var pagedList = await q.ToPagedListAsync(page.Page, page.Rows, cancellationToken);
+            var result = new TResult();
             result.PageModel = page.Adapt<PagedListQueryResultPageModel>();
             result.PageModel.TotalCount = pagedList.TotalCount;
             result.PageModel.TotalPage = pagedList.TotalPages;
@@ -169,82 +196,86 @@
         /// <param name="q"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public static async Task<PagedListQueryResult<TItem>> GetPagedListAsync<TItem>(
+        public static Task<PagedListQueryResult<TItem>> GetPagedListAsync<TItem>(
             this PagedListQueryPageModel page,
             IQueryable<TItem> q,
             CancellationToken cancellationToken = default)
             where TItem : class, new()
         {
-            q = q.OrderBy(page.OrderInput);
-            var pagedList = await q.ToPagedListAsync(page.Page, page.Rows, cancellationToken);
-            var result = new PagedListQueryResult<TItem>();
-            result.PageModel = page.Adapt<PagedListQueryResultPageModel>();
-            result.PageModel.TotalCount = pagedList.TotalCount;
-            result.PageModel.TotalPage = pagedList.TotalPages;
-            result.Data = pagedList.Items.ToList();
-            return result;
+            return GetPagedListAsync<PagedListQueryResult<TItem>, TItem>(page, q, cancellationToken);
         }
 
-        /// <summary>
-        /// 鎺掑簭
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="q"></param>
-        /// <param name="orders"></param>
-        /// <returns></returns>
-        public static IQueryable<T> OrderBy<T>(
-            this IQueryable<T> q,
-            List<PagedListQueryPageModelOrderInput> orders)
+        public static IOrderedQueryable<T> CustomOrderBy<T>(this IQueryable<T> q, List<PagedListQueryPageModelOrderInput> orders)
         {
-            if (orders.IsNull()) return q;
-
-            var entityType = typeof(T);
-            int index = 0;
-
-            var props = entityType.GetProperties();
-            foreach (var order in orders)
+            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
+            PagedListQueryPageModelOrderInput orderInput = orders[0];
+            IOrderedQueryable<T> orderedQueryable = (orderInput.Order == EnumPagedListOrder.Asc)
+                ? OrderBy(q, orderInput.Property, parameter)
+                : OrderByDescending(q, orderInput.Property, parameter);
+            for (int i = 1; i < orders.Count; i++)
             {
-                if (string.IsNullOrEmpty(order.Property)) continue;
-
-                // 鑾峰彇鎺掑簭瀛楁鐨勫睘鎬т俊鎭�
-                var propertyInfo = props.FirstOrDefault(it => it.Name.Equals(order.Property, StringComparison.OrdinalIgnoreCase));
-                if (propertyInfo == null) throw Oops.Oh(EnumErrorCodeType.s404, $"璇ユ帓搴忓瓧娈祘order.Property}");
-
-                // 鍒涘缓琛ㄨ揪寮忔爲
-                var parameter = Expression.Parameter(entityType, "x");
-                var propertyAccess = Expression.Property(parameter, propertyInfo);
-                var lambda = Expression.Lambda(propertyAccess, parameter);
-
-                string methodName;
-                if (index == 0)
-                {
-                    // 棣栨鎺掑簭
-                    methodName = order.Order == EnumPagedListOrder.Asc
-                        ? "OrderBy"
-                        : "OrderByDescending";
-                }
-                else
-                {
-                    // 浜屾鍙婁互鍚庢帓搴�
-                    methodName = order.Order == EnumPagedListOrder.Asc
-                        ? "ThenBy"
-                        : "ThenByDescending";
-                }
-
-                // 璋冪敤鐩稿簲鐨勬帓搴忔柟娉�
-                var resultExpression = Expression.Call(
-                    typeof(Queryable),
-                    methodName,
-                    [entityType, propertyInfo.PropertyType],
-                    q.Expression,
-                    Expression.Quote(lambda)
-                );
-
-                q = q.Provider.CreateQuery<T>(resultExpression);
-                index++;
+                PagedListQueryPageModelOrderInput orderInput2 = orders[i];
+                orderedQueryable = (orderInput2.Order == EnumPagedListOrder.Asc)
+                    ? ThenBy(orderedQueryable, orderInput2.Property, parameter)
+                    : ThenByDescending(orderedQueryable, orderInput2.Property, parameter);
             }
 
-            return q;
+            return orderedQueryable;
+        }
+
+        private static IOrderedQueryable<T> Ordering<T>(IQueryable<T> source, ParameterExpression parameter, string propertyName, string methodName)
+        {
+            Type typeFromHandle = typeof(T);
+            MemberExpression memberExpression = Expression.PropertyOrField(parameter, propertyName);
+            LambdaExpression expression = Expression.Lambda(memberExpression, parameter);
+            MethodCallExpression expression2 = Expression.Call(typeof(Queryable), methodName, [typeFromHandle, memberExpression.Type], source.Expression, Expression.Quote(expression));
+            return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(expression2);
+        }
+
+        public static IOrderedQueryable<T> OrderBy<T>(IQueryable<T> source, string propertyName, ParameterExpression parameter)
+        {
+            return Ordering(source, parameter, propertyName, "OrderBy");
+        }
+
+        public static IOrderedQueryable<T> OrderByDescending<T>(IQueryable<T> source, string propertyName, ParameterExpression parameter)
+        {
+            return Ordering(source, parameter, propertyName, "OrderByDescending");
+        }
+
+        public static IOrderedQueryable<T> ThenBy<T>(IOrderedQueryable<T> source, string propertyName, ParameterExpression parameter)
+        {
+            return Ordering(source, parameter, propertyName, "ThenBy");
+        }
+
+        public static IOrderedQueryable<T> ThenByDescending<T>(IOrderedQueryable<T> source, string propertyName, ParameterExpression parameter)
+        {
+            return Ordering(source, parameter, propertyName, "ThenByDescending");
+        }
+
+        public static async Task<TResult> GetDetail<TEntity, TResult>(
+            this Guid id,
+            CancellationToken cancellationToken = default)
+            where TEntity : CommonEntity, new()
+        {
+            var rep = Db.GetRepository<TEntity>();
+            return await rep.AsQueryable().AsNoTracking()
+                .Where(it => it.Id == id)
+                .GetDetail<TEntity, TResult>(cancellationToken);
+        }
+
+        public static async Task<TResult> GetDetail<TEntity, TResult>(
+            this IQueryable<TEntity> q,
+            CancellationToken cancellationToken = default)
+        {
+            var model = await q
+                .ProjectToType<TResult>()
+                .FirstOrDefaultAsync(cancellationToken);
+            if (model == null)
+            {
+                var summary = await typeof(TEntity).GetSummary();
+                throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "淇℃伅"}");
+            }
+            return model;
         }
 
         /// <summary>
@@ -299,18 +330,41 @@
                 : 0;
         }
 
+        public static async Task<Guid> UpdateData<TEntity, TRequest>(
+            this IQueryable<TEntity> q,
+            TRequest request,
+            Action<TEntity> update = null,
+            CancellationToken cancellationToken = default)
+            where TEntity : CommonEntity, new()
+        {
+            var rep = Db.GetRepository<TEntity>();
+            var entity = await q.FirstOrDefaultAsync();
+            if (entity == null)
+            {
+                var summary = await typeof(TEntity).GetSummary();
+                throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "淇℃伅"}");
+            }
+
+            if (update != null) update(entity);
+            else request.Adapt(entity);
+            await rep.UpdateAsync(entity);
+            return entity.Id;
+        }
+
         /// <summary>
         /// 淇濆瓨鏁版嵁
         /// </summary>
         /// <typeparam name="TEntity"></typeparam>
         /// <typeparam name="TRequest"></typeparam>
         /// <param name="request"></param>
+        /// <param name="query"></param>
         /// <param name="checkExist"></param>
         /// <param name="update"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public static async Task<Guid> SaveData<TEntity, TRequest>(
+        public static async Task<TEntity> SaveData<TEntity, TRequest>(
             this TRequest request,
+            Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
             Expression<Func<TEntity, bool>> checkExist = null,
             Action<TEntity> update = null,
             CancellationToken cancellationToken = default)
@@ -321,15 +375,17 @@
             var summary = await typeof(TEntity).GetSummary(xmlDoc);
             var rep = Db.GetRepository<TEntity>();
             if (checkExist != null && await rep.AsQueryable().AsNoTracking().AnyAsync(checkExist))
-                throw Oops.Oh(EnumErrorCodeType.s405, $"璇summary ?? "淇℃伅"}");
+                throw Oops.Oh(EnumErrorCodeType.s405, $"{summary ?? "淇℃伅"}");
             if (request.Id.HasValue)
             {
-                var entity = await rep.AsQueryable().FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken);
-                if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, $"璇summary ?? "淇℃伅"}");
+                var q = rep.AsQueryable();
+                if (query != null) q = query(q);
+                var entity = await q.FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken);
+                if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "淇℃伅"}");
                 if (update != null) update(entity);
                 else request.Adapt(entity);
                 await rep.UpdateAsync(entity);
-                return entity.Id;
+                return entity;
             }
             else
             {
@@ -337,7 +393,7 @@
                 if (update != null) update(entity);
                 else request.Adapt(entity);
                 await rep.InsertAsync(entity);
-                return entity.Id;
+                return entity;
             }
         }
 
@@ -451,10 +507,17 @@
                     }
 
                     // 璧嬪�肩敤鎴蜂俊鎭疘d
-                    prop = entity.Property(nameof(CommonEntity.CreatedUserInfoId));
+                    prop = entity.Property(nameof(CommonEntity.CreatedUserId));
                     if (prop != null && prop.CurrentValue == null)
                     {
-                        prop.CurrentValue = logier?.UserInfoId;
+                        prop.CurrentValue = logier?.Id;
+                    }
+
+                    // 璧嬪�间紒涓欼d
+                    prop = entity.Property(nameof(CommonEntity.CreatedEnterpriseId));
+                    if (prop != null && prop.CurrentValue == null)
+                    {
+                        prop.CurrentValue = logier?.EnterpriseId;
                     }
 
                     // 璧嬪�艰窡韪狪d
@@ -474,10 +537,10 @@
                     }
 
                     // 璧嬪�肩敤鎴蜂俊鎭疘d
-                    prop = entity.Property(nameof(CommonEntity.UpdatedUserInfoId));
+                    prop = entity.Property(nameof(CommonEntity.UpdatedUserId));
                     if (prop != null)
                     {
-                        prop.CurrentValue = logier?.UserInfoId;
+                        prop.CurrentValue = logier?.Id;
                     }
 
                     // 璧嬪�艰窡韪狪d
@@ -505,36 +568,44 @@
                     continue;
                 }
 
-                Db.GetRepository<DbAuditLog, LogDbContextLocator>().InsertNow(new DbAuditLog
+                var log = new DbAuditLog
                 {
                     Id = IDGen.NextID(),
                     TableName = entityType.Name,
                     PrimaryKey = (Guid)entity.Property("Id").CurrentValue,
-                    NewValues = entity.State == EntityState.Added || entity.State == EntityState.Modified
-                        ? GetPropertyValuesAsJson(entity)
-                        : null,
-                    OldValues = entity.State == EntityState.Deleted || entity.State == EntityState.Modified
-                        ? GetPropertyValuesAsJson(entity, entity.State == EntityState.Modified)
-                        : null,
-                    Operate = entity.State == EntityState.Added
-                        ? EnumDbAuditOperate.Added
-                        : entity.State == EntityState.Modified
-                        ? EnumDbAuditOperate.Modified
-                        : EnumDbAuditOperate.Deleted,
                     TraceId = App.GetTraceId(),
                     CreatedTime = DateTime.Now,
-                    CreatedUserInfoId = logier?.UserInfoId,
-                });
+                    CreatedUserId = logier?.Id,
+                    CreatedEnterpriseId = logier?.EnterpriseId
+                };
+                log.Operate =
+                    entity.State == EntityState.Added
+                    ? EnumDbAuditOperate.Added
+                    : entity.State == EntityState.Modified
+                    ? EnumDbAuditOperate.Modified
+                    : EnumDbAuditOperate.Deleted;
+                if (entity.Property(nameof(CommonEntity.IsDeleted)).CurrentValue is bool isDeleted && isDeleted == true)
+                {
+                    log.Operate = EnumDbAuditOperate.Deleted;
+                }
+                log.NewValues =
+                    log.Operate == EnumDbAuditOperate.Deleted
+                    ? null
+                    : JsonConvert.SerializeObject(entity.Properties
+                        .Where(p => log.Operate == EnumDbAuditOperate.Modified
+                            ? p.IsModified
+                            : true)
+                        .ToDictionary(p => p.Metadata.Name, p => p.CurrentValue));
+                log.OldValues =
+                    log.Operate == EnumDbAuditOperate.Added
+                    ? null
+                    : JsonConvert.SerializeObject(entity.Properties
+                        .Where(p => log.Operate == EnumDbAuditOperate.Modified
+                            ? p.IsModified
+                            : true)
+                        .ToDictionary(p => p.Metadata.Name, p => p.OriginalValue));
+                Db.GetRepository<DbAuditLog, LogDbContextLocator>().InsertNow(log);
             }
-        }
-
-        private static string GetPropertyValuesAsJson(EntityEntry entry, bool getOldValues = false)
-        {
-            var properties = entry.Properties
-                .Where(p => getOldValues ? p.IsModified : true)
-                .ToDictionary(p => p.Metadata.Name, p => getOldValues ? p.OriginalValue : p.CurrentValue);
-
-            return JsonConvert.SerializeObject(properties);
         }
     }
 }

--
Gitblit v1.9.1