Pārlūkot izejas kodu

机票、保险、商邀、签证、OP、酒店 新增验证(已审核、已付款 不可执行删除、编辑操作)

Lyyyi 1 dienu atpakaļ
vecāks
revīzija
5182fa6236

+ 52 - 76
OASystem/OASystem.Api/Controllers/FinancialController.cs

@@ -897,6 +897,14 @@ namespace OASystem.API.Controllers
         }
 
 
+        private readonly static Dictionary<int, string> _receivablesFeilDownloadType = new Dictionary<int, string>() 
+        {
+            { 1,"生成收款单(四川)"},
+            { 2,"生成收款单(北京)"},
+            { 3,"汇款账单"},
+            { 4,"实际报价明细"}
+        };
+
         /// <summary>
         /// 已收账单 
         /// File Download
@@ -907,13 +915,11 @@ namespace OASystem.API.Controllers
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> PostReceivablesFeilDownloadInit()
         {
-            return Ok(JsonView(true, "操作成功!", new List<dynamic> {
-                new { Id = 1, Name = "生成收款单(四川)" },
-                new { Id = 2, Name = "生成收款单(北京)" },
-                new { Id = 3, Name = "汇款账单" },
-                new { Id = 4, Name = "实际报价明细" }
-            }
-            ));
+            return Ok(JsonView(true, "操作成功!", _receivablesFeilDownloadType.Select(kv => new
+            {
+                Id = kv.Key,
+                Name = kv.Value
+            }).ToList()));
         }
 
         private class EnterExitCostCurrency
@@ -939,9 +945,9 @@ namespace OASystem.API.Controllers
                 {
                     return Ok(JsonView(false, "请传入有效DiId参数!"));
                 }
-                if (dto.FileType < 1 || dto.FileType > 3)
+                if (!_receivablesFeilDownloadType.ContainsKey(dto.FileType))
                 {
-                    return Ok(JsonView(false, "请传入有效FileType参数! 1 生成收款单(四川)  2 生成收款单(北京)  3 汇款账单"));
+                    return Ok(JsonView(false, $"未找到ID为{dto.FileType}的文件下载类型。支持的ID范围: {string.Join(", ", _receivablesFeilDownloadType.Keys)}"));
                 }
                 var _currencyDatas = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && x.STid == 66).ToList();
                 var _DelegationInfo = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(it => it.IsDel == 0 && it.Id == dto.DiId).First();
@@ -1495,14 +1501,16 @@ namespace OASystem.API.Controllers
                 {
                     try
                     {
+                        var filePaths = _DelegationInfo.FrFilePaths;
+
                         // 1. 文件验证
-                        if (_DelegationInfo.FrFilePaths == null || _DelegationInfo.FrFilePaths.Count < 1)
+                        if (filePaths == null || filePaths.Count < 1)
                         {
                             return Ok(JsonView(false, "该团组未上传实际报价相关文件!"));
                         }
 
                         // 2. 构建源文件夹路径
-                        var groupDir = @$"{_DelegationInfo.TeamName}({_DelegationInfo.Id})";
+                        var groupDir = @$"{_DelegationInfo.TeamName}_{_DelegationInfo.Id}";
                         var sourceFolderPath = AppSettingsHelper.Get("ReceivablesUploadFileBasePath") + @"/" + groupDir;
 
                         if (!Directory.Exists(sourceFolderPath))
@@ -1517,6 +1525,11 @@ namespace OASystem.API.Controllers
                             return BadRequest(JsonView(false, $"文件夹为空: {Path.GetFileName(sourceFolderPath)}"));
                         }
 
+                        for (int i = 0; i < filePaths.Count; i++)
+                        {
+                            filePaths[i] = $"{sourceFolderPath}/{filePaths[i]}";
+                        }
+
                         // 4. 生成目标Zip文件路径
                         string targetZipPath = sourceFolderPath.Trim();
                         
@@ -1533,74 +1546,37 @@ namespace OASystem.API.Controllers
                             System.IO.File.Delete(targetZipPath);
                         }
 
-                        //// 7. 创建Zip包
-                        //using (var zipFileStream = new FileStream(targetZipPath, FileMode.Create))
-                        //{
-                        //    using (var zipArchive = new ZipArchive(zipFileStream, ZipArchiveMode.Create))
-                        //    {
-                        //        foreach (string filePath in filePaths)
-                        //        {
-                        //            // 增加空值/空字符串校验,提升代码健壮性
-                        //            if (!string.IsNullOrEmpty(filePath) && System.IO.File.Exists(filePath))
-                        //            {
-                        //                // 获取文件名
-                        //                string fileName = Path.GetFileName(filePath);
-                        //                // 将文件添加到ZIP归档中
-                        //                zipArchive.CreateEntryFromFile(filePath, fileName);
-                        //            }
-                        //        }
-                        //    }
-                        //}
-
-
-                        //// 8. 验证Zip文件是否创建成功
-                        //if (!File.Exists(targetZipPath))
-                        //{
-                        //    return StatusCode(StatusCodes.Status500InternalServerError,
-                        //        JsonView(false, "Zip文件创建失败"));
-                        //}
-
-                        //var fileInfo = new FileInfo(targetZipPath);
-                        //if (fileInfo.Length == 0)
-                        //{
-                        //    SafeDeleteFile(targetZipPath);
-                        //    return StatusCode(StatusCodes.Status500InternalServerError,
-                        //        JsonView(false, "创建的Zip文件为空"));
-                        //}
-
-                        //// 9. 计算文件哈希(可选)
-                        //var fileHash = await CalculateFileHashAsync(targetZipPath);
-
-                        //// 10. 创建返回结果
-                        //var result = new ZipCreationResult
-                        //{
-                        //    Success = true,
-                        //    Message = "文件夹打包成功",
-                        //    SourceFolderPath = sourceFolderPath,
-                        //    ZipFilePath = targetZipPath,
-                        //    ZipFileSize = fileInfo.Length,
-                        //    ZipFileSizeFormatted = FormatFileSize(fileInfo.Length),
-                        //    FileCount = creationResult.FileCount,
-                        //    ZipCreationTime = fileInfo.CreationTime,
-                        //    FileHash = fileHash,
-                        //    AccessUrl = GenerateAccessUrl(targetZipPath) // 生成访问URL
-                        //};
-
-                        //// 11. 记录到数据库(可选)
-                        //await SaveZipCreationRecordAsync(request, result);
-
-                        //_logger.LogInformation("文件夹打包成功: {SourceFolderPath} -> {TargetZipPath}, 大小: {Size}, 文件数: {FileCount}",
-                        //    sourceFolderPath, targetZipPath, result.ZipFileSizeFormatted, result.FileCount);
-
-                        return Ok(JsonView(false, "操作失败!"));
+                        // 7. 创建Zip包
+                        using (var zipFileStream = new FileStream(targetZipPath, FileMode.Create))
+                        {
+                            using (var zipArchive = new ZipArchive(zipFileStream, ZipArchiveMode.Create))
+                            {
+                                foreach (string filePath in filePaths)
+                                {
+                                    // 增加空值/空字符串校验,提升代码健壮性
+                                    if (!string.IsNullOrEmpty(filePath) && System.IO.File.Exists(filePath))
+                                    {
+                                        // 获取文件名
+                                        string fileName = Path.GetFileName(filePath);
+                                        // 将文件添加到ZIP归档中
+                                        zipArchive.CreateEntryFromFile(filePath, fileName);
+                                    }
+                                }
+                            }
+                        }
+
+                        // 8. 验证Zip文件是否创建成功
+                        if (!System.IO.File.Exists(targetZipPath))
+                        {
+                            return Ok(JsonView(false, "Zip文件创建失败!"));
+                        }
+
+                        return Ok(JsonView(true, "操作成功!", targetZipPath));
                     }
                     catch (Exception ex)
                     {
-                        //_logger.LogError(ex, "文件夹打包失败: {SourceFolderPath}", request?.SourceFolderPath);
-                        //return StatusCode(StatusCodes.Status500InternalServerError,
-                        //    JsonView(false, $"文件夹打包失败: {ex.Message}"));
+                        return Ok(JsonView(false, ex.Message));
                     }
-
                 }
 
                 return Ok(JsonView(false, "操作失败!"));
@@ -1724,7 +1700,7 @@ namespace OASystem.API.Controllers
                 }
 
                 // 4. 创建文件存储目录
-                var groupDir = @$"{groupInfo.TeamName}({groupInfo.Id})";
+                var groupDir = @$"{groupInfo.TeamName}_{groupInfo.Id}";
                 var fileServerPath = AppSettingsHelper.Get("ReceivablesUploadFileBasePath") + @"/" + groupDir;
                 if (!Directory.Exists(fileServerPath)) Directory.CreateDirectory(fileServerPath);
 

+ 65 - 7
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -4,8 +4,10 @@ using Aspose.Words.Drawing;
 using Aspose.Words.Tables;
 using DiffMatchPatch;
 using Dm.util;
+using Humanizer;
 using iTextSharp.text.pdf;
 using Microsoft.AspNetCore.SignalR;
+using NPOI.SS.Formula.Functions;
 using NPOI.SS.UserModel;
 using NPOI.SS.Util;
 using NPOI.XSSF.UserModel;
@@ -31,6 +33,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.JuHeExchangeRate;
 using OASystem.Domain.ViewModels.OCR;
 using OASystem.Infrastructure.Logging;
 using OASystem.Infrastructure.Repositories.CRM;
@@ -8166,6 +8169,10 @@ FROM
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> OpAirTicketRes(AirTicketResOpDto dto)
         {
+            //验证
+            (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.AirTicketResOpData.Id, 85);
+            if (vaild) return Ok(JsonView(false, msg));
+
             Result groupData = await _airTicketResRep.OpAirTicketRes(dto, _setDataRep.PostCurrencyByDiid);
             if (groupData.Code != 0)
             {
@@ -8505,6 +8512,10 @@ FROM
         {
             try
             {
+                //验证
+                (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 85);
+                if (vaild) return Ok(JsonView(false, msg));
+
                 var res = await _airTicketResRep.SoftDeleteByIdAsync<Grp_AirTicketReservations>(dto.Id.ToString(), dto.DeleteUserId);
                 if (res)
                 {
@@ -8521,7 +8532,6 @@ FROM
             catch (Exception ex)
             {
                 return Ok(JsonView(false, "程序错误!"));
-                throw;
             }
         }
 
@@ -9747,7 +9757,6 @@ FROM
             return Ok(JsonView(true, groupData.Msg, groupData.Data));
         }
 
-
         /// <summary>
         /// 商邀费用列表
         /// 下载文件
@@ -9865,6 +9874,10 @@ FROM
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> OpInvitationOfficialActivities(OpInvitationOfficialActivitiesDto dto)
         {
+            //验证
+            (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 81);
+            if (vaild) return Ok(JsonView(false, msg));
+
             Result groupData = await _InvitationOfficialActivitiesRep.OpInvitationOfficialActivities(dto, _setDataRep.PostCurrencyByDiid);
             if (groupData.Code != 0)
             {
@@ -9912,7 +9925,12 @@ FROM
         {
             try
             {
+                //验证
+                (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 81);
+                if (vaild) return Ok(JsonView(false, msg));
+
                 _sqlSugar.BeginTran();
+
                 var res1 = _sqlSugar.Updateable<Grp_InvitationOfficialActivities>()
                                     .SetColumns(it => new Grp_InvitationOfficialActivities()
                                     {
@@ -19928,6 +19946,14 @@ FROM
         {
             _sqlSugar.BeginTran();
 
+            //验证 
+            (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 80);
+            if (vaild)
+            {
+                _sqlSugar.RollbackTran();
+                return Ok(JsonView(false, msg));
+            }
+
             var res = await _visaPriceRep.SoftDeleteByIdAsync<Grp_VisaInfo>(dto.Id.ToString(), dto.DeleteUserId);
 
             if (!res)
@@ -20018,6 +20044,10 @@ end as 'country'
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> OpVisaPrice(OpVisaPriceDto dto)
         {
+            //验证 
+            (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 80);
+            if (vaild) return Ok(JsonView(false, msg));
+
             Result groupData = await _visaPriceRep.OpVisaPrice(dto);
             if (groupData.Code != 0)
             {
@@ -20252,9 +20282,18 @@ end as 'country'
             {
                 _sqlSugar.BeginTran();
 
+                //验证 
+                (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 79);
+                if (vaild)
+                {
+                    _sqlSugar.RollbackTran();
+                    return Ok(JsonView(false, msg));
+                }
+
                 var res = await _carTouristGuideGroundRep.SoftDeleteByIdAsync<Grp_CarTouristGuideGroundReservations>(dto.Id.ToString(), dto.DeleteUserId);
                 if (!res)
                 {
+                    _sqlSugar.RollbackTran();
                     return Ok(JsonView(false, "删除失败"));
                 }
                 var result = await _sqlSugar.Updateable<Grp_CarTouristGuideGroundReservationsContent>().Where(a => a.CTGGRId == dto.Id && a.IsDel == 0).SetColumns(a => new Grp_CarTouristGuideGroundReservationsContent()
@@ -20302,7 +20341,6 @@ end as 'country'
             }
             catch (Exception ex)
             {
-
                 _sqlSugar.RollbackTran();
                 return Ok(JsonView(false, "程序错误!" + ex.Message));
             }
@@ -20390,6 +20428,14 @@ end as 'country'
                 if (di == null) return Ok(JsonView(false, "团组错误!"));
                 #endregion
 
+                //验证 
+                (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.CTGGRId, 79);
+                if (vaild)
+                {
+                    _sqlSugar.RollbackTran();
+                    return Ok(JsonView(false, msg));
+                }
+
                 Result groupData = await _carTouristGuideGroundRep.OpCarTouristGuideGroundContent(dto);
                 if (groupData.Code != 0)
                 {
@@ -20446,7 +20492,6 @@ end as 'country'
                 }
                 #endregion
 
-
                 #region 应用推送
                 try
                 {
@@ -25541,6 +25586,10 @@ AirHotelPrice
 
             #endregion
 
+            //验证 
+            (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(_dto.Id, 76);
+            if (vaild) return Ok(JsonView(false, msg));
+
             JsonView _view = await _hotelPriceRep.AddOrEdit(_dto);
             if (_view.Code != 200)
             {
@@ -25782,6 +25831,10 @@ AirHotelPrice
 
             #endregion
 
+            //验证 
+            (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(_dto.Id, 76);
+            if (vaild) return Ok(JsonView(false, msg));
+
             var data = await _hotelPriceRep.Del(_dto.Id, _dto.UserId);
 
             #region 操作记录
@@ -26226,7 +26279,6 @@ AirHotelPrice
             return Ok(JsonView(true, "操作成功!", Url));
         }
 
-
         /// <summary>
         /// 酒店预订
         /// 生成VOUCHER 批量生成 
@@ -26885,7 +26937,6 @@ AirHotelPrice
             return Ok(JsonView(true, "操作成功!", Url));
         }
 
-
         /// <summary>
         /// 酒店预订
         /// 生成 预定成本 Excel
@@ -27791,6 +27842,10 @@ AirHotelPrice
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> OpCustomers(OpCustomersDto dto)
         {
+            //验证 
+            (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 82);
+            if (vaild) return Ok(JsonView(false, msg));
+
             Result groupData = await _customersRep.OpCustomers(dto);
             if (groupData.Code != 0)
             {
@@ -27949,6 +28004,10 @@ AirHotelPrice
         {
             try
             {
+                //验证 
+                (bool vaild, string msg) = await GeneralMethod.FeeOpVaild(dto.Id, 82);
+                if (vaild) return Ok(JsonView(false, msg));
+
                 var res = await _customersRep.SoftDeleteByIdAsync<Grp_Customers>(dto.Id.ToString(), dto.DeleteUserId);
                 if (!res)
                 {
@@ -27965,7 +28024,6 @@ AirHotelPrice
             catch (Exception ex)
             {
                 return Ok(JsonView(false, "程序错误!"));
-                throw;
             }
         }
         #endregion

+ 34 - 0
OASystem/OASystem.Api/OAMethodLib/GeneralMethod.cs

@@ -518,6 +518,40 @@ namespace OASystem.API.OAMethodLib
 
         #region 团组相关 
 
+        #region 费用录入 编辑、删除前验证
+        /// <summary>
+        /// 费用录入 编辑、删除 验证
+        /// </summary>
+        /// <param name="id">费用Id</param>
+        /// <param name="feeType">
+        /// 费用类型
+        /// 85:机票
+        /// 82:保险
+        /// 81:商邀
+        /// 80:签证
+        /// 79:OP
+        /// 76:酒店
+        /// </param>
+        /// <returns></returns>
+        public static async Task<(bool, string)> FeeOpVaild(int id, int feeType)
+        {
+            var ccpInfo = await _sqlSugar.Queryable<Grp_CreditCardPayment>()
+                .Where(x => x.IsDel == 0 && x.CId == id && x.CTable == feeType)
+                .FirstAsync();
+            if (ccpInfo == null) 
+                return (true, "当前费用不存在,不可操作!");
+
+            if (ccpInfo.IsAuditGM == 1)
+                return (true, "当前费用已审核,不可操作!");
+
+            if (ccpInfo.IsPay == 1)
+                return (true, "当前费用已付款,不可操作!");
+
+            return (false, "可操作");
+        }
+
+        #endregion
+
         #region 建团按国家默认添加汇率 / 默认权限分配
 
 

+ 0 - 3
OASystem/OASystem.Infrastructure/Repositories/Groups/AirTicketResRepository.cs

@@ -502,7 +502,6 @@ namespace OASystem.Infrastructure.Repositories.Groups
                         //}
                         #endregion
 
-
                         //判断是否超出成本
                         #region 自动审核(暂时屏蔽)
                         //Grp_GroupCostParameter _GroupCostParameter = _sqlSugar.Queryable<Grp_GroupCostParameter>().First(a => a.DiId == grp_AirTicket.DIId && a.IsDel == 0);
@@ -1096,8 +1095,6 @@ namespace OASystem.Infrastructure.Repositories.Groups
             }
         }
 
-
-
         public class TranslateResult
         {
             public string Query { get; set; }

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

@@ -854,7 +854,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                     1, // 已通过
             };
 
-            if (auditStatus.Any(x => x == ccpInfo.IsAuditGM)) return new Result(-2, "该费用已手动审核,不可删除!");
+            if (auditStatus.Any(x => x == ccpInfo.IsAuditGM)) return new Result(-2, "该费用已审核,不可删除!");
 
             if (ccpInfo.IsPay == 1) return new Result(-2, "该费用已付款,不可删除!");