Kaynağa Gözat

简化异常处理并增强出入境费用报价功能

在 `BusinessController.cs` 中,简化了 `PostShareGroupInfo` 和 `PostGroupListByCTableAndUserId` 方法的异常处理逻辑,直接返回结果,移除了复杂的 SQL 查询。

在 `GroupsController.cs` 中,修改了 `QueryinvitationLetter` 方法的排序逻辑,确保按 `VisitStartDate` 排序。

新增了多个方法以处理出入境费用报价表的相关操作,并在 `EnterExitCostQuoteDto.cs` 中增加了多个 DTO 类,提升数据传输的灵活性。

在 `Grp_EnterExitCostQuoteItem.cs` 中新增了 `Index` 和 `Currency` 属性,提供更详细的费用项信息。

在 `InvitationOfficialActivityDataView.cs` 中新增了 `InvitationOfficialActivityDataView1` 类,增强了对邀请官方活动数据的处理能力。

多个仓储类的查询逻辑也进行了排序依据的调整,确保数据的时间顺序性。同时,进行了代码格式化和清理,提升了可读性和维护性。
LEIYI 1 ay önce
ebeveyn
işleme
f2c9e8696b

+ 3 - 54
OASystem/OASystem.Api/Controllers/BusinessController.cs

@@ -53,22 +53,7 @@ namespace OASystem.API.Controllers
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> PostShareGroupInfo(ShareGroupInfoDto dto)
         {
-            try
-            {
-                var groupData = await _groupRep.PostShareGroupInfo(dto);
-                if (groupData.Code != 0)
-                {
-                    return Ok(JsonView(false, groupData.Msg));
-                }
-
-                return Ok(JsonView(groupData.Data));
-            }
-            catch (Exception ex)
-            {
-
-                return Ok(JsonView(false, ex.Message));
-            }
-
+            return Ok(await _groupRep.PostShareGroupInfo(dto));
         }
 
         /// <summary>
@@ -86,7 +71,7 @@ namespace OASystem.API.Controllers
                 return Ok(JsonView(false, groupData.Msg));
             }
 
-            return Ok(JsonView(groupData.Data, groupData.Data.Count));
+            return Ok(JsonView(groupData.Data, groupData?.Count ?? 0));
         }
 
 
@@ -198,43 +183,7 @@ namespace OASystem.API.Controllers
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> PostGroupListByCTableAndUserId(GroupListByCTableAndUserIdDto dto)
         {
-            if (dto.CTable < 1) Ok(JsonView(false, @"请输入正确的员工给Id!"));
-
-            if (dto.CTable < 1)
-                return Ok(JsonView(false, @"请输入正确的CTable Id !76 酒店预订  77 行程  79 车/导游地接<br/>80 签证    81 邀请/公务活动  82 团组客户保险<br\>85 机票预订   98 其他款项 751 酒店早餐"));
-
-            if (dto.PortType == 1 || dto.PortType == 2 || dto.PortType == 3)
-            {
-                string sql = string.Format(@"Select row_number() over(order by di.CreateTime Desc) as Row_Number, 
-									         di.Id,di.TeamName,di.TourCode,di.ClientName,di.VisitCountry,di.VisitStartDate,
-									         di.VisitEndDate,di.VisitDays,di.VisitPNumber,di.CreateTime
-									         From Grp_GroupsTaskAssignment gta
-									         Inner Join Grp_DelegationInfo di On gta.DIId = di.Id
-									         Where gta.IsDel = 0 And di.IsDel = 0 And gta.IsEnable = 1
-									         And gta.CTId = {0} And gta.UId = {1}", dto.CTable, dto.UserId);
-
-                if (!string.IsNullOrEmpty(dto.TeamName))
-                {
-                    sql = string.Format($"{sql} And di.TeamName Like '%{dto.TeamName}%'");
-                }
-                //去重
-                sql = $"{sql} GROUP BY di.Id,di.TeamName,di.TourCode,di.ClientName,di.VisitCountry,di.VisitStartDate,di.VisitEndDate,di.VisitDays,di.VisitPNumber,di.CreateTime";
-
-
-                RefAsync<int> total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
-                var data = await _groupRep._sqlSugar.SqlQueryable<GroupListByCTableAndUserIdView>(sql).ToPageListAsync(dto.PageIndex, dto.PageSize, total); //ToPageAsync
-                foreach (var item in data)
-                {
-                    item.VisitStartDate = item.VisitStartDate == "" ? "" : Convert.ToDateTime(item.VisitStartDate).ToString("yyyy-MM-dd");
-                    item.VisitEndDate = item.VisitEndDate == "" ? "" : Convert.ToDateTime(item.VisitEndDate).ToString("yyyy-MM-dd");
-                }
-
-                return Ok(JsonView(true, "操作成功!", data, total));
-            }
-            else
-            {
-                return Ok(JsonView(false, @"请输入正确的PortType 1 Web 2 Android 3 IOS "));
-            }
+            return Ok(await _groupRep.ListByCTableAndUserId(dto));
         }
 
         #endregion

+ 486 - 43
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -4,6 +4,7 @@ using Aspose.Words.Drawing;
 using Aspose.Words.Tables;
 using DiffMatchPatch;
 using Microsoft.AspNetCore.SignalR;
+using Microsoft.VisualBasic;
 using MySqlX.XDevAPI.Relational;
 using NPOI.HSSF.UserModel;
 using NPOI.SS.Formula.Functions;
@@ -29,6 +30,7 @@ using OASystem.Domain.Entities.Financial;
 using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.ViewModels.Financial;
 using OASystem.Domain.ViewModels.Groups;
+using OASystem.Domain.ViewModels.QiYeWeChat;
 using OASystem.Infrastructure.Repositories.CRM;
 using OASystem.Infrastructure.Repositories.Financial;
 using OASystem.Infrastructure.Repositories.Groups;
@@ -5121,7 +5123,7 @@ FROM
         {
             try
             {
-                List<Grp_DelegationInfo> grp_Delegations = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(a => a.IsDel == 0).OrderBy(a => a.Id, OrderByType.Desc).ToList();
+                List<Grp_DelegationInfo> grp_Delegations = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(a => a.IsDel == 0).OrderBy(a => a.VisitStartDate, OrderByType.Desc).ToList();
                 List<Crm_DeleClient> crm_Deles = new List<Crm_DeleClient>();
                 if (dto.DiId == 0)
                 {
@@ -5328,7 +5330,7 @@ FROM
             var excelTypeData = dataSource.Where(it => it.STid == 73).ToList(); //三公费用-Excel明细类型
             List<SetDataInfoView> _ExcelTypeData = _mapper.Map<List<SetDataInfoView>>(excelTypeData);
 
-            List<CurrencyInfo> _currencyInfos = await GeneralMethod.EnterExitCostInitRate();
+            var _currencyInfos = await GeneralMethod.EnterExitCostInitRate();
 
             var viewPermissionData = await _enterExitCostRep.PermissionViewUsersAsync();
             return Ok(JsonView(true, "查询成功!", new
@@ -7487,7 +7489,7 @@ FROM
             var _ExcelTypeData = _mapper.Map<List<SetDataInfoView>>(excelTypeData);
 
             //默认币种显示
-            List<CurrencyInfo> _currencyInfos = await GeneralMethod.EnterExitCostInitRate();
+            var _currencyInfos = await GeneralMethod.EnterExitCostInitRate();
 
             var viewPermissionData = await _enterExitCostDraftRep.PermissionViewUsersAsync();
 
@@ -10529,7 +10531,7 @@ WHERE
             }
             else if (dto.TipsType == 3)
             {
-
+                return Ok(JsonView(false, "暂无机票费用提示信息!"));
             }
             return Ok(JsonView(false));
         }
@@ -11628,70 +11630,511 @@ WHERE
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> EnterExitCostQuoteInitData(PortDtoBase dto)
         {
-            //默认币种显示
-            var currencyInfos = new List<CurrencyInfo>()
+            var initRates = await GeneralMethod.EnterExitCostInitRate();
+            var liveRates = await GeneralMethod.EnterExitCostLiveRate();
+            var cnyInfo = new CurrencyInfo() { CurrencyCode = "CNY", CurrencyName = "人民币", Rate = 1.0000M };
+            initRates.Insert(0, cnyInfo);
+            liveRates.Insert(0, cnyInfo);
+            return Ok(JsonView(true, "查询成功!", new
+            {
+                InitRates = initRates,
+                LiveRates = liveRates
+            }));
+        }
+
+        /// <summary>
+        /// 团组模块 - 出入境费用报价表 - 报价表名称列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> EnterExitCostQuoteNameListDto(EnterExitCostQuoteNameListDto dto)
+        {
+            return Ok(await _enterExitCostQuoteRep.QuoteNameListAsync(dto));
+        }
+
+        /// <summary>
+        /// 团组模块 - 出入境费用报价表 - 团组名称列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> EnterExitCostQuoteGroupNameListDto(EnterExitCostQuoteGroupNameListDto dto)
+        {
+            return Ok(await _enterExitCostQuoteRep.GroupNameListAsync(dto));
+        }
+
+        /// <summary>
+        /// 团组模块 - 出入境费用报价表 - 根据团组Id获出入境费用相关信息
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> EnterExitCostQuoteEntryExitCosts(EnterExitCostInfobyDiIdDto dto)
+        {
+            int groupId = dto.DiId,
+                currUserId = dto.CurrUserId;
+            if (groupId < 1) return Ok(JsonView(false,"请传入有效的GroupId;"));
+            if (currUserId < 1) return Ok(JsonView(false, "请传入有效的CurrUserId;"));
+
+            var info = await _enterExitCostRep.GetEnterExitCostInfoByDiId(dto);
+            if (info.Code != StatusCodes.Status200OK) return Ok(info);
+
+            var infoView = info.Data as EnterExitCostInfoView;
+            if (infoView == null) return Ok(JsonView(false, "数据类型转换失败!;"));
+
+            var countryFees = await _sqlSugar.Queryable<Grp_NationalTravelFee>().Where(x => x.IsDel == 0).ToListAsync();
+            var cityFilter = new List<string>() { "全部城市", "其他城市" };
+            var currencys = await _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && x.STid == 66).ToListAsync();
+            var eecRates = infoView.Currencys;
+
+            var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(x => x.Id == dto.DiId && x.IsDel == 0);
+            int pplNum = 1;
+            if (groupInfo != null) pplNum = groupInfo.VisitPNumber;
+
+            var views = new List<QuoteSubItemInfo>();
+
+            #region 数据填充
+
+            var intTravelCosts = new List<QuoteSubItemInfo>();
+            #region 机票费用 1354
+            int intTravelIndex = 1;
+            if (infoView.SumJJC == 1)
+            {
+                intTravelCosts.Add(new QuoteSubItemInfo
                 {
-                    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 },
-                };
+                    ItemId = 1354,
+                    Index = intTravelIndex,
+                    FeeName = "经济舱",
+                    UnitPrice = infoView.AirJJ,
+                    Currency = "CNY",
+                    Quantity = 1,
+                    PplNum = 1,
+                    TotalAmt = infoView.AirJJ,
+                    Remark = "",
+                });
+                intTravelIndex++;
+            }
+            if (infoView.SumGWC == 1)
+            {
+                intTravelCosts.Add(new QuoteSubItemInfo
+                {
+                    ItemId = 1354,
+                    Index = intTravelIndex,
+                    FeeName = "公务舱",
+                    UnitPrice = infoView.AirGW,
+                    Currency = "CNY",
+                    Quantity = 1,
+                    PplNum = 1,
+                    TotalAmt = infoView.AirGW,
+                    Remark = "",
+                });
+                intTravelIndex++;
+            }
+            if (infoView.SumTDC == 1)
+            {
+                intTravelCosts.Add(new QuoteSubItemInfo
+                {
+                    ItemId = 1354,
+                    Index = intTravelIndex,
+                    FeeName = "头等舱",
+                    UnitPrice = infoView.AirTD,
+                    Currency = "CNY",
+                    Quantity = 1,
+                    PplNum = 1,
+                    TotalAmt = infoView.AirTD,
+                    Remark = "",
+                });
+                intTravelIndex++;
+            }
 
-            var liveRateInfos = new List<LiveRateInfo>();
-            var currencyRate = await _juHeApi.PostItemRateAsync(currencyInfos.Select(it => it.CurrencyCode!).ToArray());
-            if (currencyRate.Any())
+            intTravelCosts.Add(new QuoteSubItemInfo
             {
-                foreach (var item in currencyInfos)
+                ItemId = 1354,
+                Index = intTravelIndex,
+                FeeName = "城市间交通费用",
+                UnitPrice = infoView.CityTranffic,
+                Currency = "CNY",
+                Quantity = 1,
+                PplNum = pplNum,
+                TotalAmt = infoView.CityTranffic * pplNum,
+                Remark = "",
+            });
+
+            views.AddRange(intTravelCosts);
+            #endregion
+
+            var accomCosts = new List<QuoteSubItemInfo>();
+            #region 住宿费 1355
+            if (infoView.QuarterageData.Any())
+            {
+                int accomIndex = 1;
+                int accomItemTypeId = 1355;
+
+                var groupData = infoView.QuarterageData.GroupBy(x => x.NationalTravelFeeId);
+
+                foreach (var item in groupData)
                 {
-                    var rateInfo = currencyRate.Where(it => it.Name.Equals(item.CurrencyName)).FirstOrDefault();
-                  
-                    if (rateInfo != null)
+                    string feeName = string.Empty;
+                    var countryInfo = countryFees.FirstOrDefault(x => x.Id == item.Key);
+                    if (countryInfo != null)
                     {
-                        decimal rate1 = Convert.ToDecimal(rateInfo.FSellPri) / 100.00M;
+                        feeName = countryInfo.Country;
+                        var city = countryInfo.City;
+                        
+                        if (!string.IsNullOrEmpty(city) && cityFilter.Any(x => !x.Contains(city)))
+                        {
+                            feeName += $"-{city}";
+                        }
+                    }
 
-                        if (rateInfo.Name.Equals("日元")) rate1 *= 1.3700M;
-                        else rate1 *= 1.035M;
+                    var hotelInfo = item.FirstOrDefault();
+                    if (hotelInfo == null) continue;
+                    var thisCurrency = currencys.FirstOrDefault(x => x.Id == hotelInfo.Currency)?.Name ?? "nuknow";
+                    var thisRate = eecRates.FirstOrDefault(x => x.CurrencyCode.Equals(thisCurrency))?.Rate ?? 1.0000M;
+                    int quantity = item.ToList().Count;
 
-                        liveRateInfos.Add(new LiveRateInfo() {
-                            CurrencyCode = item.CurrencyCode,
-                            CurrencyName = item.CurrencyName,
-                            Rate = rate1.TruncDecimals(4),
-                            LastUpdTime = $"{rateInfo.Date} {rateInfo.Time}",
-                        });
+                    accomCosts.Add(new QuoteSubItemInfo
+                    {
+                        ItemId = accomItemTypeId,
+                        Index = accomIndex,
+                        FeeName = feeName,
+                        UnitPrice = hotelInfo.Cost,
+                        Currency = thisCurrency,
+                        Quantity = quantity,
+                        PplNum = pplNum,
+                        TotalAmt = hotelInfo.Cost * thisRate * quantity * pplNum,
+                        Remark = "",
+                    });
+                    accomIndex++;
+                }
+
+                views.AddRange(accomCosts);
+            }
+
+            #endregion
+
+            var mealCosts = new List<QuoteSubItemInfo>();
+            #region 餐饮费 1356
+            if (infoView.BoardWagesData.Any())
+            {
+                var mealIndex = 1;
+                int mealItemTypeId = 1356;
+
+                var groupData = infoView.BoardWagesData.GroupBy(x => x.NationalTravelFeeId);
+
+                foreach (var item in groupData)
+                {
+                    string feeName = string.Empty;
+                    var countryInfo = countryFees.FirstOrDefault(x => x.Id == item.Key);
+                    if (countryInfo != null)
+                    {
+                        feeName = countryInfo.Country;
+                        var city = countryInfo.City;
+
+                        if (!string.IsNullOrEmpty(city) && cityFilter.Any(x => !x.Contains(city)))
+                        {
+                            feeName += $"-{city}";
+                        }
                     }
+
+                    var mealInfo = item.FirstOrDefault();
+                    if (mealInfo == null) continue;
+                    var thisCurrency = currencys.FirstOrDefault(x => x.Id == mealInfo.Currency)?.Name ?? "nuknow";
+                    var thisRate = eecRates.FirstOrDefault(x => x.CurrencyCode.Equals(thisCurrency))?.Rate ?? 1.0000M;
+                    int quantity = item.ToList().Count;
+
+                    mealCosts.Add(new QuoteSubItemInfo
+                    {
+                        ItemId = mealItemTypeId,
+                        Index = mealIndex,
+                        FeeName = feeName,
+                        UnitPrice = mealInfo.Cost,
+                        Currency = thisCurrency,
+                        Quantity = quantity,
+                        PplNum = pplNum,
+                        TotalAmt = mealInfo.Cost * thisRate * quantity * pplNum,
+                        Remark = "",
+                    });
+                    mealIndex++;
                 }
+
+                views.AddRange(mealCosts);
             }
 
-            return Ok(JsonView(true, "查询成功!", new
+            #endregion
+
+            var miscCosts = new List<QuoteSubItemInfo>();
+            #region 公杂费 1364
+            if (infoView.MiscellaneousFeeData.Any())
             {
-                InitRates = await GeneralMethod.EnterExitCostInitRate(),
-                LiveRates = await GeneralMethod.EnterExitCostLiveRate()
-            }));
+                var miscIndex = 1;
+                int miscItemTypeId = 1364;
+
+                var groupData = infoView.MiscellaneousFeeData.GroupBy(x => x.NationalTravelFeeId);
+
+                foreach (var item in groupData)
+                {
+                    string feeName = string.Empty;
+                    var countryInfo = countryFees.FirstOrDefault(x => x.Id == item.Key);
+                    if (countryInfo != null)
+                    {
+                        feeName = countryInfo.Country;
+                        var city = countryInfo.City;
+
+                        if (!string.IsNullOrEmpty(city) && cityFilter.Any(x => !x.Contains(city)))
+                        {
+                            feeName += $"-{city}";
+                        }
+                    }
+
+                    var miscInfo = item.FirstOrDefault();
+                    if (miscInfo == null) continue;
+                    var thisCurrency = currencys.FirstOrDefault(x => x.Id == miscInfo.Currency)?.Name ?? "nuknow";
+                    var thisRate = eecRates.FirstOrDefault(x => x.CurrencyCode.Equals(thisCurrency))?.Rate ?? 1.0000M;
+                    int quantity = item.ToList().Count;
+
+                    mealCosts.Add(new QuoteSubItemInfo
+                    {
+                        ItemId = miscItemTypeId,
+                        Index = miscIndex,
+                        FeeName = feeName,
+                        UnitPrice = miscInfo.Cost,
+                        Currency = thisCurrency,
+                        Quantity = quantity,
+                        PplNum = pplNum,
+                        TotalAmt = miscInfo.Cost * thisRate * quantity * pplNum,
+                        Remark = "",
+                    });
+                    miscIndex++;
+                }
+
+                views.AddRange(mealCosts);
+            }
+
+            #endregion
+
+            #region 签证+保险 1362
+            int visaInsIndex = 1; 
+            int visaInsItemTypeId = 1362;
+            if (infoView.Visa > 0)
+            {
+                views.Add(new QuoteSubItemInfo() {
+                    ItemId = visaInsItemTypeId,
+                    Index = visaInsIndex,
+                    FeeName = $"签证",
+                    UnitPrice = infoView.Visa,
+                    Currency = $"CNY",
+                    Quantity = 1,
+                    PplNum = pplNum,
+                    TotalAmt = infoView.Visa * pplNum,
+                    Remark = "",
+                });
+                visaInsIndex++;
+            }
+            if (infoView.Safe > 0)
+            {
+                views.Add(new QuoteSubItemInfo()
+                {
+                    ItemId = visaInsItemTypeId,
+                    Index = visaInsIndex,
+                    FeeName = $"保险",
+                    UnitPrice = infoView.Safe,
+                    Currency = $"CNY",
+                    Quantity = 1,
+                    PplNum = pplNum,
+                    TotalAmt = infoView.Safe * pplNum,
+                    Remark = "",
+                });
+            }
+
+            #endregion
+
+            #region 服务费 1363
+
+            int serviceFeeIndex = 1;
+            int serviceFeeItemTypeId = 1363;
+            if (infoView.Service > 0)
+            {
+                views.Add(new QuoteSubItemInfo()
+                {
+                    ItemId = serviceFeeItemTypeId,
+                    Index = serviceFeeIndex,
+                    FeeName = $"服务费",
+                    UnitPrice = infoView.Service,
+                    Currency = $"CNY",
+                    Quantity = 1,
+                    PplNum = pplNum,
+                    TotalAmt = infoView.Service * pplNum,
+                    Remark = "",
+                });
+            }
+
+            #endregion
+
+            #endregion
+
+            var result = await _enterExitCostQuoteRep.InfoAsync(new EnterExitCostQuoteInfoDto() { });
+
+            result.Rates = eecRates.ToArray();
+            if (result.FeeItems.Any())
+            {
+                result.FeeItems.Select(x =>
+                        {
+                            var feeInfos = views.Where(y => y.ItemId == x.ItemId).OrderBy(y => y.Index).ToArray();
+                            if (feeInfos.Any()) x.Infos = feeInfos;
+                            return x;
+                        }
+                    )
+                    .OrderBy(x => x.Index)
+                    .ToList();
+            }
+
+            return Ok(JsonView(result));
         }
 
         /// <summary>
-        /// 团组模块 - 出入境费用报价表 - 报价表名称列表
+        /// 团组模块 - 出入境费用报价表 - Info
         /// </summary>
         /// <returns></returns>
         [HttpPost]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        public async Task<IActionResult> EnterExitCostQuoteNameListDto(EnterExitCostQuoteNameListDto dto)
+        public async Task<IActionResult> EnterExitCostQuoteInfo(EnterExitCostQuoteInfoDto dto)
         {
-            return Ok(await _enterExitCostQuoteRep.QuoteNameListAsync(dto));
+            var info = await _enterExitCostQuoteRep.InfoAsync(dto);
+
+            if (!info.Rates.Any())
+            {
+                var rates = await GeneralMethod.EnterExitCostInitRate();
+                info.Rates = rates.ToArray();
+            }
+
+            return Ok(JsonView(info));
         }
 
         /// <summary>
-        /// 团组模块 - 出入境费用报价表 - 团组名称列表
+        /// 团组模块 - 出入境费用报价表 - OP
         /// </summary>
         /// <returns></returns>
         [HttpPost]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        public async Task<IActionResult> EnterExitCostGroupNameListDto(EnterExitCostQuoteGroupNameListDto dto)
+        public async Task<IActionResult> EnterExitCostQuoteOp(EnterExitCostQuoteOpDto dto)
         {
-            return Ok(await _enterExitCostQuoteRep.GroupNameListAsync(dto));
+            return Ok(await _enterExitCostQuoteRep.OpAsync(dto));
+        }
+
+        /// <summary>
+        /// 团组模块 - 出入境费用报价表 - 删除 项
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> EnterExitCostQuoteItemDel(EnterExitCostQuoteItemDelDto dto)
+        {
+            if (dto.Id < 1) return Ok(JsonView(false,MsgTips.Id));
+            if (dto.CurrUserId < 1) return Ok(JsonView(false, MsgTips.UserId));
+
+            return Ok(await _enterExitCostQuoteRep.ItemDelAsync(dto));
+        }
+
+
+        /// <summary>
+        /// 团组模块 - 出入境费用报价表 - 导出
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> EnterExitCostQuoteExcelExport(EnterExitCostQuoteExcelExportDto dto)
+        {
+            if (dto.Id < 1) return Ok(JsonView(false, MsgTips.Id));
+            if (dto.CurrUserId < 1) return Ok(JsonView(false, MsgTips.UserId));
+
+
+            var info = await _enterExitCostQuoteRep.InfoAsync(new EnterExitCostQuoteInfoDto() { Id= dto.Id });
+            if (info == null) return Ok(JsonView(false, "报价信息未填写!"));
+
+            var rates = info.Rates;
+            var intTravelCosts = info.FeeItems.FirstOrDefault(x => x.ItemId == 1354);//国际旅费
+            var accomCosts = info.FeeItems.FirstOrDefault(x => x.ItemId == 1355);    //住宿费
+            var mealCosts = info.FeeItems.FirstOrDefault(x => x.ItemId == 1356);     //餐饮费
+            var vehArranges = info.FeeItems.FirstOrDefault(x => x.ItemId == 1357);   //车辆安排
+            var inviteTo = info.FeeItems.FirstOrDefault(x => x.ItemId == 1358);      //邀请函发放对象
+            var inviteCosts = info.FeeItems.FirstOrDefault(x => x.ItemId == 1359);   //邀请函费用
+            var inviteTime = info.FeeItems.FirstOrDefault(x => x.ItemId == 1560);    //邀请函发放时间
+            var officialActs = info.FeeItems.FirstOrDefault(x => x.ItemId == 1561);  //公务活动
+            var visaIns = info.FeeItems.FirstOrDefault(x => x.ItemId == 1562);       //签证+保险
+            var serviceCosts = info.FeeItems.FirstOrDefault(x => x.ItemId == 1563);  //服务费
+            var pubMiscs = info.FeeItems.FirstOrDefault(x => x.ItemId == 1564);      //公杂费
+            var taxCosts = info.FeeItems.FirstOrDefault(x => x.ItemId == 1565);      //税费
+
+            //获取模板
+            string tempPath = (AppSettingsHelper.Get("ExcelBasePath") + "Template/出入境费用明细报价表模板.xlsx");
+            var designer = new WorkbookDesigner();
+            designer.Workbook = new Workbook(tempPath);
+
+            designer.SetDataSource("QuoteName", info.Name);
+            designer.SetDataSource("CompanyTitle", "公司名称");
+            designer.SetDataSource("CompanyLabel", "");
+
+            #region 国际旅费
+            designer.SetDataSource("IntTravelTitle", intTravelCosts.ItemName);
+            if (intTravelCosts.Infos.Any())
+            {
+                var cabClassFilter = new string[] {"经济舱","公务舱","头等舱" };
+
+                string label = string.Empty;
+                var infos = intTravelCosts.Infos.Where(x => cabClassFilter.Contains(x.FeeName)).ToArray();
+                if (infos.Any())
+                {
+                    label = $"{infos.Sum(x => x.PplNum)}人全程机票:{infos.Sum(x => x.TotalAmt).TruncDecimals(2)}元\r\n";
+                }
+
+                foreach (var item in intTravelCosts.Infos)
+                {
+                    label += $"{item.FeeName}:{item.UnitPrice.TruncDecimals(2)}元/人*{item.PplNum}人\r\n";
+                }
+                label += $"\r\n以上小计:{intTravelCosts.TotalAmt.TruncDecimals(2)}元";
+                designer.SetDataSource("IntTravelLabel", label);
+            }
+            #endregion
+            #region 住宿费 
+            designer.SetDataSource("AccomTitle", accomCosts.ItemName);
+            if (accomCosts.Infos.Any())
+            {
+                string currencyName = string.Empty;
+                decimal rate = 1.0000M;
+                string label = "全程五星酒店,每人1间房\r\n";
+                foreach (var item in accomCosts.Infos)
+                {
+                    string hotelName = string.Empty;
+                    if (item.FeeName.Contains("-"))
+                    {
+                        var feeName = item.FeeName.Split('-');
+                        hotelName = $"\r\n{feeName[0]}:\r\n{feeName[1]}:";
+                    }
+                    else hotelName = $"\r\n{item.FeeName}:";
+
+                    var rateInfo = rates.FirstOrDefault(x => item.Currency.Equals(x.CurrencyCode));
+                    currencyName = rateInfo?.CurrencyName ?? "UnKnow";
+                    rate = rateInfo?.Rate ?? 1.0000M;
+
+                    label += $"{hotelName}{item.UnitPrice.TruncDecimals(2)}{currencyName}/间/晚*{item.Quantity.ToString("#0")}*{item.PplNum}人\r\n";
+                }
+                label += $"\r\n以上小计:{accomCosts.TotalAmt.TruncDecimals(2)}元({currencyName}汇率:{rate.TruncDecimals(4)})";
+                designer.SetDataSource("AccomLabel", label);
+            }
+            #endregion
+
+            designer.Process();
+
+            //文件名
+            string fileName = $"{info.Name}{DateTime.Now.ToString("yyyyMMddHHmmss")}.xls";
+            designer.Workbook.Save(AppSettingsHelper.Get("ExcelBasePath") + "EnterExitCostQuote/" + fileName);
+            string url = AppSettingsHelper.Get("ExcelBaseUrl") + "Office/Excel/EnterExitCostQuote/" + fileName;
+            return Ok(JsonView(true, "成功", url));
         }
 
+
         #endregion
 
         #region 签证费用录入
@@ -12791,7 +13234,7 @@ WHERE
         public IActionResult InitOpTravel(InitOpTravelDto dto)
         {
             var jw = JsonView(false);
-            var groupList = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0).OrderByDescending(x => x.Id).ToList();
+            var groupList = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0).OrderByDescending(x => x.VisitStartDate).ToList();
             var group = groupList.First();
             var diid = dto.Diid == -1 ? group?.Id : dto.Diid;
 
@@ -13489,7 +13932,7 @@ WHERE
                 Select  a.Id,TeamName GroupName,b.isTrue From  Grp_DelegationInfo  a left join  (select top 100 percent Diid, CASE 
                 WHEN COUNT(*) >= 0 THEN 'True' 
                 ELSE 'False' END as isTrue  from Grp_GroupCost where Isdel = 0 and date != '' group by Diid) b on a.Id = b.Diid
-                 Where TeamName != '' And IsDel = 0  Order By a.Id Desc
+                 Where TeamName != '' And IsDel = 0  Order By a.VisitStartDate Desc
             ").ToList(); //团组列表
             int diid = dto.Diid == -1 ? groupList.First().Id : dto.Diid;
             var groupInfo = await _groupRepository.PostShareGroupInfo(new ShareGroupInfoDto { PortType = 1, Id = diid }); //团组信息
@@ -18048,7 +18491,7 @@ ORDER by  gctggrc.id DESC
 					                              TeamLevId,TeamLev,TeamName,ClientName,ClientUnit,
 					                              VisitDate,VisitDays,VisitPNumber,JietuanOperator,IsSure,CreateTime
 					                              From (
-					                              Select row_number() over(order by gdi.CreateTime Desc) as Row_Number,
+					                              Select row_number() over(order by gdi.VisitStartDate Desc) as Row_Number,
 					                              gdi.Id,SalesQuoteNo,TourCode,ssd.Id TeamTypeId, ssd.Name TeamType,
 					                              ssd1.Id TeamLevId,ssd1.Name TeamLev,TeamName,ClientName,ClientUnit,
 					                              VisitDate,VisitDays,VisitPNumber,su.CnName JietuanOperator,IsSure,gdi.CreateTime
@@ -19644,7 +20087,7 @@ ORDER by  gctggrc.id DESC
             groupInfos = _sqlSugar.Queryable<Grp_DelegationInfo>()
                                         .Where(it => it.IsDel == 0)
                                         .WhereIF(isDepStatus, it => it.JietuanOperator == dto.CurrUserId)
-                                        .OrderByDescending(it => it.CreateUserId)
+                                        .OrderByDescending(it => it.VisitStartDate)
                                         .ToList();
             if (groupInfos.Count < 1) return Ok(JsonView(false, "暂无和你相关的团组信息!"));
 
@@ -20444,7 +20887,7 @@ And (UnitName != '' Or UnitName != null) {sqlWhere}");
             const int chiNumber = 5;
             var jw = JsonView(false);
 
-            var groupList = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0).OrderByDescending(x => x.Id).ToList();
+            var groupList = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0).OrderByDescending(x => x.VisitStartDate).ToList();
             var group = groupList.First();
             var diid = dto.Diid == -1 ? group?.Id : dto.Diid;
             group = groupList.First(x => x.Id == diid);

+ 139 - 0
OASystem/OASystem.Api/Controllers/ResourceController.cs

@@ -1593,6 +1593,145 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
             }
         }
 
+
+        /// <summary>
+        /// 商邀资料查询-欧洲
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> QueryInvitationOfficialActivityData1()
+        {
+            try
+            {
+                // 定义欧洲国家数组
+                string[] europeanCountries = {
+                    // 北欧国家
+                    "瑞典", "芬兰", "挪威", "丹麦", "冰岛",
+                    // 西欧国家
+                    "英国", "爱尔兰", "法国", "荷兰", "比利时", "卢森堡", "摩纳哥",
+                    // 中欧国家
+                    "德国", "瑞士", "奥地利", "波兰", "捷克", "斯洛伐克", "匈牙利", "列支敦士登",
+                    // 南欧国家
+                    "意大利", "西班牙", "葡萄牙", "希腊", "马耳他", "圣马力诺", "梵蒂冈", "安道尔",
+                    "克罗地亚", "斯洛文尼亚", "波斯尼亚和黑塞哥维那", "黑山", "塞尔维亚", "北马其顿", "阿尔巴尼亚", "保加利亚", "罗马尼亚",
+                    // 东欧国家
+                    "俄罗斯", "乌克兰", "白俄罗斯", "摩尔多瓦", "爱沙尼亚", "拉脱维亚", "立陶宛"
+                };
+
+
+                var InvitationOfficialActivityDataList = _sqlSugar.Queryable<Res_InvitationOfficialActivityData>()
+                    .Where(x => x.IsDel == 0)
+                    .Select(x => new Res_InvitationOfficialActivityData() {Id=x.Id,Country = x.Country })
+                    .ToList();
+
+                foreach (var item in InvitationOfficialActivityDataList)
+                {
+                    EncryptionProcessor.DecryptProperties(item);
+                }
+                
+                var ids = InvitationOfficialActivityDataList
+                    .WhereIF(europeanCountries.Any(), x => !string.IsNullOrWhiteSpace(x.Country) && europeanCountries.Contains(x.Country))
+                    .Select(x => x.Id)
+                    .ToList();
+
+                RefAsync<int> totalCount = 0;
+
+                var _ivitiesViews = await _sqlSugar.Queryable<Res_InvitationOfficialActivityData>()
+                    .LeftJoin<Sys_Users>((a, b) => b.IsDel == 0 && a.CreateUserId == b.Id)
+                    .Where((a, b) => ids.Contains(a.Id))
+                    .OrderByDescending((a, b) => a.CreateTime)
+                    .Select((a, b) => new InvitationOfficialActivityDataView1
+                    {
+                        Country = a.Country,
+                        City = a.City,
+                        UnitName = a.UnitName,
+                        Field = a.Field,
+                        Address = a.Address,
+                        UnitInfo = a.UnitInfo,
+                        Delegation = a.Delegation,
+                        OtherInfo = a.OtherInfo
+                    })
+                    .ToListAsync();
+
+                var allGroupIds = new HashSet<int>();
+                foreach (var item in _ivitiesViews)
+                {
+                    EncryptionProcessor.DecryptProperties(item);
+
+                    if (!string.IsNullOrEmpty(item.Delegation))
+                    {
+                        allGroupIds.UnionWith(item.Delegation.Split(',').Select(x =>
+                        {
+                            int id;
+                            if (int.TryParse(x, out id)) return id;
+                            return 0;
+                        }).Where(id => id != 0));
+                    }
+                }
+
+                var _DelegationInfos = _sqlSugar.Queryable<Grp_DelegationInfo>()
+                    .Where(x => allGroupIds.Contains(x.Id) && x.IsDel == 0)
+                    .ToList()
+                    .GroupBy(x => x.Id)
+                    .ToDictionary(group => group.Key, group => group.Select(g => g.TeamName));
+
+                foreach (var item in _ivitiesViews)
+                {
+                    string groupNameStr = "";
+                    if (!string.IsNullOrEmpty(item.Delegation))
+                    {
+                        var groupIds = item.Delegation.Split(',').Select(x =>
+                        {
+                            int id;
+                            if (int.TryParse(x, out id)) return id;
+                            return 0;
+                        })
+                        .Where(id => id != 0)
+                        .ToArray();
+
+                        foreach (var id in groupIds)
+                        {
+                            if (_DelegationInfos.ContainsKey(id))
+                            {
+                                groupNameStr += string.Join("", _DelegationInfos[id]) + ",";
+                            }
+                        }
+
+                        if (groupNameStr.Length > 1)
+                        {
+                            groupNameStr = groupNameStr.Substring(0, groupNameStr.Length - 1);
+                        }
+                    }
+
+                    item.DelegationStr = groupNameStr;
+                }
+
+
+
+                //获取模板
+                string tempPath = (AppSettingsHelper.Get("ExcelBasePath") + "Template/商邀资料模板.xls");
+                var designer = new WorkbookDesigner();
+                designer.Workbook = new Workbook(tempPath);
+
+                var dt = CommonFun.ToDataTableArray(_ivitiesViews);
+                dt.TableName = $"OADataView";
+
+                designer.SetDataSource(dt);
+                designer.Process();
+
+                //文件名
+                string fileName = $"商邀资料{DateTime.Now.ToString("yyyyMMddHHmmss")}.xls";
+                designer.Workbook.Save(AppSettingsHelper.Get("ExcelBasePath") + "InvitationOfficialActivityExport/" + fileName);
+                string url = AppSettingsHelper.Get("ExcelBaseUrl") + "Office/Excel/InvitationOfficialActivityExport/" + fileName;
+                return Ok(JsonView(true, "成功", url));
+            }
+            catch (Exception ex)
+            {
+                return Ok(JsonView(false, ex.Message));
+            }
+        }
+
         //[HttpPost]
         //public  IActionResult EncipherInvitationOfficialActivityData()
         //{

+ 1 - 1
OASystem/OASystem.Api/Controllers/StatisticsController.cs

@@ -109,7 +109,7 @@ namespace OASystem.API.Controllers
                        tj, tj, tj, tj, tj);
                 }
 
-                string sql = string.Format(@"Select row_number() over(order by gdi.VisitDate Desc) as Row_Number, 
+                string sql = string.Format(@"Select row_number() over(order by gdi.VisitStartDate Desc) as Row_Number, 
 											    gdi.Id,TourCode,ssd1.Id TeamLevId,ssd1.Name TeamLev,TeamName,
 											    ClientName,ClientUnit,VisitDate,ssd.Id TeamTypeId, ssd.Name TeamType,
 											    VisitDays,VisitPNumber,su.CnName JietuanOperator,IsSure,gdi.CreateTime,

+ 5 - 0
OASystem/OASystem.Domain/Dtos/DtoBase.cs

@@ -95,4 +95,9 @@ namespace OASystem.Domain.Dtos
         /// </summary>
         public int PageId { get; set; }
     }
+
+    public class CurrUserDtoBase : PortDtoBase
+    {
+        public int CurrUserId { get; set; }
+    }
 }

+ 17 - 1
OASystem/OASystem.Domain/Dtos/Groups/EnterExitCostQuoteDto.cs

@@ -1,4 +1,5 @@
-using System;
+using OASystem.Domain.ViewModels.Groups;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -30,4 +31,19 @@ namespace OASystem.Domain.Dtos.Groups
     {
         public int Id { get; set; }
     }
+
+    public class EnterExitCostQuoteOpDto : EnterExitCostQuoteInfoView
+    {
+        public int CurrUserId { get; set; }
+    }
+
+    public class EnterExitCostQuoteItemDelDto : CurrUserDtoBase
+    {
+        public int Id { get; set; }
+    }
+
+    public class EnterExitCostQuoteExcelExportDto : CurrUserDtoBase
+    {
+        public int Id { get; set; }
+    }
 }

+ 12 - 7
OASystem/OASystem.Domain/Entities/Groups/Grp_EnterExitCostQuoteItem.cs

@@ -20,11 +20,16 @@ namespace OASystem.Domain.Entities.Groups
 
         /// <summary>
         /// 项ID
-        /// 项ID == 0 在备注里存入汇率相关信息
         /// </summary>
         [SugarColumn(ColumnName = "ItemId", ColumnDescription = "项ID(1,2,3...)", IsNullable = true, ColumnDataType = "int")]
         public int ItemId { get; set; }
 
+        /// <summary>
+        /// 项排序
+        /// </summary>
+        [SugarColumn(ColumnName = "Index", ColumnDescription = "项排序", IsNullable = true, ColumnDataType = "int")]
+        public int Index { get; set; }
+
         /// <summary>
         /// 费用名称
         /// </summary>
@@ -37,6 +42,12 @@ namespace OASystem.Domain.Entities.Groups
         [SugarColumn(ColumnName = "UnitPrice", ColumnDescription = "单价", IsNullable = true, ColumnDataType = "decimal(10,2)")]
         public decimal UnitPrice { get; set; }
 
+        /// <summary>
+        /// 币种(单机币种)
+        /// </summary>
+        [SugarColumn(ColumnName = "Currency", ColumnDescription = "币种", IsNullable = true, ColumnDataType = "varchar(10)")]
+        public string Currency { get; set; }
+
         /// <summary>
         /// 数量/天数/间/晚/次
         /// </summary>
@@ -49,12 +60,6 @@ namespace OASystem.Domain.Entities.Groups
         [SugarColumn(ColumnName = "PplNum", ColumnDescription = "人数", IsNullable = true, ColumnDataType = "int")]
         public int PplNum { get; set; }
 
-        /// <summary>
-        /// 币种
-        /// </summary>
-        [SugarColumn(ColumnName = "Currency", ColumnDescription = "币种", IsNullable = true, ColumnDataType = "int")]
-        public int Currency { get; set; }
-
         /// <summary>
         /// 合计(CNY)
         /// </summary>

+ 63 - 8
OASystem/OASystem.Domain/ViewModels/Groups/EnterExitCostQuoteView.cs

@@ -49,23 +49,82 @@ namespace OASystem.Domain.ViewModels.Groups
         /// <summary>
         /// 汇率信息
         /// </summary>
-        public CurrencyInfo[] Rates { get; set; }
-
-        public int IntTravels { get; set; }
+        public CurrencyInfo[] Rates { get; set; } = Array.Empty<CurrencyInfo>();
 
+        /// <summary>
+        /// 费用列表
+        /// </summary>
+        public QuoteItemInfo[] FeeItems { get; set; } = Array.Empty<QuoteItemInfo>();
 
+        /// <summary>
+        /// 费用合计
+        /// </summary>
+        public decimal TotalAmt
+        {
+            get
+            {
+                return FeeItems.Sum(x => x.TotalAmt);
+            }
+        }
     }
 
+   
+
     public class QuoteItemInfo
     {
         public int QuoteId { get; set; }
         public int ItemId { get; set; }
+        public string ItemName { get; set; }
+
+        public decimal TotalAmt { get { return Infos.Any() ? TruncDecimals(Infos.Sum(x => x.TotalAmt)) : 0.00M; } }
+
+        public QuoteSubItemInfo[] Infos { get; set; } = Array.Empty<QuoteSubItemInfo>();
+
+        public int Index { get; set; }
+
+        /// <summary>
+        /// decimal 保留小数,不四舍五入
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="decimalPlaces"></param>
+        /// <returns></returns>
+        private decimal TruncDecimals(decimal value, int decimalPlaces = 2)
+        {
+            decimal scaleFactor = (decimal)Math.Pow(10, decimalPlaces);
+            var truncated = Math.Truncate(scaleFactor * value) / scaleFactor;
+
+            // 检查是否需要补零
+            if (GetDecimalDigits(value) < decimalPlaces)
+            {
+                string format = "0." + new string('0', decimalPlaces);
+                truncated = decimal.Parse(truncated.ToString(format));
+            }
+
+            return truncated;
+        }
+        private int GetDecimalDigits(decimal number)
+        {
+            string[] parts = number.ToString().Split('.');
+            return parts.Length > 1 ? parts[1].Length : 0;
+        }
+    }
+
+    public class QuoteSubItemInfo
+    {
+        public int Id { get; set; }
+        public int ItemId { get; set; }
+        public int Index { get; set; }
         public string FeeName { get; set; }
         /// <summary>
         /// 单价
         /// </summary>
         public decimal UnitPrice { get; set; }
 
+        /// <summary>
+        /// 币种
+        /// </summary>
+        public string Currency { get; set; }
+
         /// <summary>
         /// 数量/天数/间/晚/次
         /// </summary>
@@ -76,11 +135,6 @@ namespace OASystem.Domain.ViewModels.Groups
         /// </summary>
         public int PplNum { get; set; }
 
-        /// <summary>
-        /// 币种
-        /// </summary>
-        public int Currency { get; set; }
-
         /// <summary>
         /// 合计(CNY)
         /// </summary>
@@ -88,4 +142,5 @@ namespace OASystem.Domain.ViewModels.Groups
 
         public string Remark { get; set; }
     }
+
 }

+ 22 - 0
OASystem/OASystem.Domain/ViewModels/Resource/InvitationOfficialActivityDataView.cs

@@ -38,6 +38,28 @@ namespace OASystem.Domain.ViewModels.Resource
         }
     }
 
+    public class InvitationOfficialActivityDataView1
+    {
+        [Encrypted]
+        public string Country { get; set; }
+
+        [Encrypted]
+        public string City { get; set; }
+        [Encrypted]
+        public string UnitName { get; set; }
+        [Encrypted]
+        public string Field { get; set; }
+        [Encrypted]
+        public string Address { get; set; }
+        [Encrypted]
+        public string UnitInfo { get; set; }
+        [Encrypted]
+        public string Delegation { get; set; }
+        [Encrypted]
+        public string OtherInfo { get; set; }
+        public string DelegationStr { get; set; }
+    }
+
     public class IOAInfoView
     {
         public int Id { get; set; }

+ 2 - 2
OASystem/OASystem.Infrastructure/Repositories/Financial/ForeignReceivablesRepository.cs

@@ -61,7 +61,7 @@ namespace OASystem.Infrastructure.Repositories.Financial
 
             string sql = string.Format(@$"Select Id,TeamName GroupName From  Grp_DelegationInfo 
                                              Where TeamName != '' And IsDel = 0 {sqlWhere} 
-                                             Order By Id Desc");
+                                             Order By VisitStartDate Desc");
 
             var _groupNameList = await _sqlSugar.SqlQueryable<GroupNameView>(sql).ToListAsync();
 
@@ -307,7 +307,7 @@ namespace OASystem.Infrastructure.Repositories.Financial
 
             string sql = string.Format(@$"Select Id,TeamName GroupName From  Grp_DelegationInfo 
                                              Where TeamName != '' And IsDel = 0 {sqlWhere} 
-                                             Order By Id Desc");
+                                             Order By VisitStartDate Desc");
 
             var _groupNameList = await _sqlSugar.SqlQueryable<GroupNameView>(sql).ToListAsync();
 

+ 1 - 1
OASystem/OASystem.Infrastructure/Repositories/Groups/AirTicketResRepository.cs

@@ -337,7 +337,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 {
                     DiId = DiId.Substring(0, DiId.Length - 1);
 
-                    string sql = string.Format(@"select * from Grp_DelegationInfo where Id in({0}) and IsDel={1} Order By Id Desc", DiId, 0);
+                    string sql = string.Format(@"select * from Grp_DelegationInfo where Id in({0}) and IsDel={1} Order By VisitStartDate Desc", DiId, 0);
                     List<Grp_DelegationInfo> grp_Delegations = _sqlSugar.SqlQueryable<Grp_DelegationInfo>(sql).ToList();
 
                     if (grp_Delegations.Count == 0)

+ 1 - 1
OASystem/OASystem.Infrastructure/Repositories/Groups/DecreasePaymentsRepository.cs

@@ -97,7 +97,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
 										From Grp_DelegationInfo di With(NoLock)
 										Left Join Sys_SetData sd On di.TeamDid = sd.Id
                                         Where di.Id in({DiId}) and di.IsDel=0 
-										Order By di.CreateTime Desc");
+										Order By di.VisitStartDate Desc");
 
                 //DecreasePaymentGroupView
                 _Delegations = _sqlSugar.SqlQueryable<DecreasePaymentGroupView>(sql).ToList();

+ 103 - 23
OASystem/OASystem.Infrastructure/Repositories/Groups/DelegationInfoRepository.cs

@@ -49,16 +49,82 @@ namespace OASystem.Infrastructure.Repositories.Groups
             //_teamRateRep = teamRateRep;
         }
 
+
+
+
         #region 团组信息 团组详情共享Api
 
+        /// <summary>
+        /// 查询团组简略详情列表
+        /// Page 根据Ctable And User 返回可操作的团
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public async Task<JsonView> ListByCTableAndUserId(GroupListByCTableAndUserIdDto dto)
+        {
+            var view = new JsonView() { Code = StatusCodes.Status400BadRequest,Msg="操作失败!" };
+
+            if (dto.CTable < 1)
+            {
+                view.Msg = MsgTips.UserId;
+
+                return view;
+            }
+
+            if (dto.CTable < 1)
+            {
+                view.Msg = "请输入正确的CTable Id !76 酒店预订<br/>77 行程<br/>79 车/导游地接<br/>80 签证<br/>81 邀请/公务活动<br/>82 团组客户保险<br/>85 机票预订<br/>98 其他款项<br/>751 酒店早餐";
+                return view;
+            }
+
+            if (dto.PortType == 1 || dto.PortType == 2 || dto.PortType == 3)
+            {
+                //2025-02-17 更改团组列表排序功能 按照团出访时间排序(降序)
+                string sql = string.Format(@"Select row_number() over(order by di.VisitStartDate Desc) as Row_Number, 
+									         di.Id,di.TeamName,di.TourCode,di.ClientName,di.VisitCountry,di.VisitStartDate,
+									         di.VisitEndDate,di.VisitDays,di.VisitPNumber,di.CreateTime
+									         From Grp_GroupsTaskAssignment gta
+									         Inner Join Grp_DelegationInfo di On gta.DIId = di.Id
+									         Where gta.IsDel = 0 And di.IsDel = 0 And gta.IsEnable = 1
+									         And gta.CTId = {0} And gta.UId = {1}", dto.CTable, dto.UserId);
+
+                if (!string.IsNullOrEmpty(dto.TeamName))
+                {
+                    sql = string.Format($"{sql} And di.TeamName Like '%{dto.TeamName}%'");
+                }
+                //去重
+                sql = $"{sql} GROUP BY di.Id,di.TeamName,di.TourCode,di.ClientName,di.VisitCountry,di.VisitStartDate,di.VisitEndDate,di.VisitDays,di.VisitPNumber,di.CreateTime";
+
+
+                RefAsync<int> total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
+                var data = await _sqlSugar.SqlQueryable<GroupListByCTableAndUserIdView>(sql).ToPageListAsync(dto.PageIndex, dto.PageSize, total); //ToPageAsync
+                foreach (var item in data)
+                {
+                    item.VisitStartDate = item.VisitStartDate == "" ? "" : Convert.ToDateTime(item.VisitStartDate).ToString("yyyy-MM-dd");
+                    item.VisitEndDate = item.VisitEndDate == "" ? "" : Convert.ToDateTime(item.VisitEndDate).ToString("yyyy-MM-dd");
+                }
+
+                view.Msg = "操作成功!";
+                view.Data = data;
+                view.Count = total;
+                return view;
+            }
+            else
+            {
+                view.Msg = "请输入正确的PortType 1 Web 2 Android 3 IOS ";
+                return view;
+            }
+        }
+
+
         /// <summary>
         /// 团组信息 团组预览详情共享Api
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        public async Task<Result> PostShareGroupInfo(ShareGroupInfoDto dto)
+        public async Task<JsonView> PostShareGroupInfo(ShareGroupInfoDto dto)
         {
-            Result result = new Result() { Code = -2, Msg = "未知错误" };
+            var view = new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "操作失败!" };
 
             string sql = string.Format(@"Select Id,TeamName,TourCode,ClientName,VisitCountry,VisitStartDate,VisitEndDate,VisitDays,VisitPNumber 
                                              From Grp_DelegationInfo Where Id = {0} And IsDel = 0", dto.Id);
@@ -70,9 +136,13 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 {
                     _DelegationInfo.VisitCountry = FormartTeamName(_DelegationInfo.VisitCountry);
                 }
-                else result.Msg = "暂无该团组信息";
+                else
+                {
+                    view.Msg = "暂无该团组信息";
+                    return view;
+                }
 
-                result.Data = _DelegationInfo;
+                view.Data = _DelegationInfo;
             }
             else if (dto.PortType == 2 || dto.PortType == 3) //IOS Or Android
             {
@@ -81,19 +151,26 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 {
                     _DelegationInfo.VisitCountry = FormartTeamName(_DelegationInfo.VisitCountry);
 
-                    result.Data = _DelegationInfo;
+                    view.Data = _DelegationInfo;
+                }
+                else
+                {
+                    view.Msg = "暂无该团组信息";
+                    return view;
                 }
-                else result.Msg = "暂无该团组信息";
-
-                result.Data = _DelegationInfo;
 
+                view.Data = _DelegationInfo;
+            }
+            else
+            {
+                view.Msg = "请输入正确的端口号。1 Web 2 Android 3 IOS";
+                return view;
             }
-            else result.Msg = "请输入正确的端口号。1 Web 2 Android 3 IOS";
 
-            result.Code = 0;
-            result.Msg = "成功!";
+            view.Code = StatusCodes.Status200OK;
+            view.Msg = "成功!";
 
-            return result;
+            return view;
         }
 
         /// <summary>
@@ -106,8 +183,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
             Result result = new Result() { Code = -2, Msg = "未知错误", Data = new List<object>() { } };
 
             string sql = string.Format(@"Select Id,TeamName,TourCode,ClientName,VisitCountry,VisitStartDate,VisitEndDate,VisitDays,VisitPNumber 
-                                             From Grp_DelegationInfo With(NoLock) Where IsDel = 0 Order By Id Desc");
-
+                                             From Grp_DelegationInfo With(NoLock) Where IsDel = 0 Order By VisitStartDate Desc");
 
             var _DelegationInfo = await _sqlSugar.SqlQueryable<Web_ShareGroupInfoView>(sql).ToListAsync();
             if (_DelegationInfo.Count > 0)
@@ -169,6 +245,8 @@ namespace OASystem.Infrastructure.Repositories.Groups
             return result;
 
         }
+
+
         #region 团组
 
         /// <summary>
@@ -923,15 +1001,17 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        public async Task<Result> GetGroupNameList(GroupNameDto dto)
+        public async Task<JsonView> GetGroupNameList(GroupNameDto dto)
         {
-            Result result = new Result() { Code = -2, Msg = "未知错误" };
+
+            var view = new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "操作失败!" };
 
             if (dto.PortType == 1 || dto.PortType == 2 || dto.PortType == 3) //web
             {
+                //2025-02-17 更改团组列表排序功能 按照团出访时间排序(降序)
                 string sql = string.Format(@"Select Id,TeamName GroupName From  Grp_DelegationInfo 
                                              Where TeamName != '' And IsDel = 0
-                                             Order By Id Desc");
+                                             Order By VisitStartDate Desc");
 
                 var _groupNameList = await _sqlSugar.SqlQueryable<GroupNameView>(sql).ToListAsync();
                 if (_groupNameList.Count > 0)
@@ -942,16 +1022,16 @@ namespace OASystem.Infrastructure.Repositories.Groups
                         _groupNameList[i].GroupName = FormartTeamName(info.GroupName);
                     }
 
-                    result.Code = 0;
-                    result.Msg = "成功!";
-                    result.Data = _groupNameList;
+                    view.Code = StatusCodes.Status200OK;
+                    view.Msg = "成功!";
+                    view.Data = _groupNameList;
                 }
                 else
                 {
-                    result.Msg = "暂无团组信息";
+                    view.Msg = "暂无团组信息";
                 }
             }
-            return result;
+            return view;
         }
 
         //PostGroupNameScreen
@@ -1132,7 +1212,7 @@ FROM
 WHERE
   di.Isdel = 0
 ORDER BY
-  CreateTime Desc");
+  VisitStartDate Desc");
 
             result.Data = await _sqlSugar.SqlQueryable<EnterExitCostGroupNameView>(groupSql).ToListAsync();
             result.Code = 0;

+ 218 - 19
OASystem/OASystem.Infrastructure/Repositories/Groups/EnterExitCostQuoteRepository.cs

@@ -1,8 +1,11 @@
 using AutoMapper;
+using EyeSoft.Collections.Generic;
 using OASystem.Domain;
 using OASystem.Domain.Dtos.Groups;
 using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.ViewModels.Groups;
+using OASystem.Infrastructure.Tools;
+using Org.BouncyCastle.Utilities;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -41,7 +44,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
             var newList = origList.Select(x => new InitBasicItemView
                 {
                     Id = x.Id,
-                    Name = removeNl ? x.Name.Replace("\r\n", "") : x.Name,
+                    Name = removeNl ? x.Name.Replace("\\r\\n", "") : x.Name,
                     Index = int.TryParse(x.Index,out int index) ? index : -1
                 })
                 .OrderBy(x => x.Index)
@@ -154,43 +157,239 @@ namespace OASystem.Infrastructure.Repositories.Groups
         }
 
         /// <summary>
-        /// 获取团组名称列表
+        /// 获取报价详情
         /// </summary>
         /// <param name="name"></param>
         /// <param name="pageIndex"></param>
         /// <param name="pageSize"></param>
         /// <returns></returns>
-        public async Task<JsonView> InfoAsync(EnterExitCostQuoteInfoDto dto)
+        public async Task<EnterExitCostQuoteInfoView> InfoAsync(EnterExitCostQuoteInfoDto dto)
         {
-            if (dto.Id < 1)
+            var viewInfo = new EnterExitCostQuoteInfoView();
+            viewInfo.Id = dto.Id;
+            var basicItems = await InitBasicItemAsync(true);
+
+            if (basicItems.Any())
             {
-                return new JsonView
-                {
-                    Code = StatusCodes.Status400BadRequest,
-                    Msg = MsgTips.Id
-                };
+                viewInfo.FeeItems = basicItems.Select(x => new QuoteItemInfo { ItemId = x.Id, ItemName = x.Name,Index = x.Index }).OrderBy(x => x.Index).ToArray();
             }
 
             var quoteInfo = await _sqlSugar.Queryable<Grp_EnterExitCostQuote>()
                  .Where(x => x.IsDel == 0 && x.Id == x.Id)
                  .FirstAsync();
-            if (quoteInfo == null)
+            if (quoteInfo != null)
             {
-                return new JsonView
+                viewInfo.Name = quoteInfo.Name;
+                viewInfo.GroupId = quoteInfo.GroupId;
+                viewInfo.Rates = CommonFun.GetCurrencyChinaToList(quoteInfo.CurrencyRemark).ToArray();
+
+                var quoteItems = await _sqlSugar.Queryable<Grp_EnterExitCostQuoteItem>()
+                    .Where(x => x.IsDel == 0 && x.QuoteId == quoteInfo.Id)
+                    .Select(x => new QuoteSubItemInfo
+                    {
+                        Id = x.Id,
+                        ItemId = x.ItemId,
+                        FeeName = x.FeeName,
+                        UnitPrice = x.UnitPrice,
+                        Quantity = x.Quantity,
+                        PplNum = x.PplNum,
+                        Currency = x.Currency,
+                        TotalAmt = x.TotalAmt,
+                        Index = x.Index
+                    }).ToListAsync();
+
+                if (quoteItems.Any())
                 {
-                    Code = StatusCodes.Status400BadRequest,
-                    Msg = $"未找到Id为{dto.Id}的数据"
-                };
+                    viewInfo.FeeItems = viewInfo.FeeItems.Select(x => new QuoteItemInfo { Index = x.Index, QuoteId = dto.Id,ItemId = x.ItemId,ItemName=x.ItemName,Infos = quoteItems.Where(y => y.ItemId == x.ItemId).OrderBy(y => y.Index).ToArray() }).ToArray();
+                }
             }
 
-            //(List<CurrencyInfo>?)CommonFun.GetCurrencyChinaToList(enterExitCostData.CurrencyRemark)
+            return viewInfo;
+        }
 
-            return new JsonView
+        /// <summary>
+        /// Add Or Edit
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="pageIndex"></param>
+        /// <param name="pageSize"></param>
+        /// <returns></returns>
+        public async Task<JsonView> OpAsync(EnterExitCostQuoteOpDto dto)
+        {
+            var jw = new JsonView() { Code = StatusCodes.Status400BadRequest };
+            string quoteName = dto.Name;
+            int quoteId = dto.Id;
+            if (string.IsNullOrEmpty(dto.Name))
             {
-                Code = StatusCodes.Status200OK,
-                Msg = "获取成功",
-               // Data = pageList
+                jw.Msg = "报价名称不能为空";
+                return jw;
+            }
+
+            var quoteInfo = new Grp_EnterExitCostQuote
+            {
+                Id = quoteId,
+                Name = quoteName,
+                GroupId = dto.GroupId,
+                CurrencyRemark = CommonFun.GetCurrencyChinaToString(dto.Rates.ToList()),
+                CreateUserId = dto.CurrUserId
             };
+            var quoteItemInfos = new List<Grp_EnterExitCostQuoteItem>();
+            if (dto.FeeItems.Any())
+            {
+                foreach (var item in dto.FeeItems)
+                {
+                    if (item.Infos.Any())
+                    {
+                        quoteItemInfos.AddRange(item.Infos.Select(x => new Grp_EnterExitCostQuoteItem
+                        {
+                            Id = x.Id,
+                            QuoteId = quoteId,
+                            ItemId = x.ItemId,
+                            Index = x.Index,
+                            FeeName = x.FeeName,
+                            UnitPrice = x.UnitPrice,
+                            Currency = x.Currency,
+                            Quantity = x.Quantity,
+                            PplNum = x.PplNum,
+                            TotalAmt = x.TotalAmt,
+                            Remark = x.Remark,
+                            CreateUserId = dto.CurrUserId
+                        }));
+                    }
+                }
+            }
+
+            var isNull = await _sqlSugar.Queryable<Grp_EnterExitCostQuote>().FirstAsync(x => x.IsDel == 0 && x.Name.Equals(quoteName)) == null ? true : false;
+
+            _sqlSugar.BeginTran();
+
+            if (isNull) //新增
+            {
+                quoteId = await _sqlSugar.Insertable(quoteInfo).ExecuteReturnIdentityAsync();
+                if (quoteId < 1)
+                {
+                    jw.Msg = "新增失败!";
+                    _sqlSugar.RollbackTran();
+                    return jw;
+                }
+
+                quoteItemInfos.ForEach(x => x.QuoteId = quoteId);
+                var quoteItemIds = await _sqlSugar.Insertable(quoteItemInfos).ExecuteReturnIdentityAsync();
+                if (quoteItemIds < 1)
+                {
+                    jw.Msg = "新增失败";
+                    _sqlSugar.RollbackTran();
+                    return jw;
+                }
+                jw.Msg = "新增成功!";
+            }
+            else if (!isNull) //编辑 
+            {
+                var quoteUpd = await _sqlSugar.Updateable(quoteInfo).IgnoreColumns(x => new { x.CreateUserId, x.CreateTime, x.IsDel }).ExecuteCommandAsync();
+                if (quoteUpd < 1)
+                {
+                    jw.Msg = "编辑失败!";
+                    _sqlSugar.RollbackTran();
+                    return jw;
+                }
+
+                var addItems = quoteItemInfos.Where(x => x.Id < 1).ToList();
+                var updItems = quoteItemInfos.Where(x => x.Id > 0).ToList();
+                if (addItems.Any())
+                {
+                    var addItem = await _sqlSugar.Insertable(addItems).ExecuteCommandAsync();
+                    if (addItem < 1)
+                    {
+                        jw.Msg = "编辑失败!";
+                        _sqlSugar.RollbackTran();
+                        return jw;
+                    }
+                }
+
+                if (updItems.Any())
+                {
+                    var updItem = await _sqlSugar.Updateable(updItems).IgnoreColumns(x => new { x.CreateUserId, x.CreateTime, x.IsDel }).ExecuteCommandAsync();
+                    if (updItem < 1)
+                    {
+                        jw.Msg = "编辑失败!";
+                        _sqlSugar.RollbackTran();
+                        return jw;
+                    }
+                }
+                jw.Msg = "编辑成功!";
+            }
+
+            _sqlSugar.CommitTran();
+            jw.Code = StatusCodes.Status200OK;
+            jw.Data = quoteId;
+            return jw;
         }
+
+
+        /// <summary>
+        /// ItemDel
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="pageIndex"></param>
+        /// <param name="pageSize"></param>
+        /// <returns></returns>
+        public async Task<JsonView> ItemDelAsync(EnterExitCostQuoteItemDelDto dto)
+        {
+            var jw = new JsonView() { Code = StatusCodes.Status400BadRequest };
+            int currUserId = dto.CurrUserId,
+                id = dto.Id;
+
+            if (currUserId < 1)
+            {
+                jw.Msg = MsgTips.UserId;
+                return jw;
+            }
+            if (id < 1)
+            {
+                jw.Msg = MsgTips.Id;
+                return jw;
+            }
+            var info = await _sqlSugar.Queryable<Grp_EnterExitCostQuoteItem>().FirstAsync(x => x.IsDel == 0 && x.Id  == id);
+            if (info == null)
+            {
+                jw.Msg = $"操作成功!";
+                jw.Code = StatusCodes.Status200OK;
+                return jw;
+            }
+            var itemInfos = await _sqlSugar.Queryable<Grp_EnterExitCostQuoteItem>().Where(x => x.IsDel == 0 && x.QuoteId == info.QuoteId && x.ItemId == info.ItemId).ToListAsync();
+
+            _sqlSugar.BeginTran();
+
+            var delInfo = new Grp_EnterExitCostQuoteItem { DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), DeleteUserId = currUserId, IsDel = 1 };
+            var del = await _sqlSugar.Updateable(delInfo)
+                .UpdateColumns(x => new { x.DeleteTime, x.DeleteUserId, x.IsDel })
+                .Where(x => x.Id == id)
+                .ExecuteCommandAsync();
+            if (del < 1)
+            {
+                jw.Msg = $"删除失败!"; 
+                _sqlSugar.RollbackTran();
+                return jw;
+            }
+
+            if (itemInfos.Any())
+            {
+                // 更新剩余项的索引
+                var itemsToUpdate = itemInfos.Where(i => i.Index > itemInfos.First(i => i.Id == id).Index).ToList();
+
+                foreach (var item in itemsToUpdate)
+                {
+                    item.Index -= 1;
+                }
+
+                await _sqlSugar.Updateable(itemsToUpdate).ExecuteCommandAsync();
+            }
+            _sqlSugar.CommitTran();
+            jw.Msg = "操作成功!";
+            jw.Code = StatusCodes.Status200OK;
+
+            return jw;
+        }
+
     }
 }

+ 1 - 1
OASystem/OASystem.Infrastructure/Repositories/Groups/RestaurantRepository.cs

@@ -35,7 +35,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
             var groupData = await _sqlSugar
                 .Queryable<Grp_DelegationInfo>()
                 .Where(x => x.IsDel == 0)
-                .OrderByDescending(x => x.Id)
+                .OrderByDescending(x => x.VisitStartDate)
                 .Select(x => new { Id = x.Id, GroupName = x.TeamName })
                 .ToListAsync();
 

+ 1 - 1
OASystem/OASystem.Infrastructure/Repositories/Groups/TaskAssignmentRepository.cs

@@ -31,7 +31,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
             {
                 //团组下拉框
                 List<dynamic> _DelegationInfos = new List<dynamic>();
-                List<Grp_DelegationInfo> grp_DelegationInfos = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(a => a.IsDel == 0 && a.TourCode != "" && a.IsState == 0).OrderByDescending(s => s.Id).ToList();
+                List<Grp_DelegationInfo> grp_DelegationInfos = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(a => a.IsDel == 0 && a.TourCode != "" && a.IsState == 0).OrderByDescending(s => s.VisitStartDate).ToList();
                 foreach (var Item in grp_DelegationInfos)
                 {
                     var data = new

+ 1 - 1
OASystem/OASystem.Infrastructure/Repositories/Groups/VisaCommissionRepository.cs

@@ -56,7 +56,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                                       })
                                       .ToListAsync();
 
-            var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0 && x.Id == _dto.DiId).FirstAsync();
+            var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0 && x.Id == _dto.DiId).OrderByDescending(x => x.VisitStartDate).FirstAsync();
             if (groupInfo != null)
             {
                 string[] countryArray = _groupRep.GroupSplitCountry(groupInfo.VisitCountry).ToArray();