Bladeren bron

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

yuanrf 9 maanden geleden
bovenliggende
commit
482b16353c

+ 63 - 14
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -40,6 +40,7 @@ namespace OASystem.API.Controllers
     [Route("api/[controller]/[action]")]
     public class GroupsController : ControllerBase
     {
+        private readonly ILogger<GroupsController> _logger;
         private readonly GrpScheduleRepository _grpScheduleRep;
         private readonly IMapper _mapper;
         private readonly DelegationInfoRepository _groupRepository;
@@ -81,7 +82,7 @@ namespace OASystem.API.Controllers
         private readonly HotelInquiryRepository _hotelInquiryRep;
         private readonly FeeAuditRepository _feeAuditRep;
 
-        public GroupsController(IMapper mapper, SqlSugarClient sqlSugar, GrpScheduleRepository grpScheduleRep, DelegationInfoRepository groupRepository,
+        public GroupsController(ILogger<GroupsController> logger, IMapper mapper, SqlSugarClient sqlSugar, GrpScheduleRepository grpScheduleRep, DelegationInfoRepository groupRepository,
             TaskAssignmentRepository taskAssignmentRep, AirTicketResRepository airTicketResRep, DecreasePaymentsRepository decreasePaymentsRep,
             InvitationOfficialActivitiesRepository InvitationOfficialActivitiesRep, DelegationEnDataRepository delegationEnDataRep, EnterExitCostRepository enterExitCostRep
             , DelegationVisaRepository delegationVisaRep, MessageRepository message, VisaPriceRepository visaPriceRep, CarTouristGuideGroundRepository carTouristGuideGroundRep,
@@ -91,6 +92,7 @@ namespace OASystem.API.Controllers
             InvertedListRepository invertedListRep, VisaFeeInfoRepository visaFeeInfoRep, TicketBlackCodeRepository ticketBlackCodeRep, HotelInquiryRepository hotelInquiryRep,
             ThreeCodeRepository threeCodeRepository, FeeAuditRepository feeAuditRep)
         {
+            _logger = logger;
             _mapper = mapper;
             _grpScheduleRep = grpScheduleRep;
             _groupRepository = groupRepository;
@@ -1448,7 +1450,8 @@ namespace OASystem.API.Controllers
                     _detail.PriceName = priceModule;
 
                     _detail.PayType = initDatas.Find(it => it.Id == entity.PayDId)?.Name ?? "-";
-                    _detail.CardType = initDatas.Find(it => it.Id == entity.CTDId)?.Name ?? "-";
+                    if (_detail.PayType.Equals("现金")) _detail.CardType = "-";
+                    else _detail.CardType = initDatas.Find(it => it.Id == entity.CTDId)?.Name ?? "-";
 
 
                     /*
@@ -1527,16 +1530,29 @@ namespace OASystem.API.Controllers
                                 //是否比较房型价格
                                 bool __isSingle = false, __isDouble = false, __isSuite = false, __isOther = false;
 
-                                roomFeeStr += $"<br/><span style='width:70px;display: inline-block;'></span>";
+                                //roomFeeStr += $"<br/><span style='width:70px;display: inline-block;'></span>";
+                                roomFeeStr += $"<br/>";
 
                                 if (hotelReservations.SingleRoomPrice > 0)
-                                { roomFeestr1 += $"单间:{hotelReservations.SingleRoomPrice.ToString("#0.00")} * {hotelReservations.SingleRoomCount}"; __isSingle = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>单间:{hotelReservations.SingleRoomPrice.ToString("#0.00")} * {hotelReservations.SingleRoomCount}<br/>";
+                                    __isSingle = true;
+                                }
                                 if (hotelReservations.DoubleRoomPrice > 0)
-                                { roomFeestr1 += $"双人间:{hotelReservations.DoubleRoomPrice.ToString("#0.00")} * {hotelReservations.DoubleRoomCount}"; __isDouble = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>双人间:{hotelReservations.DoubleRoomPrice.ToString("#0.00")} * {hotelReservations.DoubleRoomCount}<br/>";
+                                    __isDouble = true;
+                                }
                                 if (hotelReservations.SuiteRoomPrice > 0)
-                                { roomFeestr1 += $"套房:{hotelReservations.SuiteRoomPrice.ToString("#0.00")} * {hotelReservations.SuiteRoomCount}"; __isSuite = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>套房:{hotelReservations.SuiteRoomPrice.ToString("#0.00")} * {hotelReservations.SuiteRoomCount}<br/>";
+                                    __isSuite = true;
+                                }
                                 if (hotelReservations.OtherRoomPrice > 0)
-                                { roomFeestr1 += $"其他:{hotelReservations.OtherRoomPrice.ToString("#0.00")} * {hotelReservations.OtherRoomCount}"; __isOther = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>其他:{hotelReservations.OtherRoomPrice.ToString("#0.00")} * {hotelReservations.OtherRoomCount}";
+                                    __isOther = true;
+                                }
 
                                 if (roomFeestr1.Length > 0) roomFeeStr += roomFeestr1;
                                 else roomFeeStr += "  0.00 * 0";
@@ -1602,7 +1618,9 @@ namespace OASystem.API.Controllers
                                 if (roomData != null)
                                 {
                                     _detail.PayType = initDatas.Find(it => it.Id == roomData.PayDId)?.Name ?? "-";
-                                    _detail.CardType = initDatas.Find(it => it.Id == roomData.CTDId)?.Name ?? "-";
+
+                                    if (_detail.PayType.Equals("现金")) _detail.CardType = "-";
+                                    else _detail.CardType = initDatas.Find(it => it.Id == roomData.CTDId)?.Name ?? "-";
 
                                     roomBool = roomData.IsOppay == 1 ? "是" : "否";
                                     roomFee = roomData.Price;
@@ -1636,13 +1654,13 @@ namespace OASystem.API.Controllers
                                     hotelCsotTotal += item.Sum(x => x.HotelSingleRoomFee) + item.Sum(x => x.HotelDoubleRoomFee) + item.Sum(x => x.HotelSuiteRoomFee) + item.Sum(x => x.HotelSuiteFee);
                                     hotelCost_day += @$"{item.First()?.Date ?? "-"}";
                                     if (item.Sum(x => x.HotelSingleRoomFee) != 0) hotelCost_day += @$"   单间:{item.Sum(x => x.HotelSingleRoomFee).ToString("#0.00")}";
-                                    else { if (__isSingle) hotelCost_day += @$"   单间:0.00"; }
+                                    //else { if (__isSingle) hotelCost_day += @$"   单间:0.00"; }
                                     if (item.Sum(x => x.HotelDoubleRoomFee) != 0) hotelCost_day += @$"   双人间:{item.Sum(x => x.HotelDoubleRoomFee).ToString("#0.00")}";
-                                    else { if (__isDouble) hotelCost_day += @$"   双人间:0.00"; }
+                                    //else { if (__isDouble) hotelCost_day += @$"   双人间:0.00"; }
                                     if (item.Sum(x => x.HotelSuiteRoomFee) != 0) hotelCost_day += @$"   小套房/豪华套房:{item.Sum(x => x.HotelSuiteRoomFee).ToString("#0.00")}";
-                                    else { if (__isSuite) hotelCost_day += @$"   小套房/豪华套房:0.00"; }
+                                    //else { if (__isSuite) hotelCost_day += @$"   小套房/豪华套房:0.00"; }
                                     if (item.Sum(x => x.HotelSuiteFee) != 0) hotelCost_day += @$"   套房:{item.Sum(x => x.HotelSuiteFee).ToString("#0.00")}";
-                                    else { if (__isOther) hotelCost_day += @$"   套房:0.00"; }
+                                    //else { if (__isOther) hotelCost_day += @$"   套房:0.00"; }
                                     hotelCost_day += @$"</br>";
                                 }
 
@@ -1656,7 +1674,7 @@ namespace OASystem.API.Controllers
                                                           $"<span style='font-weight:800;'>{hotelReservations.HotelName} [{hotelReservations.CheckInDate} - {hotelReservations.CheckOutDate}]</span><br/>" +
                                                           $"信用卡金额:{_detail.WaitPay} ({hotelCurrncyName})<br/>" +
                                                           $"房间说明: {hotelReservations.Remark} <br/>" +
-                                                          $"房间费用: {roomCode} {roomName} 当时汇率 {roomData?.Rate.ToString("#0.0000")}{roomFeeStr}  <br/>是否由地接代付:{roomBool}<br/><br/>" +
+                                                          $"房间费用: {roomCode} {roomName} 当时汇率{roomData?.Rate.ToString("#0.0000")}{roomFeeStr}  是否由地接代付:{roomBool}<br/><br/>" +
                                                           $"{hotelBreakfastStr}" +
                                                           $"{hotelGovernmentRentStr}" +
                                                           $"{hotelCityTaxStr}";
@@ -10040,8 +10058,9 @@ ORDER by  gctggrc.id DESC
                 await AppNoticeLibrary.SendChatMsg_GroupStatus_ApplyFee(ccpId, sign, QiyeWeChatEnum.GuoJiaoLeaderChat);
 
                 //自动审核
-                await _feeAuditRep.FeeAutomaticAudit(1, _dto.DiId, hotelId);
+                var autoAdit = await _feeAuditRep.FeeAutomaticAudit(1, _dto.DiId, hotelId);
 
+                _logger.LogInformation($"【酒店自动审核】【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】执行调用   调用结果:{JsonConvert.SerializeObject(autoAdit)}");
             }
             catch (Exception ex)
             {
@@ -10051,6 +10070,36 @@ ORDER by  gctggrc.id DESC
             return Ok(_view);
         }
 
+        /// <summary>
+        /// 酒店自动审核测试
+        /// Add Or Edit 
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> PostHotelAutoAuditTest(int diid,int dataId)
+        {
+            
+
+            #region 应用推送
+
+            try
+            {
+                //自动审核
+                await _feeAuditRep.FeeAutomaticAudit(1, diid, dataId);
+
+            }
+            catch (Exception ex)
+            {
+
+                return Ok(JsonView(false, "操作失败"));
+            }
+            #endregion
+
+            return Ok(JsonView(false,"操作成功"));
+        }
+
         /// <summary>
         /// 酒店预订
         /// Del 

+ 13 - 8
OASystem/OASystem.Api/Controllers/ResourceController.cs

@@ -1828,7 +1828,9 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
             else
             {
 
-                var oldFiles = JsonConvert.DeserializeObject<List<string>>(oaInfo.ScreenshotOfMailUrl);
+                var oldFiles = string.IsNullOrEmpty(oaInfo.ScreenshotOfMailUrl)
+                               ? new List<string>() 
+                               : JsonConvert.DeserializeObject<List<string>>(oaInfo.ScreenshotOfMailUrl);
 
                 if (oldFiles.Count > 0)
                 {
@@ -1837,10 +1839,10 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
 
                 fileUrls = fileUrls.Distinct().ToList();
 
-                if (oldFiles.Count()>0)
+                if (fileUrls.Count()>0)
                 {
                     var upd = await _sqlSugar.Updateable<Res_OfficialActivities>()
-                                          .SetColumns(x => x.ScreenshotOfMailUrl == JsonConvert.SerializeObject(oldFiles))
+                                          .SetColumns(x => x.ScreenshotOfMailUrl == JsonConvert.SerializeObject(fileUrls))
                                           .Where(x => x.Id == dto.id)
                                           .ExecuteCommandAsync();
 
@@ -2248,10 +2250,14 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 List<Grp_TravelList> travelList = new List<Grp_TravelList>();
                 travelList = opTripView.Data as List<Grp_TravelList>;
 
-                foreach (var item in travelList)
+                if (travelList != null)
                 {
-                    schedulingStr += $"{item.Date}({item.WeekDay})\r\n{item.Trip}\r\n";
+                    foreach (var item in travelList)
+                    {
+                        schedulingStr += $"{item.Date}({item.WeekDay})\r\n{item.Trip}\r\n";
+                    }
                 }
+                
 
                 #endregion
 
@@ -2359,17 +2365,16 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                  */
 
                 string taskStr = string.Empty ;
-                List<string> countrys = obDatas.Select(it => it.Country).ToList();
+                List<string> countrys = obDatas.Where(it => !string.IsNullOrEmpty(it.Country)).Select(it => it.Country).ToList();
                 int countryIndex = 1;
                 foreach (var item in countrys)
                 {
-
                     string taskTitle = $"({GetToUpperNumber(countryIndex)}){item ?? "[公务出访国家未填写]"}\r\n";
 
                     string taskContent = "";
                     if (!string.IsNullOrEmpty(item))
                     {
-                        var countryObDatas = obDatas.Where(it => it.Country.Contains(item)).OrderBy(it => it.Date).ToList();
+                        var countryObDatas = obDatas.Where(it => !string.IsNullOrEmpty(it.Country) && it.Country.Contains(item)).OrderBy(it => it.Date).ToList();
                         int obIndex = 1;
                         if (countryObDatas.Count == 0) taskContent = "[公务出访未录入]\r\n";
                         else

+ 496 - 50
OASystem/OASystem.Api/Controllers/StatisticsController.cs

@@ -1,4 +1,5 @@
 using Aspose.Cells;
+using NPOI.OpenXmlFormats.Dml.Diagram;
 using OASystem.API.OAMethodLib;
 using OASystem.Domain.Dtos.Statistics;
 using OASystem.Domain.Entities.Customer;
@@ -6,7 +7,10 @@ using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.ViewModels.Financial;
 using OASystem.Domain.ViewModels.Statistics;
 using OASystem.Infrastructure.Repositories.Groups;
+using OfficeOpenXml.Drawing;
 using System.Data;
+using System.Linq;
+using System.Security.Cryptography.Xml;
 using static OASystem.API.OAMethodLib.GeneralMethod;
 using TypeInfo = OASystem.Domain.ViewModels.Statistics.TypeInfo;
 
@@ -237,7 +241,7 @@ namespace OASystem.API.Controllers
                                                 Left Join Sys_SetData sd2 On ccp.PayDId = sd2.Id 
                                                 Left Join Sys_SetData sd3 On ccp.CTDId = sd3.Id
                                                 Left Join Sys_Users u On ccp.CreateUserId = u.Id
-												Where ccp.IsDel = 0 And ccp.CTable = 1015 {1} And ccp.DiId = {0} Order By CreateTime", _dto.DiId ,_dto.isAudit ? "And ccp.IsAuditGM = 1 And ccp.IsPay = 1 " : " ");
+												Where ccp.IsDel = 0 And ccp.CTable = 1015 {1} And ccp.DiId = {0} Order By CreateTime", _dto.DiId, _dto.isAudit ? "And ccp.IsAuditGM = 1 And ccp.IsPay = 1 " : " ");
 
                 List<Gsd_ExtraCostsView> _ExtraCostsViews = await _sqlSugar.SqlQueryable<Gsd_ExtraCostsView>(_ecSql).ToListAsync();
 
@@ -426,7 +430,7 @@ namespace OASystem.API.Controllers
                                                      Left Join Sys_SetData sd5 On hr.GovernmentRentCurrency = sd5.Id
                                                      Left Join Sys_SetData sd6 On hr.CityTaxCurrency = sd6.Id
                                                      Where hr.IsDel = 0 And ccp.IsDel = 0 And ccp.CTable = 76 {1} And ccp.PayMoney<> 0 And hr.DiId = {0} 
-                                                     Order By CheckInDate Asc", _dto.DiId , _dto.isAudit ? "And ccp.IsAuditGM = 1" : " ");
+                                                     Order By CheckInDate Asc", _dto.DiId, _dto.isAudit ? "And ccp.IsAuditGM = 1" : " ");
 
                 groupHotelFeeViews = await _sqlSugar.SqlQueryable<GroupHotelFeeView>(hotelFeeSql).ToListAsync();
 
@@ -463,7 +467,7 @@ namespace OASystem.API.Controllers
                                            是否由地接支付:{isFeeMark1} <br/>";
 
                         }
-                        
+
                         var breakfastData = groupHotelContentFeeViews.Find(it => it.HrId == item.HrId && it.PriceType == 2); //早餐 
 
                         item.BreakfastPrice = breakfastData?.Price ?? 0.00M;
@@ -501,7 +505,7 @@ namespace OASystem.API.Controllers
                                                  卡类型:{_setDatas.Find(it => it.Id == landTaxData?.CTDId)?.Name} <br/>
                                                  是否由地接支付:{isFeeMark3} <br/>";
                         }
-                        
+
                         var cityTaxData = groupHotelContentFeeViews.Find(it => it.HrId == item.HrId && it.PriceType == 4); //城市税 
 
                         item.CityTax = cityTaxData?.Price ?? 0.00M;
@@ -537,7 +541,7 @@ namespace OASystem.API.Controllers
                         //item.RoomPrice = item.CardPrice;
                         item.RoomPriceCurrency = item.PaymentCurrency;
                     }
-                    
+
                     HotelCNYTotalPrice += item.CNYPrice;
                     item.PayMoney = item.PayMoney.ConvertToDecimal1();
                     item.CNYPrice = item.CNYPrice.ConvertToDecimal1();
@@ -2157,7 +2161,7 @@ namespace OASystem.API.Controllers
             List<int> companyIds = companyData.Select(it => it.id).ToList();
 
             List<int> pickGroupUserIds = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(it => it.IsDel == 0)
-                                                  .Select(it => it.JietuanOperator )
+                                                  .Select(it => it.JietuanOperator)
                                                   .ToList();
 
             //var jobData = _sqlSugar.Queryable<Sys_JobPost>().Where(it => it.IsDel == 0 && companyIds.Contains(it.CompanyId) && (it.JobName.Contains("经理") || it.JobName.Contains("主管")))
@@ -2177,7 +2181,7 @@ namespace OASystem.API.Controllers
 
             var dtData = new List<dynamic>();
             int dt = DateTime.Now.Year;
-            for (int y = dt; y >= dt-4; y--)
+            for (int y = dt; y >= dt - 4; y--)
             {
                 //季度
                 var quarterDatas = new List<dynamic>();
@@ -2208,7 +2212,7 @@ namespace OASystem.API.Controllers
                         }
 
                         //quarterData = new { name = "第二季度", beginDt = $"{y}-04-01", endDt = $"{y}-06-30", monthData = monthDatas };
-                        quarterData = new { name = "第二季度",  monthData = monthDatas };
+                        quarterData = new { name = "第二季度", monthData = monthDatas };
                     }
                     else if (q == 2)
                     {
@@ -2234,7 +2238,7 @@ namespace OASystem.API.Controllers
                         //quarterData = new { name = "第四季度", beginDt = $"{y}-10-01", endDt = $"{y}-12-31", monthData = monthDatas }; 
                         quarterData = new { name = "第四季度", monthData = monthDatas };
                     }
-                    quarterDatas.Add(quarterData); 
+                    quarterDatas.Add(quarterData);
                 }
 
                 dtData.Add(new
@@ -2294,8 +2298,8 @@ namespace OASystem.API.Controllers
 
             #endregion
 
-            string beginDt = $"{_dto.BeginDt} 00:00:00",endDt = $"{_dto.EndDt} 23:59:59";
-            
+            string beginDt = $"{_dto.BeginDt} 00:00:00", endDt = $"{_dto.EndDt} 23:59:59";
+
             return Ok(JsonView(true, "操作成功!", await GroupSales(_dto.CompanyId, _dto.GroupPickupUserId, beginDt, endDt)));
         }
 
@@ -2308,7 +2312,7 @@ namespace OASystem.API.Controllers
             List<int> userIds = new List<int>();
             var userDatas = await _sqlSugar.Queryable<Sys_Users>()
                                            .InnerJoin<Sys_Company>((u, c) => u.CompanyId == c.Id)
-                                           .Where((u, c) => u.IsDel == 0 && pickGroupIds.Contains( u.Id))
+                                           .Where((u, c) => u.IsDel == 0 && pickGroupIds.Contains(u.Id))
                                            .Select((u, c) => new { u.Id, u.CompanyId, u.CnName })
                                            .ToListAsync();
 
@@ -2333,7 +2337,7 @@ namespace OASystem.API.Controllers
         /// <param name="beginDt"></param>
         /// <param name="endDt"></param>
         /// <returns></returns>
-        private async Task<SalesYOYView> GroupSales(int companyId, int groupPickupUserId,string beginDt, string endDt)
+        private async Task<SalesYOYView> GroupSales(int companyId, int groupPickupUserId, string beginDt, string endDt)
         {
             decimal thisSales = 0.00M, lastSales = 0.00M, yoy = 1.00M;
 
@@ -2392,10 +2396,10 @@ FROM
 
             var salesData = await _sqlSugar.SqlQueryable<SalesView>(salesSql).ToListAsync();
 
-             thisSales = salesData.Where(x => x.Name.Equals("ThisSales")).First()?.Sales ?? 0;
-             lastSales = salesData.Where(x => x.Name.Equals("LastSales")).First()?.Sales ?? 0;
+            thisSales = salesData.Where(x => x.Name.Equals("ThisSales")).First()?.Sales ?? 0;
+            lastSales = salesData.Where(x => x.Name.Equals("LastSales")).First()?.Sales ?? 0;
 
-                if (lastSales != 0 && thisSales != 0) yoy = (thisSales - lastSales) / lastSales;
+            if (lastSales != 0 && thisSales != 0) yoy = (thisSales - lastSales) / lastSales;
 
             return new SalesYOYView() {
                 thisYearSales = thisSales.ToString("#0.00"),
@@ -2554,7 +2558,7 @@ FROM
             string userSql = "";
             if (userIds.Count > 0)
             {
-                userSql = string.Format(@$" AND JietuanOperator IN ({string.Join(",",userIds)})");
+                userSql = string.Format(@$" AND JietuanOperator IN ({string.Join(",", userIds)})");
             }
             else
             {
@@ -2574,7 +2578,7 @@ FROM
 
             string sql = "";
 
-            if (_dto.StatisticsType == 1 )
+            if (_dto.StatisticsType == 1)
             {
                 sql = string.Format(@$"Select 
 	sd.[Name],
@@ -2629,7 +2633,7 @@ Group By [Name]
 Order By Count Desc");
                 var clientGradeData = await _sqlSugar.SqlQueryable<MarketingSalesGroupStatisticsView>(sql2).ToListAsync();
                 return Ok(JsonView(true, "操作成功!", new {
-                    customerTypeData= customerTypeData,
+                    customerTypeData = customerTypeData,
                     clientGradeData = clientGradeData
                 }));
 
@@ -2681,7 +2685,7 @@ Order By Count Desc");
             if (userIds.Count > 0)
             {
                 userSql = string.Format(@$" AND JietuanOperator IN ({string.Join(",", userIds)})");
-            }else return Ok(JsonView(true, "操作成功!", new List<object> { }, 0));
+            } else return Ok(JsonView(true, "操作成功!", new List<object> { }, 0));
 
             string sql = string.Format(@$"Select 
 	ROW_NUMBER() Over(Order By Count(*) Desc) As RowNumber,
@@ -2886,7 +2890,7 @@ Order By Count Desc");
             if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, MsgTips.CheckAuth));
             #endregion
             #endregion
-            return Ok(await _visitingClientsRep._List(_dto.PortType,_dto.PageIndex,_dto.PageSize,_dto.DiId,_dto.Search));
+            return Ok(await _visitingClientsRep._List(_dto.PortType, _dto.PageIndex, _dto.PageSize, _dto.DiId, _dto.Search));
         }
 
         /// <summary>
@@ -2930,8 +2934,8 @@ Order By Count Desc");
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> PostMarketingSalesVCDel(MarketingSalesVCDelDto _dto)
         {
-            
-            return Ok(await _visitingClientsRep._Del(_dto.Id,_dto.UserId));
+
+            return Ok(await _visitingClientsRep._Del(_dto.Id, _dto.UserId));
         }
 
         /// <summary>
@@ -2979,7 +2983,7 @@ Order By Count Desc");
         public async Task<IActionResult> DailypaymentTypeInit(DailypaymentTypeInitDto _dto)
         {
             #region  参数验证
-            if (_dto.PortType < 1 || _dto.PortType > 3) return Ok(JsonView(false, msg:MsgTips.Port));
+            if (_dto.PortType < 1 || _dto.PortType > 3) return Ok(JsonView(false, msg: MsgTips.Port));
 
             PageFunAuthViewBase pageFunAuthView = new PageFunAuthViewBase();
             #region 页面操作权限验证
@@ -3057,9 +3061,9 @@ Order By Count Desc");
                 var res = await RedisRepository.RedisFactory
                                                .CreateRedisRepository()
                                                .StringSetAsync(
-                                                    key:"DailypaymentTypeData",
+                                                    key: "DailypaymentTypeData",
                                                     _dto.TypeIds,
-                                                    timeout:null );
+                                                    timeout: null);
 
                 if (!res) return Ok(JsonView(false, "操作失败"));
 
@@ -3092,7 +3096,7 @@ Order By Count Desc");
                 }
                 return Ok(JsonView(false, sb.ToString()));
             }
-           
+
 
             PageFunAuthViewBase pageFunAuthView = new PageFunAuthViewBase();
             #region 页面操作权限验证
@@ -3107,12 +3111,12 @@ Order By Count Desc");
                 DateTime _beginDt = Convert.ToDateTime($"{_dto.BeginDt} 00:00:00"),
                          _endDt = Convert.ToDateTime($"{_dto.EndDt} 23:59:59");
 
-                string sqlWhere = string.Format(@" And dfp.CreateTime Between '{0}' And '{1}'",_beginDt,_endDt);
+                string sqlWhere = string.Format(@" And dfp.CreateTime Between '{0}' And '{1}'", _beginDt, _endDt);
 
                 var dailypaymentTypeData = await RedisRepository.RedisFactory
                                                                 .CreateRedisRepository()
                                                                 .StringGetAsync<List<int>>("DailypaymentTypeData") ?? new List<int>();
-              
+
                 string sql = string.Format(@"
 Select 
 	dfp.Id,
@@ -3138,7 +3142,7 @@ Left Join Sys_SetData sd2 On dfp.PriceTypeId = sd2.Id
 Where dfp.IsDel = 0 And dfp.IsPay = 1
 ", sqlWhere);//--Order By dfp.CreateTime Desc
 
-                
+
                 if (_dto.Type == 1) //data
                 {
                     RefAsync<int> total = 0;
@@ -3178,7 +3182,7 @@ Where dfp.IsDel = 0 And dfp.IsPay = 1
                                                .ToPageListAsync(
                                                     pageNumber: 1,
                                                     pageSize: 99999
-                                                    ) ;
+                                                    );
 
                     _sqlSugar.ThenMapper(_view, x =>
                     {
@@ -3199,10 +3203,10 @@ Where dfp.IsDel = 0 And dfp.IsPay = 1
                         x.ContentStr = str;
                     });
 
-                    if (_view.Count > 0 )
+                    if (_view.Count > 0)
                     {
                         //DataTable dt = GeneralMethod.
-                        DataTable dt = CommonFun.GetDataTableFromIList(_view );
+                        DataTable dt = CommonFun.GetDataTableFromIList(_view);
                         dt.TableName = $"_view";
                         decimal total = _view.Sum(x => x.SumPrice);
                         WorkbookDesigner designer = new WorkbookDesigner();
@@ -3213,10 +3217,10 @@ Where dfp.IsDel = 0 And dfp.IsPay = 1
 
                         designer.Process();
 
-                        string fileName = $"DailyPayment/日付报表{ DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx";
+                        string fileName = $"DailyPayment/日付报表{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx";
                         designer.Workbook.Save(AppSettingsHelper.Get("ExcelBasePath") + fileName);
                         string rst = AppSettingsHelper.Get("ExcelBaseUrl") + AppSettingsHelper.Get("ExcelFtpPath") + fileName;
-                        return Ok(JsonView(true, "操作成功", new { url = rst })) ;
+                        return Ok(JsonView(true, "操作成功", new { url = rst }));
                     }
 
                     return Ok(JsonView(true, ",暂无数据"));
@@ -3232,7 +3236,7 @@ Where dfp.IsDel = 0 And dfp.IsPay = 1
         #endregion
 
         #region 统计模块
-      
+
         /// <summary>
         ///  同比
         ///  营业额(今年和去年的)、成本支出(今年和去年的)、毛利润(今年和去年的)
@@ -3244,10 +3248,10 @@ Where dfp.IsDel = 0 And dfp.IsPay = 1
         public async Task<IActionResult> StatisticsYOY(YOYDto _dto)
         {
             //同比增长率 = (本期 - 同期) / 同期 * 100%;
-            if (_dto.Year < 1) return Ok(JsonView(false,"操作失败"));
+            if (_dto.Year < 1) return Ok(JsonView(false, "操作失败"));
 
 
-            string beginDt = $"{_dto.Year-1}-01-01 00:00:00",
+            string beginDt = $"{_dto.Year - 1}-01-01 00:00:00",
                    endDt = $"{_dto.Year}-12-31 23:59:59";
 
             string sql = string.Format(@"
@@ -3439,7 +3443,7 @@ WHERE
   AND di.VisitDate BETWEEN '{0}' AND '{1}'
 ORDER BY
   di.VisitDate
-", beginDt,endDt);
+", beginDt, endDt);
 
             var data = await _sqlSugar.SqlQueryable<StatisticsYOYView>(sql).ToListAsync();
 
@@ -3475,7 +3479,7 @@ ORDER BY
             grossProfitYOYData = grossProfitYOYData.OrderBy(x => x.Month).ToList();
 
 
-            return Ok(JsonView(true,"操作成功!", new { salesYOYData = salesYOYData, costYOYData = costYOYData, grossProfitYOYData = grossProfitYOYData }));
+            return Ok(JsonView(true, "操作成功!", new { salesYOYData = salesYOYData, costYOYData = costYOYData, grossProfitYOYData = grossProfitYOYData }));
         }
 
         /// <summary>
@@ -3550,7 +3554,7 @@ WHERE
 
                             if (!string.IsNullOrEmpty(code))
                             {
-                                if (i == cityNum-1)
+                                if (i == cityNum - 1)
                                 {
                                     cityName += threeCodeData.Find(x => x.Three.Equals(code))?.City ?? "";
                                 }
@@ -3582,7 +3586,7 @@ WHERE
                 foreach (var item in monthData)
                 {
                     string groupName = groupNames.Find(x => item.DIId == x.Id)?.GroupName ?? "";
-                    aitTicketInfos.Add(new AitTicketInfo(item.DIId,groupName,item.ClientNum));
+                    aitTicketInfos.Add(new AitTicketInfo(item.DIId, groupName, item.ClientNum));
                 }
                 var aitTicketInfosGroupBy = aitTicketInfos.GroupBy(x => x.Id);
 
@@ -3598,7 +3602,7 @@ WHERE
 
                 linkGroupIds = linkGroupIds.Distinct().ToList();
 
-                airTicketNumData.Add(new AirTicketReturnView(_dto.Year, monthIndex, airticket_quantity, aitTicketInfos1,linkGroupIds));
+                airTicketNumData.Add(new AirTicketReturnView(_dto.Year, monthIndex, airticket_quantity, aitTicketInfos1, linkGroupIds));
 
                 //机票城市处理
                 //城市处理
@@ -3612,7 +3616,7 @@ WHERE
                             var cityArray = item.FlightsCityName.Split("、").ToList();
                             foreach (var item1 in cityArray)
                             {
-                                if (!string.IsNullOrEmpty(item.FlightsCityName))
+                                if (!string.IsNullOrEmpty(item1))
                                 {
                                     airTicketCityInfos.Add(item1);
                                 }
@@ -3712,7 +3716,7 @@ WHERE
   AND hr.CheckInDate BETWEEN CONVERT(datetime,'{0}') AND CONVERT(datetime,'{1}')
 ORDER BY
   hr.CheckInDate
-", beginDt,endDt);
+", beginDt, endDt);
 
             var data = await _sqlSugar.SqlQueryable<StatisticsHotelView>(sql).ToListAsync();
 
@@ -3734,9 +3738,9 @@ ORDER BY
                                                                  otherRoomCount = g1.Sum(x => x.OtherRoomCount),
                                                              })
                                                              .ToList(),
-                                                 linkGroupIds = g.Select(x => x.DIId).Distinct().ToList()
+                                                linkGroupIds = g.Select(x => x.DIId).Distinct().ToList()
 
-                                             })
+                                            })
                                              .OrderByDescending(x => x.BookingRoomNum)
                                              .Take(10)
                                              .ToList();
@@ -3783,9 +3787,9 @@ WHERE
             var groupByData = data.GroupBy(x => x.Country)
                                   .Select(g => new
                                   {
-                                        Country = g.Key,
-                                        TimeNum = g.Count(),
-                                        LinkGroupIds = g.Select(x => x.DIId).ToList()
+                                      Country = g.Key,
+                                      TimeNum = g.Count(),
+                                      LinkGroupIds = g.Select(x => x.DIId).ToList()
 
                                   })
                                   .OrderByDescending(x => x.TimeNum)
@@ -3846,6 +3850,448 @@ WHERE
             return Ok(JsonView(true, "操作成功!", groupByData));
         }
 
+        /// <summary>
+        ///  团组数据统计
+        ///  团组合作前十的客户TOP10排序
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost("StatisticsCooperativeCustomer")]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> StatisticsCooperativeCustomer(YOYDto _dto)
+        {
+
+            if (_dto.Year < 1) return Ok(JsonView(false, "操作失败"));
+
+
+            string beginDt = $"{_dto.Year}-01-01 00:00:00",
+                   endDt = $"{_dto.Year}-12-31 23:59:59";
+            DateTime _beginDt = Convert.ToDateTime(beginDt),
+                     _endDt = Convert.ToDateTime(endDt);
+
+            var groupInfos = await _sqlSugar.Queryable<Grp_DelegationInfo>()
+                                            .Where(x => x.IsDel == 0)
+                                            .Where(x => x.IsSure == 1)
+                                            .Where(x => x.VisitDate >= _beginDt && x.VisitDate <= _endDt)
+                                            .ToListAsync();
+
+            var groupInfos1 = groupInfos.GroupBy(x => x.ClientName);
+
+            var view = groupInfos1.Select(x =>
+                                            new {
+                                                clienName = x.Key,
+                                                clientUnit = x.FirstOrDefault()?.ClientUnit ?? "",
+                                                visitsNum = x.Count()
+                                            }
+                                         )
+                                  .OrderByDescending(x => x.visitsNum)
+                                  .Take(10)
+                                  .ToList();
+            return Ok(JsonView(true, "操作成功!", view));
+        }
+
+        /// <summary>
+        ///  团组数据统计
+        ///  已出团客户单位的类型比例图(饼状图-政府团、企业团等)
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost("StatisticsCooperativeCustomerType")]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> StatisticsCooperativeCustomerType(YOYDto _dto)
+        {
+
+            if (_dto.Year < 1) return Ok(JsonView(false, "操作失败"));
+
+
+            string beginDt = $"{_dto.Year}-01-01 00:00:00",
+                   endDt = $"{_dto.Year}-12-31 23:59:59";
+            DateTime _beginDt = Convert.ToDateTime(beginDt),
+                     _endDt = Convert.ToDateTime(endDt);
+
+            var groupInfos = await _sqlSugar.Queryable<Grp_DelegationInfo>()
+                                            .LeftJoin<Sys_SetData>((di, sd) => di.TeamDid == sd.Id)
+                                            .Where((di, sd) => di.IsDel == 0)
+                                            .Where((di, sd) => di.VisitDate >= _beginDt && di.VisitDate <= _endDt)
+                                            .Select((di, sd) => new {
+                                                Id = di.Id,
+                                                GroupTypeId = di.TeamDid,
+                                                GroupTypeName = sd.Name,
+                                            })
+                                            .ToListAsync();
+
+
+            var groupInfos1 = groupInfos.GroupBy(x => x.GroupTypeName);
+
+            var view = groupInfos1.Select(x =>
+                                            new {
+                                                groupTypeName = x.Key,
+                                                groupNum = x.Count(),
+                                                linkGroupId = x.Select(x1 => x1.Id).ToList()
+                                            }
+                                         )
+                                  .OrderByDescending(x => x.groupNum)
+                                  .ToList();
+            return Ok(JsonView(true, "操作成功!", view));
+        }
+
+
+        /// <summary>
+        ///  团组数据统计
+        ///  团组数量
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost("StatisticsGroupNum")]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> StatisticsGroupNum(YOYDto _dto)
+        {
+            if (_dto.Year < 1) return Ok(JsonView(false, "操作失败"));
+
+            string beginDt = $"{_dto.Year}-01-01 00:00:00",
+                   endDt = $"{_dto.Year}-12-31 23:59:59";
+            DateTime _beginDt = Convert.ToDateTime(beginDt),
+                     _endDt = Convert.ToDateTime(endDt);
+
+            var groupInfos = await _sqlSugar.Queryable<Grp_DelegationInfo>()
+                                            .Where(x => x.IsDel == 0)
+                                            .Where(x => x.VisitDate >= _beginDt && x.VisitDate <= _endDt)
+                                            .Select(x => new StatisticsGroupInfoEntity
+                                            {
+                                                Id = x.Id,
+                                                VisitDate = x.VisitDate,
+                                                Month = x.VisitDate.Month,
+                                                //MonthName = x.VisitDate.ToString("MMM", CultureInfo.GetCultureInfo("zh-CN")),
+                                                VisitPNumber = x.VisitPNumber
+                                            })
+                                            .MergeTable()
+                                            .OrderBy(x => new { x.Month })
+                                            .ToListAsync();
+
+            string groupNumStr = $"年度出访量:{groupInfos.Count}\r\n";
+
+            var groupNumYearData = new
+            {
+                year = _dto.Year,
+                yearName = _dto.Year + "年",
+                num = groupInfos.Count,
+                linkGroupIds = groupInfos.Select(x => x.Id).ToList()
+            };
+            var groupNumData = groupInfos.GroupBy(x => x.Quarter)
+                                         .Select(x => new {
+                                             Quarter = x.Key,
+                                             QuarterName = x.FirstOrDefault()?.QuarterName ?? "-",
+                                             Num = x.Count(),
+                                             LinkGroupIds = x.Select(x1 => x1.Id).ToList()
+                                         })
+                                         .OrderBy(x => x.Quarter)
+                                         .ToList();
+            groupNumData.ForEach(x =>
+            {
+                groupNumStr += $"{x.QuarterName}出访量:{x.Num};";
+            });
+
+            var groupNumMonthData = groupInfos.GroupBy(x => x.Month)
+                                         .Select(x => new {
+                                             Month = x.Key,
+                                             MonthName = x.FirstOrDefault()?.MonthName ?? "-",
+                                             Num = x.Count(),
+                                             LinkGroupIds = x.Select(x1 => x1.Id).ToList()
+                                         })
+                                         .OrderBy(x => x.Month)
+                                         .ToList();
+
+            return Ok(JsonView(true, "操作成功!", new
+            {
+                yearData = groupNumYearData,
+                quarterData = groupNumData,
+                monthData = groupNumMonthData,
+                remark = groupNumStr
+            }));
+        }
+
+        /// <summary>
+        ///  团组数据统计
+        ///  团组人数
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost("StatisticsGroupPeopleNum")]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> StatisticsGroupPeopleNum(YOYDto _dto)
+        {
+            if (_dto.Year < 1) return Ok(JsonView(false, "操作失败"));
+
+            string beginDt = $"{_dto.Year}-01-01 00:00:00",
+                   endDt = $"{_dto.Year}-12-31 23:59:59";
+            DateTime _beginDt = Convert.ToDateTime(beginDt),
+                     _endDt = Convert.ToDateTime(endDt);
+
+            var groupInfos = await _sqlSugar.Queryable<Grp_DelegationInfo>()
+                                            .Where(x => x.IsDel == 0)
+                                            .Where(x => x.VisitDate >= _beginDt && x.VisitDate <= _endDt)
+                                            .Select(x => new StatisticsGroupInfoEntity
+                                            {
+                                                Id = x.Id,
+                                                VisitDate = x.VisitDate,
+                                                Month = x.VisitDate.Month,
+                                                VisitPNumber = x.VisitPNumber
+                                            })
+                                            .MergeTable()
+                                            .OrderBy(x => new { x.Month })
+                                            .ToListAsync();
+
+            string groupPeopleNumStr = $"年度出访人数:{groupInfos.Sum(x => x.VisitPNumber)}\r\n";
+
+            var groupPeopleNumYearData = new
+            {
+                year = _dto.Year,
+                yearName = _dto.Year + "年",
+                num = groupInfos.Sum(x => x.VisitPNumber),
+                linkGroupIds = groupInfos.Select(x => x.Id).ToList()
+            };
+            var groupPeopleNumData = groupInfos.GroupBy(x => x.Quarter)
+                                               .Select(x => new {
+                                                   Quarter = x.Key,
+                                                   QuarterName = x.FirstOrDefault()?.QuarterName ?? "-",
+                                                   Num = x.Sum(x1 => x1.VisitPNumber),
+                                                   LinkGroupIds = x.Select(x1 => x1.Id).ToList()
+                                               })
+                                               .OrderBy(x => x.Quarter)
+                                               .ToList();
+            groupPeopleNumData.ForEach(x =>
+            {
+                groupPeopleNumStr += $"{x.QuarterName}出访人数:{x.Num};";
+            });
+
+            var groupPeopleNumMonthData = groupInfos.GroupBy(x => x.Month)
+                                                    .Select(x => new {
+                                                        Month = x.Key,
+                                                        MonthName = x.FirstOrDefault()?.MonthName ?? "-",
+                                                        Num = x.Sum(x1 => x1.VisitPNumber),
+                                                        LinkGroupIds = x.Select(x1 => x1.Id).ToList()
+                                                    })
+                                                    .OrderBy(x => x.Month)
+                                                    .ToList();
+
+            return Ok(JsonView(true, "操作成功!", new
+            {
+                yearData = groupPeopleNumYearData,
+                quarterData = groupPeopleNumData,
+                monthData = groupPeopleNumMonthData,
+                remark = groupPeopleNumStr
+            }));
+        }
+
+        /// <summary>
+        ///  团组数据统计
+        ///  OP 成本   
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost("StatisticsOP")]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> StatisticsOP(StatisticsOPDto _dto)
+        {
+            if (_dto.Year < 1) return Ok(JsonView(false, "Year参数错误!"));
+            if (_dto.Type < 1 || _dto.Type > 2) return Ok(JsonView(false, "Type参数错误!"));
+
+
+            int thisYear = _dto.Year, lastYear = _dto.Year - 1;
+            string beginDt = $"{lastYear}-01-01 00:00:00",
+                   endDt = $"{thisYear}-12-31 23:59:59";
+           
+
+
+            string sql = string.Format(@"
+SELECT
+  temp.Id,
+  DiId,
+  PaymentTime,
+  [Year],
+  [Quarter],
+  [Month],
+  Area,
+  FeeType,
+  sd1.Name AS FeeTypeName,
+  FeeSubType,
+  sd2.Name AS FeeSubTypeName,
+  CONVERT(DECIMAL(12, 2), Price * Qauntity * ExchangeRate) AS Price
+FROM
+  (
+    SELECT
+      ctggr.Id,
+      ctggr.DiId,
+      ctggr.Area,
+      CASE
+        WHEN ctggr.PriceType IS NULL THEN 1069
+        ELSE ctggr.PriceType
+      END AS FeeType,
+      ctggrc.SId AS FeeSubType,
+      ctggrc.Price,
+      CASE
+        WHEN ctggrc.Count IS NULL THEN 1
+        ELSE ctggrc.Count
+      END AS Qauntity,
+      ccp.DayRate AS ExchangeRate,
+      ctggrc.CreateTime AS PaymentTime,
+      YEAR(ctggrc.CreateTime) AS [Year],
+      CONVERT(INT,DATENAME(QUARTER, ctggrc.CreateTime)) AS [Quarter],
+      MONTH(ctggrc.CreateTime) AS [Month]
+    FROM
+      Grp_CarTouristGuideGroundReservations ctggr
+      INNER JOIN Grp_CarTouristGuideGroundReservationsContent ctggrc ON ctggr.Id = ctggrc.CTGGRId
+      AND ctggrc.IsDel = 0
+      INNER JOIN Grp_CreditCardPayment ccp ON ctggr.Id = ccp.CId
+      AND ccp.CTable = 79
+      AND ccp.IsDel = 0
+    WHERE
+      ctggr.IsDel = 0
+      AND ctggrc.SId != 1070 --费用子项筛掉尾款
+      AND ctggrc.Price > 0 --筛选真实存在的数据
+      AND ccp.IsPay = 1
+  ) temp
+  LEFT JOIN Sys_SetData sd1 ON FeeType = sd1.Id
+  LEFT JOIN Sys_SetData sd2 ON FeeSubType = sd2.Id
+WHERE
+  temp.Area NOT LIKE '%尾款%'  -- 筛选掉尾款相关信息
+  AND temp.FeeType != 1062 --费用类型筛选掉全款和首付款数据
+  AND temp.PaymentTime BETWEEN CONVERT(datetime,'{0}') AND CONVERT(datetime,'{1}')
+ORDER BY
+  temp.[Year],
+  temp.[Quarter],
+  temp.[Month]
+", beginDt,endDt);
+
+            var opInfos = await _sqlSugar.SqlQueryable<StatisticsOP>(sql).ToListAsync();
+
+            //处理地区相关信息
+            var countrys = await _sqlSugar.Queryable<Grp_NationalTravelFee>().Where(x => x.IsDel == 0).ToListAsync();
+
+            for (int i = 0; i < opInfos.Count; i++)
+            {
+                string country = string.Empty,city =string.Empty;
+
+                int dataId = 0;
+                bool isCountryId = int.TryParse(opInfos[i].Area, out dataId);
+                string[] citySelecter = new string[] {"其他城市","所有城市" };
+                if (isCountryId)
+                {
+                    var countryInfo = countrys.Find(x => x.Id == dataId);
+                    country = countryInfo?.Country ?? "";
+                    if (citySelecter.Contains(countryInfo?.City)) city = country;
+                    else city = countryInfo?.City ?? "";
+
+                }
+                else
+                {
+                    var countryInfo1 = countrys.Find(x => opInfos[i].Area.Contains(x.Country));
+                    if (countryInfo1 != null)
+                    {
+                        country = countryInfo1?.Country ?? "";
+                        city = countryInfo1?.City ?? country;
+                        var countryInfo2 = countrys.Find(x => opInfos[i].Area.Contains(x.City));
+
+                        if (citySelecter.Contains(countryInfo2?.City)) city = country;
+                        else city = countryInfo2?.City ?? country;
+
+                    }
+                    else
+                    {
+                        var countryInfo2 = countrys.Find(x => opInfos[i].Area.Contains(x.City));
+
+                        if (countryInfo2 != null)
+                        {
+                            country = countryInfo2?.Country ?? "";
+                            city = countryInfo2?.City ?? "";
+
+                            if (citySelecter.Contains(countryInfo2?.City)) city = country;
+
+                        }
+                    }
+                }
+                opInfos[i].Country = country;
+                opInfos[i].City = city;
+            }
+
+            if (_dto.Type == 1)
+            {
+                //同比增长率=(本期数-同期数)/ 同期数
+                var yearData = opInfos.GroupBy(x => x.ParentFeeName)
+                                      .Select(x => new StatisticsOPYOY(
+                                                   feeId: x.FirstOrDefault()?.ParentFeeId ?? 0,
+                                                   feeName: x.Key,
+                                                   currPeriodFee: x.Where(x => x.Year == thisYear).Sum(x => x.Price),
+                                                   samePeriodFee: x.Where(x => x.Year == lastYear).Sum(x => x.Price),
+                                                   currPeriodGroupTotal: x.Where(x => x.Year == thisYear).Select(x => x.DiId).Distinct().Count(),
+                                                   samePeriodGroupTotal: x.Where(x => x.Year == lastYear).Select(x => x.DiId).Distinct().Count(),
+                                                   subFeeData: x.GroupBy(x1 => x1.FeeSubType)
+                                                                .Select(x1 => new StatisticsOPSubFeeYOY(
+                                                                              feeId: x1.Key,
+                                                                              feeName: x1.FirstOrDefault()?.FeeSubTypeName ?? "",
+                                                                              currPeriodFee: x1.Where(x1 => x1.Year == thisYear).Sum(x1 => x1.Price),
+                                                                              samePeriodFee: x1.Where(x1 => x1.Year == lastYear).Sum(x1 => x1.Price),
+                                                                              currPeriodGroupTotal: x1.Where(x1 => x1.Year == thisYear).Select(x1 => x1.DiId).Distinct().Count(),
+                                                                              samePeriodGroupTotal: x1.Where(x1 => x1.Year == lastYear).Select(x1 => x1.DiId).Distinct().Count(),
+                                                                              cityData: x1.GroupBy(x2 => x2.City)
+                                                                                          .Select(x2 => new StatisticsOPCityYOY(
+                                                                                                        cityName: x2.Key,
+                                                                                                        currPeriodGroupTotal: x2.Where(x2 => x2.Year == thisYear).Select(x2 => x2.DiId).Distinct().Count(),
+                                                                                                        samePeriodGroupTotal: x2.Where(x2 => x2.Year == lastYear).Select(x2 => x2.DiId).Distinct().Count(),
+                                                                                                        currPeriodFee: x2.Where(x2 => x2.Year == thisYear).Sum(x2 => x2.Price),
+                                                                                                        samePeriodFee: x2.Where(x2 => x2.Year == lastYear).Sum(x2 => x2.Price)
+                                                                                              ))
+                                                                                          .ToArray()
+                                                                    ))        
+                                                                .ToArray()
+                                             ))
+                                      .OrderBy(x => x.FeeId)
+                                      .ToList();
+                return Ok(JsonView(true, "操作成功!", yearData));
+            }
+            else if (_dto.Type == 2)
+            {
+                var monthData = opInfos.GroupBy(x => x.Month)
+                                       .Select(x => new StatisticsOPMonthYOY(
+                                               monthId: x.Key,
+                                               monthName: Enum.IsDefined(typeof(MonthEnum), (int)x.Key) ? ((MonthEnum)(int)x.Key).GetEnumDescription() : "",
+                                               feeDatas:x.GroupBy(x1 => x1.ParentFeeId)
+                                                         .Select(x1 => new StatisticsOPYOY(
+                                                                       feeId:x1.Key,
+                                                                       feeName: x1.FirstOrDefault()?.ParentFeeName ?? "",
+                                                                       currPeriodFee: x1.Where(x1 => x1.Year == thisYear).Sum(x1 => x1.Price),
+                                                                       samePeriodFee: x1.Where(x1 => x1.Year == lastYear).Sum(x1 => x1.Price),
+                                                                       currPeriodGroupTotal: x1.Where(x1 => x1.Year == thisYear).Select(x1 => x1.DiId).Distinct().Count(),
+                                                                       samePeriodGroupTotal: x1.Where(x1 => x1.Year == lastYear).Select(x1 => x1.DiId).Distinct().Count(),
+                                                                       subFeeData:x1.GroupBy(x2 => x2.FeeSubType)
+                                                                                    .Select(x2 => new StatisticsOPSubFeeYOY(
+                                                                                                  feeId: x2.Key,
+                                                                                                  feeName: x2.FirstOrDefault()?.FeeSubTypeName ?? "",
+                                                                                                  currPeriodFee: x2.Where(x2 => x2.Year == thisYear).Sum(x2 => x2.Price),
+                                                                                                  samePeriodFee: x2.Where(x2 => x2.Year == lastYear).Sum(x2 => x2.Price),
+                                                                                                  currPeriodGroupTotal: x2.Where(x2 => x2.Year == thisYear).Select(x2 => x2.DiId).Distinct().Count(),
+                                                                                                  samePeriodGroupTotal: x2.Where(x2 => x2.Year == lastYear).Select(x2 => x2.DiId).Distinct().Count(),
+                                                                                                  cityData: x2.GroupBy(x3 => x3.City)
+                                                                                                              .Select(x3 => new StatisticsOPCityYOY(
+                                                                                                                            cityName: x3.Key,
+                                                                                                                            currPeriodFee: x3.Where(x3 => x3.Year == thisYear).Sum(x3 => x3.Price),
+                                                                                                                            samePeriodFee: x3.Where(x3 => x3.Year == lastYear).Sum(x3 => x3.Price),
+                                                                                                                            currPeriodGroupTotal: x3.Where(x3 => x3.Year == thisYear).Select(x3 => x3.DiId).Distinct().Count(),
+                                                                                                                            samePeriodGroupTotal: x3.Where(x3 => x3.Year == lastYear).Select(x3 => x3.DiId).Distinct().Count()
+                                                                                                                  ))
+                                                                                                              .ToArray()
+                                                                                        ))
+                                                                                    .ToArray()
+
+                                                             ))
+                                                         .ToArray()
+                                               ))
+                                       .OrderBy(x => x.MonthId)
+                                       .ToList();
+                return Ok(JsonView(true, "操作成功!", monthData));
+            }
+            return Ok(JsonView(false, "操作失败!"));
+        }
         #endregion
     }
 }

+ 11 - 0
OASystem/OASystem.Domain/Dtos/Statistics/MarketingSalesDto.cs

@@ -204,4 +204,15 @@ namespace OASystem.Domain.Dtos.Statistics
 
     #endregion
 
+
+    public class StatisticsOPDto
+    {
+        public int Year { get; set; }
+        /// <summary>
+        /// 1 年、2 月
+        /// </summary>
+        public int Type { get; set; }
+    }
+
+
 }

+ 0 - 1
OASystem/OASystem.Domain/Entities/Groups/Grp_CarTouristGuideGroundReservations.cs

@@ -64,7 +64,6 @@ namespace OASystem.Domain.Entities.Groups
         /// <summary>
         /// 服务时间起
         /// </summary>
-        /// 
         [SugarColumn(IsNullable = true, ColumnDataType = "varchar(80)")]
         public string ServiceStartTime { get; set; }
         /// <summary>

+ 86 - 0
OASystem/OASystem.Domain/Enums/MonthEnum.cs

@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Enums
+{
+    /// <summary>
+    /// 月份枚举
+    /// </summary>
+    public enum MonthEnum
+    {
+        /// <summary>
+        /// 一月
+        /// </summary>
+        [Description("一月")]
+        Jan = 1,
+        /// <summary>
+        /// 二月
+        /// </summary>
+        [Description("二月")]
+        Feb,
+        /// <summary>
+        /// 三月
+        /// </summary>
+        [Description("三月")]
+        Mar,
+        /// <summary>
+        /// 四月
+        /// </summary>
+        [Description("四月")]
+        Apr,
+        /// <summary>
+        /// 五月
+        /// </summary>
+        [Description("五月")]
+        May,
+        /// <summary>
+        /// 六月
+        /// </summary>
+        [Description("六月")]
+        Jun,
+        /// <summary>
+        /// 七月
+        /// </summary>
+        [Description("七月")]
+        Jul,
+        /// <summary>
+        /// 八月
+        /// </summary>
+        [Description("八月")]
+        Aug,
+        /// <summary>
+        /// 九月
+        /// </summary>
+        [Description("九月")]
+        Sep,
+        /// <summary>
+        /// 十月
+        /// </summary>
+        [Description("十月")]
+        Oct,
+        /// <summary>
+        /// 十一月
+        /// </summary>
+        [Description("十一月")]
+        Nov,
+        /// <summary>
+        /// 十二月
+        /// </summary>
+        [Description("十二月")]
+        Dec,
+    }
+    
+    static class EnumExtensions
+    {
+        public static string GetDescription(this Enum val)
+        {
+            var field = val.GetType().GetField(val.ToString());
+            var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
+            return customAttribute == null ? val.ToString() : ((DescriptionAttribute)customAttribute).Description;
+        }
+    }
+}

+ 404 - 1
OASystem/OASystem.Domain/ViewModels/Financial/Fin_DailyFeePaymentView.cs

@@ -4,9 +4,11 @@ using OASystem.Domain.Entities.Financial;
 using OASystem.Domain.ViewModels.System;
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Xml.Linq;
 
 namespace OASystem.Domain.ViewModels.Financial
 {
@@ -925,8 +927,409 @@ namespace OASystem.Domain.ViewModels.Financial
     public class StatisticsInvitation
     {
         public int DIId { get; set; }
-        public string Country { get; set; }    }
+        public string Country { get; set; }
+    }
     #endregion
 
+    #region 团组相关
+
+    public class StatisticsGroupInfoEntity
+    {
+        public int Id { get; set; }
+        public DateTime VisitDate { get; set; }
+        public int Month { get; set; }
+
+        public string MonthName { get { return VisitDate.ToString("MMM", CultureInfo.GetCultureInfo("zh-CN")); } }
+
+        public int Quarter
+        {
+            get
+            {
+                int quarter = 0;
+                if (Month < 1 || Month > 12) return quarter;
+                if (Month >= 1 && Month <= 3) quarter = 1;
+                else if (Month >= 4 && Month <= 6) quarter = 2;
+                else if (Month >= 7 && Month <= 9) quarter = 3;
+                else if (Month >= 10 && Month <= 12) quarter = 4;
+                return quarter;
+            }
+        }
+
+        public string QuarterName
+        {
+            get
+            {
+                string quarterName = "-";
+                if (Month < 1 || Month > 12) return quarterName;
+                if (Month >= 1 && Month <= 3) quarterName = "第一季度";
+                else if (Month >= 4 && Month <= 6) quarterName = "第二季度";
+                else if (Month >= 7 && Month <= 9) quarterName = "第三季度";
+                else if (Month >= 10 && Month <= 12) quarterName = "第四季度";
+                return quarterName;
+            }
+        }
+        public int VisitPNumber { get; set; }
+    }
+
+    #endregion
+
+    #region OP
+    public class StatisticsOP
+    {
+        /*
+         * OP统计图(实际成本同比年/月)
+         *分块:如车费/导游费/导游交通/接送机费/司机工资/翻译费 	
+         *用于判断实际成本是否有增长【真实使用的时候估计是2025年和2024年对比,2023年的数据格式和数据量有问题】
+         * 
+         * 车费:91	车费  982 车超时费
+         * 导游费:92 导游费  985 导游交通  1059 导游超时费用
+         * 司机费:979 司机工资    
+         * 小费:980 司机小费 95 导游小费
+         * 接送机费:96 接送机费  
+         * 餐费:93	客户午餐费用  981 司机餐补  983	导游餐补  988 客户早餐费用  989	客户晚餐费用  
+         *       1074 早餐超支费用  1075 午餐超支费用  1076 晚餐超支费用
+         * 住补费:992 住补费用  984 导游房补
+         * 景点费:94 导游景点费  990	景点门票费  1085 景点门票超支费用
+         * 翻译费:994 翻译费  1073	翻译超时费
+         * 饮料/零食/水果费:991 饮料/零食/水果
+         * 其他费:97 其他费用  1071 其他额外费用
+         */
+        //车费
+        private static int[] _carFeeIds = new int[] {
+                                            91,   //车费
+                                            982,  //车超时费
+                                        };
+        //导游费
+        private static int[] _guideFeeIds = new int[] {
+                                                92,   //导游费
+                                                985,  //导游交通
+                                                1059, //导游超时费用
+                                            };
+        //司机费
+        private static int[] _driverFeeIds = new int[]{
+                                                979,  //司机工资
+                                            };
+        //小费
+        private static int[] _tipsFeeIds = new int[] {
+                                               980,  //司机小费
+                                               95,   //导游小费
+                                            };
+        //接送机费
+        private static int[] _airportTransferFeeIds = new int[] {
+                                                         96,  //接送机费
+                                                      };
+        //餐费
+        private static int[] _mealFeeIds = new[] {
+                                          93,  //客户午餐费用
+                                          981, //司机餐补
+                                          983, //导游餐补
+                                          988, //客户早餐费用
+                                          989, //客户晚餐费用
+                                          1074,//早餐超支费用
+                                          1075,//午餐超支费用
+                                          1076,//晚餐超支费用
+                                       };
+        //住补费
+        private static int[] _sububoFeeIds = new[] {
+                                         992,  //住补费用  
+                                         984,  //导游房补
+                                       };
+        //景点费
+        private static int[] _scenicSpotFeeIds = new[] {
+                                        94,  //导游景点费  
+                                        990, //景点门票费  
+                                        1085,//景点门票超支费用
+                                       };
+        //翻译费
+        private static int[] _translationFeeIds = new[] {
+                                                994,  //翻译费  
+                                                1073, //翻译超时费
+                                               };
+        //饮料/零食/水果费
+        private static int[] _DSFFeeIds = new int[] {
+                                             991,  //饮料/零食/水果
+                                         };
+        //其他费
+        private static int[] _otherFeeIds = new int[] {
+                                                97,  //其他费用  
+                                                1071,//其他额外费用
+                                            };
+
+
+        public int Id { get; set; }
+        public int DiId { get; set; }
+        public DateTime PaymentTime { get; set; }
+        public int Year { get; set; }
+        public int Quarter { get; set; }
+        public int Month { get; set; }
+        public string Area { get; set; }
+        public string Country { get; set; }
+        public string City { get; set; }
+        public int ParentFeeId {
+            get
+            {
+                return int.TryParse(GetFeeParentInfo(FeeSubType, 1), out int id) ? id : 0;
+            }
+        }
+        public string ParentFeeName
+        {
+            get
+            {
+                return GetFeeParentInfo(FeeSubType, 2);
+            }
+        }
+
+        public string ParentFeeRemark { get; set; }
+        public int FeeType { get; set; }
+        public string FeeTypeName { get; set; }
+        public int FeeSubType { get; set; }
+        public string FeeSubTypeName { get; set; }
+
+        public decimal Price { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="subFee"></param>
+        /// <param name="type">1 id 2 name 3 备注 </param>
+        /// <returns></returns>
+        private static string GetFeeParentInfo(int subFee,int type)
+        {
+           int id = -1;
+           string name =string.Empty;
+           string remark = string.Empty;
+            // 车费:91 车费  982 车超时费
+            if (_carFeeIds.Contains(subFee))
+            {
+                id = 1;
+                name = "车费";
+                remark = "费用组成:车费、车超时费";
+            }
+            // 导游费:92 导游费  985 导游交通  1059 导游超时费用
+            if (_guideFeeIds.Contains(subFee))
+            {
+                id = 2;
+                remark = "费用组成:导游费、导游交通、导游超时费用";
+                name = "导游费";
+            }
+            // 司机费:979 司机工资
+            if (_driverFeeIds.Contains(subFee))
+            {
+                id = 3;
+                remark = "费用组成:司机工资";
+                name = "司机费";
+            }
+            // 小费:980 司机小费 95 导游小费
+            if (_tipsFeeIds.Contains(subFee))
+            {
+                id = 4;
+                remark = "费用组成:司机小费、导游小费";
+                name = "小费";
+            }
+            // 接送机费:96 接送机费
+            if (_airportTransferFeeIds.Contains(subFee))
+            {
+                id = 5;
+                remark = "费用组成:接送机费";
+                name = "接送机费";
+            }
+            // 餐费:93 客户午餐费用  981 司机餐补  983   导游餐补  988 客户早餐费用  989   客户晚餐费用
+            // 1074 早餐超支费用  1075 午餐超支费用  1076 晚餐超支费用
+            if (_mealFeeIds.Contains(subFee))
+            {
+                id = 6;
+                remark = "费用组成:客户早餐费用、客户午餐费用、客户晚餐费用、司机餐补、导游餐补、早餐超支费用、午餐超支费用、晚餐超支费用";
+                name = "餐费";
+            }
+            // 住补费:992 住补费用  984 导游房补
+            if (_sububoFeeIds.Contains(subFee))
+            {
+                id = 7;
+                remark = "费用组成:住补费用、导游房补";
+                name = "住补费";
+            }
+            // 景点费:94 导游景点费  990 景点门票费  1085 景点门票超支费用
+            if (_scenicSpotFeeIds.Contains(subFee))
+            {
+                id = 8;
+                remark = "费用组成:导游景点费、景点门票费、景点门票超支费用";
+                name = "景点费";
+            }
+            // 翻译费:994 翻译费  1073 翻译超时费
+            if (_translationFeeIds.Contains(subFee))
+            {
+
+                id = 9;
+                remark = "费用组成:翻译费、翻译超时费";
+                name = "翻译费";
+            }
+            // 饮料/ 零食 / 水果费:991 饮料 / 零食 / 水果
+            if (_DSFFeeIds.Contains(subFee))
+            {
+                id = 10;
+                remark = "费用组成:饮料/零食/水果费";
+                name = "饮料/零食/水果费";
+            }
+            // 其他费用:97 其他费用  1071 其他额外费用
+            if (_otherFeeIds.Contains(subFee))
+            {
+                id = 11;
+                remark = "费用组成:其他费用、其他额外费用";
+                name = "其他费用";
+            }
+
+            string returnStr = string.Empty;
+            if (type == 1) returnStr = id.ToString();
+            else if (type == 2) returnStr = name;
+            else if (type == 3) returnStr = remark;
+
+            return returnStr;
+        }
+    }
+
+
+      
+
+
+
+    public class StatisticsOPYOY
+    {
+        public int FeeId { get; set; }
+        public string FeeName { get; set; }
+        /// <summary>
+        /// 本期
+        /// </summary>
+        public decimal CurrPeriodFee { get; set; }
+        /// <summary>
+        /// 同期
+        /// </summary>
+        public decimal SamePeriodFee { get; set; }
+        public decimal Yoy { get; set; }
+        public int CurrPeriodGroupTotal { get; set; }
+        public int SamePeriodGroupTotal { get; set; }
+        public StatisticsOPSubFeeYOY[] SubFeeData { get; set; }
+
+        public StatisticsOPYOY() { }
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="year"></param>
+        /// <param name="month"></param>
+        /// <param name="thisAmount"></param>
+        /// <param name="lastAmount"></param>
+        /// <param name="thisIds"></param>
+        /// <param name="lastIds"></param>
+        public StatisticsOPYOY(int feeId, string feeName, decimal currPeriodFee, decimal samePeriodFee,
+           int currPeriodGroupTotal ,int samePeriodGroupTotal, StatisticsOPSubFeeYOY[] subFeeData)
+        {
+            this.FeeId = feeId;
+            this.FeeName = feeName;
+            this.CurrPeriodFee = currPeriodFee;
+            this.SamePeriodFee = samePeriodFee;
+            decimal _yoy = 0.00M;
+            if (samePeriodFee != 0.00M)
+            {
+                _yoy = (currPeriodFee - samePeriodFee) / samePeriodFee;
+            }
+
+            this.Yoy = decimal.Parse(_yoy.ToString("0.##")); 
+            this.CurrPeriodGroupTotal = currPeriodGroupTotal;
+            this.SamePeriodGroupTotal = samePeriodGroupTotal;
+            this.SubFeeData = subFeeData;
+        }
+    }
+
+    public class StatisticsOPSubFeeYOY : StatisticsOPYOY
+    {
+        public StatisticsOPCityYOY[] CityData { get; set; }
+
+        public StatisticsOPSubFeeYOY() { }
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="year"></param>
+        /// <param name="month"></param>
+        /// <param name="thisAmount"></param>
+        /// <param name="lastAmount"></param>
+        /// <param name="thisIds"></param>
+        /// <param name="lastIds"></param>
+        public StatisticsOPSubFeeYOY(int feeId, string feeName, decimal currPeriodFee, decimal samePeriodFee,
+           int currPeriodGroupTotal, int samePeriodGroupTotal, StatisticsOPCityYOY[] cityData)
+        {
+            this.FeeId = feeId;
+            this.FeeName = feeName;
+            this.CurrPeriodFee = currPeriodFee;
+            this.SamePeriodFee = samePeriodFee;
+            decimal _yoy = 0.00M;
+            if (samePeriodFee != 0.00M)
+            {
+                _yoy = (currPeriodFee - samePeriodFee) / samePeriodFee;
+            }
+            this.Yoy = decimal.Parse(_yoy.ToString("0.##"));
+            this.CurrPeriodGroupTotal = currPeriodGroupTotal;
+            this.SamePeriodGroupTotal = samePeriodGroupTotal;
+            this.CityData = cityData;
+        }
+    }
+
+    public class StatisticsOPCityYOY
+    {
+        public string CityName { get; set; }
+
+        public int CurrPeriodGroupTotal { get; set; }
+        public int SamePeriodGroupTotal { get; set; }
+
+        /// <summary>
+        /// 本期
+        /// </summary>
+        public decimal CurrPeriodFee { get; set; }
+        /// <summary>
+        /// 同期
+        /// </summary>
+        public decimal SamePeriodFee { get; set; }
+        public decimal Yoy { get; set; }
+
+        public StatisticsOPCityYOY() { }
+
+        public StatisticsOPCityYOY(string cityName, decimal currPeriodFee, decimal samePeriodFee,
+            int currPeriodGroupTotal,int samePeriodGroupTotal) 
+        {
+            this.CityName = cityName;
+            this.CurrPeriodGroupTotal = currPeriodGroupTotal;
+            this.SamePeriodGroupTotal = samePeriodGroupTotal;
+            this.CurrPeriodFee = currPeriodFee;
+            this.SamePeriodFee = samePeriodFee;
+            string _yoy = "0.00";
+            if (samePeriodFee != 0)
+            {
+                _yoy = ((currPeriodFee - samePeriodFee) / samePeriodFee).ToString("0.##");
+            }
+
+            this.Yoy = decimal.TryParse(_yoy, out decimal yoy1) ? yoy1 : 0.00M;
+        }
+
+    }
+
+
+    public class StatisticsOPMonthYOY
+    {
+        public int MonthId { get; set; }
+
+        public string MonthName { get; set; }
+
+        public StatisticsOPYOY[] FeeDatas { get; set; }
+
+        public StatisticsOPMonthYOY() { }
+
+        public StatisticsOPMonthYOY(int monthId, string monthName, StatisticsOPYOY[] feeDatas)
+        {
+            MonthId = monthId;
+            MonthName = monthName;
+            FeeDatas = feeDatas;
+        }
+    }
+
+    #endregion
     #endregion
 }

+ 2 - 1
OASystem/OASystem.Infrastructure/Repositories/Groups/FeeAuditRepository.cs

@@ -1,4 +1,5 @@
-using NPOI.SS.Formula.Functions;
+using EyeSoft.Logging;
+using NPOI.SS.Formula.Functions;
 using OASystem.Domain;
 using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.ViewModels.Groups;