From 85279c0daafcfea80db14cdd8dfe85f7c7fddba4 Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期五, 08 八月 2025 13:40:09 +0800
Subject: [PATCH] fix:bug

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

diff --git a/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs b/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs
index e37e10c..55647c2 100644
--- a/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs
+++ b/FlexJobApi.Core/Utils/DbUtils/DbUtils.cs
@@ -8,6 +8,7 @@
 using Microsoft.EntityFrameworkCore.ChangeTracking;
 using Microsoft.EntityFrameworkCore.Diagnostics;
 using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Microsoft.EntityFrameworkCore.Migrations;
 using Microsoft.Extensions.Configuration;
 using Newtonsoft.Json;
 using System;
@@ -98,7 +99,7 @@
         /// <param name="query"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public static async Task<List<SelectQueryResultOption<TValue, TData>>> GetSelect<TEntity, TValue, TData>(
+        public static async Task<List<SelectOption<TValue, TData>>> GetSelect<TEntity, TValue, TData>(
             this SelectQuery<TValue, TData> request,
             Func<TData, TValue> getValue,
             Func<TData, string> getLabel,
@@ -113,10 +114,10 @@
             var models = await q
                 .ProjectToType<TData>()
                 .ToListAsync(cancellationToken);
-            var options = new List<SelectQueryResultOption<TValue, TData>>();
+            var options = new List<SelectOption<TValue, TData>>();
             foreach (var model in models)
             {
-                var option = new SelectQueryResultOption<TValue, TData>();
+                var option = new SelectOption<TValue, TData>();
                 option.Data = model;
                 option.Value = getValue(model);
                 option.Label = getLabel(model);
@@ -147,7 +148,7 @@
             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);
+            q = q.CustomOrderBy(page.OrderInput);
             var s = selector == null
                 ? q.ProjectToType<TItem>()
                 : q.Select(selector);
@@ -174,7 +175,7 @@
             CancellationToken cancellationToken = default)
             where TItem : class, new()
         {
-            q = q.OrderBy(page.OrderInput);
+            q = q.CustomOrderBy(page.OrderInput);
             var pagedList = await q.ToPagedListAsync(page.Page, page.Rows, cancellationToken);
             var result = new PagedListQueryResult<TItem>();
             result.PageModel = page.Adapt<PagedListQueryResultPageModel>();
@@ -184,66 +185,51 @@
             return result;
         }
 
-        /// <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");
         }
 
         /// <summary>
@@ -304,12 +290,14 @@
         /// <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>(
             this TRequest request,
+            Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
             Expression<Func<TEntity, bool>> checkExist = null,
             Action<TEntity> update = null,
             CancellationToken cancellationToken = default)
@@ -323,7 +311,9 @@
                 throw Oops.Oh(EnumErrorCodeType.s405, $"璇summary ?? "淇℃伅"}");
             if (request.Id.HasValue)
             {
-                var entity = await rep.AsQueryable().FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken);
+                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);
@@ -348,35 +338,41 @@
         /// <returns></returns>
         public static async Task BuildEntity(ModelBuilder modelBuilder, Type dbContextLocator = null)
         {
-            var xmlDoc = await XmlDocUtils.GetXmlDocAsync();
-            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
+            if (App.GetService<IMigrator>() != null)
             {
-                Console.WriteLine($"姝e湪鐢熸垚琛細{entityType.Name}");
-                // 鑾峰彇瀹炰綋绫荤殑XML娉ㄩ噴锛屽苟璁剧疆涓鸿〃娉ㄩ噴
-                var entityBuilder = modelBuilder.Entity(entityType.ClrType);
-                string typeComment = (await entityType.ClrType.GetXmlDocMemberAsync(xmlDoc))?.Summary;
-                if (!string.IsNullOrEmpty(typeComment))
+                var xmlDoc = await XmlDocUtils.GetXmlDocAsync();
+                foreach (var entityType in modelBuilder.Model.GetEntityTypes())
                 {
-                    Console.WriteLine($"姝e湪鐢熸垚琛ㄦ敞閲婏細{entityType.Name}-{typeComment}");
-                    entityBuilder.ToTable(it => it.HasComment(typeComment));
-                }
-                // 鑾峰彇瀹炰綋灞炴�х殑XML娉ㄩ噴锛屽苟璁剧疆涓哄垪娉ㄩ噴
-                var properties = entityType.ClrType.GetProperties()
-                    .Where(p =>
-                        p.CanRead
-                        && p.CanWrite
-                        && !typeof(System.Collections.ICollection).IsAssignableFrom(p.PropertyType)
-                        && (p.PropertyType.IsClass ? p.PropertyType.FullName.Contains("System.") : true));
-                foreach (var property in properties)
-                {
-                    string propComment = (await property.GetXmlDocMemberAsync(xmlDoc))?.Summary;
-                    if (!string.IsNullOrEmpty(propComment))
+                    Console.WriteLine($"姝e湪鐢熸垚琛細{entityType.Name}");
+                    // 鑾峰彇瀹炰綋绫荤殑XML娉ㄩ噴锛屽苟璁剧疆涓鸿〃娉ㄩ噴
+                    var entityBuilder = modelBuilder.Entity(entityType.ClrType);
+                    string typeComment = (await entityType.ClrType.GetXmlDocMemberAsync(xmlDoc))?.Summary;
+                    if (!string.IsNullOrEmpty(typeComment))
                     {
-                        Console.WriteLine($"姝e湪鐢熸垚灞炴�ф敞閲婏細{property.Name}-{propComment}");
-                        entityBuilder.Property(property.Name).HasComment(propComment);
+                        Console.WriteLine($"姝e湪鐢熸垚琛ㄦ敞閲婏細{entityType.Name}-{typeComment}");
+                        entityBuilder.ToTable(it => it.HasComment(typeComment));
+                    }
+                    // 鑾峰彇瀹炰綋灞炴�х殑XML娉ㄩ噴锛屽苟璁剧疆涓哄垪娉ㄩ噴
+                    var properties = entityType.ClrType.GetProperties()
+                        .Where(p =>
+                            p.CanRead
+                            && p.CanWrite
+                            && !typeof(System.Collections.ICollection).IsAssignableFrom(p.PropertyType)
+                            && (p.PropertyType.IsClass ? p.PropertyType.FullName.Contains("System.") : true));
+                    foreach (var property in properties)
+                    {
+                        string propComment = (await property.GetXmlDocMemberAsync(xmlDoc))?.Summary;
+                        if (!string.IsNullOrEmpty(propComment))
+                        {
+                            Console.WriteLine($"姝e湪鐢熸垚灞炴�ф敞閲婏細{property.Name}-{propComment}");
+                            entityBuilder.Property(property.Name).HasComment(propComment);
+                        }
                     }
                 }
+            }
 
+            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
+            {
                 if (typeof(CommonEntity).IsAssignableFrom(entityType.ClrType))
                 {
                     // 鏋勫缓绛涢�夋潯浠讹細IsDeleted == false
@@ -390,8 +386,6 @@
                     modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambda);
                 }
             }
-
-            Console.WriteLine("鏁版嵁搴撻摼鎺ュ湴鍧�锛�" + App.Configuration.GetConnectionString("FlexJobApi"));
         }
 
         /// <summary>
@@ -420,6 +414,7 @@
 
             // 閫氳繃璇锋眰涓幏鍙栧綋鍓嶆搷浣滀汉
             var logier = JwtUtils.GetCurrentLogier();
+            var traceId = App.GetTraceId();
 
             // 鑾峰彇鎵�鏈夊凡鏇存敼鐨勫疄浣�
             foreach (var entity in entities)
@@ -445,17 +440,24 @@
                     }
 
                     // 璧嬪�肩敤鎴蜂俊鎭疘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
                     prop = entity.Property(nameof(CommonEntity.TraceId));
-                    if (prop != null)
+                    if (prop != null && prop.CurrentValue == null && traceId.IsNotNull())
                     {
-                        prop.CurrentValue = App.GetTraceId();
+                        prop.CurrentValue = traceId;
                     }
                 }
                 else
@@ -468,17 +470,17 @@
                     }
 
                     // 璧嬪�肩敤鎴蜂俊鎭疘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
                     prop = entity.Property(nameof(CommonEntity.TraceId));
-                    if (prop != null)
+                    if (prop != null && traceId.IsNotNull())
                     {
-                        prop.CurrentValue = App.GetTraceId();
+                        prop.CurrentValue = traceId;
                     }
 
                     // 杞垹闄�
@@ -517,7 +519,8 @@
                         : EnumDbAuditOperate.Deleted,
                     TraceId = App.GetTraceId(),
                     CreatedTime = DateTime.Now,
-                    CreatedUserInfoId = logier?.UserInfoId,
+                    CreatedUserId = logier?.Id,
+                    CreatedEnterpriseId = logier?.EnterpriseId
                 });
             }
         }

--
Gitblit v1.9.1