Browse Source

Merge branch 'develop' of http://132.232.92.186:3000/XinXiBu/OA2023 into develop

Lyyyi 4 days ago
parent
commit
6d3c976f2d

+ 127 - 28
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -26394,6 +26394,7 @@ ORDER BY
             .ToListAsync();
             var groupList = await _sqlSugar.Queryable<Grp_DelegationInfo>()
             .Where(x => x.IsDel == 0)
+            .OrderByDescending(x => x.VisitDate)
             .Select(x => new { x.Id, x.TeamName })
             .ToListAsync();
             var currenyList = await GeneralMethod.PostGroupTeamRateByDiIdAndCTableId(1, di.Id, 98);
@@ -26455,7 +26456,8 @@ ORDER BY
                     units,
                     isReview,
                     operatorUser = ids,
-                    di
+                    di,
+                    FileType
                 }));
             }
             #endregion
@@ -26466,6 +26468,11 @@ ORDER BY
                 .OrderBy(x=>x.Index)
                 .ToList();
 
+            for (int i = 1; i <= ConferenceAffairsCostChi.Count; i++)
+            {
+                ConferenceAffairsCostChi[i - 1].Index = i;
+            }
+
             var backData = new
             {
                 ConferenceAffairsCost,
@@ -26478,7 +26485,8 @@ ORDER BY
                 units,
                 isReview,
                 operatorUser = ids,
-                di
+                di,
+                FileType
             };
 
             return Ok(JsonView(true, "SUCCESS", backData));
@@ -26516,8 +26524,8 @@ ORDER BY
                 else
                 {
                     _sqlSugar.Updateable<Grp_ConferenceAffairsCost>(data)
-                        .IgnoreColumns(ignoreAllNullColumns: true)
-                        .ExecuteCommand();
+                             .ExecuteCommand();
+                    data.Id = data.Id;
                 }
 
 
@@ -26530,7 +26538,7 @@ ORDER BY
 
                     var inrsetCount = insertArr.Any() ? _sqlSugar.Insertable<Grp_ConferenceAffairsCostChild>(insertArr).ExecuteCommand() : 0;
                     var updateCount = updateArr.Any() ? _sqlSugar.Updateable<Grp_ConferenceAffairsCostChild>(updateArr)
-                        .IgnoreColumns(ignoreAllNullColumns: true)
+                        .IgnoreColumns(x=> new { x.ConferenceAffairsCostId })
                         .ExecuteCommand() : 0;
                 }
 
@@ -26564,6 +26572,11 @@ ORDER BY
             return Ok(JsonView(true, "操作成功!",count));
         }
 
+        /// <summary>
+        /// 会务成本所有数据清除
+        /// </summary>
+        /// <param name="Dto"></param>
+        /// <returns></returns>
         [HttpPost]
         public async Task<IActionResult> ConferenceAffairsDelete(ConferenceAffairsDeleteDto Dto)
         {
@@ -26615,6 +26628,30 @@ ORDER BY
             return Ok(JsonView(true, "操作成功!"));
         }
 
+        /// <summary>
+        /// 子项数据删除
+        /// </summary>
+        /// <param name="Dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<IActionResult> ConferenceAffairSinglesDelete(ConferenceAffairsDeleteSingleDto Dto)
+        {
+            var isAudit = _sqlSugar.Queryable<Grp_ConferenceAffairsCostChild>().Where(x => x.IsDel == 0 && Dto.ids.Contains(x.Id))
+                .Any(x => x.ReviewStatus == 1);
+            if (isAudit) return Ok(JsonView(false, "包含已审核数据无法删除!"));
+
+            var count = _sqlSugar.Updateable<Grp_ConferenceAffairsCostChild>()
+                       .Where(x => Dto.ids.Contains(x.Id) && x.IsDel == 0)
+                       .SetColumns(x => new Grp_ConferenceAffairsCostChild
+                       {
+                           IsDel = 1,
+                           DeleteTime = DateTime.Now.ToString("yyyy-MM-dd"),
+                           DeleteUserId = Dto.UserId
+                       })
+                       .ExecuteCommand();
+
+            return Ok(JsonView(true, "SUCCESS!", count));
+        }
 
         [HttpPost]
         public async Task<IActionResult> PermissionSetting(PermissionSettingDto Dto)
@@ -26674,46 +26711,108 @@ ORDER BY
 
             var main = _sqlSugar.Queryable<Grp_ConferenceAffairsCost>()
                      .First(x => x.Diid == Dto.GroupId && x.IsDel == 0);
-            var chi = _sqlSugar.Queryable<Grp_ConferenceAffairsCostChild>()
-                     .Where(x => x.Diid == Dto.GroupId && x.IsDel == 0 && x.ConferenceAffairsCostId == main.Id);
 
             if (main == null)
             {
                 return Ok(JsonView(false, "团组会务成本信息不存在!"));
             }
 
+            JsonView jw = JsonView(false);
+
+            //总表下载
+            var loadPath = $"{AppSettingsHelper.Get("ExcelBasePath")}ConferenceAffairs/template/";
+            var outputPath = $"{AppSettingsHelper.Get("ExcelBasePath")}ConferenceAffairs/output/total/";
+            var networkPath = outputPath.Replace(AppSettingsHelper.Get("ExcelBasePath"), AppSettingsHelper.Get("ExcelBaseUrl") + AppSettingsHelper.Get("ExcelFtpPath"));
+            var field = string.Empty;
+            var fileTypeName = string.Empty;
+            field = @$"
+                     a.[Index],a.PriceName,a.CostPrice,a.Count,a.Coefficient,a.BaoJiaPrice,a.AddedValue,a.Details,a.Remark,a.Rate,
+                            b.Name as PriceTypeStr ,
+                            c.Name as CurrencyStr ,
+                            d.Name as UnitStr ,
+                            case a.ReviewStatus 
+	                                     WHEN 1 THEN '已通过'
+                                     WHEN 0 THEN '未审核'
+                                     WHEN -1 THEN '未通过'
+                                     ELSE '未审核'
+                                END AS ReviewStatusStr 
+                ";
+
             if (Dto.FileTypeId == 0)
             {
-
+                fileTypeName = "会务成本成本表";
+                loadPath += $"{fileTypeName}.xlsx";
+                outputPath += $"{di.TeamName}_{fileTypeName}.xlsx";
+                networkPath += $"{di.TeamName}_{fileTypeName}.xlsx";
             }
             else if (Dto.FileTypeId == 1)
             {
-                //报价下载
-                var filePath = $"{AppSettingsHelper.Get("GrpFileBasePath")}ConferenceAffairs/Quote/{main.Diid}/";
-                if (!Directory.Exists(filePath))
-                {
-                    Directory.CreateDirectory(filePath);
-                }
-                var fileName = $"报价单_{di.TeamName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx";
-                var fullPath = Path.Combine(filePath, fileName);
-
-
+                fileTypeName = "会务成本报价表";
+                loadPath += $"{fileTypeName}.xlsx";
+                outputPath += $"{di.TeamName}_{fileTypeName}.xlsx";
+                networkPath += $"{di.TeamName}_{fileTypeName}.xlsx";
             }
             else if (Dto.FileTypeId == 2)
             {
-                //总表下载
-                var filePath = $"{AppSettingsHelper.Get("GrpFileBasePath")}ConferenceAffairs/Total/{main.Diid}/";
-                if (!Directory.Exists(filePath))
-                {
-                    Directory.CreateDirectory(filePath);
-                }
-                var fileName = $"总表_{di.TeamName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx";
-                var fullPath = Path.Combine(filePath, fileName);
+                fileTypeName = "会务成本总表";
+                loadPath += $"{fileTypeName}.xlsx";
+                outputPath += $"{di.TeamName}_{fileTypeName}.xlsx";
+                networkPath += $"{di.TeamName}_{fileTypeName}.xlsx";
+            }
+
+            var chiExcelContent = _sqlSugar.SqlQueryable<ConferenceAffairsExcelContent>(@$"
+              SELECT 
+                 {field}
+  
+              FROM Grp_ConferenceAffairsCostChild a 
+              LEFT JOIN Sys_SetData b on b.IsDel = 0 AND b.Id  = a.PriceType 
+              LEFT JOIN Sys_SetData c on c.IsDel = 0 AND c.Id  = a.Currency
+              LEFT JOIN Sys_SetData d on d.IsDel = 0 AND d.Id  = a.Unit
+              WHERE a.isdel = 0
+                  AND a.Diid  = {main.Diid}
+                  AND a.ConferenceAffairsCostId  = {main.Id}
+            ").ToList();
+
+            var currLists = chiExcelContent.Select(x => new CurrList
+                                            {
+                                                CurrName = x.CurrencyStr,
+                                                CurrRate = x.Rate
+                                            })
+                                            .Distinct()
+                                            .ToList();
+
+            var designer = new WorkbookDesigner
+            {
+                Workbook = new Workbook(loadPath)
+            };
+
+            var MostCurr = _sqlSugar.Queryable<Sys_SetData>().First(x=>x.IsDel == 0 && x.Id == main.MostCurr);
+            MostCurr ??= new Sys_SetData { Name = "暂无!" };
 
+            designer.SetDataSource("TeamName", di.TeamName);
+            designer.SetDataSource("City", main.City);
+            designer.SetDataSource("AllCost", main.CostAll);
+            designer.SetDataSource("AllBaoJia", main.BaoJiaAll);
+            designer.SetDataSource("Curr", MostCurr.Name);
+            designer.SetDataSource("Curr1", MostCurr.Name);
 
-            } 
+            DataTable dt = CommonFun.GetDataTableFromIList<ConferenceAffairsExcelContent>(chiExcelContent);
+            dt.TableName = "TB";
+            designer.SetDataSource(dt);
+            DataTable dt1 = CommonFun.GetDataTableFromIList<CurrList>(currLists);
+            dt1.TableName = "currTb";
+            designer.SetDataSource(dt1);
 
-            throw new NotImplementedException("文件下载功能尚未实现!");
+            designer.Process();
+            designer.Workbook.Save(outputPath);
+
+            jw = JsonView(true, "操作成功!", new
+            {
+                FileName = $"{di.TeamName}_{fileTypeName}.xlsx",
+                FilePath = networkPath
+            });
+
+            return Ok(jw);
         }
         #endregion
 

+ 21 - 0
OASystem/OASystem.Api/Program.cs

@@ -1,5 +1,6 @@
 using Microsoft.AspNetCore.Http.Connections;
 using Microsoft.AspNetCore.Http.Features;
+using Microsoft.AspNetCore.ResponseCompression;
 using Microsoft.AspNetCore.Server.Kestrel.Core;
 using Microsoft.Extensions.DependencyInjection.Extensions;
 using OASystem.API.Middlewares;
@@ -17,6 +18,7 @@ using Quartz.Spi;
 using QuzrtzJob.Factory;
 using Serilog.Events;
 using System.Diagnostics;
+using System.IO.Compression;
 
 Console.Title = $"FMGJ OASystem Server";
 var builder = WebApplication.CreateBuilder(args);
@@ -77,6 +79,21 @@ builder.Services.AddControllers()
 
 builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
 
+#region Gzip
+
+builder.Services.AddResponseCompression(options =>
+{
+    options.EnableForHttps = true;
+    options.Providers.Add<GzipCompressionProvider>();
+});
+
+builder.Services.Configure<GzipCompressionProviderOptions>(options =>
+{
+    options.Level = CompressionLevel.Optimal;
+});
+
+#endregion
+
 #region Cors
 builder.Services.AddCors(policy =>
 {
@@ -497,6 +514,10 @@ app.UseMiddleware<RecordAPIOperationMiddleware>();
 app.UseAuthentication(); // ÈÏÖ¤
 app.UseAuthorization();  // ÊÚȨ
 
+app.UseWhen(context =>
+    context.Request.Path.StartsWithSegments("/api/MarketCustomerResources/QueryNewClientData"),
+    branch => branch.UseResponseCompression());
+
 // ÊÚȨ·¾¶
 //app.MapGet("generatetoken", c => c.Response.WriteAsync(JWTBearer.GenerateToken(c)));
 

+ 63 - 0
OASystem/OASystem.Domain/Dtos/Groups/ConferenceAffairsInIt.cs

@@ -50,6 +50,12 @@ namespace OASystem.Domain.Dtos.Groups
         public int GroupId { get; set; }
     }
 
+    public class ConferenceAffairsDeleteSingleDto
+    {
+        public int UserId { get; set; }
+        public List<int> ids { get; set; }
+    }
+
     public class PermissionSettingDto
     {
         /// <summary>
@@ -70,5 +76,62 @@ namespace OASystem.Domain.Dtos.Groups
     {
         public int FileTypeId { get; set; }
         public int GroupId { get; set; }
+
+        //public List<CurrList> CurrLists { get; set; }
+    }
+
+    public class CurrList
+    {
+        public string CurrName { get; set; }
+
+        public decimal CurrRate { get; set; }
+
+    }
+
+    public class ConferenceAffairsExcelContent
+    {
+        /// <summary>&=[TB].Index</summary>
+        public int Index { get; set; }
+
+        /// <summary>&=[TB].PriceTypeStr</summary>
+        public string PriceTypeStr { get; set; } = string.Empty;
+
+        /// <summary>&=[TB].PriceName</summary>
+        public string PriceName { get; set; } = string.Empty;
+
+        /// <summary>&=[TB].CostPrice</summary>
+        public decimal CostPrice { get; set; }
+
+        /// <summary>&=[TB].CurrencyStr</summary>
+        public string CurrencyStr { get; set; } = string.Empty;
+
+        /// <summary>&=[TB].Count</summary>
+        public decimal Count { get; set; }
+
+        /// <summary>&=[TB].UnitStr</summary>
+        public string UnitStr { get; set; } = string.Empty;
+
+        /// <summary>&=[TB].Coefficient</summary>
+        public decimal Coefficient { get; set; }
+
+        /// <summary>&=[TB].BaoJiaPrice</summary>
+        public decimal BaoJiaPrice { get; set; }
+
+        /// <summary>&=[TB].AddedValue</summary>
+        public decimal AddedValue { get; set; }
+
+        /// <summary>&=[TB].Details</summary>
+        public string Details { get; set; } = string.Empty;
+
+        /// <summary>&=[TB].Remark</summary>
+        public string Remark { get; set; } = string.Empty;
+
+        /// <summary>&=[TB].ReviewStatusStr</summary>
+        public string ReviewStatusStr { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 汇率
+        /// </summary>
+        public decimal Rate { get; set; }
     }
 }

+ 5 - 0
OASystem/OASystem.Domain/Entities/Groups/ConferenceAffairsCost.cs

@@ -55,6 +55,11 @@ namespace OASystem.Domain.Entities.Groups
         /// 报价总计
         /// </summary>
         public decimal BaoJiaAll { get; set; }
+
+        /// <summary>
+        /// 最终币种
+        /// </summary>
+        public int MostCurr { get; set; }
     }
 
 

+ 5 - 0
OASystem/OASystem.Domain/ViewModels/Groups/ConferenceAffairsCostView.cs

@@ -58,6 +58,11 @@ namespace OASystem.Domain.ViewModels.Groups
         /// </summary>
         public decimal BaoJiaAll { get; set; }
 
+        /// <summary>
+        /// 最终币种
+        /// </summary>
+        public int MostCurr { get; set; }
+
     }
 
 

+ 388 - 210
OASystem/OASystem.Infrastructure/Repositories/CRM/NewClientDataRepository.cs

@@ -20,6 +20,8 @@ using OASystem.Domain.ViewModels.CRM;
 using OASystem.Domain.ViewModels.JuHeExchangeRate;
 using OASystem.Domain.ViewModels.QiYeWeChat;
 using OASystem.Infrastructure.Tools;
+using OASystem.RedisRepository;
+using OASystem.RedisRepository.RedisAsyncHelper;
 using SqlSugar;
 using System;
 using System.Collections;
@@ -33,18 +35,263 @@ using System.Runtime.Intrinsics.Arm;
 using System.Text;
 using System.Threading.Tasks;
 using System.Xml.Linq;
+using System.Runtime.Serialization;
 using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
 using static OASystem.Domain.Dtos.CRM.NewClientDataQueryDto;
 
 namespace OASystem.Infrastructure.Repositories.CRM
 {
+    /// <summary>
+    /// 客户资料仓储类
+    /// </summary>
     public class NewClientDataRepository : BaseRepository<Crm_NewClientData, NewClientDataView>
     {
         private readonly IMapper _mapper;
+        private readonly IRedisHelper _redisHelper;
+        
         public NewClientDataRepository(SqlSugarClient sqlSugar, IMapper mapper) :
          base(sqlSugar)
         {
             _mapper = mapper;
+            _redisHelper = RedisFactory.CreateRedisRepository();
+        }
+
+        /// <summary>
+        /// 下拉框数据模型
+        /// </summary>
+        [Serializable]
+        public class DropdownItem
+        {
+            public int Id { get; set; }
+            public string Name { get; set; }
+            public string Remark { get; set; }
+        }
+
+        /// <summary>
+        /// 下拉框数据缓存模型
+        /// </summary>
+        [Serializable]
+        public class DropdownData
+        {
+            public List<DropdownItem> Users { get; set; } = new List<DropdownItem>();
+            public List<DropdownItem> Province { get; set; } = new List<DropdownItem>();
+            public List<DropdownItem> Level { get; set; } = new List<DropdownItem>();
+            public List<DropdownItem> CustomerClass { get; set; } = new List<DropdownItem>();
+            public List<DropdownItem> ServiceClass { get; set; } = new List<DropdownItem>();
+        }
+
+        /// <summary>
+        /// 获取缓存的下拉框数据
+        /// </summary>
+        /// <param name="operationUserId">操作用户ID</param>
+        /// <returns></returns>
+        private async Task<DropdownData> GetCachedDropdownDataAsync(int operationUserId)
+        {
+            var cacheKey = $"NewClientData_Dropdown_{operationUserId}";
+            var cachedData = await _redisHelper.StringGetAsync<DropdownData>(cacheKey);
+            
+            if (cachedData != null)
+            {
+                return cachedData;
+            }
+
+            // 缓存未命中,从数据库获取
+            var setDatas = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0).ToList();
+            
+            var dropdownData = new DropdownData();
+            
+            //负责人下拉框
+            dropdownData.Users = GetNewExistClient(operationUserId)
+                .Select(x => new DropdownItem { Id = x.Id, Name = x.CnName })
+                .ToList();
+
+            //省域数据
+            dropdownData.Province = setDatas
+                .Where(u => u.STid == 42)
+                .Select(x => new DropdownItem { Id = x.Id, Name = x.Name })
+                .ToList();
+
+            //客户级别数据
+            dropdownData.Level = setDatas
+                .Where(u => u.STid == 33)
+                .Select(x => new DropdownItem { Id = x.Id, Name = x.Name })
+                .ToList();
+
+            //客户类别
+            var customerClassList = new List<DropdownItem>();
+            List<Sys_SetData> CustomerClass = setDatas
+                .Where(u => u.STid == 37 && u.IsDel == 0)
+                .ToList();
+            foreach (Sys_SetData item in CustomerClass)
+            {
+                customerClassList.Add(new DropdownItem
+                {
+                    Id = item.Id,
+                    Name = item.Name,
+                    Remark = item.Remark
+                });
+            }
+
+            // 按ID排序客户类别
+            dropdownData.CustomerClass = customerClassList.OrderBy(x => x.Id).ToList();
+
+            //业务分类 
+            dropdownData.ServiceClass = setDatas
+                .Where(u => u.STid == 36)
+                .Select(x => new DropdownItem { Id = x.Id, Name = x.Name })
+                .ToList();
+
+            // 缓存30分钟
+            await _redisHelper.StringSetAsync(cacheKey, dropdownData, TimeSpan.FromMinutes(30));
+            
+            return dropdownData;
+        }
+
+        /// <summary>
+        /// 可序列化的关联用户信息
+        /// </summary>
+        [Serializable]
+        public class SerializableAscribedUser
+        {
+            public int UserId { get; set; }
+            public string CnName { get; set; }
+            public int NewClientDataId { get; set; }
+        }
+
+        /// <summary>
+        /// 可序列化的关联部门信息
+        /// </summary>
+        [Serializable]
+        public class SerializableAscribedDepartment
+        {
+            public int Id { get; set; }
+            public string Name { get; set; }
+            public int NewClientDataId { get; set; }
+        }
+
+        /// <summary>
+        /// 获取缓存的客户资料关联信息
+        /// </summary>
+        /// <param name="clientIds">客户ID列表</param>
+        /// <returns></returns>
+        private async Task<(List<AscribedUser> ascribedUsers, List<AscribedDepartment> ascribedDepartments)> GetCachedClientRelationsAsync(List<int> clientIds)
+        {
+            if (clientIds == null || !clientIds.Any())
+                return (new List<AscribedUser>(), new List<AscribedDepartment>());
+
+            var cacheKey = $"NewClientData_Relations_{string.Join("_", clientIds.OrderBy(x => x))}";
+            var cachedData = await _redisHelper.StringGetAsync<(List<SerializableAscribedUser>, List<SerializableAscribedDepartment>)>(cacheKey);
+            
+            if (cachedData.Item1 != null && cachedData.Item2 != null)
+            {
+                // 转换为原始类型
+                var ascribedUsers = cachedData.Item1.Select(x => new AscribedUser
+                {
+                    UserId = x.UserId,
+                    CnName = x.CnName,
+                    NewClientDataId = x.NewClientDataId
+                }).ToList();
+
+                var ascribedDepartments = cachedData.Item2.Select(x => new AscribedDepartment
+                {
+                    Id = x.Id,
+                    Name = x.Name,
+                    NewClientDataId = x.NewClientDataId
+                }).ToList();
+
+                return (ascribedUsers, ascribedDepartments);
+            }
+
+            // 批量查询关联信息 - 使用同步方法避免数据读取器问题
+            var queriedUsers = _sqlSugar.SqlQueryable<AscribedUser>(
+                "select u1.UsersId as UserId ,u2.CnName,u1.NewClientDataId from Crm_ClientDataAndUser u1,Sys_Users u2 where u1.UsersId=u2.Id and NewClientDataId in (" + string.Join(",", clientIds) + ") AND u1.ISDEL = 0")
+                .ToList();
+
+            var queriedDepartments = _sqlSugar.SqlQueryable<AscribedDepartment>(
+                "select d2.Id,d2.Name,d1.NewClientDataId from Crm_ClientDataAndBusiness d1,Sys_SetData d2 where d1.SetDataId=d2.Id and NewClientDataId in (" + string.Join(",", clientIds) + ") AND d1.ISDEL = 0")
+                .ToList();
+
+            // 转换为可序列化类型进行缓存
+            var serializableUsers = queriedUsers.Select(x => new SerializableAscribedUser
+            {
+                UserId = x.UserId,
+                CnName = x.CnName,
+                NewClientDataId = x.NewClientDataId
+            }).ToList();
+
+            var serializableDepartments = queriedDepartments.Select(x => new SerializableAscribedDepartment
+            {
+                Id = x.Id,
+                Name = x.Name,
+                NewClientDataId = x.NewClientDataId
+            }).ToList();
+
+            var result = (serializableUsers, serializableDepartments);
+            
+            // 缓存10分钟
+            await _redisHelper.StringSetAsync(cacheKey, result, TimeSpan.FromMinutes(10));
+            
+            return (queriedUsers, queriedDepartments);
+        }
+
+        /// <summary>
+        /// 获取缓存的省域数据
+        /// </summary>
+        /// <param name="range">省域范围</param>
+        /// <returns></returns>
+        private async Task<List<int>> GetCachedRangeSetDataAsync(int range)
+        {
+            if (range == 0) return new List<int>();
+
+            var cacheKey = $"NewClientData_Range_{range}";
+            var cachedData = await _redisHelper.StringGetAsync<List<int>>(cacheKey);
+            
+            if (cachedData != null)
+            {
+                return cachedData;
+            }
+
+            string setDataSql = "select * from Sys_SetData where STid = 33 and isdel = 0  ";
+            switch (range)
+            {
+                case 419:
+                    setDataSql += " and (Name like '%四%川%' or Name like '%成%都%')";
+                    break;
+                case 421:
+                    setDataSql += " and (Name like '%贵%州%' or Name like '%贵%阳%')";
+                    break;
+                case 420:
+                    setDataSql += " and (Name like '%云%南%' or Name like '%昆%明%')";
+                    break;
+                case 423:
+                    setDataSql += " and (Name like '%重庆%')";
+                    break;
+                case 422:
+                    setDataSql += " and (Name like '%西%藏%' or Name like '%拉%萨%')";
+                    break;
+                case 578:
+                    setDataSql += " and (Name like '%青%海%' or Name like '%西%宁%')";
+                    break;
+                case 605:
+                    setDataSql += " and (Name like '%陕%西%' or Name like '%西%安%')";
+                    break;
+                case 606:
+                    setDataSql += " and (Name like '%宁%夏%' or Name like '%银%川%')";
+                    break;
+                case 625:
+                    setDataSql += " and (Name like '%甘%肃%' or Name like '%兰%州%')";
+                    break;
+                case 634:
+                    setDataSql += " and (Name like '%新%疆%' or Name like '%乌%鲁%木%齐%')";
+                    break;
+            }
+
+            var rangeSetDataList = _sqlSugar.SqlQueryable<Sys_SetData>(setDataSql).Select(x => x.Id).ToList();
+            
+            // 缓存1小时
+            await _redisHelper.StringSetAsync(cacheKey, rangeSetDataList, TimeSpan.FromHours(1));
+            
+            return rangeSetDataList;
         }
 
         /// <summary>
@@ -213,7 +460,7 @@ namespace OASystem.Infrastructure.Repositories.CRM
         }
 
         /// <summary>
-        /// 客户资料初识初始化
+        /// 客户资料查询 - 优化版本
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
@@ -225,238 +472,165 @@ namespace OASystem.Infrastructure.Repositories.CRM
             int pageIndex = dto.PageIndex, pageSize = dto.PageSize;
             try
             {
-                #region 交集
-                List<int> NewClientDataId1 = new List<int>();
-                List<int> NewClientDataId2 = new List<int>();
+                // 并行获取缓存数据
+                var rangeSetDataTask = GetCachedRangeSetDataAsync(dto.Range);
+                var dropdownDataTask = GetCachedDropdownDataAsync(dto.OperationUserId);
+
+                #region 交集计算优化
+                List<int> intList = new List<int>();
                 int state = 0;
 
-                #region 负责人
-                if (dto.OperationUserId != 21)
+                // 负责人筛选
+                if (dto.OperationUserId != 21 && string.IsNullOrWhiteSpace(dto.Userid))
                 {
-                    if (string.IsNullOrWhiteSpace(dto.Userid))
-                    {
-                        dto.Userid = dto.OperationUserId.ToString();
-                    }
+                    dto.Userid = dto.OperationUserId.ToString();
                 }
 
+                List<int> NewClientDataId1 = new List<int>();
+                List<int> NewClientDataId2 = new List<int>();
+
                 if (!string.IsNullOrWhiteSpace(dto.Userid))
                 {
-                    string sql = string.Format(@"select u1.UsersId as UserId,u2.CnName,u1.NewClientDataId from Crm_ClientDataAndUser u1,Sys_Users u2 where u1.UsersId=u2.Id and u1.UsersId in ({0})  and u1.IsDel = 0", dto.Userid);
-                    List<AscribedUser> ascribedUsers = await _sqlSugar.SqlQueryable<AscribedUser>(sql).ToListAsync();
-                    if (ascribedUsers.Count != 0)
-                    {
-                        foreach (var ascribedUser in ascribedUsers)
-                        {
-                            if (ascribedUser.NewClientDataId != 0)
-                            {
-                                NewClientDataId1.Add(ascribedUser.NewClientDataId);
-                            }
-                        }
-                    }
-                    else
-                    {
-                        result = new Result() { Code = -1, Msg = "暂无数据" };
-                    }
+                    string sql = string.Format(@"
+                      select u1.NewClientDataId
+                      from Crm_ClientDataAndUser u1
+                      where u1.IsDel = 0 AND u1.UsersId in ({0})
+                    ", dto.Userid);
+                    NewClientDataId1 = _sqlSugar.Ado.SqlQuery<int>(sql).ToList();
                     state = -1;
                 }
-                #endregion
 
-                #region 业务归属
+                // 业务归属筛选
                 if (!string.IsNullOrWhiteSpace(dto.Business))
                 {
-                    string sql = string.Format(@"select   d2.Id,d2.Name,d1.NewClientDataId   from Crm_ClientDataAndBusiness d1,Sys_SetData d2 where d1.SetDataId=d2.Id and d1.SetDataId in ({0}) and d1.isdel = 0", dto.Business);
-                    List<AscribedDepartment> AscribedDepartment = await _sqlSugar.SqlQueryable<AscribedDepartment>(sql).ToListAsync();
-                    if (AscribedDepartment.Count != 0)
-                    {
-                        foreach (var item in AscribedDepartment)
-                        {
-                            if (item.NewClientDataId != 0)
-                            {
-                                NewClientDataId2.Add(item.NewClientDataId);
-                            }
-                        }
-                    }
-                    else
-                    {
-                        result = new Result() { Code = -1, Msg = "暂无数据" };
-                    }
+                    string sql = string.Format(@"  
+                      select d1.NewClientDataId
+                      from Crm_ClientDataAndBusiness d1
+                      where d1.SetDataId in ({0}) and d1.isdel = 0
+                    ", dto.Business);
+                    NewClientDataId2 = _sqlSugar.Ado.SqlQuery<int>(sql).ToList();
                     state = -1;
                 }
-                #endregion
-
-                List<int> intList = new List<int>();
 
+                // 交集计算
                 if (NewClientDataId1.Count != 0 && NewClientDataId2.Count != 0)
                 {
                     intList = NewClientDataId1.Intersect(NewClientDataId2).ToList();
-
                 }
                 else if (NewClientDataId1.Count != 0)
                 {
                     intList = NewClientDataId1;
                 }
-                else if (NewClientDataId2.Count != 0)
+                else if (NewClientDataId2.Count != 0 && dto.OperationUserId == 21)
                 {
-                    if (dto.OperationUserId == 21)
-                    {
-                        intList = NewClientDataId2;
-                    }
+                    intList = NewClientDataId2;
                 }
 
-                if (state == -1)
+                if (state == -1 && intList.Count < 1) 
                 {
-                    if (intList.Count < 1) intList.Add(-1);
+                    intList.Add(-1);
                 }
-
-                
                 #endregion
 
-                #region 省域条件
-                var rangeSetDataList = new List<int>();
-                if (dto.Range != 0)
-                {
-                    string setDataSql = "select * from Sys_SetData where STid = 33 and isdel = 0  ";
-                    switch (dto.Range)
-                    {
-                        case 419:
-                            setDataSql += " and (Name like '%四%川%' or Name like '%成%都%')";
-                            break;
-                        case 421:
-                            setDataSql += " and (Name like '%贵%州%' or Name like '%贵%阳%')";
-                            break;
-                        case 420:
-                            setDataSql += " and (Name like '%云%南%' or Name like '%昆%明%')";
-                            break;
-                        case 423:
-                            setDataSql += " and (Name like '%重庆%')";
-                            break;
-                        case 422:
-                            setDataSql += " and (Name like '%西%藏%' or Name like '%拉%萨%')";
-                            break;
-                        case 578:
-                            setDataSql += " and (Name like '%青%海%' or Name like '%西%宁%')";
-                            break;
-                        case 605:
-                            setDataSql += " and (Name like '%陕%西%' or Name like '%西%安%')";
-                            break;
-                        case 606:
-                            setDataSql += " and (Name like '%宁%夏%' or Name like '%银%川%')";
-                            break;
-                        case 625:
-                            setDataSql += " and (Name like '%甘%肃%' or Name like '%兰%州%')";
-                            break;
-                        case 634:
-                            setDataSql += " and (Name like '%新%疆%' or Name like '%乌%鲁%木%齐%')";
-                            break;
-                    }
-
-                    rangeSetDataList = _sqlSugar.SqlQueryable<Sys_SetData>(setDataSql).Select(x => x.Id).ToList();
+                // 等待缓存数据
+                var rangeSetDataList = await rangeSetDataTask;
+                var dropdownData = await dropdownDataTask;
 
-                }
-                #endregion
-
-                var NewClientDataView = new List<NewClientDataView>();
-                var count = 0;
+                #region 模糊搜索优化
+                var searchDataIds = new List<int>();
+                var isSelectSearch = false;
                 string contact = dto.Contact, location = dto.Location, clientDto = dto.Client;
 
-                var isSelectSearch = false;
-                var searchDataIds = new List<int>();
-                if (string.IsNullOrEmpty(contact) || string.IsNullOrEmpty(location) || string.IsNullOrEmpty(clientDto))
+                if (!string.IsNullOrEmpty(contact) || !string.IsNullOrEmpty(location) || !string.IsNullOrEmpty(clientDto))
                 {
                     isSelectSearch = true;
-                    var searchClientDatas = await _sqlSugar.Queryable<Crm_NewClientData>()
-                        .Where(x => x.IsDel == 0)
-                        .Select(x => new Crm_NewClientData() { Id = x.Id, Client = x.Client, Location = x.Location, Contact = x.Contact })
-                        .ToListAsync();
-
-                    foreach (var item in searchClientDatas) EncryptionProcessor.DecryptProperties(item);
-
-                    if (dto.PortType == 1)
+                    
+                    // 使用缓存键进行搜索
+                    var searchCacheKey = $"NewClientData_Search_{contact}_{location}_{clientDto}_{dto.PortType}";
+                    var cachedSearchIds = await _redisHelper.StringGetAsync<List<int>>(searchCacheKey);
+                    
+                    if (cachedSearchIds != null)
                     {
-                        searchDataIds = searchClientDatas
-                            .WhereIF(!string.IsNullOrEmpty(contact), x => !string.IsNullOrEmpty(x.Contact) && x.Contact.Contains(contact))     //联系人条件
-                            .WhereIF(!string.IsNullOrEmpty(location), x => !string.IsNullOrEmpty(x.Location) && x.Location.Contains(location)) //地区条件
-                            .WhereIF(!string.IsNullOrEmpty(clientDto), x => !string.IsNullOrEmpty(x.Client) && x.Client.Contains(clientDto))   //单位条件
-                            .Select(x => x.Id)
-                            .ToList();
+                        searchDataIds = cachedSearchIds;
                     }
-                    else if (dto.PortType == 2 || dto.PortType == 3)
+                    else
                     {
-                        searchDataIds = searchClientDatas
-                            .Where(x => (!string.IsNullOrEmpty(x.Contact) && x.Contact.Contains(clientDto)) ||
-                                        (!string.IsNullOrEmpty(x.Location) && x.Location.Contains(clientDto)) ||
-                                        (!string.IsNullOrEmpty(x.Client) && x.Client.Contains(clientDto)))
-                            .Select(x => x.Id)
-                            .ToList();
-                    }
+                        var searchClientDatas = await _sqlSugar.Queryable<Crm_NewClientData>()
+                            .Where(x => x.IsDel == 0)
+                            .Select(x => new Crm_NewClientData() { Id = x.Id, Client = x.Client, Location = x.Location, Contact = x.Contact })
+                            .ToListAsync();
 
-                    if (searchDataIds.Count < 1) searchDataIds.Add(0);
+                        // 批量解密
+                        foreach (var item in searchClientDatas) 
+                        {
+                            EncryptionProcessor.DecryptProperties(item);
+                        }
+
+                        if (dto.PortType == 1)
+                        {
+                            searchDataIds = searchClientDatas
+                                .WhereIF(!string.IsNullOrEmpty(contact), x => !string.IsNullOrEmpty(x.Contact) && x.Contact.Contains(contact))
+                                .WhereIF(!string.IsNullOrEmpty(location), x => !string.IsNullOrEmpty(x.Location) && x.Location.Contains(location))
+                                .WhereIF(!string.IsNullOrEmpty(clientDto), x => !string.IsNullOrEmpty(x.Client) && x.Client.Contains(clientDto))
+                                .Select(x => x.Id)
+                                .ToList();
+                        }
+                        else if (dto.PortType == 2 || dto.PortType == 3)
+                        {
+                            searchDataIds = searchClientDatas
+                                .Where(x => (!string.IsNullOrEmpty(x.Contact) && x.Contact.Contains(clientDto)) ||
+                                            (!string.IsNullOrEmpty(x.Location) && x.Location.Contains(clientDto)) ||
+                                            (!string.IsNullOrEmpty(x.Client) && x.Client.Contains(clientDto)))
+                                .Select(x => x.Id)
+                                .ToList();
+                        }
+
+                        if (searchDataIds.Count < 1) searchDataIds.Add(0);
+                        
+                        // 缓存搜索结果5分钟
+                        await _redisHelper.StringSetAsync(searchCacheKey, searchDataIds, TimeSpan.FromMinutes(5));
+                    }
                 }
+                #endregion
 
+                #region 主查询
                 RefAsync<int> total = 0;
                 var clientDatas = await _sqlSugar.Queryable<Crm_NewClientData>()
-                .Where(x => x.IsDel == 0)
-                .WhereIF(state == -1 && intList.Count > 0, x => intList.Contains(x.Id))
-                .WhereIF(dto.Lvlid != 0, x => x.Lvlid == dto.Lvlid) //地市州条件
-                .WhereIF(rangeSetDataList.Count > 0, x => rangeSetDataList.Contains(x.Lvlid)) //省域条件
-                .WhereIF(dto.Category > 0, x => x.Category == dto.Category) //客户类别
-                .WhereIF(isSelectSearch && searchDataIds.Count > 0 , x => searchDataIds.Contains(x.Id)) //条件模糊查询
-                .OrderByDescending(x => x.LastUpdateTime)
-                .ToPageListAsync(pageIndex, pageSize, total);
-
-                NewClientDataView = _mapper.Map<List<NewClientDataView>>(clientDatas);
-                count = total;
-
-
-                var setDatas = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0).ToList();
-                
-                #region 下拉框初始化数据
-                //负责人下拉框
-                var _Users = GetNewExistClient(dto.OperationUserId).Select(x => new { x.Id, Name = x.CnName }).ToList();
-
-                //省域数据
-                var _Province = setDatas.Where(u => u.STid == 42).Select(x => new { x.Id, x.Name }).ToList();
-
-                //客户级别数据
-                var _level = setDatas.Where(u => u.STid == 33).Select(x => new { x.Id, x.Name }).ToList();
-
-                //客户类别
-                ArrayList _CustomerClass = new ArrayList();
-                List<Sys_SetData> CustomerClass = setDatas.Where(u => u.STid == 37 && u.IsDel == 0).ToList();
-                foreach (Sys_SetData item in CustomerClass)
-                {
-                    var data = new
-                    {
-                        Id = item.Id,
-                        Name = item.Name,
-                        item.Remark
-                    };
-                    _CustomerClass.Add(data);
-                };
-                // 创建比较器实例
-                IComparer remakeComparer = new RemakeComparer();
-                _CustomerClass.Sort(remakeComparer);
-
-                //业务分类 
-                var _ServiceClass = setDatas.Where(u => u.STid == 36).Select(x => new { x.Id, x.Name }).ToList();
-
+                    .Where(x => x.IsDel == 0)
+                    .WhereIF(state == -1 && intList.Count > 0, x => intList.Contains(x.Id))
+                    .WhereIF(dto.Lvlid != 0, x => x.Lvlid == dto.Lvlid)
+                    .WhereIF(rangeSetDataList.Count > 0, x => rangeSetDataList.Contains(x.Lvlid))
+                    .WhereIF(dto.Category > 0, x => x.Category == dto.Category)
+                    .WhereIF(isSelectSearch && searchDataIds.Count > 0, x => searchDataIds.Contains(x.Id))
+                    .OrderByDescending(x => x.LastUpdateTime)
+                    .ToPageListAsync(pageIndex, pageSize, total);
+
+                var NewClientDataView = _mapper.Map<List<NewClientDataView>>(clientDatas);
+                var count = total;
                 #endregion
 
+                // 计算出团总量
                 var groupNumber = await QueryNumberGroups();
 
                 if (NewClientDataView.Count > 0)
                 {
-                    float totalPage = (float)count / dto.PageSize;//总页数
+                    float totalPage = (float)count / dto.PageSize;
                     if (totalPage == 0) totalPage = 1;
                     else totalPage = (int)Math.Ceiling((double)totalPage);
 
                     if (dto.PortType == 1)
                     {
+                        // 批量获取关联信息
+                        var clientIds = NewClientDataView.Select(x => x.Id).ToList();
+                        var (ascribedUsers, ascribedDepartments) = await GetCachedClientRelationsAsync(clientIds);
+
+                        // 获取设置数据用于显示名称
+                        var setDatas = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0).ToList();
+
                         int index = 1;
                         foreach (var item in NewClientDataView)
                         {
-                            //EncryptionProcessor.DecryptProperties(item); //解密
-
+                            // 批量解密
                             item.Weight = AesEncryptionHelper.Decrypt(item.Weight);
                             item.Client = AesEncryptionHelper.Decrypt(item.Client);
                             item.Contact = AesEncryptionHelper.Decrypt(item.Contact);
@@ -470,37 +644,33 @@ namespace OASystem.Infrastructure.Repositories.CRM
                             item.CategoryStr = setDatas.Find(x => x.Id == item.Category)?.Name ?? "-";
                             item.LvlidStr = setDatas.Find(x => x.Id == item.Lvlid)?.Name ?? "-";
 
-                            List<AscribedUser> AscribedUser = await _sqlSugar.SqlQueryable<AscribedUser>
-                           ("select u1.UsersId as UserId ,u2.CnName,u1.NewClientDataId from Crm_ClientDataAndUser u1,Sys_Users u2 where u1.UsersId=u2.Id and NewClientDataId=" + item.Id + "   AND u1.ISDEL = 0").ToListAsync();
-                            item.AscribedUser = AscribedUser;
-
-                            List<AscribedDepartment> AscribedDepartment = await _sqlSugar.SqlQueryable<AscribedDepartment>
-                          ("select  d2.Id,d2.Name,d1.NewClientDataId  from Crm_ClientDataAndBusiness d1,Sys_SetData d2 where d1.SetDataId=d2.Id and NewClientDataId=" + item.Id + "  AND d1.ISDEL = 0").ToListAsync();
-                            item.AscribedDepartment = AscribedDepartment;
+                            // 从批量查询结果中获取关联信息
+                            item.AscribedUser = ascribedUsers.Where(x => x.NewClientDataId == item.Id).ToList();
+                            item.AscribedDepartment = ascribedDepartments.Where(x => x.NewClientDataId == item.Id).ToList();
+                            
                             index++;
                         }
 
                         var Data = new
                         {
-                            ClientTableData = new { pageCount = count, totalPage = (int)totalPage, pageIndex = dto.PageIndex, pageSize = dto.PageSize, pageSource = NewClientDataView },
-                            Users = _Users,
-                            Province = _Province,
-                            level = _level,
-                            CustomerClass = _CustomerClass,
-                            ServiceClass = _ServiceClass,
+                            ClientTableData = new { pageCount = count.Value, totalPage = (int)totalPage, pageIndex = dto.PageIndex, pageSize = dto.PageSize, pageSource = NewClientDataView },
+                            Users = dropdownData.Users,
+                            Province = dropdownData.Province,
+                            level = dropdownData.Level,
+                            CustomerClass = dropdownData.CustomerClass,
+                            ServiceClass = dropdownData.ServiceClass,
                             groupNumber = groupNumber.Data,
                         };
+                        
                         return result = new Result()
                         {
                             Code = 0,
-                            Msg = $"查询成功!解密耗时: {stopwatch.ElapsedMilliseconds} 毫秒",
+                            Msg = $"查询成功!耗时: {stopwatch.ElapsedMilliseconds} 毫秒",
                             Data = Data
                         };
-
                     }
                     else if (dto.PortType == 2 || dto.PortType == 3)
                     {
-
                         List<NewClientDataAndroidIOSView> newClientDataIOSViews = new List<NewClientDataAndroidIOSView>();
 
                         int index = 1;
@@ -523,11 +693,10 @@ namespace OASystem.Infrastructure.Repositories.CRM
                         result = new Result()
                         {
                             Code = 0,
-                            Msg = $"查询成功!解密耗时: {stopwatch.ElapsedMilliseconds} 毫秒",
-                            Data = new { pageCount = count, totalPage = (int)totalPage, pageIndex = dto.PageIndex, pageSize = dto.PageSize, pageSource = newClientDataIOSViews },
+                            Msg = $"查询成功!耗时: {stopwatch.ElapsedMilliseconds} 毫秒",
+                            Data = new { pageCount = count.Value, totalPage = (int)totalPage, pageIndex = dto.PageIndex, pageSize = dto.PageSize, pageSource = newClientDataIOSViews },
                         };
                     }
-
                 }
                 else
                 {
@@ -541,25 +710,34 @@ namespace OASystem.Infrastructure.Repositories.CRM
                         var Data = new
                         {
                             ClientTableData = new { pageCount = 0, totalPage = 0, pageIndex = dto.PageIndex, pageSize = dto.PageSize, pageSource = NewClientDataView },
-                            Users = _Users,
-                            Province = _Province,
-                            level = _level,
-                            CustomerClass = _CustomerClass,
-                            ServiceClass = _ServiceClass,
+                            Users = dropdownData.Users,
+                            Province = dropdownData.Province,
+                            level = dropdownData.Level,
+                            CustomerClass = dropdownData.CustomerClass,
+                            ServiceClass = dropdownData.ServiceClass,
                             groupNumber = groupNumber.Data,
                         };
                         result = new Result() { Code = 0, Msg = "获取成功!", Data = Data };
                     }
                 }
-
             }
             catch (Exception ex)
             {
-                result = new Result() { Code = -2, Msg = "未知错误" };
+                //记录详细错误信息
+                //Console.WriteLine($"QueryNewClientData 异常: {ex.Message}");
+                //Console.WriteLine($"异常堆栈: {ex.StackTrace}");
+                
+                result = new Result() { Code = -2, Msg = $"查询异常: {ex.Message}" };
+            }
+            finally
+            {
+                stopwatch.Stop();
+                if (result.Code == 0)
+                {
+                    result.Msg = $"查询成功!总耗时: {stopwatch.ElapsedMilliseconds} 毫秒";
+                }
             }
 
-            stopwatch.Stop();
-            result.Msg = $"耗时: {stopwatch.ElapsedMilliseconds} 毫秒";
             return result;
         }
 
@@ -592,10 +770,10 @@ namespace OASystem.Infrastructure.Repositories.CRM
                 if (!string.IsNullOrWhiteSpace(dto.Userid))
                 {
                     string sql = string.Format(@"select u1.UsersId as UserId,u2.CnName,u1.NewClientDataId from Crm_ClientDataAndUser u1,Sys_Users u2 where u1.UsersId=u2.Id and u1.UsersId in ({0})  and u1.IsDel = 0", dto.Userid);
-                    List<AscribedUser> ascribedUsers = await _sqlSugar.SqlQueryable<AscribedUser>(sql).ToListAsync();
-                    if (ascribedUsers.Count != 0)
+                    List<AscribedUser> userList = await _sqlSugar.SqlQueryable<AscribedUser>(sql).ToListAsync();
+                    if (userList.Count != 0)
                     {
-                        foreach (var ascribedUser in ascribedUsers)
+                        foreach (var ascribedUser in userList)
                         {
                             if (ascribedUser.NewClientDataId != 0)
                             {
@@ -615,10 +793,10 @@ namespace OASystem.Infrastructure.Repositories.CRM
                 if (!string.IsNullOrWhiteSpace(dto.Business))
                 {
                     string sql = string.Format(@"select   d2.Id,d2.Name,d1.NewClientDataId   from Crm_ClientDataAndBusiness d1,Sys_SetData d2 where d1.SetDataId=d2.Id and d1.SetDataId in ({0}) and d1.isdel = 0", dto.Business);
-                    List<AscribedDepartment> AscribedDepartment = await _sqlSugar.SqlQueryable<AscribedDepartment>(sql).ToListAsync();
-                    if (AscribedDepartment.Count != 0)
+                    List<AscribedDepartment> deptList = await _sqlSugar.SqlQueryable<AscribedDepartment>(sql).ToListAsync();
+                    if (deptList.Count != 0)
                     {
-                        foreach (var item in AscribedDepartment)
+                        foreach (var item in deptList)
                         {
                             if (item.NewClientDataId != 0)
                             {