Преглед изворни кода

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

yuanrf пре 3 месеци
родитељ
комит
8c31b12469
33 измењених фајлова са 3823 додато и 747 уклоњено
  1. 14 9
      OASystem/OASystem.Api/Controllers/FinancialController.cs
  2. 1318 161
      OASystem/OASystem.Api/Controllers/GroupsController.cs
  3. 71 136
      OASystem/OASystem.Api/Controllers/PersonnelModuleController.cs
  4. 70 0
      OASystem/OASystem.Api/Controllers/SearchController.cs
  5. 785 0
      OASystem/OASystem.Api/Controllers/SystemController.cs
  6. 2 3
      OASystem/OASystem.Api/Middlewares/ExceptionHandlingMiddleware.cs
  7. 98 5
      OASystem/OASystem.Api/OAMethodLib/GeneralMethod.cs
  8. 4 2
      OASystem/OASystem.Api/OASystem.API.csproj
  9. 0 4
      OASystem/OASystem.Api/Program.cs
  10. BIN
      OASystem/OASystem.Api/wwwroot/exports/exports/excel/客户资料资料(YQY)_0f4beae08b7b4f53b9f27113563fc5d2.xlsx
  11. BIN
      OASystem/OASystem.Api/wwwroot/exports/exports/excel/客户资料资料(ZQ)_6c09dbea11914d2eafe96e5a4fdb0a5d.xlsx
  12. 15 8
      OASystem/OASystem.Domain/Dtos/Groups/EnterExitCostDraftDto.cs
  13. 29 1
      OASystem/OASystem.Domain/Dtos/Groups/EnterExitCostDto.cs
  14. 12 9
      OASystem/OASystem.Domain/Entities/Groups/Grp_ConfProcess.cs
  15. 23 3
      OASystem/OASystem.Domain/Entities/Groups/Grp_EnterExitCostDraft.cs
  16. 10 2
      OASystem/OASystem.Domain/Entities/Groups/Grp_ProcessOverview.cs
  17. 18 1
      OASystem/OASystem.Domain/Result.cs
  18. 11 0
      OASystem/OASystem.Domain/ViewModels/Financial/Fin_ForeignReceivablesView.cs
  19. 11 2
      OASystem/OASystem.Domain/ViewModels/Groups/EnterExitCostDraftView.cs
  20. 17 6
      OASystem/OASystem.Domain/ViewModels/Groups/EnterExitCostView.cs
  21. 1 4
      OASystem/OASystem.Domain/ViewModels/Groups/ProcessOverView.cs
  22. 72 0
      OASystem/OASystem.Domain/ViewModels/Groups/ProcessView.cs
  23. 1 1
      OASystem/OASystem.Domain/ViewModels/JsonView.cs
  24. 7 12
      OASystem/OASystem.Domain/ViewModels/PersonnelModule/TaskAllocationView.cs
  25. 5 1
      OASystem/OASystem.Domain/ViewModels/Resource/OverseaVehicleView.cs
  26. 1 1
      OASystem/OASystem.Infrastructure/Repositories/CRM/NewClientDataRepository.cs
  27. 14 14
      OASystem/OASystem.Infrastructure/Repositories/Groups/EnterExitCostDraftRepository.cs
  28. 3 2
      OASystem/OASystem.Infrastructure/Repositories/Groups/InvertedListRepository.cs
  29. 1117 327
      OASystem/OASystem.Infrastructure/Repositories/Groups/ProcessOverviewRepository.cs
  30. 4 4
      OASystem/OASystem.Infrastructure/Repositories/Groups/VisaProcessRepository.cs
  31. 40 5
      OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/CompanyDailyKpiRepository.cs
  32. 47 21
      OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/TaskAllocationRepository.cs
  33. 3 3
      OASystem/OASystem.Infrastructure/Repositories/Resource/CountryFeeRepository.cs

+ 14 - 9
OASystem/OASystem.Api/Controllers/FinancialController.cs

@@ -2359,17 +2359,19 @@ namespace OASystem.API.Controllers
                 .AnyAsync();
 
             var list_rst = await _sqlSugar.Queryable<Grp_DelegationInfo>()
-                .Where(x => x.IsDel == 0)
-                .WhereIF(startTimeFlag && endTimeFlag, x => x.VisitDate >= begintime && x.VisitDate <= endtime)
-                .WhereIF(!string.IsNullOrEmpty(groupName), x => x.TeamName.Contains(groupName))
-                .WhereIF(marketStaffFlag, x => x.JietuanOperator == currUserId)
-                .OrderBy(x => x.VisitDate)
-                .Select(x => new PostSyntheticalReceivableByDateRangeView()
+                .LeftJoin<Sys_Users>((x, y) => x.JietuanOperator == y.Id)
+                .Where((x, y) => x.IsDel == 0)
+                .WhereIF(startTimeFlag && endTimeFlag, (x, y) => x.VisitDate >= begintime && x.VisitDate <= endtime)
+                .WhereIF(!string.IsNullOrEmpty(groupName), (x, y) => x.TeamName.Contains(groupName))
+                .WhereIF(marketStaffFlag, (x, y) => x.JietuanOperator == currUserId)
+                .OrderBy((x, y) => x.VisitDate)
+                .Select((x, y) => new PostSyntheticalReceivableByDateRangeView()
                 {
                     diid = x.Id,
                     teamName = x.TeamName,
                     clientUnit = x.ClientUnit,
-                    visitDate = x.VisitDate.ToString("yyyy-MM-dd")
+                    visitDate = x.VisitDate.ToString("yyyy-MM-dd"),
+                    fulfiller = y.CnName,
                 })
                 .ToListAsync();
 
@@ -2789,6 +2791,7 @@ namespace OASystem.API.Controllers
                             Balance = item.balPrice,
                             Collection = item.schedule,
                             GroupCost = item.groupCost.ToString("#0.00"),
+                            fulfiller = item.fulfiller
                         };
                         excNo++;
                         DateTime time = Convert.ToDateTime(item.visitDate);
@@ -2851,7 +2854,8 @@ namespace OASystem.API.Controllers
                             ClientUnit = item.clientUnit,
                             VisitDate = item.visitDate,
                             ChangeColorLabel = item.ChangeColorLabel,
-                            GroupCost = item.groupCost.ToString("#0.00")
+                            GroupCost = item.groupCost.ToString("#0.00"),
+                            fulfiller = item.fulfiller
                         };
                         excNo1++;
                         list_Ex_Orange.Add(exc);
@@ -2865,7 +2869,8 @@ namespace OASystem.API.Controllers
                             ClientUnit = item.clientUnit,
                             VisitDate = item.visitDate,
                             ChangeColorLabel = item.ChangeColorLabel,
-                            GroupCost = item.groupCost.ToString("#0.00")
+                            GroupCost = item.groupCost.ToString("#0.00"),
+                            fulfiller = item.fulfiller
                         };
                         excNo2++;
                         list_Ex_Red.Add(exc);

Разлика између датотеке није приказан због своје велике величине
+ 1318 - 161
OASystem/OASystem.Api/Controllers/GroupsController.cs


+ 71 - 136
OASystem/OASystem.Api/Controllers/PersonnelModuleController.cs

@@ -1,5 +1,7 @@
 using Aspose.Cells;
+using Dm.util;
 using FluentValidation;
+using k8s.KubeConfigModels;
 using Markdig;
 using Microsoft.AspNetCore.SignalR;
 using OASystem.API.OAMethodLib;
@@ -1050,141 +1052,71 @@ namespace OASystem.API.Controllers
                 groupArr = groupNames.Split(',').Select(part => part.Trim()).ToArray();
             }
 
-            string whereSql = "", currUserName = "";
-            #region 分页参数处理
-
-            //类型处理
-            if (dto.Type == 0) whereSql = "";
-            else if (dto.Type == 1) //1 由我指派
-            {
-                //whereSql = string.Format(@" And ta.CreateUserId = {0} Or (Select COUNT(1) As PeopleNumber From Pm_TaskRelevanceUser Where IsDel = 0 And ta.Id = TAId And UserId = {0}) > 0", dto.UserId);
-            }
-            else if (dto.Type == 2)// 2 指派给我
-            {
-                //whereSql = string.Format(@" And (Select COUNT(1) As PeopleNumber From Pm_TaskRelevanceUser Where IsDel = 0 And ta.Id = TAId And UserId = {0}) > 0", dto.UserId);
-            }
-            //状态 -1 全部 0 未开始 1 进行中 2 待审核 3 未完成 4 已完成
-            if (dto.Status == -1) //全部
-            {
-                whereSql += "";
-            }
-            else
-            {
-                whereSql += string.Format(@" And ta.Status = {0} ", dto.Status);
-            }
-
-            //任务类型
-            if (dto.TaskType == -1) //全部
-            {
-                whereSql += "";
-            }
-            else
-            {
-                whereSql += string.Format(@" And ta.TaskType = {0} ", dto.TaskType);
-            }
-
-            //任务名称
-            if (!string.IsNullOrEmpty(dto.TaskName))
-            {
-                whereSql += string.Format(@" And ta.TaskName Like '%{0}%' ", dto.TaskName);
-            }
-
-            //人员名称
-            string taskUserWhereSql = string.Empty;
-            if (dto.TaskUserId > 0)
+            //任务人员限定 发布者可看范围内的人员,接受者只能看自己的任务
+            var taskPublisher = await _taskAllocationRep.ValidateTaskPublisher(dto.UserId);
+            var taskUserIds = new List<int>();
+            if (taskPublisher.isTaskPublisher)
             {
-                var taskUserInfo = await _sqlSugar.Queryable<Sys_Users>().FirstAsync(x => x.IsDel == 0 && x.Id == dto.TaskUserId);
-                if (taskUserInfo != null)
+                taskUserIds = taskPublisher.userIds;
+                //查询指定人员
+                if (dto.TaskUserId > -1)
                 {
-                    taskUserWhereSql = $" AND [Participant] like '%{taskUserInfo.CnName}%'";
+                    taskUserIds = taskPublisher.userIds.Where(x => x == dto.TaskUserId).ToList();
                 }
             }
-
-            #endregion
-
-            var currUserInfo = await _sqlSugar.Queryable<Sys_Users>().FirstAsync(x => x.Id == dto.UserId);
-            if (currUserInfo != null) currUserName = currUserInfo.CnName;
-
-            string pageSql = string.Format(@"Select
- ROW_NUMBER() OVER(
-        ORDER BY
-          CreateTime Desc
-      ) AS RowNumber,
-  *
-From
-(
-    Select
-      ta.Id,
-      ta.TaskName,
-      ta.TaskContent,
-      s.Name as 'TaskTypeName',
-      ta.TaskPriority,
-      d.DepName,
-      di.TeamName,
-      ta.Status,
-      ta.PredictBeginTime,
-      ta.PredictEndTime,
-      ta.CreateUserId,
-      u.CnName As CreateUserName,
-      ta.CreateTime,
-      ta.Remark,
-      ta.OverTime,
-      (
-        SELECT
-          STUFF(
-            (
-              Select
-                ',' + u.CnName
-              From
-                Pm_TaskRelevanceUser tra
-                Left Join Sys_Users u On tra.UserId = u.Id
-              Where
-                tra.Isdel = 0
-                And tra.TAId = ta.Id FOR XML PATH('')
-            ),
-            1,
-            1,
-            ''
-          )
-      ) As Participant
-      --,(
-      --  SELECT
-      --    STUFF(
-      --      (
-      --        Select
-      --          ',' + u.CnName
-      --        From
-      --          Pm_TaskRelevanceUser tra
-      --          Left Join Sys_Users u On tra.UserId = u.Id
-      --        Where
-      --          tra.Isdel = 0
-      --          And tra.TAId = ta.Id
-      --          And tra.TaskStatus = 4 FOR XML PATH('')
-      --      ),
-      --      1,
-      --      1,
-      --      ''
-      --    )
-      --) As Consummator
-    From
-      Pm_TaskAllocation ta
-      Left Join Sys_Department d On ta.DepId = d.Id
-      Left Join Grp_DelegationInfo di On ta.DiId = di.Id
-      Left Join Sys_Users u On ta.CreateUserId = u.Id
-      left join Sys_SetData s on ta.TaskType = s.Id 
-    Where
-      ta.IsDel = 0 {0}
-  ) As temp
-WHERE
-  [CreateUserName] like '%{1}%' {2}", whereSql, currUserName, taskUserWhereSql);
+            else taskUserIds.Add(dto.UserId);
 
             RefAsync<int> total = 0;
-            var _view = await _sqlSugar.SqlQueryable<TaskListView>(pageSql)
-                .WhereIF(groupArr.Any(), x => groupArr.Contains(x.TeamName))
-                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
+            var view = await _sqlSugar.Queryable<Pm_TaskAllocation>()
+                .LeftJoin<Sys_Department>((ta, d) => ta.DepId == d.Id)
+                .LeftJoin<Grp_DelegationInfo>((ta, d, di) => ta.DiId == di.Id)
+                .LeftJoin<Sys_Users>((ta, d, di, u) => ta.CreateUserId == u.Id)
+                .LeftJoin<Sys_SetData>((ta, d, di, u, sd) => ta.TaskType == sd.Id)
+                .Where((ta, d, di, u, sd) => ta.IsDel == 0)
+                //任务发布者和任务接受者
+                .Where((ta, d, di, u, sd) =>
+                    SqlFunc.Subqueryable<Pm_TaskRelevanceUser>()
+                    .Where(tr => tr.TAId == ta.Id && taskUserIds.Contains(tr.UserId))
+                    .Any())
+                //状态 
+                .WhereIF(dto.Status > -1, (ta, d, di, u, sd) => (int)ta.Status == dto.Status)
+                //任务类型
+                .WhereIF(dto.TaskType > -1, (ta, d, di, u, sd) => ta.TaskType == dto.TaskType)
+                //团组
+                .WhereIF(groupArr.Any(), (ta, d, di, u, sd) => groupArr.Contains(di.TeamName))
+                .OrderByDescending((ta, d, di, u, sd) => ta.CreateTime)
+                .Select((ta, d, di, u, sd) => new TaskListView()
+                {
+                    Id = ta.Id,
+                    TaskName = ta.TaskName,
+                    TaskContent = ta.TaskContent,
+                    TaskTypeName = sd.Name,
+                    TaskPriority = ta.TaskPriority,
+                    DepName = d.DepName,
+                    TeamName = di.TeamName,
+                    Status = (int)ta.Status,
+                    PredictBeginTime = ta.PredictBeginTime,
+                    PredictEndTime = ta.PredictEndTime,
+                    CreateUserId = ta.CreateUserId,
+                    CreateUserName = u.CnName,
+                    CreateTime = ta.CreateTime,
+                    Remark = ta.Remark,
+                    OverTime = ta.OverTime
+                })
+                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+
+            int index = 1;
+            foreach (var item in view)
+            {
+                item.RowNumber = index;
+                //设置参与人
+                var userNames = await _sqlSugar.Queryable<Pm_TaskRelevanceUser>()
+                    .LeftJoin<Sys_Users>((tru, u) => tru.UserId == u.Id)
+                    .Where((tru, u) => tru.IsDel == 0 && tru.TAId == item.Id)
+                    .Select((tru, u) => u.CnName)
+                    .ToListAsync();
+                item.Participant = string.Join("、", userNames);
 
-            foreach (var item in _view)
-            {
                 //设置编辑权限
                 (bool editPerm, string msg1) = _taskAllocationRep.EditPerm(item.Id, dto.UserId);
                 item.EditPerm = editPerm;
@@ -1197,9 +1129,11 @@ WHERE
                 item.TaskDetailsPerm = _sqlSugar.Queryable<Pm_TaskRelevanceUser>()
                     .Where(it => it.IsDel == 0 && it.TAId == item.Id && (it.UserId == dto.UserId || it.CreateUserId == dto.UserId))
                     .Any();
+
+                index++;
             }
 
-            return Ok(JsonView(true, "查询成功!", _view, total));
+            return Ok(JsonView(true, "查询成功!", view, total));
         }
 
         /// <summary>
@@ -4239,6 +4173,7 @@ OPTION (MAXRECURSION 0); -- 允许无限递归      ";
         /// <param name="start"></param>
         /// <param name="end"></param>
         /// <param name="createUserId"></param>
+        /// <param name="setdataId"></param>
         /// <returns></returns>
         private async Task<JsonView> AiPerformanceAnalysis_TaskAllocationAsync(int userId, DateTime start, DateTime end, int createUserId, int setdataId)
         {
@@ -4496,8 +4431,8 @@ OPTION (MAXRECURSION 0); -- 允许无限递归      ";
         /// <summary>
         /// 通用绩效分析pdf下载
         /// </summary>
-        /// <param name="year"></param>
-        /// <param name="month"></param>
+        /// <param name="start"></param>
+        /// <param name="end"></param>
         /// <param name="userId"></param>
         /// <returns></returns>
         [HttpPost]
@@ -5300,7 +5235,7 @@ OPTION (MAXRECURSION 0); -- 允许无限递归      ";
                 dto.PageIndex = 1;
             }
 
-            if (dto.PageSize < 1 || dto.PageSize > 100)
+            if ((dto.PageSize < 1 || dto.PageSize > 100) && dto.PortType != 3)
             {
                 dto.PageSize = 10;
             }
@@ -5523,11 +5458,12 @@ ORDER BY MonthNumber, CollectionDays";
         /// <summary>
         /// 公司日常绩效 初始化数据
         /// </summary>
+        /// <param name="currUserId">当前用户ID</param>
         /// <returns></returns>
-        [HttpGet]
-        public async Task<IActionResult> CompanyDailyKpiInit()
+        [HttpGet("{currUserId}")]
+        public async Task<IActionResult> CompanyDailyKpiInit(int currUserId)
         {
-            return Ok(await _companyDailyKyiRep.InitAsync());
+            return Ok(await _companyDailyKyiRep.InitAsync(currUserId));
         }
 
         /// <summary>
@@ -5594,6 +5530,5 @@ ORDER BY MonthNumber, CollectionDays";
 
         #endregion
 
-
     }
 }

+ 70 - 0
OASystem/OASystem.Api/Controllers/SearchController.cs

@@ -204,5 +204,75 @@ namespace OASystem.API.Controllers
         }
 
 
+        /// <summary>
+        /// 团组、会务流程 关键字输入提示(智能版)
+        /// </summary>
+        /// <param name="keyword">关键字</param>
+        /// <returns></returns>
+        [HttpGet]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> ProcessKeywordSearch(string keyword)
+        {
+            try
+            {
+                // 验证请求参数
+                if (string.IsNullOrEmpty(keyword))
+                {
+                    return Ok(JsonView(true, $"暂无数据!"));
+                }
+
+                var searchRequest = new DynamicSearchRequest
+                {
+                    Keyword = keyword,
+                    RequireAllSingleChars = true,
+                    PageIndex = 1,
+                    PageSize = 999999,
+                    FieldWeights = new Dictionary<string, int>
+                    {
+                        { "TeamName", 10 }
+                    },
+                    Filters = new List<SearchFilter>()
+                    {
+                        new(){Field = "IsDel",Operator="eq",Value="0" }
+                    },
+                    OrderBy = "VisitDate",
+                    ReturnFields = new List<string>() { "TeamName" }
+                };
+
+                // 验证字段配置
+                var validation = _groupSearchService.ValidateFieldConfig(
+                    searchRequest.FieldWeights,
+                    searchRequest.ReturnFields);
+
+                if (!validation.IsValid)
+                {
+                    return Ok(JsonView(true, $"暂无数据!{validation.Message}"));
+                }
+
+                var result = await _groupSearchService.SearchAsync(searchRequest);
+
+                if (result.Success)
+                {
+                    var data = new List<dynamic>();
+
+                    foreach (var item in result.Items)
+                    {
+                        data.Add(new
+                        {
+                            item.Data.Id,
+                            item.Data.TeamName,
+                        });
+                    }
+
+                    return Ok(JsonView(true, result.Message, data, data.Count));
+                }
+
+                return Ok(JsonView(true, result.Message));
+            }
+            catch (Exception ex)
+            {
+                return Ok(JsonView(true, $"搜索服务暂时不可用!"));
+            }
+        }
     }
 }

+ 785 - 0
OASystem/OASystem.Api/Controllers/SystemController.cs

@@ -6,10 +6,12 @@ using OASystem.API.OAMethodLib.DeepSeekAPI;
 using OASystem.API.OAMethodLib.GenericSearch;
 using OASystem.Domain.AesEncryption;
 using OASystem.Domain.Attributes;
+using OASystem.Domain.Entities;
 using OASystem.Domain.Entities.Customer;
 using OASystem.Domain.Entities.Financial;
 using OASystem.Domain.Entities.Groups;
 using System.Collections;
+using System.ComponentModel;
 using System.Data;
 using System.Dynamic;
 using System.Linq;
@@ -4644,6 +4646,789 @@ GROUP BY
             public string Remark { get; set; }
 
         }
+
+        /// <summary>
+        /// excel导出 客户资料 (YQY)
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> ExcelDownloadClientYQY()
+        {
+            var yqyClientIds = new List<int>() {
+2468,
+2539,
+2345,
+2322,
+2685,
+6066,
+2531,
+2293,
+2339,
+2631,
+2485,
+2359,
+2551,
+6630,
+2645,
+6481,
+2522,
+6587,
+2402,
+2365,
+2353,
+6550,
+2565,
+2316,
+2608,
+6664,
+2419,
+2396,
+6687,
+2465,
+2442,
+6478,
+2471,
+6432,
+2342,
+2542,
+2588,
+2333,
+2582,
+2488,
+2482,
+2634,
+2880,
+2574,
+2883,
+2382,
+6057,
+6578,
+6627,
+6063,
+2356,
+2611,
+2605,
+2462,
+2313,
+2466,
+2297,
+2391,
+2589,
+2380,
+6659,
+2629,
+6613,
+2483,
+2477,
+2643,
+6064,
+2569,
+2669,
+2620,
+2520,
+6648,
+2320,
+2663,
+6585,
+2463,
+2314,
+2609,
+2586,
+2371,
+2540,
+2417,
+2772,
+2517,
+2494,
+2580,
+6908,
+6622,
+6668,
+2285,
+2486,
+6439,
+2523,
+2646,
+6061,
+2603,
+2403,
+6055,
+2305,
+2411,
+6617,
+2372,
+2541,
+6780,
+2303,
+2518,
+2495,
+6431,
+2627,
+2426,
+2687,
+2286,
+2529,
+2635,
+6663,
+2581,
+2406,
+2475,
+6654,
+6554,
+2661,
+6683,
+2612,
+2363,
+2538,
+2492,
+2515,
+2369,
+2352,
+2469,
+2323,
+2300,
+2398,
+6528,
+2592,
+6067,
+6906,
+2392,
+2784,
+2678,
+2684,
+2584,
+6912,
+2621,
+2289,
+2552,
+2452,
+6651,
+2521,
+2644,
+2615,
+6053,
+6588,
+2315,
+2309,
+2409,
+2301,
+2633,
+2610,
+2516,
+2441,
+2393,
+6429,
+2639,
+2284,
+6907,
+2673,
+6669,
+2622,
+6440,
+6583,
+2453,
+2524,
+2596,
+6652,
+6775,
+6054,
+2318,
+2659,
+6589,
+2410,
+2891,
+6480,
+2390,
+2473,
+6065,
+6612,
+2630,
+2381,
+2530,
+2484,
+2407,
+2599,
+2527,
+2670,
+2570,
+6778,
+6586,
+2613,
+2364,
+            };
+
+            var datas = await _sqlSugar.Queryable<Crm_NewClientData>().Where(x => x.IsDel == 0 && yqyClientIds.Contains(x.Id)).ToListAsync();
+
+            //解密
+            var dataView = new List<Crm_NewClientDataView>();
+            foreach (var item in datas)
+            {
+                EncryptionProcessor.DecryptProperties(item);
+
+                var area = await _sqlSugar.Queryable<Sys_SetData>()
+                    .Where(x => x.IsDel == 0 && x.Id == item.Lvlid)
+                    .Select(x => x.Name)
+                    .FirstAsync();
+
+                var sex = item.Gender switch { 
+                    0 => "男",
+                    1 => "女",
+                    _ => "未设置"
+                };
+
+                var category = await _sqlSugar.Queryable<Sys_SetData>()
+                    .Where(x => x.IsDel == 0 && x.Id == item.Category)
+                    .Select(x => x.Name)
+                    .FirstAsync();
+
+                var lastUpdateUserName = await _sqlSugar.Queryable<Sys_Users>()
+                    .Where(x => x.Id == item.LastUpdateUserId)
+                    .Select(x => x.CnName)
+                    .FirstAsync();
+
+                dataView.Add(new Crm_NewClientDataView
+                {
+                    Id = item.Id,
+                    Area = area,
+                    Client = item.Client,
+                    Weight = item.Weight,
+                    ClientShort = item.ClientShort,
+                    Contact = item.Contact,
+                    Sex = sex,
+                    Passport = item.Passport,
+                    PassportDate = item.PassportDate,
+                    Job = item.Job,
+                    Telephone = item.Telephone,
+                    Phone = item.Phone,
+                    Email = item.Email,
+                    Location = item.Location,
+                    Address = item.Address,
+                    Birthday = item.Birthday,
+                    OtherInfo = item.OtherInfo,
+                    Wechat = item.Wechat,
+                    Category = category,
+                    LastUpdateUserName = lastUpdateUserName,
+                    LastUpdateTime = item.LastUpdateTime,
+                });
+            }
+
+            var exportResult = await GeneralMethod.ExportToExcel<Crm_NewClientDataView>(dataView, "客户资料资料(YQY)", "客户资料资料(YQY)");
+
+            return Ok(JsonView(exportResult));
+        }
+
+        /// <summary>
+        /// excel导出 客户资料 (ZQ)
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> ExcelDownloadClientZQ()
+        {
+            var yqyClientIds = new List<int>() {
+5763,
+5764,
+5765,
+5766,
+5767,
+5768,
+5769,
+5770,
+5771,
+5781,
+5782,
+5783,
+5784,
+5785,
+5786,
+5787,
+5788,
+5789,
+5790,
+5801,
+5802,
+5803,
+5804,
+5805,
+5806,
+5807,
+5808,
+5809,
+5810,
+5821,
+5822,
+5823,
+5824,
+5825,
+5826,
+5827,
+5828,
+5829,
+5830,
+5841,
+5842,
+5843,
+5844,
+5845,
+5846,
+5847,
+5848,
+5849,
+5850,
+5861,
+5862,
+2572,
+2575,
+6593,
+2366,
+2433,
+2436,
+6660,
+2548,
+2619,
+4114,
+2385,
+6200,
+2583,
+2903,
+2412,
+2839,
+2384,
+2681,
+2877,
+6632,
+6645,
+2388,
+2354,
+2373,
+2375,
+6682,
+2470,
+2432,
+2472,
+2379,
+2290,
+2431,
+2434,
+2585,
+2580,
+2586,
+2599,
+6652,
+2584,
+2608,
+2541,
+6583,
+6053,
+2588,
+2540,
+2589,
+6617,
+6780,
+6664,
+6439,
+6630,
+2634,
+2565,
+2552,
+2592,
+2345,
+6063,
+2359,
+6054,
+6627,
+2352,
+2391,
+6550,
+2468,
+2471,
+2685,
+2639,
+2333,
+2629,
+2610,
+2645,
+2477,
+2315,
+2316,
+2323,
+2880,
+2772,
+6654,
+6065,
+2530,
+6651,
+2453,
+2615,
+2409,
+2284,
+2406,
+2570,
+2542,
+2419,
+2452,
+6554,
+2417,
+2465,
+2475,
+2611,
+2393,
+2411,
+6528,
+2390,
+2687,
+2466,
+2301,
+2380,
+2527,
+6683,
+6480,
+6481,
+2784,
+2678,
+2643,
+2669,
+2486,
+2492,
+2300,
+2673,
+6586,
+6588,
+2891,
+2520,
+2521,
+6778,
+6669,
+6668,
+6663,
+6659,
+2551,
+2369,
+6648,
+2441,
+2883,
+2630,
+2631,
+2633,
+2635,
+2613,
+2469,
+2605,
+2342,
+6429,
+2398,
+2402,
+2403,
+2646,
+2314,
+2309,
+2320,
+2627,
+2612,
+2463,
+6578,
+6061,
+2396,
+2371,
+2365,
+2286,
+2313,
+2372,
+2353,
+2356,
+2407,
+2381,
+2644,
+6622,
+2297,
+2609,
+2620,
+2473,
+6432,
+6067,
+2410,
+2322,
+2621,
+2289,
+6066,
+2303,
+2495,
+2426,
+6057,
+2603,
+2582,
+2285,
+2318,
+2293,
+2622,
+2462,
+6055,
+2488,
+6440,
+2659,
+2515,
+6906,
+6587,
+6907,
+2523,
+2529,
+2539,
+2516,
+6912,
+2663,
+6478,
+2538,
+2522,
+2531,
+2485,
+2484,
+6589,
+6064,
+2483,
+6612,
+6613,
+6585,
+2517,
+2684,
+2574,
+2339,
+2524,
+2670,
+2569,
+2596,
+2518,
+2494,
+2305,
+2392,
+6775,
+2482,
+6687,
+6431,
+2363,
+6908,
+2382,
+2364,
+2442,
+2661,
+2581,
+2576,
+
+            };
+
+            var datas = await _sqlSugar.Queryable<Crm_NewClientData>().Where(x => x.IsDel == 0 && yqyClientIds.Contains(x.Id)).ToListAsync();
+
+            //解密
+            var dataView = new List<Crm_NewClientDataView>();
+            foreach (var item in datas)
+            {
+                EncryptionProcessor.DecryptProperties(item);
+
+                var area = await _sqlSugar.Queryable<Sys_SetData>()
+                    .Where(x => x.IsDel == 0 && x.Id == item.Lvlid)
+                    .Select(x => x.Name)
+                    .FirstAsync();
+
+                var sex = item.Gender switch
+                {
+                    0 => "男",
+                    1 => "女",
+                    _ => "未设置"
+                };
+
+                var category = await _sqlSugar.Queryable<Sys_SetData>()
+                    .Where(x => x.IsDel == 0 && x.Id == item.Category)
+                    .Select(x => x.Name)
+                    .FirstAsync();
+
+                var lastUpdateUserName = await _sqlSugar.Queryable<Sys_Users>()
+                    .Where(x => x.Id == item.LastUpdateUserId)
+                    .Select(x => x.CnName)
+                    .FirstAsync();
+
+                dataView.Add(new Crm_NewClientDataView
+                {
+                    Id = item.Id,
+                    Area = area,
+                    Client = item.Client,
+                    Weight = item.Weight,
+                    ClientShort = item.ClientShort,
+                    Contact = item.Contact,
+                    Sex = sex,
+                    Passport = item.Passport,
+                    PassportDate = item.PassportDate,
+                    Job = item.Job,
+                    Telephone = item.Telephone,
+                    Phone = item.Phone,
+                    Email = item.Email,
+                    Location = item.Location,
+                    Address = item.Address,
+                    Birthday = item.Birthday,
+                    OtherInfo = item.OtherInfo,
+                    Wechat = item.Wechat,
+                    Category = category,
+                    LastUpdateUserName = lastUpdateUserName,
+                    LastUpdateTime = item.LastUpdateTime,
+                });
+            }
+
+            var exportResult = await GeneralMethod.ExportToExcel<Crm_NewClientDataView>(dataView, "客户资料资料(ZQ)", "客户资料资料(ZQ)");
+
+            return Ok(JsonView(exportResult));
+        }
+
+        /// <summary>
+        /// 新客户资料表
+        /// </summary>
+        public class Crm_NewClientDataView : EntityBase
+        {
+            private int number;
+            private string client;
+            private string weight;
+            private string clientshort;
+            private string contact;
+            private int gender;
+            private string passport;
+            private DateTime? passportDate;
+            private string job;
+            private string telephone;
+            private string phone;
+            private string email;
+            private string location;
+            private string address;
+            private string birthday;
+            private string otherinfo;
+            private string wechat;
+            private string category;
+            private int predele;
+            private int finlishedDele;
+            private string lastUpdateUserName;
+            private DateTime lastUpdateTime;
+            private string area;
+            private string sex;
+
+            /// <summary>
+            /// 序号
+            /// </summary>
+            public int Number { get => number; set => number = value; }
+
+            /// <summary>
+            /// 客户区域
+            /// </summary>
+
+            public string Area { get => area; set => area = value; }
+
+            /// <summary>
+            /// 客户单位
+            /// </summary>
+            public string Client { get => client; set => client = value; }
+
+            /// <summary>
+            /// 权重
+            /// </summary>
+            public string Weight { get => weight; set => weight = value; }
+
+            /// <summary>
+            /// 客户单位简写
+            /// </summary>
+            public string ClientShort { get => clientshort; set => clientshort = value; }
+
+            /// <summary>
+            /// 联系人
+            /// </summary>
+            public string Contact { get => contact; set => contact = value; }
+
+            /// <summary>
+            /// 联系人性别
+            /// </summary>
+            public string Sex { get => sex; set => sex = value; }
+
+            /// <summary>
+            /// 护照
+            /// </summary>
+            public string Passport { get => passport; set => passport = value; }
+
+            /// <summary>
+            /// 护照日期
+            /// </summary>
+            public DateTime? PassportDate { get => passportDate; set => passportDate = value; }
+
+            /// <summary>
+            /// 职位
+            /// </summary>
+            [Encrypted]
+            public string Job { get => job; set => job = value; }
+
+            /// <summary>
+            /// 联系手机号
+            /// </summary>
+            [Encrypted]
+            public string Telephone { get => telephone; set => telephone = value; }
+
+            /// <summary>
+            /// 联系座机号
+            /// </summary>
+            [Encrypted]
+            public string Phone { get => phone; set => phone = value; }
+
+            /// <summary>
+            /// 邮件
+            /// </summary>
+            [Encrypted]
+            public string Email { get => email; set => email = value; }
+
+            /// <summary>
+            /// 所属区域(所在城市)
+            /// </summary>
+            public string Location { get => location; set => location = value; }
+
+            /// <summary>
+            /// 地址
+            /// </summary>
+            public string Address { get => address; set => address = value; }
+
+            /// <summary>
+            /// 生日
+            /// </summary>
+            public string Birthday { get => birthday; set => birthday = value; }
+
+            /// <summary>
+            /// 其他信息
+            /// </summary>
+            public string OtherInfo { get => otherinfo; set => otherinfo = value; }
+
+            /// <summary>
+            /// 微信
+            /// </summary>
+            public string Wechat { get => wechat; set => wechat = value; }
+
+            /// <summary>
+            /// 分类
+            /// </summary>
+            public string Category { get => category; set => category = value; }
+
+            /// <summary>
+            /// 预计出团
+            /// </summary>
+            public int PreDele { get => predele; set => predele = value; }
+
+            /// <summary>
+            /// 已出团
+            /// </summary>
+            public int FinlishedDele { get => finlishedDele; set => finlishedDele = value; }
+
+            /// <summary>
+            /// 最后更新者Id
+            /// </summary>
+            public string LastUpdateUserName { get => lastUpdateUserName; set => lastUpdateUserName = value; }
+
+            /// <summary>
+            /// 最后更新时间
+            /// </summary>
+            public DateTime LastUpdateTime { get => lastUpdateTime; set => lastUpdateTime = value; }
+        }
+
+
         #endregion
 
         #region DeepSeek 测试

+ 2 - 3
OASystem/OASystem.Api/Middlewares/ExceptionHandlingMiddleware.cs

@@ -80,7 +80,6 @@ namespace OASystem.API.Middlewares
                         errorResponse.Msg = businessEx.Message;
                         errorResponse.Code = StatusCodes.Status400BadRequest; // 设置正确的 HTTP 状态码
                         break;
-
                     case SqlException sqlEx when sqlEx.Number == -2:
                         response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                         errorResponse.Msg = "数据库连接超时,请稍后重试。";
@@ -110,8 +109,8 @@ namespace OASystem.API.Middlewares
                             : ex.Message;
                         break;
                     default:
-                        response.StatusCode = StatusCodes.Status500InternalServerError;
-                        errorResponse.Msg = "服务器内部错误"; // 不直接暴露异常详细信息
+                        response.StatusCode = StatusCodes.Status400BadRequest;
+                        errorResponse.Msg = exception.Message; // 不直接暴露异常详细信息
                         break;
                 }
 

+ 98 - 5
OASystem/OASystem.Api/OAMethodLib/GeneralMethod.cs

@@ -4328,6 +4328,7 @@ namespace OASystem.API.OAMethodLib
                     CurrencyCode = sd.Name.ToUpper(),
                     CurrencyName = sd.Remark
                 })
+                .Distinct()
                 .ToListAsync();
 
             //出入境费用存储的币种及汇率
@@ -4344,6 +4345,101 @@ namespace OASystem.API.OAMethodLib
             //合并已使用币种及汇率
             infos.ForEach(x =>
             {
+                if (x.CurrencyCode.Equals("CNY")) x.Rate = 1.0000M;
+
+                var eexCurrencyInfo = eexCurrencyInfos.Where(y => y.CurrencyCode == x.CurrencyCode).FirstOrDefault();
+                if (eexCurrencyInfo != null)
+                {
+                    x.Rate = eexCurrencyInfo.Rate;
+                }
+            });
+
+            //未存储费用集合
+            var unSaveCurrInfos = infos.Where(x => !eexCurrencyInfos.Any(y => y.CurrencyCode == x.CurrencyCode)).ToList();
+            if (unSaveCurrInfos.Any())
+            {
+                var currencyRate = await _juHeApi.PostItemRateAsync(unSaveCurrInfos.Select(it => it.CurrencyCode!).ToArray());
+                if (currencyRate.Count > 0)
+                {
+                    foreach (var item in infos)
+                    {
+                        var rateInfo = currencyRate.Where(it => it.Name.Equals(item.CurrencyName)).FirstOrDefault();
+                        if (rateInfo != null)
+                        {
+                            decimal rate1 = Convert.ToDecimal(rateInfo.FSellPri) / 100.00M;
+                            rate1 *= _fxRateRise;
+
+                            item.Rate = rate1.TruncDecimals(4) + _xchgRateAdj;
+                        }
+                    }
+                }
+            }
+
+            return infos;
+        }
+
+        /// <summary>
+        /// 城市区间-草稿费用详情 使用的币种及汇率
+        /// </summary>
+        /// <param name="draftId"></param>
+        /// <returns></returns>
+        public static async Task<List<CurrencyInfo>> EnterExitCostDrafOVFeeUsedCurrencyAsync(int draftId = 0)
+        {
+            var infos = new List<CurrencyInfo>();
+
+            bool isUsedDraft = false;
+            var countryies = new List<string>();
+
+            var drafInfo = await _sqlSugar.Queryable<Grp_EnterExitCostDraft>().Where(x => x.Id == draftId).FirstAsync();
+
+            if (drafInfo != null)
+            {
+
+                var cityIds = await _sqlSugar.Queryable<Grp_DayAndCostDraft>()
+               .Where(x => x.IsDel == 0 && x.ParentId == draftId)
+               .Select(x => x.NationalTravelFeeId)
+               .Distinct()
+               .ToListAsync();
+
+                var countries = await _sqlSugar.Queryable<Grp_NationalTravelFee>()
+                    .Where(x => x.IsDel == 0 && cityIds.Contains(x.Id))
+                    .Select(x => x.Country)
+                    .Distinct()
+                    .ToListAsync();
+
+                if (countryies.Any())
+                {
+                    isUsedDraft = true;
+                }
+            }
+
+            infos = await _sqlSugar.Queryable<Res_OverseaVehicle>()
+                .LeftJoin<Sys_SetData>((ov, sd) => ov.Currency == sd.Id)
+                .Where((ov, sd) => ov.IsDel == 0)
+                .WhereIF(isUsedDraft, (ov, sd) => countryies.Contains(ov.CountryName))
+                .Select((ov, sd) => new CurrencyInfo()
+                {
+                    CurrencyCode = sd.Name.ToUpper(),
+                    CurrencyName = sd.Remark
+                })
+                .Distinct()
+                .ToListAsync();
+
+            //出入境费用存储的币种及汇率
+            var eexCurrencyInfos = new List<CurrencyInfo>();
+            if (infos.Any())
+            {
+                if (drafInfo != null)
+                {
+                    eexCurrencyInfos = CommonFun.GetCurrencyChinaToList(drafInfo.CurrencyRemark);
+                }
+            }
+
+            //合并已使用币种及汇率
+            infos.ForEach(x =>
+            {
+                if (x.CurrencyCode.Equals("CNY")) x.Rate = 1.0000M;
+
                 var eexCurrencyInfo = eexCurrencyInfos.Where(y => y.CurrencyCode == x.CurrencyCode).FirstOrDefault();
                 if (eexCurrencyInfo != null)
                 {
@@ -5938,8 +6034,8 @@ namespace OASystem.API.OAMethodLib
             result = kimiApiResult_JObject["content"].ToString();
             if (!string.IsNullOrEmpty(result))
             {
-                TimeSpan ts = TimeSpan.FromHours(2); //过期时间 2 小时
-                await RedisRepository.RedisFactory.CreateRedisRepository().StringSetAsync<string>(redisKeyName, result, ts);//string 存
+                TimeSpan expiry = TimeSpan.FromMinutes(5);  // 5分钟
+                await RedisRepository.RedisFactory.CreateRedisRepository().StringSetAsync<string>(redisKeyName, result, expiry);//string 存
             }
 
             return result;
@@ -5991,8 +6087,6 @@ namespace OASystem.API.OAMethodLib
         }
         #endregion
 
-
-
         public static async Task<ExportResult> ExportToExcel<T>(IEnumerable<T> data, string fileName, string sheetName = "Sheet1", string templateType = "default")
         {
             try
@@ -6637,7 +6731,6 @@ namespace OASystem.API.OAMethodLib
         }
         #endregion
 
-
         #region 动态参数字符串格式化
 
         /// <summary>

+ 4 - 2
OASystem/OASystem.Api/OASystem.API.csproj

@@ -9,11 +9,13 @@
   </PropertyGroup>
 
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
-    <NoWarn>1701;1702;1591;8618;1570;8603;8604;8602;8600;0168;8601;1998;</NoWarn>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
+    <NoWarn>$(NoWarn);1591;701;1702;8618;1570;8603;8604;8602;8600;0168;8601;1998;</NoWarn>
   </PropertyGroup>
 
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
-    <NoWarn>1701;1702;1591;8618;1570;8603;8604;8602;8600;0168;8601;1998;</NoWarn>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
+    <NoWarn>$(NoWarn);1591;701;1702;8618;1570;8603;8604;8602;8600;0168;8601;1998;</NoWarn>
   </PropertyGroup>
 
   <ItemGroup>

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

@@ -250,10 +250,6 @@ builder.Services.AddScoped(options =>
             //获取无参数SQL对性能有影响,特别大的SQL参数多的,调试使用
             //UtilMethods.GetSqlString(DbType.SqlServer, exp.sql, exp.parameters);
 
-
-
-
-
         };
         //修改SQL和参数的值
         db.Aop.OnExecutingChangeSql = (sql, pars) =>

BIN
OASystem/OASystem.Api/wwwroot/exports/exports/excel/客户资料资料(YQY)_0f4beae08b7b4f53b9f27113563fc5d2.xlsx


BIN
OASystem/OASystem.Api/wwwroot/exports/exports/excel/客户资料资料(ZQ)_6c09dbea11914d2eafe96e5a4fdb0a5d.xlsx


+ 15 - 8
OASystem/OASystem.Domain/Dtos/Groups/EnterExitCostDraftDto.cs

@@ -1,9 +1,4 @@
 using OASystem.Domain.ViewModels.Groups;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace OASystem.Domain.Dtos.Groups
 {
@@ -164,10 +159,20 @@ namespace OASystem.Domain.Dtos.Groups
         public decimal AirTD { get; set; }
 
         /// <summary>
-        ///  国外城市间交通费
+        ///  国外城市间交通费 - 经济舱
         /// </summary>
         public decimal CityTranffic { get; set; }
 
+        /// <summary>
+        ///  国外城市间交通费 - 公务舱
+        /// </summary>
+        public decimal CityTranffic1 { get; set; }
+
+        /// <summary>
+        ///  国外城市间交通费 - 头等舱
+        /// </summary>
+        public decimal CityTranffic2 { get; set; }
+
         public string TwoItemRemark { get; set; }
 
         /// <summary>
@@ -276,7 +281,8 @@ namespace OASystem.Domain.Dtos.Groups
     }
     public class EnterExitCostDraftCorrelationTipsDto : PortDtoBase { }
 
-    public class EnterExitCostDraftVisaTipsDto : PortDtoBase {
+    public class EnterExitCostDraftVisaTipsDto : PortDtoBase
+    {
 
         public int DraftId { get; set; }
     }
@@ -315,7 +321,8 @@ namespace OASystem.Domain.Dtos.Groups
     public class EnterExitCostDraftOtherExpensesDelDto : DelBaseDto { }
 
 
-    public class EnterExitCostDraftImportDataDto: PortDtoBase {
+    public class EnterExitCostDraftImportDataDto : PortDtoBase
+    {
         public int UserId { get; set; }
         public int DraftId { get; set; }
         public int GroupId { get; set; }

+ 29 - 1
OASystem/OASystem.Domain/Dtos/Groups/EnterExitCostDto.cs

@@ -483,10 +483,28 @@ namespace OASystem.Domain.Dtos.Groups
 
     public class GetEnterExitCostOVFeeSaveDto: CityIntervalInfo
     {
+        /// <summary>
+        /// 团组Id
+        /// </summary>
         public int GroupId { get; set; }
+        /// <summary>
+        /// 当前登录用户
+        /// </summary>
         public int CurrUserId { get; set; }
     }
 
+
+    public class EnterExitCostDraftOVFeeSaveDto : CityIntervalDraftInfo
+    {
+        /// <summary>
+        /// 草稿Id
+        /// </summary>
+        public int DraftId { get; set; }
+        /// <summary>
+        /// 当前用户Id
+        /// </summary>
+        public int CurrUserId { get; set; }
+    }
     #endregion
 
     #region Mobile Request Dto
@@ -1162,9 +1180,19 @@ namespace OASystem.Domain.Dtos.Groups
         public decimal AirTD { get; set; }
 
         /// <summary>
-        ///  国外城市间交通费
+        ///  国外城市间交通费 - 经济舱
         /// </summary>
         public decimal CityTranffic { get; set; }
+
+        /// <summary>
+        ///  国外城市间交通费 - 公务舱
+        /// </summary>
+        public decimal CityTranffic1 { get; set; }
+
+        /// <summary>
+        ///  国外城市间交通费 - 头等舱 
+        /// </summary>
+        public decimal CityTranffic2 { get; set; }
         public string TwoItemRemark { get; set; }
     }
 

+ 12 - 9
OASystem/OASystem.Domain/Entities/Groups/Grp_ConfProcess.cs

@@ -122,8 +122,8 @@ namespace OASystem.Domain.Entities.Groups
         /// <summary>
         /// 参与人 
         /// </summary>
-        [SugarColumn(ColumnName = "Participator", ColumnDescription = "参与人 [1,2,3]", IsNullable = true, ColumnDataType = "varchar(200)")]
-        public string Participator { get; set; }
+        [SugarColumn(ColumnName = "Participators", ColumnDescription = "参与人 [1,2,3]", IsNullable = true, IsJson = true, ColumnDataType = "varchar(300)")]
+        public List<int> Participators { get; set; } = new List<int>() { 213 /*李新江*/ };
 
         /// <summary>
         /// 操作人 
@@ -157,6 +157,13 @@ namespace OASystem.Domain.Entities.Groups
         [DefaultValue(false)]
         public bool IsFileUp { get; set; }
 
+        /// <summary>
+        /// 节点操作权限
+        /// </summary>
+        [SugarColumn(ColumnName = "OpUserList", ColumnDescription = "节点操作权限", IsJson = true, ColumnDataType = "varchar(300)")]
+        [DefaultValue(false)]
+        public List<int> OpUserList { get; set; } = new List<int>();
+
         public Grp_ConfProcessNode() { }
 
         /// <summary>
@@ -165,12 +172,6 @@ namespace OASystem.Domain.Entities.Groups
         [SugarColumn(IsIgnore = true)]
         public bool IsEnaFileUpBtn { get; set; }
 
-        /// <summary>
-        /// 参与人
-        /// </summary>
-        [SugarColumn(IsIgnore = true)]
-        public List<int> Participators { get; set; }
-
         /// <summary>
         /// Create
         /// </summary>
@@ -182,10 +183,11 @@ namespace OASystem.Domain.Entities.Groups
         /// <param name="isFileUp">是否上传文件</param>
         /// <param name="currUserId">当前用户Id</param>
         /// <param name="participators">参与人</param>
+        /// <param name="opUserList">节点操作权限</param>
         /// <param name="remark">备注</param>
         /// <returns></returns>
         public static Grp_ConfProcessNode Create(int nodeOrder, string nodeName, string nodeDescTips, ProcessStatus status, bool isCurrent, bool isFileUp, int currUserId,
-            List<int> participators, string remark = null)
+            List<int> participators, List<int> opUserList, string? remark = null)
         {
             bool isEnaFileUpBtn = isFileUp;
 
@@ -199,6 +201,7 @@ namespace OASystem.Domain.Entities.Groups
                 Participators = participators,
                 IsEnaFileUpBtn = isEnaFileUpBtn,
                 IsFileUp = isFileUp,
+                OpUserList = opUserList,
                 CreateUserId = currUserId,
                 Remark = remark
             };

+ 23 - 3
OASystem/OASystem.Domain/Entities/Groups/Grp_EnterExitCostDraft.cs

@@ -1,4 +1,5 @@
-using System;
+using OASystem.Domain.ViewModels.Groups;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -12,7 +13,6 @@ namespace OASystem.Domain.Entities.Groups
     [SugarTable("Grp_EnterExitCostDraft")]
     public class Grp_EnterExitCostDraft : EntityBase
     {
-
         /// <summary>
         /// 归属省份Id
         /// </summary>
@@ -123,11 +123,31 @@ namespace OASystem.Domain.Entities.Groups
         public decimal AirTD { get; set; }
 
         /// <summary>
-        ///  国外城市间交通费
+        ///  国外城市间交通费 - 经济舱
         /// </summary>
         [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
         public decimal CityTranffic { get; set; }
 
+        /// <summary>
+        ///  国外城市间交通费 - 公务舱
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal CityTranffic1{ get; set; }
+
+
+        /// <summary>
+        ///  国外城市间交通费 - 头等舱
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal CityTranffic2 { get; set; }
+
+        /// <summary>
+        /// 城市区间费用详情 
+        /// json 格式存储 CityIntervalInfo
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "varchar(max)",IsJson = true)]
+        public CityIntervalDraftInfo CityIntervalFeeDetails { get; set; } = new CityIntervalDraftInfo();
+
         [SugarColumn(IsNullable = true, ColumnDataType = "varchar(500)")]
         public string TwoItemRemark { get; set; }
         #region 汇率币种

+ 10 - 2
OASystem/OASystem.Domain/Entities/Groups/Grp_ProcessOverview.cs

@@ -169,6 +169,11 @@ namespace OASystem.Domain.Entities.Groups
         [DefaultValue(false)]
         public bool IsPart { get; set; }
 
+        /// <summary>
+        /// 节点可操作用户列表
+        /// </summary>
+        [SugarColumn(ColumnName = "OpUserList", ColumnDescription = "节点可操作用户列表", ColumnDataType = "varchar(max)",IsJson = true)]
+        public List<int> OpUserList { get; set; } = new List<int>();
 
         public Grp_ProcessNode() { }
 
@@ -184,9 +189,11 @@ namespace OASystem.Domain.Entities.Groups
         /// <param name="isFileUp">是否上传文件</param>
         /// <param name="isPart">是否参与</param>
         /// <param name="currUserId">当前用户Id</param>
+        /// <param name="opUserList">节点可操作用户列表</param>
         /// <param name="remark">备注</param>
         /// <returns></returns>
-        public static Grp_ProcessNode Create(int nodeOrder, string nodeName, string nodeDescTips,ProcessStatus status, bool isCurrent, bool isAssist, bool isFileUp,bool isPart, int currUserId, string remark=null)
+        public static Grp_ProcessNode Create(int nodeOrder, string nodeName, string nodeDescTips, ProcessStatus status,
+            bool isCurrent, bool isAssist, bool isFileUp, bool isPart, int currUserId, List<int> opUserList, string? remark = null)
         {
             return new Grp_ProcessNode
             {
@@ -199,6 +206,7 @@ namespace OASystem.Domain.Entities.Groups
                 IsPart = isPart,
                 IsFileUp = isFileUp,
                 CreateUserId = currUserId,
+                OpUserList = opUserList,
                 Remark = remark
             };
         }
@@ -354,7 +362,7 @@ namespace OASystem.Domain.Entities.Groups
         /// <summary>
         /// 操作描述
         /// </summary>
-        [SugarColumn(ColumnName = "OpDesc", ColumnDescription = "操作描述", ColumnDataType = "varchar(500)")]
+        [SugarColumn(ColumnName = "OpDesc", ColumnDescription = "操作描述", ColumnDataType = "varchar(max)")]
         public string OpDesc { get; set; }
 
         /// <summary>

+ 18 - 1
OASystem/OASystem.Domain/Result.cs

@@ -31,32 +31,49 @@
         /// </summary>
         public int Code { get; set; }
 
+
+        /// <summary>
+        /// 错误消息
+        /// </summary>
+        public string Msg{ get; set; }
+
         /// <summary>
         /// 错误详情
         /// </summary>
-        public object Data { get; set; }
+        public new object Data { get; set; }
 
         public BusinessException(string message) : base(message)
         {
             Code = 400;
+            Msg = message;
         }
 
         public BusinessException(int code, string message) : base(message)
         {
             Code = code;
+            Msg = message;
         }
 
         public BusinessException(string message, object details) : base(message)
         {
             Code = 400;
+            Msg = message;
             Data = details;
         }
 
         public BusinessException(int code, string message, object details) : base(message)
         {
             Code = code;
+            Msg = message;
             Data = details;
         }
+
+        public BusinessException(string message, Exception innerException)
+        : base(message, innerException)
+        {
+            Code = 400;
+            Msg = message;
+        }
     }
 
 

+ 11 - 0
OASystem/OASystem.Domain/ViewModels/Financial/Fin_ForeignReceivablesView.cs

@@ -319,6 +319,12 @@ namespace OASystem.Domain.ViewModels.Financial
         public string ChangeColorLabel { get; set; }
 
         public string GroupCost { get; set; }
+
+        /// <summary>
+        /// 成单人
+        /// 2025-12-23 新增
+        /// </summary>
+        public string fulfiller { get; set; }
     }
 
     public class PostSyntheticalReceivableByDateRangeResultView
@@ -434,6 +440,11 @@ namespace OASystem.Domain.ViewModels.Financial
         /// 团组成本 - 报价 明细
         /// </summary>
         public List<ChildFeeInfo> groupCostItem { get; set; }
+
+        /// <summary>
+        /// 成单人
+        /// </summary>
+        public string fulfiller { get; set; }
     }
 
 

+ 11 - 2
OASystem/OASystem.Domain/ViewModels/Groups/EnterExitCostDraftView.cs

@@ -100,7 +100,6 @@ namespace OASystem.Domain.ViewModels.Groups
         /// </summary>
         public decimal OutsideGWPay { get; set; }
 
-
         /// <summary>
         /// 国际旅费合计(头等舱)
         /// </summary>
@@ -124,10 +123,20 @@ namespace OASystem.Domain.ViewModels.Groups
         public decimal AirTD { get; set; }
 
         /// <summary>
-        ///  国外城市间交通费
+        ///  国外城市间交通费 - 经济舱
         /// </summary>
         public decimal CityTranffic { get; set; }
 
+        /// <summary>
+        ///  国外城市间交通费 - 公务舱
+        /// </summary>
+        public decimal CityTranffic1 { get; set; }
+
+        /// <summary>
+        ///  国外城市间交通费 - 头等舱
+        /// </summary>
+        public decimal CityTranffic2 { get; set; }
+
         public string TwoItemRemark { get; set; }
 
         #region 汇率币种

+ 17 - 6
OASystem/OASystem.Domain/ViewModels/Groups/EnterExitCostView.cs

@@ -1293,6 +1293,14 @@ namespace OASystem.Domain.ViewModels.Groups
 
     #region 境外用车
 
+    public class CityIntervalDraftInfo : CityIntervalInfo
+    {
+        /// <summary>
+        /// 团组人数
+        /// </summary>
+        public int GroupSize { get; set; } = 1;
+    }
+
     /// <summary>
     /// 城市区间费用详情
     /// </summary>
@@ -1306,7 +1314,7 @@ namespace OASystem.Domain.ViewModels.Groups
         /// <summary>
         /// 接送机费用详情
         /// </summary>
-        public List<RoundTripTransferInfo> APTFeeDetails { get; set; }
+        public List<RoundTripTransferInfo> APTFeeDetails { get; set; } = new List<RoundTripTransferInfo>();
 
         /// <summary>
         /// 拉车费用合计
@@ -1316,7 +1324,7 @@ namespace OASystem.Domain.ViewModels.Groups
         /// <summary>
         /// 拉车费用详情
         /// </summary>
-        public List<PullCartInfo> PullCartFeeDetails { get; set; }
+        public List<PullCartInfo> PullCartFeeDetails { get; set; } = new List<PullCartInfo>();
 
         /// <summary>
         /// 火车费用合计
@@ -1326,7 +1334,7 @@ namespace OASystem.Domain.ViewModels.Groups
         /// <summary>
         /// 火车费用详情
         /// </summary>
-        public List<TrainInfo> TrainFeeDetails { get; set; }
+        public List<TrainInfo> TrainFeeDetails { get; set; } = new List<TrainInfo>();
 
         /// <summary>
         /// 城市机票费用合计
@@ -1336,12 +1344,12 @@ namespace OASystem.Domain.ViewModels.Groups
         /// <summary>
         /// 城市机票费用详情
         /// </summary>
-        public List<CityAirTicketInfo> CityAirTicketFeeDetails { get; set; }
+        public List<CityAirTicketInfo> CityAirTicketFeeDetails { get; set; } = new List<CityAirTicketInfo>();
 
         /// <summary>
         /// 币种信息
         /// </summary>
-        public List<CurrencyInfo> Currencies { get; set; }
+        public List<CurrencyInfo> Currencies { get; set; } = new List<CurrencyInfo>();
 
         /// <summary>
         /// 最后操作人
@@ -1409,6 +1417,9 @@ namespace OASystem.Domain.ViewModels.Groups
 
     public class CityIntervalBase
     {
+        /// <summary>
+        /// 序号
+        /// </summary>
         public int No { get; set; }
 
         /// <summary>
@@ -1422,7 +1433,7 @@ namespace OASystem.Domain.ViewModels.Groups
         public decimal Coefficient { get; set; }
 
         /// <summary>
-        /// 国家、城市 成本币种
+        /// 成本币种
         /// </summary>
         public string CurrencyName { get; set; }
 

+ 1 - 4
OASystem/OASystem.Domain/ViewModels/Groups/ProcessOverView.cs

@@ -37,9 +37,6 @@ namespace OASystem.Domain.ViewModels.Groups
     public class ConfProcessOverInfoView
     { 
         public int Id { get; set; }
-
-        
-
         public int GroupId { get; set; }
         public ConfProcessType ProcessType { get; set; }
         public string ProcessName { get; set; }
@@ -54,11 +51,11 @@ namespace OASystem.Domain.ViewModels.Groups
         public string NodeDescTips { get; set; }
         public ProcessStatus OverallStatus { get; set; }
         public List<int> Participators { get; set; }
+        public List<int> OpUserList { get; set; }
         public string StatusText { get; set; }
         public string Operator { get; set; }
         public string OpeateTime { get; set; }
         public string ActualDone { get; set; }
-
         public bool IsEnaFileUpBtn { get; set; }
         public bool IsFileUp { get; set; }
     }

+ 72 - 0
OASystem/OASystem.Domain/ViewModels/Groups/ProcessView.cs

@@ -0,0 +1,72 @@
+using OASystem.Domain.Entities.Groups;
+using OASystem.Domain.Enums;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.ViewModels.Groups
+{
+    public class ProcessView
+    {
+    }
+
+    /// <summary>
+    /// 团组流程View
+    /// </summary>
+    public class ProcessDetailsView
+    {
+        public int Id { get; set; }
+        public int GroupId { get; set; }
+        public GroupProcessType ProcessType { get; set; }
+        public string ProcessName { get; set; }
+        public List<ProcessNodeDetailsView> Nodes { get; set; } = new List<ProcessNodeDetailsView>();
+    }
+
+    public class ProcessNodeDetailsView
+    {
+        public int Id { get; set; }
+        public int ProcessId { get; set; }
+        public int NodeOrder { get; set; }
+        public string NodeName { get; set; }
+        public ProcessStatus OverallStatus { get; set; }
+        public string StatusText { get; set; }
+        public string Operator { get; set; }
+        public string OpeateTime { get; set; }
+        public string ActualDone { get; set; }
+        /// <summary>
+        /// 可操作用户列表
+        /// </summary>
+        public List<int> OpUserList { get; set; } = new List<int>();
+        public string NodeDescTips { get; set; }
+        /// <summary>
+        /// 是否启用财务流程首节点协助按钮
+        /// </summary>
+        public bool IsEnaAssistBtn { get; set; }
+        /// <summary>
+        /// 财务流程首节点 存储值
+        /// </summary>
+        public bool IsAssist { get; set; }
+        /// <summary>
+        /// 是否启用上传文件按钮
+        /// </summary>
+        public bool IsEnaFileUpBtn { get; set; }
+        /// <summary>
+        /// 票据上传节点 存储值
+        /// </summary>
+        public bool IsFileUp { get; set; }
+        /// <summary>
+        /// 是否启用参与按钮
+        /// </summary>
+        public bool IsEnaPartBtn { get; set; }
+        /// <summary>
+        /// 参与按钮 存储值
+        /// </summary>
+        public bool IsPart { get; set; }
+        /// <summary>
+        /// 签证节点类型使用
+        /// </summary>
+        public List<VisaProcessNode> VisaSubNodes { get; set; } = new List<VisaProcessNode>();
+    }
+}

+ 1 - 1
OASystem/OASystem.Domain/ViewModels/JsonView.cs

@@ -20,7 +20,7 @@ public class JsonView
     /// <summary>
     /// 数据
     /// </summary>
-    public object? Data { get; set; } = new { };
+    public object? Data { get; set; }
 
     public JsonView() { }
     public JsonView(bool isSuccess, string msg)

+ 7 - 12
OASystem/OASystem.Domain/ViewModels/PersonnelModule/TaskAllocationView.cs

@@ -24,7 +24,7 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
         /// <summary>
         /// 任务操作权限
         /// </summary>
-        public TaskOperationAudit TaskOperationAudit { get; set; }
+        public TaskOperationPerm OperationPerm { get; set; }
         /// <summary>
         /// 任务名称 Items
         /// </summary>
@@ -82,37 +82,32 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
     /// <summary>
     /// 任务操作权限
     /// </summary>
-    public class TaskOperationAudit
+    public class TaskOperationPerm
     {
         /// <summary>
         /// 任务添权限
-        /// 0 否 1 是
         /// </summary>
-        public int TaskAddAudit { get; set; } = 0;
+        public bool IsAddPerm { get; set; } = false;
 
         /// <summary>
         /// 任务删除权限
-        /// 0 否 1 是
         /// </summary>
-        public int TaskDelAudit { get; set; } = 0;
+        public bool IsDelPerm { get; set; } = false;
 
         /// <summary>
         /// 任务终止权限
-        /// 0 否 1 是
         /// </summary>
-        public int TasStopAudit { get; set; } = 0;
+        public bool IsStopPerm { get; set; } = false;
 
         /// <summary>
         /// 任务确认权限
-        /// 0 否 1 是
         /// </summary>
-        public int TaskComfirmAudit { get; set; } = 0;
+        public bool IsComfirmPerm { get; set; } = false;
 
         /// <summary>
         /// 任务评分权限
-        /// 0 否 1 是
         /// </summary>
-        public int TaskScoreAudit { get; set; } = 0;
+        public bool IsScorePerm { get; set; } = false;
     }
 
     /// <summary>

+ 5 - 1
OASystem/OASystem.Domain/ViewModels/Resource/OverseaVehicleView.cs

@@ -68,7 +68,7 @@ namespace OASystem.Domain.ViewModels.Resource
     public class OverseaVehicleInfoView : OverseaVehicleView
     {
         /// <summary>
-        /// 洲名称
+        /// 洲名称
         /// </summary>
         public string ContinentName { get; set; }
 
@@ -127,21 +127,25 @@ namespace OASystem.Domain.ViewModels.Resource
         /// <summary>
         /// 车型名称
         /// </summary>
+        /// <example>七座</example>
         public string CarTypeName { get; set; }
 
         /// <summary>
         /// 服务类型
         /// </summary>
+        /// <example>1</example>
         public VehicleServiceTypeEnum ServiceType { get; set; }
 
         /// <summary>
         /// 价格
         /// </summary>
+        /// <example>2000.50</example>
         public decimal Price { get; set; }
 
         /// <summary>
         /// 备注
         /// </summary>
+        /// <example>默认备注</example>
         public string Remark { get; set; }
     }
 

+ 1 - 1
OASystem/OASystem.Infrastructure/Repositories/CRM/NewClientDataRepository.cs

@@ -190,7 +190,7 @@ namespace OASystem.Infrastructure.Repositories.CRM
                 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);
+            var cachedData = await _redisHelper.StringGetAsync<(List<SerializableAscribedUser>?, List<SerializableAscribedDepartment>?)>(cacheKey);
             cachedData.Item1 = null;
             cachedData.Item2 = null;
 

+ 14 - 14
OASystem/OASystem.Infrastructure/Repositories/Groups/EnterExitCostDraftRepository.cs

@@ -243,20 +243,20 @@ namespace OASystem.Infrastructure.Repositories.Groups
                     enterExitCostInfoView.TrainingExpenseData = dayAndCostDraftData.Where(it => it.Type == 4).ToList();  //培训费 4
 
                     enterExitCostInfoView.DayOtherPriceData = _sqlSugar.Queryable<Grp_DayOtherPriceDraft>()
-                                                                .Where(x => x.IsDel == 0 && x.ParentId == id)
-                                                                .Select(x => new DayOtherPriceDraftView
-                                                                {
-                                                                    ParentId = x.ParentId,
-                                                                    Id = x.Id,
-                                                                    Cost = x.Cost,
-                                                                    Currency = x.Currency,
-                                                                    Index = x.Index,
-                                                                    SetDataId = x.SetDataId,
-                                                                    SubTotal = x.SubTotal,
-                                                                    Remark = x.Remark,
-                                                                })
-                                                                .OrderBy(x => x.Index)
-                                                                .ToList();
+                        .Where(x => x.IsDel == 0 && x.ParentId == id)
+                        .Select(x => new DayOtherPriceDraftView
+                        {
+                            ParentId = x.ParentId,
+                            Id = x.Id,
+                            Cost = x.Cost,
+                            Currency = x.Currency,
+                            Index = x.Index,
+                            SetDataId = x.SetDataId,
+                            SubTotal = x.SubTotal,
+                            Remark = x.Remark,
+                        })
+                        .OrderBy(x => x.Index)
+                        .ToList();
 
                     enterExitCostInfoView.Currencys = (List<CurrencyInfo>?)CommonFun.GetCurrencyChinaToList(enterExitCostDraftData.CurrencyRemark);
 

+ 3 - 2
OASystem/OASystem.Infrastructure/Repositories/Groups/InvertedListRepository.cs

@@ -167,7 +167,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// </summary>
         /// <param name="diId"></param>
         /// <returns></returns>
-        public async Task<Result> _Create(int userId,int diId)
+        public async Task<Result> _Create(int userId,int diId,string remark = "")
         {
             #region 参数验证
             if (diId < 1)
@@ -196,7 +196,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 return _result;
             }
 
-            if (string.IsNullOrEmpty( groupInfo.VisitDate.ToString()))
+            if (string.IsNullOrEmpty(groupInfo.VisitDate.ToString()))
             {
                 _result.Msg = @$"团组出访时间未填写,不可创建!";
                 return _result;
@@ -275,6 +275,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 PreTripMeetingDt = visitDt.AddDays(preTripMeeting_advanceDays).ToString("yyyy-MM-dd"),
                 AirportdDropOffDt = visitDt.AddDays(airportdDropOff_advanceDays).ToString("yyyy-MM-dd"),
                 CreateUserId = userId,
+                Remark = remark
             };
 
             if (!string.IsNullOrEmpty(sqqzRemark)) info.SendVisaRemark = sqqzRemark;

Разлика између датотеке није приказан због своје велике величине
+ 1117 - 327
OASystem/OASystem.Infrastructure/Repositories/Groups/ProcessOverviewRepository.cs


+ 4 - 4
OASystem/OASystem.Infrastructure/Repositories/Groups/VisaProcessRepository.cs

@@ -384,7 +384,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// <param name="operatorId">操作人用户ID</param>
         /// <returns>表示异步操作的任务</returns>
         /// <remarks>此方法会自动比较前后数据的差异,生成变更字段列表和操作描述</remarks>
-        public async Task LogOperationAsync(Grp_VisaProcessSteps before, Grp_VisaProcessSteps after,string opType, int operatorId)
+        public async Task LogOperationAsync(Grp_VisaProcessSteps? before, Grp_VisaProcessSteps? after,string opType, int operatorId)
         {
             // 合并基础排除字段和额外排除字段
             var allExcludedFields = GetDefaultExcludedFields();
@@ -421,7 +421,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// <param name="after">变更后</param>
         /// <param name="exclFields">排除字段</param>
         /// <returns>变更详情列表</returns>
-        private List<FieldChangeDetail> GetChangeDetails(Grp_VisaProcessSteps before, Grp_VisaProcessSteps after, List<string> exclFields = null)
+        private List<FieldChangeDetail> GetChangeDetails(Grp_VisaProcessSteps? before, Grp_VisaProcessSteps? after, List<string>? exclFields = null)
         {
             var changeDetails = new List<FieldChangeDetail>();
             var defaultExclFields = GetDefaultExcludedFields();
@@ -516,8 +516,8 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// <param name="after">操作后</param>
         /// <param name="chgDetails">变更详情</param>
         /// <returns>操作描述</returns>
-        private static string GenerateOpDesc(string opType, Grp_VisaProcessSteps before,
-            Grp_VisaProcessSteps after, List<FieldChangeDetail> chgDetails)
+        private static string GenerateOpDesc(string opType, Grp_VisaProcessSteps? before,
+            Grp_VisaProcessSteps? after, List<FieldChangeDetail>? chgDetails)
         {
             if (!chgDetails.Any())
             {

+ 40 - 5
OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/CompanyDailyKpiRepository.cs

@@ -166,9 +166,39 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         /// 基础数据
         /// </summary>
         /// <returns></returns>
-        public async Task<JsonView> InitAsync()
+        public async Task<JsonView> InitAsync(int currUserId)
         {
-            var depNames = new List<string> { "财务部", "市场部" };
+            var currUserInfo = await _sqlSugar.Queryable<Sys_Users>()
+                .LeftJoin<Sys_JobPost>((u, jp) => u.JobPostId == jp.Id)
+                .LeftJoin<Sys_Department>((u, jp, d) => u.DepId == d.Id)
+                .LeftJoin<Sys_Company>((u, jp, d, c) => u.CompanyId == c.Id)
+                .Where((u, jp, d, c) => u.IsDel == 0 && u.Id == currUserId)
+                .Select((u, jp, d, c) => new
+                {
+                    UserId = u.Id,
+                    u.CompanyId,
+                    c.CompanyName,
+                    u.DepId,
+                    d.DepName,
+                    u.JobPostId,
+                    jp.JobName,
+                    UserName = u.CnName
+                })
+                .OrderBy(u => u.CompanyId)
+                .FirstAsync();
+            if (currUserInfo == null)
+            {
+                _jv.Msg = $"当前登录用户信息不存在。";
+                return _jv;
+            }
+
+            //验证是否是经理主管 是 可操作保存;是被考核人只能查看自己
+            var isSave = !string.IsNullOrEmpty(currUserInfo.JobName) &&
+                          (currUserInfo.JobName.Contains("总监") ||
+                           currUserInfo.JobName.Contains("经理") ||
+                           currUserInfo.JobName.Contains("主管"));
+
+            var depNames = new List<string> { currUserInfo?.DepName ?? "" };
             var result = await KpiDepartmentsAndJobs(depNames);
             if (!result.Success)
             {
@@ -199,9 +229,14 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 .SelectMany(x => x.JobNames)
                 .ToList();
 
-            var view = userInfos.Where(x => jobNames.Contains(x.JobName))
-                .Select(x => new KpiTempUserInfo() { Id = x.UserId, DepName = x.DepName, JobName = x.JobName, Name = x.UserName })
-                .ToList();
+            var view = new
+            {
+                isOp = isSave,
+                userInfos = userInfos.Where(x => jobNames.Contains(x.JobName))
+                    .WhereIF(!isSave, x=> x.UserId == currUserId)
+                    .Select(x => new KpiTempUserInfo() { Id = x.UserId, DepName = x.DepName, JobName = x.JobName, Name = x.UserName })
+                    .ToList()
+            };
             _jv.Code = StatusCodes.Status200OK;
             _jv.Data = view;
             _jv.Msg = $"操作成功";

+ 47 - 21
OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/TaskAllocationRepository.cs

@@ -47,19 +47,19 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         /// <param name="taskAllocation"></param>
         /// <param name="userId"></param>
         /// <returns></returns>
-        public TaskOperationAudit TaskOperationAudit(Pm_TaskAllocation taskAllocation, int userId)
+        public TaskOperationPerm TaskOperationAudit(Pm_TaskAllocation taskAllocation, int userId)
         {
-            TaskOperationAudit taskOperationAudit = new TaskOperationAudit();
+            TaskOperationPerm taskOperationPrem = new TaskOperationPerm();
             if (taskAllocation.CreateUserId == userId)
             {
-                taskOperationAudit.TaskAddAudit = 1;
-                taskOperationAudit.TaskDelAudit = 1;
-                taskOperationAudit.TasStopAudit = 1;
-                taskOperationAudit.TaskComfirmAudit = 1;
-                taskOperationAudit.TaskScoreAudit = 1;
+                taskOperationPrem.IsAddPerm = true;
+                taskOperationPrem.IsDelPerm = true;
+                taskOperationPrem.IsStopPerm = true;
+                taskOperationPrem.IsComfirmPerm = true;
+                taskOperationPrem.IsScorePerm = true;
             }
 
-            return taskOperationAudit;
+            return taskOperationPrem;
         }
 
         /// <summary>
@@ -77,16 +77,25 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 }
 
                 //任务类型
-                var taskTypeInfos = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.STid == 127 && x.IsDel == 0)
+                var taskTypeInfos = _sqlSugar.Queryable<Sys_SetData>()
+                    .Where(x => x.STid == 127 && x.IsDel == 0)
                     .Select(x => new ValueInfo { Id = x.Id, Name = x.Name })
                     .ToList();
 
-                //任务名称
-                var taskNameInfos = _sqlSugar.Queryable<Pm_TaskAllocation, Pm_TaskRelevanceUser>((ta, tau) => new JoinQueryInfos(JoinType.Left, ta.Id == tau.TAId))
-                    .Where((ta, tau) => ta.IsDel == 0 && tau.IsDel == 0)
-                    .Where((ta, tau) => ta.CreateUserId == userId || tau.UserId == userId)
-                    .Select(ta => ta.TaskName).ToList()
-                    .Distinct().ToList();
+                //任务名称 
+                var taskNameInfos = _sqlSugar.Queryable<Pm_TaskAllocation, Pm_TaskRelevanceUser>((ta, taru) => new JoinQueryInfos(JoinType.Left, ta.Id == taru.TAId))
+                    .Where((ta, taru) => ta.IsDel == 0 && taru.IsDel == 0)
+                    .Where((ta, taru) => ta.CreateUserId == userId || taru.UserId == userId)
+                    .OrderByDescending((ta, taru) => ta.CreateTime)
+                    .Select((ta, taru) => new
+                    {
+                        ta.TaskName,
+                        ta.CreateTime 
+                    })
+                    .ToList()
+                    .DistinctBy(x => x.TaskName)
+                    .Select(x => x.TaskName) 
+                    .ToList();
 
                 //团组名称
                 var groupNameInfos = _sqlSugar.Queryable<Grp_DelegationInfo>()
@@ -104,7 +113,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
 
                 //执行任务人员信息 1 公司总经理/副总 可分配 所有人的任务 2 公司 部门经理/主管 可分配 部门下的人员的任务
                 var executeTaskUserInfos = new List<ExecuteTaskUserInfo>();
-                var taskOpertionAudit = new TaskOperationAudit();
+                var taskOpertionAudit = new TaskOperationPerm();
 
                 var taskAudits = _sqlSugar.Queryable<Pm_TaskJobRelevancy>().Where(it => it.IsDel == 0 && it.PrimaryUserId == userId).ToList();
                 var taslPerm = taskAudits.Any();
@@ -122,9 +131,9 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     //任务权限
                     if (taslPerm)
                     {
-                        taskOpertionAudit.TaskAddAudit = 1;
-                        taskOpertionAudit.TaskDelAudit = 1;
-                        taskOpertionAudit.TasStopAudit = 1;
+                        taskOpertionAudit.IsAddPerm = true;
+                        taskOpertionAudit.IsDelPerm = true;
+                        taskOpertionAudit.IsStopPerm = true;
                     }
 
                     var userIds = taskAudits.Select(it => it.SubUserId).ToList();
@@ -141,7 +150,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
 
                 var view = new InitView()
                 {
-                    TaskOperationAudit = taskOpertionAudit,
+                    OperationPerm = taskOpertionAudit,
                     TaskNameInfos = taskNameInfos,
                     ExecuteTaskUserInfos = executeTaskUserInfos,
                     GroupNameInfos = groupNameInfos,
@@ -156,6 +165,23 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             return _result;
         }
 
+        /// <summary>
+        /// 任务发布者验证
+        /// </summary>
+        /// <returns></returns>
+        public async Task<(bool isTaskPublisher, List<int> userIds)> ValidateTaskPublisher(int userId)
+        {
+            var taskAudits = await _sqlSugar.Queryable<Pm_TaskJobRelevancy>().Where(it => it.IsDel == 0 && it.PrimaryUserId == userId).ToListAsync();
+            
+            if (taskAudits.Any())
+            {
+                return (true, taskAudits.Select(x => x.SubUserId).ToList());
+            }
+
+            return (false, new List<int>());
+        }
+
+
         /// <summary>
         /// 任务指派
         /// 详情
@@ -1353,7 +1379,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         /// <param name="after">变更后</param>
         /// <param name="exclFields">排除字段</param>
         /// <returns>变更详情列表</returns>
-        private List<FieldChangeDetail> GetChangeDetails(Pm_TaskAllocation before, Pm_TaskAllocation after, List<string> exclFields = null)
+        private List<FieldChangeDetail> GetChangeDetails(Pm_TaskAllocation before, Pm_TaskAllocation after, List<string>? exclFields = null)
         {
             var changeDetails = new List<FieldChangeDetail>();
             var defaultExclFields = GetDefaultExcludedFields();

+ 3 - 3
OASystem/OASystem.Infrastructure/Repositories/Resource/CountryFeeRepository.cs

@@ -388,9 +388,9 @@ namespace OASystem.Infrastructure.Repositories.Resource
                 return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = $"{countryName} 该国家签证费用信息不存在" };
 
 
-            decimal largeVisaQuote = 0.00M,  // 公务签证报价
-                    smallVisaQuote = 0.00M,  // 公务普通签证报价
-                    quotePrice1 = 0.00M;     // 报价费用1
+            //decimal largeVisaQuote = 0.00M,  // 公务签证报价
+            //        smallVisaQuote = 0.00M,  // 公务普通签证报价
+            //        quotePrice1 = 0.00M;     // 报价费用1
             var visaFeeLabel = new StringBuilder(); //签证费用描述
 
             // 103  重庆