Kaynağa Gözat

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

yuanrf 1 gün önce
ebeveyn
işleme
06a6d05782

+ 48 - 24
OASystem/OASystem.Api/Controllers/FinancialController.cs

@@ -1087,29 +1087,42 @@ namespace OASystem.API.Controllers
                     }
 
                     //数据源
-                    List<Grp_DayAndCost> dac1 = _DayAndCosts.Where(it => it.Type == 1).ToList(); //住宿费
-                    List<Grp_DayAndCost> dac2 = _DayAndCosts.Where(it => it.Type == 2).ToList(); //伙食费
-                    List<Grp_DayAndCost> dac3 = _DayAndCosts.Where(it => it.Type == 3).ToList(); //公杂费
-                    List<Grp_DayAndCost> dac4 = _DayAndCosts.Where(it => it.Type == 4).ToList(); //培训费
+                    //住宿费 伙食费 公杂费 培训费 选中才计算出费用
+
+                    //住宿费 选中赋值
+                    List<Grp_DayAndCost> dac1 = new List<Grp_DayAndCost>(); 
+                    if (_EnterExitCosts.ChoiceThree == 1) dac1 = _DayAndCosts.Where(it => it.Type == 1).ToList(); //住宿费
+
+                    //伙食费 选中赋值
+                    List<Grp_DayAndCost> dac2 = new List<Grp_DayAndCost>();
+                    if (_EnterExitCosts.ChoiceFour == 1) dac1 = _DayAndCosts.Where(it => it.Type == 2).ToList(); //伙食费
+
+                    //公杂费 选中赋值
+                    List<Grp_DayAndCost> dac3 = new List<Grp_DayAndCost>();
+                    if (_EnterExitCosts.ChoiceFour == 1) dac1 = _DayAndCosts.Where(it => it.Type == 3).ToList(); //公杂费
+
+                    //培训费 选中赋值
+                    List<Grp_DayAndCost> dac4 = new List<Grp_DayAndCost>();
+                    if (_EnterExitCosts.ChoiceFour == 1) dac1 = _DayAndCosts.Where(it => it.Type == 4).ToList(); //培训费
 
                     //币种Data
                     var currData = _sqlSugar.Queryable<Sys_SetData>().Where(it => it.IsDel == 0 && it.STid == 66).ToList();
 
                     var DeleClientList = _sqlSugar.Queryable<Grp_TourClientList>()
-                                                  .LeftJoin<Crm_DeleClient>((tcl, dc) => tcl.ClientId == dc.Id && dc.IsDel == 0)
-                                                  .LeftJoin<Crm_CustomerCompany>((tcl, dc, cc) => dc.CrmCompanyId == cc.Id && dc.IsDel == 0)
-                                                  .Where((tcl, dc, cc) => tcl.IsDel == 0 && tcl.DiId == dto.DiId)
-                                                  .Select((tcl, dc, cc) => new ClientAirInfo
-                                                  {
-                                                      LastName = dc.LastName,
-                                                      FirstName = dc.FirstName,
-                                                      Sex = dc.Sex,
-                                                      Birthday = dc.BirthDay,
-                                                      Company = cc.CompanyFullName,
-                                                      Job = dc.Job,
-                                                      AirType = tcl.ShippingSpaceTypeId
-                                                  })
-                                                  .ToList();
+                        .LeftJoin<Crm_DeleClient>((tcl, dc) => tcl.ClientId == dc.Id && dc.IsDel == 0)
+                        .LeftJoin<Crm_CustomerCompany>((tcl, dc, cc) => dc.CrmCompanyId == cc.Id && dc.IsDel == 0)
+                        .Where((tcl, dc, cc) => tcl.IsDel == 0 && tcl.DiId == dto.DiId)
+                        .Select((tcl, dc, cc) => new ClientAirInfo
+                        {
+                            LastName = dc.LastName,
+                            FirstName = dc.FirstName,
+                            Sex = dc.Sex,
+                            Birthday = dc.BirthDay,
+                            Company = cc.CompanyFullName,
+                            Job = dc.Job,
+                            AirType = tcl.ShippingSpaceTypeId
+                        })
+                        .ToList();
                     if (DeleClientList.Count < 1)
                     {
                         return Ok(JsonView(false, "暂无团组成员,请先填写团组成员!!!"));
@@ -1124,7 +1137,6 @@ namespace OASystem.API.Controllers
                     var _ClientNames = DeleClientList.Select(x => x.Name).ToList();
                     var _GroupClient = DeleClientList.GroupBy(x => x.Company).ToList();
 
-
                     Dictionary<string, string> bookmarkArr = null;
 
                     string tempPath = AppSettingsHelper.Get("WordBasePath") + $"ForeignReceivables/Temp/汇款通知.docx";
@@ -1169,26 +1181,30 @@ namespace OASystem.API.Controllers
                              *  458	公务舱
                              *  460	经济舱
                              */
-                            decimal airPrice = 0.00M;
+                            decimal airPrice = 0.00M,
+                                    cityTranffic = 0.00M;
                             string airName = string.Empty;
                             if (client.AirType == 457)
                             {
                                 airName = $"头等舱";
                                 airPrice = _EnterExitCosts.AirTD;
+                                cityTranffic = _EnterExitCosts.CityTranffic;
                             }
                             else if (client.AirType == 458)
                             {
                                 airName = $"公务舱";
                                 airPrice = _EnterExitCosts.AirGW;
+                                cityTranffic = _EnterExitCosts.CityTranffic1;
                             }
                             else if (client.AirType == 460)
                             {
                                 airName = $"经济舱";
                                 airPrice = _EnterExitCosts.AirJJ;
+                                cityTranffic = _EnterExitCosts.CityTranffic2;
                             }
 
                             //计算费用总和
-                            decimal AllPrice = airPrice + _EnterExitCosts.CityTranffic + dac1.Sum(x => x.SubTotal) + dac2.Sum(x => x.SubTotal) +
+                            decimal AllPrice = airPrice + cityTranffic + dac1.Sum(x => x.SubTotal) + dac2.Sum(x => x.SubTotal) +
                                                dac3.Sum(x => x.SubTotal) + dac4.Sum(x => x.SubTotal) + _EnterExitCosts.Visa + _EnterExitCosts.Safe +
                                                +_EnterExitCosts.YiMiao + _EnterExitCosts.YiMiao + _EnterExitCosts.Ticket + _EnterExitCosts.Service;
                             WordAllPrice += AllPrice;
@@ -1196,7 +1212,7 @@ namespace OASystem.API.Controllers
                             UsersTop += firstName + "出访费用为¥" + AllPrice.ToString("#0.00") + "元、";
 
                             TeableBookmarkArr.Add("jp", airPrice.ToString("#0.00") + " 元"); //机票金额
-                            TeableBookmarkArr.Add("cs", _EnterExitCosts.CityTranffic.ToString("#0.00") + " 元"); //城市交通费用
+                            TeableBookmarkArr.Add("cs", $"{cityTranffic:#0.00} 元"); //城市交通费用
                             TeableBookmarkArr.Add("zs", dac1.Sum(x => Convert.ToDecimal(x.SubTotal)).ToString("#0.00") + " 元"); //住宿费
                             string zsinfo = string.Empty;
                             string hsinfo = string.Empty;
@@ -1209,6 +1225,7 @@ namespace OASystem.API.Controllers
                             Aspose.Words.Tables.Table ChildTable2 = (Aspose.Words.Tables.Table)FirstTable.GetChild(NodeType.Table, 2, true);
 
                             int rowIndex = 0;
+                            if (dac1.Count <= 0 && ChildTable != null) ChildTable.Remove(); //删除表格
                             foreach (var item in dac1)
                             {
                                 if (string.IsNullOrWhiteSpace(item.Place))
@@ -1258,7 +1275,9 @@ namespace OASystem.API.Controllers
 
                             }
                             placeArr.Clear();
+
                             rowIndex = 0;
+                            if (dac2.Count <= 0 && ChildTable1 != null) ChildTable1.Remove(); //删除表格
                             foreach (var item in dac2)
                             {
                                 if (string.IsNullOrWhiteSpace(item.Place))
@@ -1308,7 +1327,9 @@ namespace OASystem.API.Controllers
 
                             }
                             placeArr.Clear();
+
                             rowIndex = 0;
+                            if (dac2.Count <= 0 && ChildTable2 != null) ChildTable2.Remove(); //删除表格
                             foreach (var item in dac3)
                             {
                                 if (string.IsNullOrWhiteSpace(item.Place))
@@ -1357,6 +1378,7 @@ namespace OASystem.API.Controllers
 
                             }
                             placeArr.Clear();
+                            
                             TeableBookmarkArr.Add("zsinfo", zsinfo); //住宿费详情
                             TeableBookmarkArr.Add("hs", dac2.Sum(x => Convert.ToDecimal(x.SubTotal)).ToString("#0.00") + " 元"); //伙食费
                             TeableBookmarkArr.Add("hsinfo", hsinfo); //伙食费详情
@@ -1772,7 +1794,7 @@ namespace OASystem.API.Controllers
                .ToListAsync();
 
             decimal visaFee = costInfo?.Visa ?? 0.00M, //签证费
-                    IntercityFare = costInfo?.CityTranffic ?? 0.00M, //城市区间交通费
+                    //intercityFare = costInfo?.CityTranffic ?? 0.00M, //城市区间交通费
                     hotelFee = hotelCostInfos.Sum(x => x.Cost), //住宿费
                     hotelCNYEquivalent = hotelCostInfos.Sum(x => x.SubTotal), //住宿费CNY折算价
                     hotelRate = rateInfos.FirstOrDefault(x => x.CurrencyCode.Equals(hotelCostInfos.FirstOrDefault().Name))?.Rate ?? 0.00M; //住宿费汇率
@@ -1780,7 +1802,9 @@ namespace OASystem.API.Controllers
 
             var costInfosNew = new List<GroupAccFee‌ExcelView>() {
                 new (){ CostName = "酒店",CostAmt = hotelFee,CostCurrency = hotelCurrency, CostRate = hotelRate, CNYEquivalent = hotelCNYEquivalent},
-                new (){ CostName = "市区间交通",CostAmt = IntercityFare,CostCurrency = "人民币" },
+                new (){ CostName = "市区间交通-经济舱",CostAmt = costInfo?.CityTranffic ?? 0.00M,CostCurrency = "人民币" },
+                new (){ CostName = "市区间交通-公务舱",CostAmt = costInfo?.CityTranffic1 ?? 0.00M,CostCurrency = "人民币" },
+                new (){ CostName = "市区间交通-头等舱",CostAmt = costInfo?.CityTranffic2 ?? 0.00M,CostCurrency = "人民币" },
                 new (){ CostName = "签证",CostAmt = visaFee,CostCurrency = "人民币" },
             };
 

+ 395 - 151
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -28,6 +28,7 @@ using OASystem.Domain.Dtos.CRM;
 using OASystem.Domain.Dtos.FileDto;
 using OASystem.Domain.Dtos.Financial;
 using OASystem.Domain.Dtos.Groups;
+using OASystem.Domain.Dtos.System;
 using OASystem.Domain.Entities.Customer;
 using OASystem.Domain.Entities.Financial;
 using OASystem.Domain.Entities.Groups;
@@ -349,7 +350,8 @@ namespace OASystem.API.Controllers
             * 获取今天时间往前推5天查询团组c表里有没有费用
             */
             var today_startDate = DateTime.Now.Date.AddDays(-daysAgo);
-            var today_endDate = DateTime.Now.Date.AddDays(-daysAgo).AddDays(1).AddSeconds(-1);
+            //var today_endDate = DateTime.Now.Date.AddDays(-daysAgo).AddDays(1).AddSeconds(-1);
+            var today_endDate = DateTime.Now.Date.AddDays(1).AddSeconds(-1);
 
             var groupNames = await _sqlSugar.Queryable<Grp_DelegationInfo>()
                 .Where(di => di.IsDel == 0)
@@ -365,6 +367,7 @@ namespace OASystem.API.Controllers
                 // 新增条件:不在确认记录表中(排除已确认的团组)
                 .Where(di => !SqlFunc.Subqueryable<Grp_FeeEntryAcknowledge>()
                     .Where(ack => ack.GroupId == di.Id && ack.IsDel == 0 && ack.UserId == currUserId)
+                    .Where(ack => feeTypeIds.Contains(ack.FeeTypeId))
                     .Where(ack => ack.IsAcknowledged == AcknowledgeStatusEnum.Acknowledged) // 只排除已确认的记录
                     .Any())
                 .Select(di => new
@@ -386,7 +389,7 @@ namespace OASystem.API.Controllers
 
         /// <summary>
         /// 提示用户录入团组费用信息
-        /// 已知晓确认操作记录(添加)
+        /// 已知晓确认操作记录(添加) 批量
         /// </summary>
         /// <param name="dto">请求体</param>
         /// <returns></returns>
@@ -396,37 +399,26 @@ namespace OASystem.API.Controllers
         {
             // 1. 参数验证
             if (dto?.GroupIds == null || !dto.GroupIds.Any())
-            {
                 return Ok(JsonView(false, "请选择需要确认的团组!"));
-            }
 
             if (dto.GroupIds.Count > 100)
-            {
                 return Ok(JsonView(false, "一次性确认团组数量不能超过100个!"));
-            }
 
             if (dto.CurrUserId <= 0)
-            {
                 return Ok(JsonView(false, "用户ID无效!"));
-            }
 
-            //2. 验证用户存在性
+            // 2. 验证用户存在性
             var userInfo = await _sqlSugar.Queryable<Sys_Users>()
                 .Where(x => x.Id == dto.CurrUserId && x.IsDel == 0)
                 .Select(x => new { x.Id, x.JobPostId, x.CnName })
                 .FirstAsync();
 
             if (userInfo == null)
-            {
                 return Ok(JsonView(false, "用户不存在或已被禁用!"));
-            }
 
             // 3. 获取费用类型
-            var feeTypeIds = new List<int>() { };
-            if (_dataInit.TryGetValue(userInfo.JobPostId, out var values))
-            {
-                feeTypeIds = values;
-            }
+            if (!_dataInit.TryGetValue(userInfo.JobPostId, out var feeTypeIds) || feeTypeIds?.Count == 0)
+                return Ok(JsonView(false, "当前用户岗位无对应的费用类型配置!"));
 
             // 4. 验证团组存在性
             var validGroupIds = await _sqlSugar.Queryable<Grp_DelegationInfo>()
@@ -435,31 +427,56 @@ namespace OASystem.API.Controllers
                 .ToListAsync();
 
             if (!validGroupIds.Any())
-            {
                 return Ok(JsonView(false, "未找到有效的团组信息!"));
+
+            // 5. 检查团组费用表中是否存在对应费用类型的数据
+            var existingFeeRecords = await _sqlSugar.Queryable<Grp_CreditCardPayment>()
+                .Where(x => validGroupIds.Contains(x.DIId) && x.IsDel == 0)
+                .Where(x => feeTypeIds.Contains(x.CTable))
+                .Select(x => new { GroupId = x.DIId, FeeTypeId = x.CTable })
+                .ToListAsync();
+
+            if (existingFeeRecords.Count > 0)
+            {
+                // 找出有问题的团组和费用类型
+                var problematicGroups = existingFeeRecords
+                    .GroupBy(x => x.GroupId)
+                    .Select(g => new
+                    {
+                        GroupId = g.Key,
+                        FeeTypeIds = string.Join(",", g.Select(x => x.FeeTypeId).Distinct())
+                    })
+                    .ToList();
+
+                var errorMessage = $"以下团组的费用表中已存在费用数据,不可添加确认记录:";
+                foreach (var group in problematicGroups)
+                {
+                    errorMessage += $"\n团组 {group.GroupId} - 费用类型ID: [{group.FeeTypeIds}]";
+                }
+
+                return Ok(JsonView(false, errorMessage));
             }
 
-            // 5. 检查是否已存在确认记录(避免重复确认)
-            var existingRecords = await _sqlSugar.Queryable<Grp_FeeEntryAcknowledge>()
-                .Where(x => validGroupIds.Contains(x.GroupId) &&
-                           x.UserId == dto.CurrUserId &&
-                           x.IsDel == 0)
+            // 6. 检查是否已存在确认记录(避免重复确认)
+            var existingAcknowledgeRecords = await _sqlSugar.Queryable<Grp_FeeEntryAcknowledge>()
+                .Where(x => x.UserId == dto.CurrUserId && x.IsDel == 0)
+                .Where(x => validGroupIds.Contains(x.GroupId))
+                .Where(x => feeTypeIds.Contains(x.FeeTypeId))
                 .Select(x => new { x.GroupId, x.FeeTypeId })
                 .ToListAsync();
 
-            // 6. 准备插入数据(过滤已存在的记录)
-            var infos = new List<Grp_FeeEntryAcknowledge>();
+            // 7. 准备插入数据(过滤已存在的记录)
+            var recordsToInsert = new List<Grp_FeeEntryAcknowledge>();
 
             foreach (var groupId in validGroupIds)
             {
-                // 为每个费用类型创建确认记录
                 foreach (var feeTypeId in feeTypeIds)
                 {
                     // 检查是否已存在相同记录
-                    var exists = existingRecords.Any(x => x.GroupId == groupId && x.FeeTypeId == feeTypeId);
+                    var exists = existingAcknowledgeRecords.Any(x => x.GroupId == groupId && x.FeeTypeId == feeTypeId);
                     if (!exists)
                     {
-                        infos.Add(new Grp_FeeEntryAcknowledge()
+                        recordsToInsert.Add(new Grp_FeeEntryAcknowledge()
                         {
                             GroupId = groupId,
                             UserId = dto.CurrUserId,
@@ -469,23 +486,126 @@ namespace OASystem.API.Controllers
                             AcknowledgeTime = DateTime.Now,
                             AcknowledgeType = Domain.Enums.AcknowledgeTypeEnum.WebConfirm,
                             CreateUserId = 4, // 系统创建
+                            CreateTime = DateTime.Now
                         });
                     }
                 }
             }
 
-            if (!infos.Any())
-            {
+            if (!recordsToInsert.Any())
                 return Ok(JsonView(true, "所选团组已确认,无需重复操作!"));
+
+            // 8. 批量插入数据
+            var successCount = await _sqlSugar.Insertable(recordsToInsert).ExecuteCommandAsync();
+            if (successCount <= 0)
+                return Ok(JsonView(false, "操作失败,未能保存确认记录!"));
+
+            // 9. 记录操作日志
+            _logger.LogInformation("用户 {UserName}(ID:{UserId}) 批量确认了 {GroupCount} 个团组的费用类型,共添加 {RecordCount} 条确认记录",
+                userInfo.CnName, dto.CurrUserId, validGroupIds.Count, successCount);
+
+            // 10. 操作成功 返回成功视图
+            var result = await GetGroupNamesByUserId(dto.CurrUserId,dto.DaysAgo);
+
+            if (result is OkObjectResult okObjectResult)
+            {
+                return Ok(okObjectResult.Value);
             }
 
-            // 7. 批量插入数据
-            var successCount = await _sqlSugar.Insertable(infos).ExecuteCommandAsync();
-            if (successCount < 1)
+            //return Ok(result);
+            return Ok(JsonView(true, $"操作成功!共为 {validGroupIds.Count} 个团组添加了 {successCount} 条确认记录"));
+        }
+
+        /// <summary>
+        /// 提示用户录入团组费用信息
+        /// 已知晓确认操作记录(添加) 单个
+        /// </summary>
+        /// <param name="dto">请求体</param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> FeeEntryAcknowledgeSingleCreate(FeeEntryAcknowledgeSingleDto dto)
+        {
+            // 1. 参数验证
+            if (dto.GroupId <= 0)
+                return Ok(JsonView(false, "请选择有效的团组ID!"));
+
+            if (dto.CurrUserId <= 0)
+                return Ok(JsonView(false, "用户ID无效!"));
+
+            // 2. 验证用户存在性
+            var userInfo = await _sqlSugar.Queryable<Sys_Users>()
+                .Where(x => x.Id == dto.CurrUserId && x.IsDel == 0)
+                .Select(x => new { x.Id, x.JobPostId, x.CnName })
+                .FirstAsync();
+
+            if (userInfo == null)
+                return Ok(JsonView(false, "用户不存在或已被禁用!"));
+
+            // 3. 获取费用类型
+            if (!_dataInit.TryGetValue(userInfo.JobPostId, out var feeTypeIds) || feeTypeIds?.Count == 0)
+                return Ok(JsonView(false, "当前用户岗位无对应的费用类型配置!"));
+
+            // 4. 验证团组存在性
+            var groupExists = await _sqlSugar.Queryable<Grp_DelegationInfo>()
+                .AnyAsync(x => x.Id == dto.GroupId && x.IsDel == 0);
+
+            if (!groupExists)
+                return Ok(JsonView(false, "未找到有效的团组信息!"));
+
+            // 5. 检查团组费用表中是否存在对应费用类型的数据
+            var existingFeeRecords = await _sqlSugar.Queryable<Grp_CreditCardPayment>()
+                .Where(x => x.DIId == dto.GroupId && x.IsDel == 0)
+                .Where(x => feeTypeIds.Contains(x.CTable))
+                .Select(x => new { x.CTable }) 
+                .ToListAsync();
+
+            if (existingFeeRecords.Count > 0)
             {
-                return Ok(JsonView(false, $"操作失败!"));
+                var existingFeeTypeNames = existingFeeRecords.Select(x => x.CTable).Distinct().ToList();
+                return Ok(JsonView(false, $"团组费用表中已存在费用类型ID [{string.Join(",", existingFeeTypeNames)}] 的数据,不可添加确认无费用记录!"));
             }
 
+            // 6. 检查已存在的确认记录
+            var existingAcknowledgeRecords = await _sqlSugar.Queryable<Grp_FeeEntryAcknowledge>()
+                .Where(x => x.UserId == dto.CurrUserId && x.IsDel == 0)
+                .Where(x => x.GroupId == dto.GroupId)
+                .Where(x => feeTypeIds.Contains(x.FeeTypeId))
+                .Select(x => new { x.FeeTypeId })
+                .ToListAsync();
+
+            var existingAcknowledgeFeeTypeIds = existingAcknowledgeRecords.Select(x => x.FeeTypeId).ToHashSet();
+
+            // 7. 准备插入数据(过滤已存在的记录)
+            var recordsToInsert = feeTypeIds
+                .Where(feeTypeId => !existingAcknowledgeFeeTypeIds.Contains(feeTypeId))
+                .Select(feeTypeId => new Grp_FeeEntryAcknowledge
+                {
+                    GroupId = dto.GroupId,
+                    UserId = dto.CurrUserId,
+                    JobPostId = userInfo.JobPostId,
+                    FeeTypeId = feeTypeId,
+                    IsAcknowledged = Domain.Enums.AcknowledgeStatusEnum.Acknowledged,
+                    AcknowledgeTime = DateTime.Now,
+                    AcknowledgeType = Domain.Enums.AcknowledgeTypeEnum.WebConfirm,
+                    CreateUserId = 4, // 系统创建
+                    CreateTime = DateTime.Now
+                })
+                .ToList();
+
+            if (recordsToInsert.Count == 0)
+                return Ok(JsonView(true, "所选团组已确认,无需重复操作!"));
+
+            // 8. 批量插入数据
+            var successCount = await _sqlSugar.Insertable(recordsToInsert).ExecuteCommandAsync();
+
+            if (successCount <= 0)
+                return Ok(JsonView(false, "操作失败,未能保存确认记录!"));
+
+            // 9. 记录操作日志(可选)
+            _logger.LogInformation("用户 {UserName}(ID:{UserId}) 确认了团组 {GroupId} 的费用类型",
+                userInfo.CnName, dto.CurrUserId, dto.GroupId);
+
             return Ok(JsonView(true, $"操作成功!"));
         }
 
@@ -1057,108 +1177,167 @@ namespace OASystem.API.Controllers
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> PostGroupPageList(GroupPageListDto dto)
         {
-            #region  参数验证
-            if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
-            if (dto.PageId < 1) return Ok(JsonView(false, "页面Id为空"));
+            #region 参数验证
+            if (dto.UserId < 1)
+                return Ok(JsonView(false, "员工Id为空"));
+            if (dto.PageId < 1)
+                return Ok(JsonView(false, "页面Id为空"));
 
             #region 页面操作权限验证
             var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
-
-            if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限"));
+            if (pageFunAuthView.CheckAuth == 0)
+                return Ok(JsonView(false, "您没有查看权限"));
             #endregion
-
             #endregion
-            if (dto.PortType == 1 || dto.PortType == 2) // web/Android
-            {
-                string sqlWhere = string.Empty;
-                if (dto.IsSure == 0) //未完成
-                {
-                    sqlWhere += string.Format(@" And IsSure = 0");
-                }
-                else if (dto.IsSure == 1) //已完成
-                {
-                    sqlWhere += string.Format(@" And IsSure = 1");
-                }
-
-                if (!string.IsNullOrEmpty(dto.SearchCriteria))
-                {
-                    string tj = dto.SearchCriteria;
-                    sqlWhere += string.Format(@"And (ssd.Name Like '%{0}%' Or TeamName Like '%{1}%' Or ClientName Like '%{2}%' Or  ClientName Like '%{3}%' Or su.CnName  Like '%{4}%')",
-                       tj, tj, tj, tj, tj);
-                }
-
-                if (int.TryParse(dto.Rank, out int rankId))
-                {
-                    if (rankId > 0) sqlWhere += string.Format("And gdi.TeamLevSId = {0}", rankId);
-                }
 
-                string sqlWhere1 = string.Empty;
-                if (!string.IsNullOrEmpty(dto.Department) && !dto.Department.Equals("全部"))
-                {
-                    sqlWhere1 = string.Format("Where Department = '{0}'", dto.Department);
-                }
+            //if (dto.PortType != 1 && dto.PortType != 2) // web/Android
+            //    return Ok(JsonView(false, "不支持的端口类型"));
 
-                string sql = string.Format(@"Select Row_Number,Id,SalesQuoteNo,TourCode,TeamTypeId, TeamType,Department,
-                                             	TeamLevId,TeamLev,TeamName,ClientName,ClientUnit,
-                                             	VisitDate,VisitDays,VisitPNumber,JietuanOperatorId,
-                                             	JietuanOperator,IsSure,CreateTime,IsBid,Step
-                                             	From (
-                                             	Select row_number() over(order by gdi.VisitStartDate Desc) as Row_Number,
-                                                CASE WHEN gdi.JietuanOperator = 4 OR gdi.JietuanOperator = 21 THEN '国交部'
-                                                ELSE (Select DepName FROM OA2023DB.dbo.Sys_Department WHERE Id = su.DepId) END AS 'Department',
-                                             	gdi.Id,SalesQuoteNo,TourCode,ssd.Id TeamTypeId, ssd.Name TeamType,gdi.Step,
-                                             	ssd1.Id TeamLevId,ssd1.Name TeamLev,TeamName,ClientName,ClientUnit,
-                                             	VisitDate,VisitDays,VisitPNumber,JietuanOperator JietuanOperatorId,
-                                             	su.CnName JietuanOperator,IsSure,gdi.CreateTime,gdi.IsBid
-                                             	From  Grp_DelegationInfo gdi
-                                             	Left Join Sys_SetData ssd On gdi.TeamDid = ssd.Id 
-                                             	Left Join Sys_SetData ssd1 On gdi.TeamLevSId = ssd1.Id
-                                             	Left Join Sys_Users su On gdi.JietuanOperator = su.Id
-                                             	Where gdi.IsDel = 0 {0}
-                                             ) temp {1}", sqlWhere, sqlWhere1);
+            // 构建查询条件
+            var sqlWhereBuilder = new StringBuilder(" WHERE gdi.IsDel = 0");
+            var parameters = new List<SugarParameter>();
 
-                RefAsync<int> total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
-                var _DelegationList = await _sqlSugar.SqlQueryable<DelegationListView>(sql).ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
+            // 完成状态筛选
+            if (dto.IsSure == 0 || dto.IsSure == 1)
+            {
+                sqlWhereBuilder.Append(" AND gdi.IsSure = @IsSure");
+                parameters.Add(new SugarParameter("@IsSure", dto.IsSure));
+            }
 
-                //处理 团组模块实际操作人
-                _DelegationList.ForEach(async x =>
-                {
+            // 搜索条件
+            if (!string.IsNullOrWhiteSpace(dto.SearchCriteria))
+            {
+                var searchParam = $"%{dto.SearchCriteria.Trim()}%";
+                sqlWhereBuilder.Append(@"
+                AND (ssd.Name LIKE @SearchCriteria 
+                     OR gdi.TeamName LIKE @SearchCriteria 
+                     OR gdi.ClientName LIKE @SearchCriteria 
+                     OR su.CnName LIKE @SearchCriteria)");
+                parameters.Add(new SugarParameter("@SearchCriteria", searchParam));
+            }
 
-                    var operators = GeneralMethod.GetGroupModuleOperators(x.Id);
-                    var operatorNames = new StringBuilder();
-                    //operatorNames.AppendLine("各模块实际操作人:");
-                    if (operators.Any())
-                    {
-                        operators.ForEach(y =>
-                        {
+            // 等级筛选
+            if (int.TryParse(dto.Rank, out int rankId) && rankId > 0)
+            {
+                sqlWhereBuilder.Append(" AND gdi.TeamLevSId = @RankId");
+                parameters.Add(new SugarParameter("@RankId", rankId));
+            }
 
-                            string label = string.Empty;
-                            if (y.OperationUsers.Any())
-                            {
-                                var users = y.OperationUsers.Select(x => x.UserName).ToList();
-                                label = string.Join('、', users);
-                            }
-                            else label = "暂未指定";
+            // 部门筛选
+            var departmentWhere = string.Empty;
+            if (!string.IsNullOrWhiteSpace(dto.Department) && !dto.Department.Equals("全部"))
+            {
+                departmentWhere = " WHERE Department = @Department";
+                parameters.Add(new SugarParameter("@Department", dto.Department));
+            }
 
-                            operatorNames.AppendLine($"{y.CTableName}:{label}");
-                            operatorNames.AppendLine();
-                        });
-                    }
+            // 构建SQL查询
+            string sql = $@"
+            SELECT Row_Number, Id, SalesQuoteNo, TourCode, TeamTypeId, TeamType, Department,
+                   TeamLevId, TeamLev, TeamName, ClientName, ClientUnit,
+                   VisitDate, VisitDays, VisitPNumber, JietuanOperatorId,
+                   JietuanOperator, IsSure, CreateTime, IsBid, Step
+            FROM (
+                SELECT ROW_NUMBER() OVER(ORDER BY gdi.VisitStartDate DESC) AS Row_Number,
+                       CASE 
+                           WHEN gdi.JietuanOperator IN (4, 21) THEN '国交部'
+                           ELSE (SELECT DepName FROM OA2023DB.dbo.Sys_Department WHERE Id = su.DepId) 
+                       END AS 'Department',
+                       gdi.Id, SalesQuoteNo, TourCode, ssd.Id AS TeamTypeId, ssd.Name AS TeamType, gdi.Step,
+                       ssd1.Id AS TeamLevId, ssd1.Name AS TeamLev, TeamName, ClientName, ClientUnit,
+                       VisitDate, VisitDays, VisitPNumber, JietuanOperator AS JietuanOperatorId,
+                       su.CnName AS JietuanOperator, IsSure, gdi.CreateTime, gdi.IsBid
+                FROM Grp_DelegationInfo gdi
+                LEFT JOIN Sys_SetData ssd ON gdi.TeamDid = ssd.Id 
+                LEFT JOIN Sys_SetData ssd1 ON gdi.TeamLevSId = ssd1.Id
+                LEFT JOIN Sys_Users su ON gdi.JietuanOperator = su.Id
+                {sqlWhereBuilder}
+            ) temp {departmentWhere}";
 
-                    x.OperatorLabel = operatorNames.ToString().TrimEnd('\n', '\r');
-                });
+            // 执行分页查询
+            RefAsync<int> total = 0;
+            var delegationList = await _sqlSugar.SqlQueryable<DelegationListView>(sql)
+                .AddParameters(parameters)
+                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
 
-                var _view = new
+            if (!delegationList.Any())
+            {
+                var emptyView = new
                 {
                     PageFuncAuth = pageFunAuthView,
-                    Data = _DelegationList
+                    Data = delegationList
                 };
-                return Ok(JsonView(true, "查询成功!", _view, total));
+                return Ok(JsonView(true, "查询成功,暂无数据", emptyView, total));
             }
-            else
+
+            // 批量处理团组模块实际操作人和背景颜色设置
+            await ProcessDelegationListData(delegationList);
+
+            var resultView = new
             {
-                return Ok(JsonView(false, "查询失败"));
-            }
+                PageFuncAuth = pageFunAuthView,
+                Data = delegationList
+            };
+
+            return Ok(JsonView(true, "查询成功!", resultView, total));
+        }
+
+        /// <summary>
+        /// 批量处理团组数据
+        /// </summary>
+        private async Task ProcessDelegationListData(List<DelegationListView> delegationList)
+        {
+            var groupIds = delegationList.Select(x => x.Id).ToList();
+
+            // 批量查询信用卡支付记录
+            var creditCardPayments = await _sqlSugar.Queryable<Grp_CreditCardPayment>()
+                .Where(y => groupIds.Contains(y.DIId) && y.IsDel == 0)
+                .Select(y => y.DIId)
+                .Distinct()
+                .ToListAsync();
+
+            // 批量查询费用确认记录
+            var feeAcknowledgements = await _sqlSugar.Queryable<Grp_FeeEntryAcknowledge>()
+                .Where(y => groupIds.Contains(y.GroupId) && y.IsDel == 0)
+                .Where(y => y.IsAcknowledged == AcknowledgeStatusEnum.Acknowledged)
+                .Select(y => y.GroupId)
+                .Distinct()
+                .ToListAsync();
+
+            var creditCardPaymentSet = creditCardPayments.ToHashSet();
+            var feeAcknowledgementSet = feeAcknowledgements.ToHashSet();
+
+            // 并行处理每个团组
+            var tasks = delegationList.Select(async x =>
+            {
+                // 处理团组模块实际操作人
+                var operators = GeneralMethod.GetGroupModuleOperators(x.Id);
+                var operatorNames = new StringBuilder();
+
+                if (operators.Any())
+                {
+                    foreach (var operatorInfo in operators)
+                    {
+                        string label = operatorInfo.OperationUsers.Any()
+                            ? string.Join('、', operatorInfo.OperationUsers.Select(u => u.UserName))
+                            : "暂未指定";
+
+                        operatorNames.AppendLine($"{operatorInfo.CTableName}:{label}");
+                        operatorNames.AppendLine();
+                    }
+                }
+
+                x.OperatorLabel = operatorNames.ToString().TrimEnd('\n', '\r'); 
+
+                // 设置背景颜色为红色
+                // C表没数据并且没点提醒确认按钮(无成本费用按钮)的团组该行显示红色
+                bool hasCreditCardPayment = creditCardPaymentSet.Contains(x.Id);
+                bool hasFeeAcknowledgement = feeAcknowledgementSet.Contains(x.Id);
+
+                x.UseRedBackground = !hasCreditCardPayment && !hasFeeAcknowledgement;
+            });
+
+            await Task.WhenAll(tasks);
         }
 
         /// <summary>
@@ -8872,46 +9051,55 @@ FROM
                             dic.Add("Row1Str", row1);
                         }
 
-                        string airTotalStr = string.Empty,
-                               airPriceStr = string.Empty;
+                        var airTotalStr = new StringBuilder();
+                        var airPriceStr = new StringBuilder();
                         //经济舱
                         if (_EnterExitCosts.SumJJC == 1)
                         {
-                            airTotalStr += $"{_EnterExitCosts.OutsideJJPay:#0.00}元/人(经济舱)";
-                            airPriceStr += $"{_EnterExitCosts.AirJJ:#0.00}元/人(经济舱)";
+                            airTotalStr.Append($"{_EnterExitCosts.OutsideJJPay:#0.00}元/人(经济舱)");
+                            airPriceStr.Append($"{_EnterExitCosts.AirJJ:#0.00}元/人(经济舱)");
                         }
                         //公务舱
                         if (_EnterExitCosts.SumGWC == 1)
                         {
-                            airTotalStr += $" {_EnterExitCosts.OutsideGWPay:#0.00} 元/人(公务舱)";
-                            airPriceStr += $" {_EnterExitCosts.AirGW:#0.00} 元/人(公务舱)";
+                            airTotalStr.Append($"{_EnterExitCosts.OutsideGWPay:#0.00} 元/人(公务舱)");
+                            airPriceStr.Append($"{_EnterExitCosts.AirGW:#0.00} 元/人(公务舱)");
                         }
                         //头等舱
                         if (_EnterExitCosts.SumTDC == 1)
                         {
-                            airTotalStr += $" {_EnterExitCosts.OutsideTDPay:#0.00} 元/人(头等舱)";
-                            airPriceStr += $" {_EnterExitCosts.AirTD:#0.00} 元/人(头等舱)";
+                            airTotalStr.Append($"{_EnterExitCosts.OutsideTDPay:#0.00} 元/人(头等舱)");
+                            airPriceStr.Append($"{_EnterExitCosts.AirTD:#0.00} 元/人(头等舱)");
                         }
 
+                        //描述
+                        var remarkLable = new StringBuilder();
+                        //第二项描述
+                        remarkLable.Append("备注:");
+                        if (!string.IsNullOrEmpty(_EnterExitCosts.TwoItemRemark)) remarkLable.Append( _EnterExitCosts.TwoItemRemark);
+
                         //汇率描述
-                        string rateStr = "";
                         if (peiceItemCurrencyInfos.Any())
                         {
-                            rateStr = "\r\n汇率描述:";
+                            remarkLable.AppendLine();
+                            remarkLable.Append("汇率描述:");
                             foreach (var item in peiceItemCurrencyInfos)
                             {
-                                rateStr += $"{item.CurrencyName}({item.CurrencyCode}):{item.Rate:#0.0000}  ";
+                                remarkLable.Append($"{item.CurrencyName}({item.CurrencyCode}):{item.Rate:#0.0000}  ");
                             }
                         }
 
-                        string twoItemRemark = "备注:";
-                        if (!string.IsNullOrEmpty(_EnterExitCosts.TwoItemRemark)) twoItemRemark += _EnterExitCosts.TwoItemRemark;
-                        if (!string.IsNullOrEmpty(rateStr)) twoItemRemark += rateStr;
+                        //城市交通费 处理
+                        var cityTrafficLabel = new StringBuilder()
+                            .AppendFormat("  经济舱:{0:#0.00} 元/人", _EnterExitCosts.CityTranffic)
+                            .AppendFormat("  公务舱:{0:#0.00} 元/人", _EnterExitCosts.CityTranffic1)
+                            .AppendFormat("  头等舱:{0:#0.00} 元/人", _EnterExitCosts.CityTranffic2)
+                            .ToString();
 
-                        dic.Add("AirTotalStr", airTotalStr);
-                        dic.Add("AirPriceStr", airPriceStr);
-                        dic.Add("CityTranffic", _EnterExitCosts.CityTranffic.ToString("#0.00"));
-                        dic.Add("TwoItemRemark", twoItemRemark);
+                        dic.Add("AirTotalStr", airTotalStr.ToString());
+                        dic.Add("AirPriceStr", airPriceStr.ToString());
+                        dic.Add("CityTranffic", cityTrafficLabel);
+                        dic.Add("TwoItemRemark", remarkLable.ToString());
 
                         NodeCollection allTables = doc.GetChildNodes(NodeType.Table, true);
                         Aspose.Words.Tables.Table table1 = allTables[0] as Aspose.Words.Tables.Table;
@@ -9412,7 +9600,13 @@ FROM
                             table1.Rows.RemoveAt(i - 1);
                         }
 
-                        dic.Add("CityTranffic", _EnterExitCosts.CityTranffic.ToString("#0.00"));
+                        var cityTrafficLabel = new StringBuilder()
+                            .AppendFormat("  经济舱:{0:#0.00} 元", _EnterExitCosts.CityTranffic)
+                            .AppendFormat("  公务舱:{0:#0.00} 元", _EnterExitCosts.CityTranffic1)
+                            .AppendFormat("  头等舱:{0:#0.00} ", _EnterExitCosts.CityTranffic2)
+                            .ToString();
+
+                        dic.Add("CityTranffic", cityTrafficLabel);
 
                         string otherFeeStr = "";
                         if (_EnterExitCosts.Visa > 0) otherFeeStr += $"签证费:{_EnterExitCosts.Visa:#0.00} 元,";
@@ -9428,7 +9622,6 @@ FROM
 
                         #endregion
 
-
                         if (otherFeeStr.Length > 0)
                         {
                             otherFeeStr = otherFeeStr.Substring(0, otherFeeStr.Length - 1);
@@ -9644,8 +9837,17 @@ FROM
 
                         designer.SetDataSource("dac1totalPrice", dac1totalPrice.ToString("#0.00"));
                         designer.SetDataSource("dac2totalPrice", dac2totalPrice);
-                        designer.SetDataSource("cityTranffic", @$"其中:国外城市间机票费: {_EnterExitCosts.CityTranffic:#0.00} 元");
-                        designer.SetDataSource("sumCityTranffic", @$"{_EnterExitCosts.CityTranffic:#0.00} ");
+
+                        var cityTrafficLabel = new StringBuilder()
+                            .AppendFormat("  其中:国外城市间")
+                            .AppendFormat("  经济舱费:{0:#0.00} 元、", _EnterExitCosts.CityTranffic)
+                            .AppendFormat("  公务舱费:{0:#0.00} 元、", _EnterExitCosts.CityTranffic1)
+                            .AppendFormat("  头等舱费:{0:#0.00} 元", _EnterExitCosts.CityTranffic2)
+                            .ToString();
+
+                        //decimal cityTraffic =_EnterExitCosts.CityTranffic + _EnterExitCosts.CityTranffic1 + _EnterExitCosts.CityTranffic2;
+                        designer.SetDataSource("cityTranffic", cityTrafficLabel);
+                       // designer.SetDataSource("sumCityTranffic", @$"{cityTraffic:#0.00} ");
 
                         string cell4Str1 = string.Empty;
                         if (_EnterExitCosts.SumJJC == 1) cell4Str1 += $"经济舱:{_EnterExitCosts.AirJJ:#0.00} 元/人;";
@@ -9859,14 +10061,20 @@ FROM
 
                         decimal hotelFeeTotal = dac1.Sum(it => it.SubTotal);//住宿费
                         dic.Add("HotelFeeTotal", hotelFeeTotal.ToString("#0.00"));
+
                         decimal mealsFeeTotal = dac2.Sum(it => it.SubTotal);//伙食费
                         dic.Add("MealsFeeTotal", mealsFeeTotal.ToString("#0.00"));
+
                         decimal miscellaneousFeeTotal = dac3.Sum(it => it.SubTotal);//公杂费
                         dic.Add("MiscellaneousFeeTotal", miscellaneousFeeTotal.ToString("#0.00"));
+
                         decimal trainingFeeTotal = dac4.Sum(it => it.SubTotal);//培训费
                         dic.Add("TrainingFeeTotal", trainingFeeTotal.ToString("#0.00"));
-                        decimal cityTranfficFeeToatal = _EnterExitCosts.CityTranffic; //城市区间交通费
-                        dic.Add("CityTranfficFeeToatal", cityTranfficFeeToatal.ToString("#0.00"));//
+
+                        //decimal cityTranfficFeeToatal = _EnterExitCosts.CityTranffic; //城市区间交通费
+                        decimal cityTranfficFeeToatal = 0.00M;
+                        //dic.Add("CityTranfficFeeToatal", cityTranfficFeeToatal.ToString("#0.00"));
+
                         //其他费用
                         decimal otherFeeTotal = _EnterExitCosts.Visa + _EnterExitCosts.Safe + _EnterExitCosts.Ticket + _EnterExitCosts.YiMiao + _EnterExitCosts.HeSuan + _EnterExitCosts.Service + dac5.Sum(x => x.SubTotal);
                         dic.Add("OtherFeeTotal", otherFeeTotal.ToString("#0.00"));
@@ -9874,8 +10082,8 @@ FROM
                         //其他费用合计
                         decimal _otherFeeTotal = hotelFeeTotal + mealsFeeTotal + miscellaneousFeeTotal + trainingFeeTotal + cityTranfficFeeToatal + otherFeeTotal;
 
-                        decimal _jjcFeeToatal = _EnterExitCosts.AirJJ + _otherFeeTotal; //经济舱
-                        decimal _gwcFeeToatal = _EnterExitCosts.AirGW + _otherFeeTotal; //公务舱
+                        decimal _jjcFeeToatal = _EnterExitCosts.OutsideJJPay + _otherFeeTotal; //经济舱
+                        decimal _gwcFeeToatal = _EnterExitCosts.OutsideGWPay + _otherFeeTotal; //公务舱
 
                         //公务舱合计
 
@@ -9885,18 +10093,18 @@ FROM
                         //string allPriceJJ = "";
                         if (_EnterExitCosts.SumJJC == 1 && _EnterExitCosts.SumGWC == 0)
                         {
-                            dic.Add("AirFeeTotal", _EnterExitCosts.AirJJ.ToString("#0.00"));
+                            dic.Add("AirFeeTotal", _EnterExitCosts.OutsideJJPay.ToString("#0.00"));
                             dic.Add("FeeTotal", _jjcFeeToatal.ToString("#0.00"));
                         }
                         if (_EnterExitCosts.SumGWC == 1 && _EnterExitCosts.SumJJC == 0)
                         {
-                            dic.Add("AirFeeTotal", _EnterExitCosts.AirGW.ToString("#0.00"));
+                            dic.Add("AirFeeTotal", _EnterExitCosts.OutsideGWPay.ToString("#0.00"));
                             dic.Add("FeeTotal", _gwcFeeToatal.ToString("#0.00"));
                         }
 
                         if (_EnterExitCosts.SumJJC == 1 && _EnterExitCosts.SumGWC == 1)
                         {
-                            string airFeeTotalStr = string.Format(@$"经济舱:{_EnterExitCosts.AirJJ:#0.00} 公务舱:{_EnterExitCosts.AirGW:#0.00}");
+                            string airFeeTotalStr = string.Format(@$"经济舱:{_EnterExitCosts.OutsideJJPay:#0.00} 公务舱:{_EnterExitCosts.OutsideGWPay:#0.00}");
                             dic.Add("AirFeeTotal", airFeeTotalStr);
                             string feeTotalStr = string.Format(@$"经济舱:{_jjcFeeToatal:#0.00} 公务舱:{_gwcFeeToatal:#0.00}");
                             dic.Add("FeeTotal", feeTotalStr);
@@ -10138,7 +10346,13 @@ FROM
                         //    }
                         //}
 
-                        dic.Add("CityTranffic", _EnterExitCosts.CityTranffic.ToString("#0.00"));
+                        var citytrafficLable = new StringBuilder()
+                            .AppendFormat($"经济舱费用:{_EnterExitCosts.CityTranffic:#0.00} 元、")
+                            .AppendFormat($"公务舱费用:{_EnterExitCosts.CityTranffic1:#0.00}元、")
+                            .AppendFormat($"头等舱费用:{_EnterExitCosts.CityTranffic2:#0.00}")
+                            .ToString();
+
+                        dic.Add("CityTranffic", citytrafficLable);
 
                         string otherFeeStr = "";
                         if (_EnterExitCosts.Visa > 0) otherFeeStr += $"签证费:{_EnterExitCosts.Visa:#0.00}元,";
@@ -12616,6 +12830,8 @@ FROM
                     AirGW = eecInfo.AirGW,
                     AirTD = eecInfo.AirTD,
                     CityTranffic = eecInfo.CityTranffic,
+                    CityTranffic1 = eecInfo.CityTranffic1,
+                    CityTranffic2 = eecInfo.CityTranffic2,
                     TwoItemRemark = eecInfo.TwoItemRemark
                 };
                 return Ok(JsonView(twoData));
@@ -13229,6 +13445,8 @@ FROM
             info.AirGW = dto.AirGW;
             info.AirTD = dto.AirTD;
             info.CityTranffic = dto.CityTranffic;
+            info.CityTranffic1 = dto.CityTranffic1;
+            info.CityTranffic2 = dto.CityTranffic2;
             info.TwoItemRemark = dto.TwoItemRemark;
             info.SumJJC = dto.ChoiceTwoJJ;
             info.SumGWC = dto.ChoiceTwoGW;
@@ -13266,6 +13484,8 @@ FROM
                         x.AirGW,
                         x.AirTD,
                         x.CityTranffic,
+                        x.CityTranffic1,
+                        x.CityTranffic2,
                         x.TwoItemRemark,
                         x.LastUpdateTime,
                         x.LastUpdateUserId
@@ -13276,8 +13496,8 @@ FROM
             }
 
             jjcItemTotal = info.AirJJ + info.CityTranffic;
-            gwcItemTotal = info.AirGW + info.CityTranffic;
-            tdcItemTotal = info.AirTD + info.CityTranffic;
+            gwcItemTotal = info.AirGW + info.CityTranffic1;
+            tdcItemTotal = info.AirTD + info.CityTranffic2;
 
             //消息通知
             //await EnterExitCostMobileOpNotice(dto.DiId, id, dto.CurrUserId);
@@ -15145,7 +15365,6 @@ FROM
                 eecRates.Insert(0, new CurrencyInfo() { CurrencyCode = "CNY", CurrencyName = "人民币", Rate = 1.00000M });
             }
 
-
             //处理团组人数
             int pplNum = 1;
             if (groupInfo != null) pplNum = groupInfo.VisitPNumber;
@@ -15210,7 +15429,7 @@ FROM
             {
                 ItemId = 1354,
                 Index = intTravelIndex,
-                FeeName = "城市间交通费用",
+                FeeName = "城市间交通费用(经济舱)",
                 UnitPrice = infoView.CityTranffic,
                 Currency = "CNY",
                 Quantity = 1,
@@ -15219,6 +15438,32 @@ FROM
                 Remark = "",
             });
 
+            intTravelCosts.Add(new QuoteSubItemInfo
+            {
+                ItemId = 1354,
+                Index = intTravelIndex,
+                FeeName = "城市间交通费用(公务舱)",
+                UnitPrice = infoView.CityTranffic1,
+                Currency = "CNY",
+                Quantity = 1,
+                PplNum = pplNum,
+                TotalAmt = infoView.CityTranffic1 * pplNum,
+                Remark = "",
+            });
+
+            intTravelCosts.Add(new QuoteSubItemInfo
+            {
+                ItemId = 1354,
+                Index = intTravelIndex,
+                FeeName = "城市间交通费用(头等舱)",
+                UnitPrice = infoView.CityTranffic2,
+                Currency = "CNY",
+                Quantity = 1,
+                PplNum = pplNum,
+                TotalAmt = infoView.CityTranffic2 * pplNum,
+                Remark = "",
+            });
+
             views.AddRange(intTravelCosts);
             #endregion
 
@@ -15456,7 +15701,6 @@ FROM
                 }
             }
 
-
             return Ok(JsonView(result));
         }
 

+ 33 - 21
OASystem/OASystem.Api/OAMethodLib/GeneralMethod.cs

@@ -4333,12 +4333,11 @@ namespace OASystem.API.OAMethodLib
             //默认币种显示
             List<CurrencyInfo> currencyInfos = new List<CurrencyInfo>()
                 {
-                    new CurrencyInfo (){ CurrencyCode="USD",CurrencyName = "美元",Rate = 7.5000M },
-                    new CurrencyInfo (){ CurrencyCode="EUR",CurrencyName = "欧元",Rate = 8.0000M },
-                    new CurrencyInfo (){ CurrencyCode="GBP",CurrencyName = "英镑",Rate = 9.5000M },
-                    new CurrencyInfo (){ CurrencyCode="JPY",CurrencyName = "日元",Rate = 0.0500M },
-                    new CurrencyInfo (){ CurrencyCode="HKD",CurrencyName = "港币",Rate = 0.9500M },
-
+                    new(){ CurrencyCode="USD",CurrencyName = "美元",Rate = 7.5000M },
+                    new(){ CurrencyCode="EUR",CurrencyName = "欧元",Rate = 8.0000M },
+                    new(){ CurrencyCode="GBP",CurrencyName = "英镑",Rate = 9.5000M },
+                    new(){ CurrencyCode="JPY",CurrencyName = "日元",Rate = 0.0500M },
+                    new(){ CurrencyCode="HKD",CurrencyName = "港币",Rate = 0.9500M }
                 };
 
             var currencyRate = await _juHeApi.PostItemRateAsync(currencyInfos.Select(it => it.CurrencyCode!).ToArray());
@@ -4351,7 +4350,12 @@ namespace OASystem.API.OAMethodLib
                     {
                         item.Rate = Convert.ToDecimal((Convert.ToDecimal(rateInfo.FSellPri == null ? 0.00M : rateInfo.FSellPri) / 100.00M).ToString("#0.0000"));
 
-                        decimal rate1 = item.Rate * 1.0350M;
+                        //currency == usd  上浮比例 1.0300
+                        decimal increaseRate = 1.0350M;
+
+                        //if (item.CurrencyCode.ToUpper().equals("USD")) increaseRate = 1.0300M;
+
+                        decimal rate1 = item.Rate * increaseRate;
                         //rate1 += 0.01M;
 
                         reteInfos.Add(new
@@ -4561,7 +4565,7 @@ namespace OASystem.API.OAMethodLib
                         if (enterExitCosts.Visa > 0)
                         {
                             //insidePayTotal += enterExitCosts.Visa;
-                            row1_1 = $"签证费: {enterExitCosts.Visa.ToString("#0.00")} 人民币/人";
+                            row1_1 = $"签证费: {enterExitCosts.Visa:#0.00} 人民币/人";
                             //if (!string.IsNullOrEmpty(enterExitCosts.VisaRemark))
                             //{
                             //    row1_1 += $"\t签证费用描述: {enterExitCosts.VisaRemark}";
@@ -4572,29 +4576,29 @@ namespace OASystem.API.OAMethodLib
                         if (enterExitCosts.YiMiao > 0)
                         {
                             //insidePayTotal += enterExitCosts.YiMiao;
-                            row1_2 += $"疫苗费:{enterExitCosts.YiMiao.ToString("#0.00")} 人民币/人";
+                            row1_2 += $"疫苗费:{enterExitCosts.YiMiao:#0.00} 人民币/人";
                         }
                         if (enterExitCosts.HeSuan > 0)
                         {
                             //insidePayTotal += enterExitCosts.HeSuan;
-                            row1_2 += $"核酸检测费:{enterExitCosts.HeSuan.ToString("#0.00")} 人民币/人";
+                            row1_2 += $"核酸检测费:{enterExitCosts.HeSuan:#0.00} 人民币/人";
                         }
                         if (enterExitCosts.Service > 0)
                         {
                             //insidePayTotal += enterExitCosts.Service;
-                            row1_2 += $"服务费:{enterExitCosts.Service.ToString("#0.00")} 人民币/人";
+                            row1_2 += $"服务费:{enterExitCosts.Service:#0.00} 人民币/人";
                         }
 
                         string row1_3 = "";
                         if (enterExitCosts.Safe > 0)
                         {
                             //insidePayTotal += enterExitCosts.Safe;
-                            row1_3 += $"保险费:{enterExitCosts.Safe.ToString("#0.00")} 人民币/人";
+                            row1_3 += $"保险费:{enterExitCosts.Safe:#0.00} 人民币/人";
                         }
                         if (enterExitCosts.Ticket > 0)
                         {
                             //insidePayTotal += enterExitCosts.Ticket;
-                            row1_3 += $"参展门票:{enterExitCosts.Ticket.ToString("#0.00")} 人民币/人";
+                            row1_3 += $"参展门票:{enterExitCosts.Ticket:#0.00} 人民币/人";
                         }
                         string row1 = "";
                         if (!string.IsNullOrEmpty(row1_1)) row1 += $"{row1_1}\r\n";
@@ -4608,7 +4612,14 @@ namespace OASystem.API.OAMethodLib
                         dic.Add("OutsaideGW", enterExitCosts.OutsideGWPay.ToString("#0.00"));
                         dic.Add("AirJJ", enterExitCosts.AirJJ.ToString("#0.00"));
                         dic.Add("AirGW", enterExitCosts.AirGW.ToString("#0.00"));
-                        dic.Add("CityTranffic", enterExitCosts.CityTranffic.ToString("#0.00"));
+
+                        var cityTrafficLable = new StringBuilder()
+                            .AppendFormat($"经济舱费用:{enterExitCosts.CityTranffic:#0.00} 元/人、")
+                            .AppendFormat($"公务舱费用:{enterExitCosts.CityTranffic1:#0.00} 元/人、")
+                            .AppendFormat($"头等舱费用:{enterExitCosts.CityTranffic2:#0.00}")
+                            .ToString();
+
+                        dic.Add("CityTranffic", cityTrafficLable);
                         dic.Add("SubZS", stayFeeTotal.ToString("#0.00"));
                         dic.Add("SubHS", mealsFeeTotal.ToString("#0.00"));
 
@@ -4953,7 +4964,7 @@ namespace OASystem.API.OAMethodLib
                         }
 
 
-                        dic.Add("CityTranffic", enterExitCosts.CityTranffic.ToString("#0.00"));
+                        //dic.Add("CityTranffic", enterExitCosts.CityTranffic.ToString("#0.00"));
 
                         string otherFeeStr = "";
                         if (enterExitCosts.Visa > 0) otherFeeStr += $"签证费: {enterExitCosts.Visa.ToString("#0.00")} 元,";
@@ -5174,8 +5185,8 @@ namespace OASystem.API.OAMethodLib
 
                         designer.SetDataSource("dac1totalPrice", dac1totalPrice.ToString("#0.00"));
                         designer.SetDataSource("dac2totalPrice", dac2totalPrice);
-                        designer.SetDataSource("cityTranffic", @$"其中:国外城市间机票费: {enterExitCosts.CityTranffic.ToString("#0.00")} 元");
-                        designer.SetDataSource("sumCityTranffic", @$"{enterExitCosts.CityTranffic.ToString("#0.00")} ");
+                        //designer.SetDataSource("cityTranffic", @$"其中:国外城市间机票费: {enterExitCosts.CityTranffic.ToString("#0.00")} 元");
+                        //designer.SetDataSource("sumCityTranffic", @$"{enterExitCosts.CityTranffic.ToString("#0.00")} ");
 
 
                         string cell4Str = $"  4.国际旅费:经济舱:{enterExitCosts.AirJJ.ToString("#0.00")} 元/人,公务舱:{enterExitCosts.AirGW.ToString("#0.00")} 元/人";
@@ -5386,9 +5397,10 @@ namespace OASystem.API.OAMethodLib
                         dic.Add("MiscellaneousFeeTotal", miscellaneousFeeTotal.ToString("#0.00"));
                         decimal trainingFeeTotal = dac4.Sum(it => it.SubTotal);//培训费
                         dic.Add("TrainingFeeTotal", trainingFeeTotal.ToString("#0.00"));
-                        decimal cityTranfficFeeToatal = enterExitCosts.CityTranffic; //城市区间交通费
-                        dic.Add("CityTranfficFeeToatal", cityTranfficFeeToatal.ToString("#0.00"));//
-                                                                                                  //其他费用
+                        decimal cityTranfficFeeToatal = 0.00M;
+                        //decimal cityTranfficFeeToatal = enterExitCosts.CityTranffic; //城市区间交通费
+                        //dic.Add("CityTranfficFeeToatal", cityTranfficFeeToatal.ToString("#0.00"));//
+                        //其他费用
                         decimal otherFeeTotal = enterExitCosts.Visa + enterExitCosts.Safe + enterExitCosts.Ticket + enterExitCosts.YiMiao + enterExitCosts.HeSuan + enterExitCosts.Service;
                         dic.Add("OtherFeeTotal", otherFeeTotal.ToString("#0.00"));
 
@@ -5664,7 +5676,7 @@ namespace OASystem.API.OAMethodLib
                             //}
                         }
 
-                        dic.Add("CityTranffic", enterExitCosts.CityTranffic.ToString("#0.00"));
+                        //dic.Add("CityTranffic", enterExitCosts.CityTranffic.ToString("#0.00"));
 
                         string otherFeeStr = "";
                         if (enterExitCosts.Visa > 0) otherFeeStr += $"签证费: {enterExitCosts.Visa.ToString("#0.00")} 元,";

+ 23 - 3
OASystem/OASystem.Domain/Dtos/Groups/EnterExitCostDto.cs

@@ -188,10 +188,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; }
+
         /// <summary>
         ///  多个币种存储
         ///  存储方式: 美元(USD):6.2350|.......|墨西哥比索(MXN):1.0000
@@ -709,7 +719,6 @@ namespace OASystem.Domain.Dtos.Groups
         /// 复选框选中(头等舱)
         /// 0 未选中 1 选中
         /// </summary>
-
         public int ChoiceTwoTD { get; set; }
 
         /// <summary>
@@ -733,9 +742,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; }
     }
 

+ 14 - 2
OASystem/OASystem.Domain/Dtos/Groups/FeeEntryAcknowledgeDtos.cs

@@ -10,18 +10,30 @@ namespace OASystem.Domain.Dtos.Groups
     {
     }
 
-    public class FeeEntryAcknowledgeCrateDto
+    public class FeeEntryAcknowledgeBaseDto
     {
 
         /// <summary>
         /// 人员ID
         /// </summary>
         public int CurrUserId { get; set; }
+    }
+
+    public class FeeEntryAcknowledgeCrateDto : FeeEntryAcknowledgeBaseDto
+    {
 
         /// <summary>
         /// 团组ID
         /// </summary>
         public List<int> GroupIds { get; set; }
-        
+
+        public int DaysAgo { get; set; } = 5;
+
+    }
+
+    public class FeeEntryAcknowledgeSingleDto : FeeEntryAcknowledgeBaseDto
+    {
+
+        public int GroupId { get; set; }
     }
 }

+ 13 - 2
OASystem/OASystem.Domain/Entities/Groups/Grp_EnterExitCost.cs

@@ -93,7 +93,6 @@
         [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
         public decimal OutsideTDPay { get; set; }
 
-
         #region 国际旅费合计(经济舱\公务舱\头等舱)
 
         /// <summary>
@@ -115,11 +114,23 @@
         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>
         ///  第二项费用描述
         /// </summary>

+ 1 - 1
OASystem/OASystem.Domain/Entities/Groups/Grp_FeeEntryAcknowledge.cs

@@ -38,7 +38,7 @@ namespace OASystem.Domain.Entities.Groups
         public int FeeTypeId { get; set; }
 
         /// <summary>
-        /// 是否已确认:0-未确认 1-已确认
+        /// 是否已确认(此团组->板块 无成本费用数据确认):0-未确认 1-已确认
         /// </summary>
         [SugarColumn(ColumnDescription = "是否已确认", IsNullable = true, ColumnDataType = "int")]
         public AcknowledgeStatusEnum IsAcknowledged { get; set; } = AcknowledgeStatusEnum.Acknowledged;

+ 5 - 1
OASystem/OASystem.Domain/ViewModels/Groups/DelegationInfoView.cs

@@ -546,10 +546,14 @@ namespace OASystem.Domain.ViewModels.Groups
                     2 => "企微消息通知(报批)",
                     _ => "未设置"
                 };
-
             }
         }
 
+        /// <summary>
+        /// 使用红色背景
+        /// </summary>
+        public bool UseRedBackground { get; set; } = false;
+
     }
 
     

+ 22 - 2
OASystem/OASystem.Domain/ViewModels/Groups/EnterExitCostView.cs

@@ -338,10 +338,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; }
+
         /// <summary>
         /// 第二项备注
         /// </summary>
@@ -718,10 +728,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; }
     }
 

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

@@ -356,7 +356,6 @@ namespace OASystem.Infrastructure.Repositories.Groups
 
                     //if (dto.DiId == 2775) enterExitCostInfoView.ProvinceId = 122;
 
-
                     //enterExitCostInfoView.FirstItemRemark = enterExitCostData.Remark;
                     var dayAndCostSql = string.Format(@"Select ntf.Country,ntf.City,ssd.Name CurremcyCode,ssd.Remark CurrencyName,gdac.* From Grp_DayAndCost gdac
                                                         Left Join Grp_NationalTravelFee ntf On ntf.Id = gdac.NationalTravelFeeId
@@ -457,7 +456,9 @@ namespace OASystem.Infrastructure.Repositories.Groups
                         AirJJ = enterExitCostData.AirJJ,
                         AirGW = enterExitCostData.AirGW,
                         AirTD = enterExitCostData.AirTD,
-                        CityTranffic = enterExitCostData.CityTranffic
+                        CityTranffic = enterExitCostData.CityTranffic,
+                        CityTranffic1 = enterExitCostData.CityTranffic1,
+                        CityTranffic2 = enterExitCostData.CityTranffic2
                     };
                     mobileInfo.ChoiceThreeDetails = dayAndCostData.Where(it => it.Type == 1).OrderBy(it => it.Days).ToArray(); //住宿费 1
                     mobileInfo.ChoiceFourDetails = dayAndCostData.Where(it => it.Type == 2).OrderBy(it => it.Days).ToArray();  //伙食费 2