Sfoglia il codice sorgente

优化代码结构并增加签证费用管理功能

在 `Program.cs` 中移除冗余命名空间,更新数据库连接字符串以启用加密和信任证书。
在 `GroupsController.cs` 中简化方法参数和返回类型,优化文件处理逻辑。
在 `ResourceController.cs` 中新增 API 接口以处理签证费用标准的查询、保存和软删除,并增加参数验证。
在 `DtoBase.cs` 和 `CountryFeeCostDto.cs` 中添加数据验证特性。
在 `Res_CountryFeeCost.cs` 和 `Res_VisaFeeStandard.cs` 中增加新属性以支持签证费用标准的详细信息。
在 `VisaFeeInfoRepository.cs` 中重构方法以提高可读性,增加事务处理。
在 `CountryFeeRepository.cs` 中实现分页查询功能。
在 `VisaDeleClientView.cs` 中更新类结构以确保与前端一致。
在 `VisaFeeStandardDetails.cs` 中增加详细的签证费用信息类,支持费用排序和管理。
Lyyyi 2 mesi fa
parent
commit
165c9ef528

+ 7 - 9
OASystem/EntitySync/Program.cs

@@ -1,13 +1,9 @@
-using OASystem.Domain.Entities.Financial;
-using OASystem.Domain.Entities.Groups;
-using OASystem.Domain.Entities.PersonnelModule;
-using OASystem.Domain.Entities.Resource;
-using OASystem.Domain.Entities.System;
+using OASystem.Domain.Entities.Resource;
 using SqlSugar;
 
 var db = new SqlSugarClient(new ConnectionConfig()
 {
-    ConnectionString = "server=132.232.92.186;uid=sa;pwd=Yjx@158291;database=OA2023DB;",
+    ConnectionString = "server=132.232.92.186;uid=sa;pwd=Yjx@158291;database=OA2023DB;Encrypt=True;TrustServerCertificate=True;",
     DbType = DbType.SqlServer,
     IsAutoCloseConnection = true,
     InitKeyType = InitKeyType.Attribute
@@ -32,7 +28,7 @@ var db = new SqlSugarClient(new ConnectionConfig()
 #region 对话框
 Console.WriteLine("是否确定同步数据库表结构?(同名数据表将会被备份,生产环境慎用,回车确认)");
 var str = Console.ReadKey();
-if (str.Key == ConsoleKey.Enter) 
+if (str.Key == ConsoleKey.Enter)
 {
     Console.WriteLine("同步中,请稍后...");
 }
@@ -173,6 +169,8 @@ db.CodeFirst.SetStringDefaultLength(50).BackupTable().InitTables(new Type[]
     //typeof(Sys_AuditTemplateNode),//审核模板节点表 
     //typeof(Sys_AuditTemplateNodeUser),//审核模板节点人员表 
     //typeof(Fin_ApplicationLinkGoods),//日服申请单物品关联表 
-    typeof(Grp_GamesBudgetMaster‌),//世运会成本预算明细 
-}); 
+    //typeof(Grp_GamesBudgetMaster‌),//世运会成本预算明细 
+    typeof(Res_VisaFeeStandard),//签证费用标准 
+    typeof(Res_VisaFeeStandardDetails),//签证费用标准详情 
+});
 Console.WriteLine("数据库结构同步完成!");

+ 30 - 34
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -3,7 +3,6 @@ using Aspose.Words;
 using Aspose.Words.Drawing;
 using Aspose.Words.Tables;
 using DiffMatchPatch;
-using Dm.util;
 using Microsoft.AspNetCore.SignalR;
 using NPOI.SS.UserModel;
 using NPOI.SS.Util;
@@ -591,11 +590,10 @@ namespace OASystem.API.Controllers
         ///  团组前期信息 Info
         /// </summary>
         /// <param name="dto">Id</param>
-        /// <param name="portType">Id</param>
         /// <returns></returns>
         [HttpGet("{Id}/{TempId}")]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        public async Task<IActionResult> GroupOrderPreInfo([FromRoute] GroupOrderPreInfoDto dto, int portType = 1)
+        public async Task<IActionResult> GroupOrderPreInfo([FromRoute] GroupOrderPreInfoDto dto)
         {
             return Ok(await _grpOrderPreInfoRep.InfoAsync(dto.Id, dto.TempId));
         }
@@ -886,14 +884,16 @@ namespace OASystem.API.Controllers
                 var _DelegationList = await _sqlSugar.SqlQueryable<DelegationListView>(sql).ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
 
                 //处理 团组模块实际操作人
-                _DelegationList.ForEach(async x => { 
-                
+                _DelegationList.ForEach(async x =>
+                {
+
                     var operators = GeneralMethod.GetGroupModuleOperators(x.Id);
                     var operatorNames = new StringBuilder();
                     //operatorNames.AppendLine("各模块实际操作人:");
                     if (operators.Any())
                     {
-                        operators.ForEach(y => {
+                        operators.ForEach(y =>
+                        {
 
                             string label = string.Empty;
                             if (y.OperationUsers.Any())
@@ -2747,13 +2747,13 @@ FROM
         /// <returns></returns>
         [HttpPost]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        public async Task<IActionResult> VisaFileUploadAndUpdate(IFormFile file,int fileTypeId)
+        public async Task<IActionResult> VisaFileUploadAndUpdate(IFormFile file, int fileTypeId)
         {
             //文件验证
-            if (file.Length < 1) return Ok(JsonView(false,"请选择文件!"));
-            
-            var visaFiles = new VisaUploadFileTypeView();
-            var filetypes = visaFiles.GetVisaUploadFileTypeViewItemInit();
+            if (file.Length < 1) return Ok(JsonView(false, "请选择文件!"));
+
+            //var visaFiles = new VisaUploadFileTypeView();
+            var filetypes = VisaUploadFileTypeView.GetVisaUploadFileTypeViewItemInit();
             if (!filetypes.Any(x => x.FileId == fileTypeId)) return Ok(JsonView(false, "请选择文件类型!"));
 
             //服务器存储文件
@@ -2797,7 +2797,7 @@ FROM
                 // 判断并清除开头部分
                 if (jsonString.StartsWith(startStr))
                 {
-                    jsonString = jsonString.Remove(0, startStr.Length);
+                    jsonString = jsonString.Replace(startStr, "");
                 }
 
                 // 判断并清除结尾部分
@@ -2819,7 +2819,6 @@ FROM
                 }
             }
 
-
             var clientInfo = new Crm_DeleClient();            //客户资料表
             var clientFamily = new Crm_VisaCustomerFamily();  //客户家庭表
             var clientCompany = new Crm_CustomerCompany();    //客户公司表
@@ -2827,7 +2826,8 @@ FROM
             var clientSchool = new Crm_VisaCustomerSchool();  //客户学历表
 
             //按照表格类型分别进行参数处理
-            switch (fileTypeId) {
+            switch (fileTypeId)
+            {
                 //澳新签证个人申请表
                 case 1:
 
@@ -2838,7 +2838,7 @@ FROM
                 default:
 
                     break;
-            
+
             }
 
 
@@ -4306,7 +4306,7 @@ FROM
                 {
                     foreach (var ccpId in dic_ccp_user.Keys)
                     {
-                        List<string> templist = new List<string>() { dic_ccp_user[ccpId].ToString() };
+                        var templist = new List<string>() { dic_ccp_user[ccpId].ToString() };
                         await AppNoticeLibrary.SendUserMsg_GroupStatus_AuditFee(ccpId, templist, QiyeWeChatEnum.CaiWuChat);
                     }
                 }
@@ -4345,7 +4345,7 @@ FROM
             }
             catch (Exception ex)
             {
-                return Ok(JsonView(false, ex.Message)); 
+                return Ok(JsonView(false, ex.Message));
             }
         }
 
@@ -5504,6 +5504,7 @@ FROM
         }
 
         /// <summary>
+        /// 
         /// 团组增减款项操作 删除
         /// </summary>
         /// <param name="dto"></param>
@@ -9458,8 +9459,8 @@ FROM
 
             return Ok(JsonView(true, "查询成功!", new
             {
-                totalAmt = totalAmt,
-                remark = remark
+                totalAmt,
+                remark
             }));
         }
 
@@ -16924,7 +16925,7 @@ FROM
 
             Func<string, bool> isEmpty = (str) =>
             {
-                if (decimal.TryParse(str,out decimal str_De) && str_De == 0)
+                if (decimal.TryParse(str, out decimal str_De) && str_De == 0)
                 {
                     return true;
                 }
@@ -17026,7 +17027,7 @@ FROM
                         var val = List_GC1.Sum(x =>
                         {
                             var str = (string)x.GetType().GetProperty(item.Name).GetValue(x);
-                            if (decimal.TryParse(str , out decimal str_De))
+                            if (decimal.TryParse(str, out decimal str_De))
                             {
                                 return str_De;
                             }
@@ -19558,14 +19559,15 @@ AirHotelPrice
 
             internal decimal SUITE { get; set; }
 
-            internal decimal AllPrice {
+            internal decimal AllPrice
+            {
                 get { return SGR + TBR + JSES + SUITE; }
             }
         }
 
 
 
-            [HttpPost]
+        [HttpPost]
         public async Task<IActionResult> QueryGroupCostCoefficient(QueryGroupCostCoefficientDto dto)
         {
             var di = await _sqlSugar.Queryable<Grp_DelegationInfo>()
@@ -19586,11 +19588,11 @@ AirHotelPrice
 
             var groupHotelNumberDefault = groupHotelNumber.FirstOrDefault(x => x.Type == "Default");
 
-            HotelSum hotelSumP = new ();
+            HotelSum hotelSumP = new();
 
             if (groupCost.Any())
             {
-                hotelSumP.SGR = groupHotelNumberDefault.SGR > 0 ?  groupCost.Sum(x => x.SGR) * groupHotelNumberDefault.SGR : 0 ;
+                hotelSumP.SGR = groupHotelNumberDefault.SGR > 0 ? groupCost.Sum(x => x.SGR) * groupHotelNumberDefault.SGR : 0;
                 hotelSumP.TBR = groupHotelNumberDefault.TBR > 0 ? groupCost.Sum(x => x.TBR) * groupHotelNumberDefault.TBR : 0;
                 hotelSumP.JSES = groupHotelNumberDefault.JSES > 0 ? groupCost.Sum(x => x.JS_ES) * groupHotelNumberDefault.JSES : 0;
                 hotelSumP.SUITE = groupHotelNumberDefault.SUITE > 0 ? groupCost.Sum(x => x.Suite) * groupHotelNumberDefault.SUITE : 0;
@@ -19615,7 +19617,7 @@ AirHotelPrice
             #endregion
 
             #region 酒店系数
-            
+
             #endregion
 
 
@@ -23572,13 +23574,7 @@ AirHotelPrice
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> PostVisaFeeList(VisaFeeListDto _dto)
         {
-            var _view = await _visaFeeInfoRep._List(_dto.PortType, _dto.DiId);
-            if (_view.Code != 0)
-            {
-                return Ok(JsonView(false, _view.Msg));
-            }
-
-            return Ok(JsonView(true, "操作成功!", _view.Data));
+            return Ok(await _visaFeeInfoRep.List(_dto.PortType, _dto.DiId));
         }
 
         /// <summary>
@@ -23590,7 +23586,7 @@ AirHotelPrice
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> PostVisaFeeAddAndUpdate(VisaFeeAddAndUpdateDto _dto)
         {
-            var _view = await _visaFeeInfoRep._Update(_dto);
+            var _view = await _visaFeeInfoRep.Update(_dto);
             if (_view.Code != 0)
             {
                 return Ok(JsonView(false, _view.Msg));

+ 96 - 66
OASystem/OASystem.Api/Controllers/ResourceController.cs

@@ -804,16 +804,21 @@ namespace OASystem.API.Controllers
         public async Task<IActionResult> QueryCountryFeeCost(DtoBase dto)
         {
             var portType = dto.PortType;
+
+            if (portType != 1 && portType != 2 && portType != 3)
+                return Ok(JsonView(false, "请传入PortType参数!1:Web,2:Android,3:IOS"));
+
+
             var countryVisaFees = await _countryFeeRep
                 .QueryDto<Res_CountryFeeCost, CountryFeeCostView>()
                 .OrderByDescending(x => x.CreateTime)
                 .ToListAsync();
 
-            if (!countryVisaFees.Any()) return Ok(JsonView(false, "暂无数据!"));
+            if (countryVisaFees == null || countryVisaFees.Count == 0)
+                return Ok(JsonView(false, "暂无数据!"));
+
+            return Ok(JsonView(true, "查询成功", countryVisaFees));
 
-            if (portType == 1) return Ok(JsonView(true, "查询成功", countryVisaFees));
-            else if (portType == 2 || portType == 3) return Ok(JsonView(true, "查询成功", countryVisaFees));
-            else return Ok(JsonView(false, "请传入PortType参数!1:Web,2:Android,3:IOS"));
         }
 
         /// <summary>
@@ -840,7 +845,7 @@ namespace OASystem.API.Controllers
 
             var countryVisaFees = await query.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
 
-            if (!countryVisaFees.Any()) return Ok(JsonView(false, "暂无数据!"));
+            if (!countryVisaFees.Any()) return Ok(JsonView(true, "暂无数据!"));
             var view = _mapper.Map<List<CountryFeeCostView>>(countryVisaFees);
 
             return Ok(JsonView(true, "查询成功", view, total));
@@ -878,6 +883,63 @@ namespace OASystem.API.Controllers
         }
         #endregion
 
+        #region 签证费用资料 New
+
+        /// <summary>
+        /// 签证费用标准 Info 
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> VisaFeeStandardInfo(VisaFeeStandardInfoDto dto)
+        {
+            var portType = dto.PortType;
+
+            if (portType != 1 && portType != 2 && portType != 3)
+                return Ok(JsonView(false, "请传入PortType参数!1:Web,2:Android,3:IOS"));
+
+            return Ok(await _countryFeeRep.InfoAsync(dto.Id));
+        }
+
+        /// <summary>
+        /// 签证费用标准 List 
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> VisaFeeStandardList(VisaFeeStandardListDto dto)
+        {
+            return Ok(await _countryFeeRep.PageListAsync(dto));
+        }
+
+        /// <summary>
+        /// 签证费用标准 Save 
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> VisaFeeStandardSave(VisaFeeStandardSaveDto dto)
+        {
+            return Ok(await _countryFeeRep.SaveAsync(dto));
+        }
+
+        /// <summary>
+        /// 签证费用标准 SoftDel 
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> VisaFeeStandardSoftDel(VisaFeeStandardSoftDelDto dto)
+        {
+            return Ok(await _countryFeeRep.SoftDelAsync(dto.CurrUserId, dto.Id));
+        }
+
+        #endregion
+
         #region 物料信息、供应商维护
         #region 供应商
         /// <summary>
@@ -2271,7 +2333,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 //文件名称
                 string[] fileNameArray = file.FileName.Split(".");
 
-                string projectFileName = $"{fileNameArray[0].ToString().Replace("-", "_").Replace("/", "_")}{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.{fileNameArray[1].ToString()}";
+                string projectFileName = $"{fileNameArray[0].ToString().Replace("-", "_").Replace("/", "_")}{DateTime.UtcNow:yyyyMMddHHmmss}.{fileNameArray[1]}";
                 //上传的文件的路径
                 string filePath = $@"{localPath}公务相关文件";
                 if (!Directory.Exists(filePath))
@@ -2293,7 +2355,6 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 }
                 catch (Exception ex)
                 {
-
                     failFiles.Append(file.FileName);
                 }
             }
@@ -2333,7 +2394,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
 
                 fileUrls = fileUrls.Distinct().ToList();
 
-                if (fileUrls.Count() > 0)
+                if (fileUrls.Count > 0)
                 {
                     var upd = await _sqlSugar.Updateable<Res_OfficialActivities>()
                                           .SetColumns(x => x.ScreenshotOfMailUrl == JsonConvert.SerializeObject(fileUrls))
@@ -2844,12 +2905,12 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 DocumentBuilder builder = new DocumentBuilder(doc);
 
                 //键值对存放数据
-                Dictionary<string, string> dic = new Dictionary<string, string>();
-
-                //××(组团单位):接团客户信息团组
-                dic.Add("GroupClient", $"{groupInfo.ClientUnit}");
-
-                dic.Add("GroupClient1", $"{groupInfo.ClientUnit}");
+                var dic = new Dictionary<string, string>
+                {
+                    //××(组团单位):接团客户信息团组
+                    { "GroupClient", $"{groupInfo.ClientUnit}" },
+                    { "GroupClient1", $"{groupInfo.ClientUnit}" }
+                };
                 //关于××(职务、姓名)等×人赴××(国家或地区)进行×××(出访目的)的请示
                 string guestName = "";
                 string guestJob = "";
@@ -2975,7 +3036,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 }
 
                 var fileDir = AppSettingsHelper.Get("WordBasePath");
-                var fileName = $"{groupInfo.TeamName}市外办出访请示{DateTime.Now.ToString("yyyyMMddHHmmss")}.docx";
+                var fileName = $"{groupInfo.TeamName}市外办出访请示{DateTime.Now:yyyyMMddHHmmss}.docx";
                 var filePath = fileDir + $@"OfficialActivities/{fileName}";
                 doc.Save(filePath);
 
@@ -2987,7 +3048,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
             return Ok(JsonView(true, "操作失败!", ""));
         }
 
-        private string GetToUpperNumber(int num)
+        private static string GetToUpperNumber(int num)
         {
             string numStr = "";
 
@@ -3548,7 +3609,7 @@ WHERE
             }
             else
             {
-                for (int i = 0; i < clientList.Count(); i++)
+                for (int i = 0; i < clientList.Count; i++)
                 {
                     builder.MoveToCell(0, i + 1, 0, 0);
                     builder.Write((i + 1).ToString());
@@ -3605,7 +3666,7 @@ WHERE
                     {
                         string[] str = temp1.Replace("\r\n", " ").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                         string[] str2 = temp2.Replace("\r\n", " ").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
-                        for (int j = 0; j < str.Count(); j++)
+                        for (int j = 0; j < str.Length; j++)
                         {
                             content = content + " " + str[j] + str2[j] + "\r\n";
                         }
@@ -4005,7 +4066,7 @@ WHERE
             }
             else
             {
-                for (int i = 0; i < clientList.Count(); i++)
+                for (int i = 0; i < clientList.Count; i++)
                 {
                     builder.MoveToCell(0, i + 1, 0, 0);
                     builder.Write((i + 1).ToString());
@@ -4062,7 +4123,7 @@ WHERE
                     {
                         string[] str = temp1.Replace("\r\n", " ").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                         string[] str2 = temp2.Replace("\r\n", " ").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
-                        for (int j = 0; j < str.Count(); j++)
+                        for (int j = 0; j < str.Length; j++)
                         {
                             content = content + " " + str[j] + str2[j] + "\r\n";
                         }
@@ -4103,20 +4164,12 @@ WHERE
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> QueryTicketBlackCodeByDiId(QueryTicketBlackCodeByDiIdDto dto)
         {
-            try
-            {
-                Result groupData = await _ticketBlackCodeRep.QueryTicketBlackCodeByDiId(dto);
-                if (groupData.Code != 0)
-                {
-                    return Ok(JsonView(false, groupData.Msg));
-                }
-                return Ok(JsonView(true, groupData.Msg, groupData.Data));
-            }
-            catch (Exception ex)
+            Result groupData = await _ticketBlackCodeRep.QueryTicketBlackCodeByDiId(dto);
+            if (groupData.Code != 0)
             {
-                return Ok(JsonView(false, "程序错误!"));
-                throw;
+                return Ok(JsonView(false, groupData.Msg));
             }
+            return Ok(JsonView(true, groupData.Msg, groupData.Data));
         }
         /// <summary>
         /// 根据黑屏代码数据Id查询信息
@@ -4127,20 +4180,12 @@ WHERE
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> QueryTicketBlackCodeById(QueryTicketBlackCodeByIdDto dto)
         {
-            try
-            {
-                Result groupData = await _ticketBlackCodeRep.QueryTicketBlackCodeById(dto);
-                if (groupData.Code != 0)
-                {
-                    return Ok(JsonView(false, groupData.Msg));
-                }
-                return Ok(JsonView(true, groupData.Msg, groupData.Data));
-            }
-            catch (Exception ex)
+            Result groupData = await _ticketBlackCodeRep.QueryTicketBlackCodeById(dto);
+            if (groupData.Code != 0)
             {
-                return Ok(JsonView(false, "程序错误!"));
-                throw;
+                return Ok(JsonView(false, groupData.Msg));
             }
+            return Ok(JsonView(true, groupData.Msg, groupData.Data));
         }
         /// <summary>
         /// 黑屏代码操作(Status:1.新增,2.修改)
@@ -4173,7 +4218,7 @@ WHERE
                 //行程代码变更通知
                 await AppNoticeLibrary.SendUserMsg_GroupShare_ToDP(dto.DiId, dto.CreateUserId);
             }
-            catch (Exception ex)
+            catch (Exception)
             {
 
                 throw;
@@ -4193,20 +4238,12 @@ WHERE
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> DelTicketBlackCode(DelBaseDto dto)
         {
-            try
-            {
-                var res = await _ticketBlackCodeRep.SoftDeleteByIdAsync<Air_TicketBlackCode>(dto.Id.ToString(), dto.DeleteUserId);
-                if (!res)
-                {
-                    return Ok(JsonView(false, "删除失败"));
-                }
-                return Ok(JsonView(true, "删除成功!"));
-            }
-            catch (Exception ex)
+            var res = await _ticketBlackCodeRep.SoftDeleteByIdAsync<Air_TicketBlackCode>(dto.Id.ToString(), dto.DeleteUserId);
+            if (!res)
             {
-                return Ok(JsonView(false, "程序错误!"));
-                throw;
+                return Ok(JsonView(false, "删除失败"));
             }
+            return Ok(JsonView(true, "删除成功!"));
         }
         #endregion
 
@@ -4217,7 +4254,7 @@ WHERE
         /// Init
         /// </summary>
         /// <returns></returns>
-        [HttpGet()]
+        [HttpGet]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> TranslatorLibraryInit()
         {
@@ -4251,7 +4288,7 @@ WHERE
                 .ToList();
             var view = new
             {
-                currencyData = currencyData,
+                currencyData,
                 officialDutyData = officialDutyData1
             };
 
@@ -4631,7 +4668,6 @@ WHERE
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> MediaSupplierOp(MediaSupplierAddOrEditDto dto)
         {
-            var result = new JsonView() { Code = 400, Msg = "操作失败" };
             var userId = dto.CurrUserId;
             if (!_portIds.Contains(dto.PortType)) return Ok(JsonView(false, MsgTips.Port));
 
@@ -4650,7 +4686,6 @@ WHERE
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> MediaSupplierSoftDel(MediaSupplierSoftDelDto dto)
         {
-            var result = new JsonView() { Code = 400, Msg = "操作失败" };
             int userId = dto.CurrUserId, id = dto.Id;
             if (!_portIds.Contains(dto.PortType)) return Ok(JsonView(false, MsgTips.Port));
 
@@ -4660,11 +4695,6 @@ WHERE
             return Ok(await _mediaSupplierRep.SoftDel(dto));
         }
 
-
-
-
-
-
         #endregion
 
         #region 保险国家基础费用

+ 223 - 1
OASystem/OASystem.Api/Controllers/SystemController.cs

@@ -3260,7 +3260,6 @@ And u.UId = {0} And u.FId = 1 ", dto.UserId);
 
         #endregion
 
-
         #region 资料相关Excel 导入
         /// <summary>
         /// excel导入 策划部供应商资料
@@ -3659,6 +3658,229 @@ And u.UId = {0} And u.FId = 1 ", dto.UserId);
             }
             return Ok(JsonView(false, "excel导入失败!"));
         }
+
+        /// <summary>
+        /// excel导入 签证费用标准
+        /// </summary>
+        /// <param name="file"></param>
+        /// <param name="currUserId">录入人userId</param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> ExcelImportVisaFeeStandard(IFormFile file, [FromQuery] int currUserId = 208)
+        {
+            // 检查文件是否为空
+            if (file == null || file.Length == 0)
+            {
+                return Ok(JsonView(false, "请选择文件!"));
+            }
+
+            // 文件签名验证
+            var perExtensions = new[] { ".xls", ".xlsx" };
+            Dictionary<string, List<byte[]>> fileSignature = CommonFun.FileSignature;
+            fileSignature = fileSignature.Where(pair => perExtensions.Contains(pair.Key)).ToDictionary(pair => pair.Key, pair => pair.Value);
+
+            // 文件扩展名验证
+            var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
+            if (string.IsNullOrEmpty(ext) || !fileSignature.ContainsKey(ext))
+            {
+                return Ok(JsonView(false, "不支持的文件类型!"));
+            }
+
+            using (var memoryStream = new MemoryStream())
+            {
+                await file.CopyToAsync(memoryStream);
+
+                // 检查文件签名
+                var fileData = memoryStream.ToArray();
+                var signatures = fileSignature[ext];
+                bool signatureValid = signatures.Any(signature =>
+                    fileData.Take(signature.Length).SequenceEqual(signature));
+
+                if (!signatureValid)
+                {
+                    return Ok(JsonView(false, "文件内容与类型不匹配!"));
+                }
+            }
+
+            // 保存文件到服务器
+            var uploadsFolder = @$"D:\FTP\File\OA2023\Office\Excel\CarDataSouceImportFile";
+            if (!Directory.Exists(uploadsFolder))
+            {
+                Directory.CreateDirectory(uploadsFolder);
+            }
+
+            var fileName = CommonFun.ValidFileName(file.Name);
+
+            var filePath = Path.Combine(uploadsFolder, fileName);
+            using (var stream = new FileStream(filePath, FileMode.Create))
+            {
+                await file.CopyToAsync(stream);
+            }
+
+            var workbook = new Workbook(filePath);
+
+
+            // 获取第一个工作表
+            Worksheet worksheet = workbook.Worksheets[0]; // 因公护照签证费用标准
+            Worksheet worksheet1 = workbook.Worksheets[1]; // 因私护照签证费用标准
+
+            var oldVisaFeeStandards = await _sqlSugar.Queryable<Res_CountryFeeCost>()
+                .Where(x => x.IsDel == 0)
+                .ToListAsync();
+
+            // 获取表头(第一行作为列名)
+            int headerRowIndex = 0;
+            Row headerRow = worksheet.Cells.Rows[headerRowIndex];
+            int colCount = worksheet.Cells.MaxDataColumn + 1;
+
+            // 动态存储列名
+            var datas = new List<VisaFeeStandardInfoView>();
+
+            // 遍历数据行(从第3行开始)
+            int rowCount = worksheet.Cells.MaxDataRow + 1;
+            var msgs = new StringBuilder();
+            for (int row = headerRowIndex + 1; row < rowCount; row++)
+            {
+                var cellVal0 = worksheet.Cells[row, 0].Value;      //国家
+                var cellVal1 = worksheet.Cells[row, 1].Value;      //公务护照免签
+                var cellVal2 = worksheet.Cells[row, 2].Value;      //公务护照签证费
+                var cellVal3 = worksheet.Cells[row, 3].Value;      //公务护照签证代办费
+                var cellVal4 = worksheet.Cells[row, 4].Value;      //公务普通护照免签
+                var cellVal5 = worksheet.Cells[row, 5].Value;      //公务普通护照签证费
+                var cellVal6 = worksheet.Cells[row, 6].Value;      //公务普通护照代办费
+                var cellVal7 = worksheet.Cells[row, 7].Value;      //云南代办费
+                var cellVal8 = worksheet.Cells[row, 8].Value;      //贵州代办费
+                var cellVal9 = worksheet.Cells[row, 9].Value;      //重庆代办费
+                var cellVal10 = worksheet.Cells[row, 10].Value;    //重庆外办出入境证明费用
+                var cellVal11 = worksheet.Cells[row, 11].Value;    //送签地点
+                var cellVal12 = worksheet.Cells[row, 12].Value;    //办理时间(工作日)
+
+                var dtTimeNoew = DateTime.Now;
+
+                var isVisaExemptionLargeVal = cellVal1?.ToString() == "是"; //公务护照免签
+                _ = decimal.TryParse(cellVal2?.ToString(), out decimal largeVisaPrice);    //公务护照签证费
+                _ = decimal.TryParse(cellVal3?.ToString(), out decimal largeAgencyFee);    //公务护照签证代办费
+                var isVisaExemptionSmallVal = cellVal4?.ToString() == "是" ? true : false; //公务普通护照免签
+                _ = decimal.TryParse(cellVal5?.ToString(), out decimal smallVisaPrice);    //公务普通护照签证费
+                _ = decimal.TryParse(cellVal6?.ToString(), out decimal smallAgencyFee);    //公务普通护照签证代办费
+
+                _ = decimal.TryParse(cellVal7?.ToString(), out decimal yunNanAgencyFee);    //云南代办费
+                _ = decimal.TryParse(cellVal8?.ToString(), out decimal guiZhouAgencyFee);    //贵州代办费
+                _ = decimal.TryParse(cellVal9?.ToString(), out decimal chongQingAgencyFee);    //重庆代办费
+
+                string countryName = cellVal0?.ToString() ?? "";
+                string continent=string.Empty,
+                       remark =string.Empty;
+                var oldDataInfo = oldVisaFeeStandards.FirstOrDefault(x => x.VisaFeeType == 0 && x.VisaCountry == countryName);
+                if (oldDataInfo != null)
+                {
+                    continent = oldDataInfo.VisaContinent;
+                    remark = oldDataInfo.VisaPriceDesc;
+                }
+
+                var detailsList = new List<VisaFeeStandardDetails>() {
+                    new(){
+                        ProvinceId = 122,
+                        ProvinceName = "四川",
+                        VisaAddress = cellVal11?.ToString() ?? "",
+                        VisaTime = cellVal12?.ToString() ?? "0",
+                        IsVisaExemptionLarge = isVisaExemptionLargeVal,
+                        LargeVisaPrice = largeVisaPrice,
+                        LargeAgencyFee = largeAgencyFee,
+                        IsVisaExemptionSmall = isVisaExemptionSmallVal,
+                        SmallVisaPrice = smallVisaPrice,
+                        SmallAgencyFee = smallAgencyFee,
+                        Remark = remark,
+                    },
+                    new(){
+                        ProvinceId = 103,
+                        ProvinceName = "重庆",
+                        SmallAgencyFee = chongQingAgencyFee,
+                        NormExtFee = 40.00M,
+                        UrgExtFee = 140.00M,
+                    },
+                    new(){
+                        ProvinceId = 108,
+                        ProvinceName = "贵州",
+                        SmallAgencyFee = guiZhouAgencyFee,
+                    },
+                    new(){
+                        ProvinceId = 132,
+                        ProvinceName = "云南",
+                        SmallAgencyFee = yunNanAgencyFee,
+                    },
+                };
+
+                var rowData = new VisaFeeStandardInfoView()
+                {
+                   Continent = continent,
+                   Country = countryName,
+                   FeeType = 0,
+                   VisaFees = detailsList
+                };
+
+                datas.Add(rowData);
+            }
+
+            // 获取表头(第一行作为列名)
+            int headerRowIndex1 = 0;
+            Row headerRow1 = worksheet1.Cells.Rows[headerRowIndex1];
+            int colCount1 = worksheet1.Cells.MaxDataColumn + 1;
+
+            // 遍历数据行(从第3行开始)
+            int rowCount1 = worksheet1.Cells.MaxDataRow + 1;
+            for (int row = headerRowIndex1 + 1; row < rowCount1; row++)
+            {
+                var cellVal0 = worksheet1.Cells[row, 0].Value;      //国家
+                var cellVal1 = worksheet1.Cells[row, 1].Value;      //普通护照免签
+                var cellVal2 = worksheet1.Cells[row, 2].Value;      //签证费
+                var cellVal3 = worksheet1.Cells[row, 3].Value;      //送签地点
+                var cellVal4 = worksheet1.Cells[row, 4].Value;      //办理时间(工作日)
+
+                var dtTimeNoew = DateTime.Now;
+
+                var isVisaExemptionSmallVal = cellVal1?.ToString() == "是"; //普通护照免签
+                _ = decimal.TryParse(cellVal2?.ToString(), out decimal smallVisaPrice);    //普通护照签证费
+
+                string countryName = cellVal0?.ToString() ?? "";
+                string continent = string.Empty;
+                var oldDataInfo = oldVisaFeeStandards.FirstOrDefault(x => x.VisaFeeType == 1 && x.VisaCountry == countryName);
+                if (oldDataInfo != null)
+                {
+                    continent = oldDataInfo.VisaContinent;
+                }
+
+                var detailsList = new List<VisaFeeStandardDetails>() {
+                    new(){
+                        ProvinceId = 122,
+                        ProvinceName = "四川",
+                        VisaAddress = cellVal1?.ToString() ?? "",
+                        VisaTime = cellVal4?.ToString() ?? "0",
+                        IsVisaExemptionSmall = isVisaExemptionSmallVal,
+                        SmallVisaPrice = smallVisaPrice,
+                    }
+                };
+
+                var rowData = new VisaFeeStandardInfoView()
+                {
+                    Continent = continent,
+                    Country = countryName,
+                    FeeType = 1,
+                    VisaFees = detailsList
+                };
+
+                datas.Add(rowData);
+            }
+
+
+            if (datas.Any())
+            {
+                return Ok(datas);
+            }
+            return Ok(JsonView(false, "excel导入失败!"));
+        }
+
         #endregion
 
     }

+ 3 - 0
OASystem/OASystem.Domain/AutoMappers/_baseMappingProfile.cs

@@ -264,6 +264,9 @@ namespace OASystem.Domain.AutoMappers
             #region 签证费用资料
             CreateMap<Res_CountryFeeCost, CountryFeeCostView>();
             CreateMap<OperationCountryFeeCostDto, Res_CountryFeeCost>();
+            CreateMap<Res_VisaFeeStandardDetails, VisaFeeStandardDetails>();
+            CreateMap<VisaFeeStandardDetails, Res_VisaFeeStandardDetails>();
+            CreateMap<VisaFeeStandardInfoView, Res_VisaFeeStandard>();
             #endregion
 
             #region 物料供应商

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

@@ -1,6 +1,7 @@
 using Microsoft.AspNetCore.Http;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -27,6 +28,7 @@ namespace OASystem.Domain.Dtos
         /// 请求端口分类
         /// 1 Web 2 Android 3 IOS
         /// </summary>
+        [Range(-1, 1, ErrorMessage = $"请传入PortType参数!1:Web,2:Android,3:IOS")]
         public int PortType { get; set; } = 1;
     }
 

+ 44 - 1
OASystem/OASystem.Domain/Dtos/Resource/CountryFeeCostDto.cs

@@ -1,4 +1,5 @@
-using System;
+using OASystem.Domain.ViewModels.Resource;
+using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.Linq;
@@ -226,4 +227,46 @@ namespace OASystem.Domain.Dtos.Resource
 
         public string CountryName { get; set; }
     }
+
+
+    public class VisaFeeStandardInfoDto : PortDtoBase
+    {
+        /// <summary>
+        /// Id
+        /// </summary>
+        [Range(1, int.MaxValue, ErrorMessage = "请传入有效的Id!")]
+        public int Id { get; set; }
+    }
+
+    public class VisaFeeStandardListDto : DtoBase
+    {
+        [Range(-1, 1, ErrorMessage = $"请选择正确的签证费用类型,-1:全部 0:因公 1:因私 ")]
+        public int VisaFeeType { get; set; }
+
+
+
+        public string CountryName { get; set; }
+    }
+
+
+    
+    public class VisaFeeStandardSaveDto : VisaFeeStandardInfoView 
+    {
+        public int CurrUserId { get; set; }
+    }
+
+    public class VisaFeeStandardSoftDelDto
+    {
+        /// <summary>
+        /// Id
+        /// </summary>
+        [Range(1, int.MaxValue, ErrorMessage = "请传入有效的Id!")]
+        public int Id { get; set; }
+
+        /// <summary>
+        /// 当前操作人
+        /// </summary>
+        [Range(1, int.MaxValue, ErrorMessage = "请传入有效的CurrUserId!")]
+        public int CurrUserId { get; set; }
+    }
 }

+ 3 - 8
OASystem/OASystem.Domain/Entities/Resource/Res_CountryFeeCost.cs

@@ -1,16 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace OASystem.Domain.Entities.Resource
+namespace OASystem.Domain.Entities.Resource
 {
     /// <summary>
     /// 签证费用资料
     /// </summary>
     [SugarTable("Res_CountryFeeCost")]
-    public class Res_CountryFeeCost:EntityBase
+    public class Res_CountryFeeCost : EntityBase
     {
         /// <summary>
         /// 洲名
@@ -74,6 +68,7 @@ namespace OASystem.Domain.Entities.Resource
         [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
         public decimal PettyBusinessAgencyFee { get; set; }
 
+
         /// <summary>
         /// 一般签证时间
         /// </summary>

+ 40 - 0
OASystem/OASystem.Domain/Entities/Resource/Res_VisaFeeStandard.cs

@@ -0,0 +1,40 @@
+namespace OASystem.Domain.Entities.Resource
+{
+    /// <summary>
+    /// 签证费用标准
+    /// </summary>
+    [SugarTable("Res_VisaFeeStandard", "签证费用标准")]
+    public class Res_VisaFeeStandard : EntityBase
+    {
+        /// <summary>
+        /// 洲名
+        /// </summary>
+        [SugarColumn(ColumnName = "Continent", ColumnDescription = "洲名", IsNullable = true, ColumnDataType = "varchar(50)")]
+        public string Continent { get; set; }
+
+        /// <summary>
+        /// 国家名
+        /// </summary>
+        [SugarColumn(ColumnName = "Country", ColumnDescription = "国家名", IsNullable = true, ColumnDataType = "varchar(50)")]
+        public string Country { get; set; }
+
+        /// <summary>
+        /// 签证费用类型 0 因公 1 因私
+        /// </summary>
+        [SugarColumn(ColumnName = "FeeType", ColumnDescription = "签证费用类型 0 因公 1 因私", IsNullable = true, ColumnDataType = "int")]
+        public int FeeType { get; set; } = 0;
+
+        /// <summary>
+        /// 最后更新者Id
+        /// </summary>
+        [SugarColumn(ColumnName = "LastUpdateTime", ColumnDescription = "最后更新者Id", IsNullable = true, ColumnDataType = "int")]
+        public int LastUpdateUserId { get; set; }
+
+        /// <summary>
+        /// 最后更新时间
+        /// </summary>
+        [SugarColumn(ColumnName = "LastUpdateTime", ColumnDescription = "最后更新时间", IsNullable = true, ColumnDataType = "DateTime")]
+        public DateTime LastUpdateTime { get; set; } = DateTime.Now;
+
+    }
+}

+ 118 - 0
OASystem/OASystem.Domain/Entities/Resource/Res_VisaFeeStandardDetails.cs

@@ -0,0 +1,118 @@
+namespace OASystem.Domain.Entities.Resource
+{
+    /// <summary>
+    /// 签证费用标准详情
+    /// </summary>
+    [SugarTable("Res_VisaFeeStandardDetails", "签证费用标准详情")]
+    public class Res_VisaFeeStandardDetails : EntityBase
+    {
+        /// <summary>
+        /// 签证费用表Id(Res_VisaFeeStandard)
+        /// </summary>
+        [SugarColumn(ColumnName = "ParentId", ColumnDescription = "签证费用表Id(Res_VisaFeeStandard)", IsNullable = true, ColumnDataType = "int")]
+        public int ParentId { get; set; } = 0;
+
+        /// <summary>
+        /// 签证费用归属省份Id(Sys_Cities)
+        /// </summary>
+        [SugarColumn(ColumnName = "ProvinceId", ColumnDescription = "签证费用归属省份Id(Sys_Cities)", IsNullable = true, ColumnDataType = "int")]
+        public int ProvinceId { get; set; }
+
+        /// <summary>
+        /// 送签地址
+        /// </summary>
+        [SugarColumn(ColumnName = "VisaAddress", ColumnDescription = "送签地址", IsNullable = true, ColumnDataType = "varchar(255)")]
+        public string VisaAddress { get; set; }
+
+        /// <summary>
+        /// 是否落地签
+        /// </summary>
+        [SugarColumn(ColumnName = "IsVisaOnArrival", ColumnDescription = "是否落地签", IsNullable = true, ColumnDataType = "bit")]
+        public bool IsVisaOnArrival { get; set; }
+
+        /// <summary>
+        /// 是否电子签 0:是 1:否
+        /// </summary>
+        [SugarColumn(ColumnName = "IsElectronicSign", ColumnDescription = "是否电子签", IsNullable = true, ColumnDataType = "bit")]
+        public bool IsElectronicSign { get; set; }
+
+        /// <summary>
+        /// 签证时间(工作日)
+        /// </summary>
+        [SugarColumn(ColumnName = "VisaTime", ColumnDescription = "签证时间(工作日)", IsNullable = true, ColumnDataType = "varchar(50)")]
+        public string VisaTime { get; set; }
+
+        /// <summary>
+        ///  是否免签(大公务) 0:是 1:否
+        /// </summary>
+        [SugarColumn(ColumnName = "IsVisaExemptionLarge", ColumnDescription = "是否免签(大公务) 0:是 1:否", IsNullable = true, ColumnDataType = "bit")]
+        public bool IsVisaExemptionLarge { get; set; }
+
+        /// <summary>
+        /// 签证费用(大公务)
+        /// </summary>
+        [SugarColumn(ColumnName = "LargeVisaPrice", ColumnDescription = "签证费用(大公务)", IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal LargeVisaPrice { get; set; }
+
+        /// <summary>
+        /// 代办费(大公务)
+        /// </summary>
+        [SugarColumn(ColumnName = "LargeAgencyFee", ColumnDescription = "代办费(大公务)", IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal LargeAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        ///  是否免签(小公务) 0:是 1:否
+        /// </summary>
+        [SugarColumn(ColumnName = "IsVisaExemptionSmall", ColumnDescription = "是否免签(小公务) 0:是 1:否", IsNullable = true, ColumnDataType = "bit")]
+        public bool IsVisaExemptionSmall { get; set; }
+
+        /// <summary>
+        /// 签证费用(小公务)
+        /// </summary>
+        [SugarColumn(ColumnName = "SmallVisaPrice", ColumnDescription = "签证费用(小公务)", IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal SmallVisaPrice { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 代办费(小公务)
+        /// </summary>
+        [SugarColumn(ColumnName = "SmallAgencyFee", ColumnDescription = "代办费(小公务)", IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal SmallAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        ///  外办费用(普通)
+        /// </summary>
+        [SugarColumn(ColumnName = "NormExtFee", ColumnDescription = "外办费用(普通)", IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal NormExtFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 外办费用(加急)
+        /// </summary>
+        [SugarColumn(ColumnName = "UrgExtFee", ColumnDescription = "外办费用(加急)", IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal UrgExtFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 签证是否加急 0:加急  1: 不加急
+        /// </summary>
+        [SugarColumn(ColumnName = "IsUrgent", ColumnDescription = "签证是否加急 0:加急  1: 不加急", IsNullable = true, ColumnDataType = "bit")]
+        public bool IsUrgent { get; set; }
+
+        /// <summary>
+        /// 加急时间(工作日)
+        /// </summary>
+        [SugarColumn(ColumnName = "UrgentTime", ColumnDescription = "加急时间(工作日)", IsNullable = true, ColumnDataType = "varchar(50)")]
+        public string UrgentTime { get; set; }
+
+        /// <summary>
+        /// 加急费用
+        /// </summary>
+        [SugarColumn(ColumnName = "UrgentPrice", ColumnDescription = "加急费用", IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal UrgentPrice { get; set; }
+
+        /// <summary>
+        /// 加急费用描述 
+        /// </summary>
+        [SugarColumn(ColumnName = "UrgentPriceDesc", ColumnDescription = "加急费用描述", IsNullable = true, ColumnDataType = "varchar(300)")]
+        public string UrgentPriceDesc { get; set; }
+
+    }
+}

+ 348 - 62
OASystem/OASystem.Domain/ViewModels/CRM/VisaDeleClientView.cs

@@ -112,6 +112,351 @@ namespace OASystem.Domain.ViewModels.CRM
     #region 签证客户资料 New
 
 
+    public class VisaUploadFileTypeView
+    {
+        /// <summary>
+        /// 文件Id
+        /// </summary>
+        public int FileId { get; set; }
+        /// <summary>
+        /// 文件名称
+        /// </summary>
+        public string FileName { get; set; }
+
+        /// <summary>
+        /// kimi AI 提示语
+        /// </summary>
+        public string KimiAITips { get; set; }
+
+        public VisaUploadFileTypeView() { }
+
+        /// <summary>
+        /// 初始化 文件类型item
+        /// </summary>
+        /// <returns></returns>
+        public static List<VisaUploadFileTypeView> GetVisaUploadFileTypeViewItemInit()
+        {
+            #region 新西兰、澳大利亚签证申请资料表 实体类cs
+
+            string json1 = @"
+public class VisaApplication
+    {
+        /// <summary>
+        /// 其他国家访问记录
+        /// </summary>
+        [JsonPropertyName(""其他国家"")]
+        public string OtherCountries { get; set; }
+
+        /// <summary>
+        /// 申请人个人信息
+        /// </summary>
+        [JsonPropertyName(""申请人个人信息"")]
+        public ApplicantInfo ApplicantInfo { get; set; }
+
+        /// <summary>
+        /// 新西兰澳大利亚访问记录
+        /// </summary>
+        [JsonPropertyName(""新西兰澳大利亚访问记录"")]
+        public List<VisitHistory> VisitHistory { get; set; }
+
+        /// <summary>
+        /// 拒签记录
+        /// </summary>
+        [JsonPropertyName(""拒签记录"")]
+        public List<RejectionRecord> RejectionRecords { get; set; }
+
+        /// <summary>
+        /// 教育经历
+        /// </summary>
+        [JsonPropertyName(""教育经历"")]
+        public List<EducationExperience> EducationExperiences { get; set; }
+
+        /// <summary>
+        /// 工作经历
+        /// </summary>
+        [JsonPropertyName(""工作经历"")]
+        public List<WorkExperience> WorkExperiences { get; set; }
+
+        /// <summary>
+        /// 服兵役历史(识别成一段话)
+        /// </summary>
+        [JsonPropertyName(""服兵役历史"")]
+        public string MilitaryServices { get; set; }
+
+    }
+
+    /// <summary>
+    /// 申请人个人信息
+    /// </summary>
+    public class ApplicantInfo
+    {
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        [JsonPropertyName(""姓名"")]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 曾用名
+        /// </summary>
+        [JsonPropertyName(""曾用名"")]
+        public string FormerName { get; set; }
+
+        /// <summary>
+        /// 婚姻状况
+        /// </summary>
+        [JsonPropertyName(""婚姻状况"")]
+        public string MaritalStatus { get; set; }
+
+        /// <summary>
+        /// 出生地
+        /// </summary>
+        [JsonPropertyName(""出生地"")]
+        public string BirthPlace { get; set; }
+
+        /// <summary>
+        /// 出生日期
+        /// </summary>
+        [JsonPropertyName(""出生日期"")]
+        public string BirthDate { get; set; }
+
+        /// <summary>
+        /// 性别
+        /// </summary>
+        [JsonPropertyName(""性别"")]
+        public string Gender { get; set; }
+
+        /// <summary>
+        /// 手机
+        /// </summary>
+        [JsonPropertyName(""手机"")]
+        public string Mobile { get; set; }
+
+        /// <summary>
+        /// 现在住址
+        /// </summary>
+        [JsonPropertyName(""现在住址"")]
+        public string CurrentAddress { get; set; }
+
+        /// <summary>
+        /// 在职人员信息
+        /// </summary>
+        [JsonPropertyName(""在职人员信息"")]
+        public EmploymentInfo EmploymentInfo { get; set; }
+
+        /// <summary>
+        /// 关系信息
+        /// </summary>
+        [JsonPropertyName(""关系信息"")]
+        public List<RelationInfo> RelationInfos { get; set; }
+    }
+
+    /// <summary>
+    /// 在职人员信息
+    /// </summary>
+    public class EmploymentInfo
+    {
+        /// <summary>
+        /// 现单位名称
+        /// </summary>
+        [JsonPropertyName(""现单位名称"")]
+        public string CurrentCompanyName { get; set; }
+
+        /// <summary>
+        /// 现单位地址
+        /// </summary>
+        [JsonPropertyName(""现单位地址"")]
+        public string CurrentCompanyAddress { get; set; }
+
+        /// <summary>
+        /// 单位电话
+        /// </summary>
+        [JsonPropertyName(""单位电话"")]
+        public string CompanyPhone { get; set; }
+
+        /// <summary>
+        /// 目前职位
+        /// </summary>
+        [JsonPropertyName(""目前职位"")]
+        public string CurrentPosition { get; set; }
+
+        /// <summary>
+        /// 月收入
+        /// </summary>
+        [JsonPropertyName(""月收入"")]
+        public string MonthlyIncome { get; set; }
+    }
+
+    /// <summary>
+    /// 关系信息
+    /// </summary>
+    public class RelationInfo
+    {
+        /// <summary>
+        /// 关系
+        /// <summary>
+        /// 关系
+        /// </summary>
+        [JsonPropertyName(""关系"")]
+        public string Relation { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        [JsonPropertyName(""姓名"")]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 出生日期
+        /// </summary>
+        [JsonPropertyName(""出生日期"")]
+        public string BirthDate { get; set; }
+
+        /// <summary>
+        /// 地址
+        /// </summary>
+        [JsonPropertyName(""地址"")]
+        public string Address { get; set; }
+
+        /// <summary>
+        /// 联系方式
+        /// </summary>
+        [JsonPropertyName(""联系方式"")]
+        public string ContactNumber { get; set; }
+    }
+
+    /// <summary>
+    /// 新西兰澳大利亚访问记录
+    /// </summary>
+    public class VisitHistory
+    {
+        /// <summary>
+        /// 抵达日期
+        /// </summary>
+        [JsonPropertyName(""抵达日期"")]
+        public string ArrivalDate { get; set; }
+
+        /// <summary>
+        /// 离开日期
+        /// </summary>
+        [JsonPropertyName(""离开日期"")]
+        public string DepartureDate { get; set; }
+    }
+
+    /// <summary>
+    /// 拒签记录
+    /// </summary>
+    public class RejectionRecord
+    {
+        /// <summary>
+        /// 国家
+        /// </summary>
+        [JsonPropertyName(""国家"")]
+        public string Country { get; set; }
+
+        /// <summary>
+        /// 申请日期地点
+        /// </summary>
+        [JsonPropertyName(""申请日期地点"")]
+        public string ApplicationDateLocation { get; set; }
+
+        /// <summary>
+        /// 申请签证类别
+        /// </summary>
+        [JsonPropertyName(""申请签证类别"")]
+        public string VisaCategory { get; set; }
+
+        /// <summary>
+        /// 拒签原因
+        /// </summary>
+        [JsonPropertyName(""拒签原因"")]
+        public string RejectionReason { get; set; }
+    }
+
+    /// <summary>
+    /// 教育经历
+    /// </summary>
+    public class EducationExperience
+    {
+        /// <summary>
+        /// 院校名称
+        /// </summary>
+        [JsonPropertyName(""院校名称"")]
+        public string SchoolName { get; set; }
+
+        /// <summary>
+        /// 入学时间
+        /// </summary>
+        [JsonPropertyName(""入学时间"")]
+        public string EnrollmentDate { get; set; }
+
+        /// <summary>
+        /// 毕业时间
+        /// </summary>
+        [JsonPropertyName(""毕业时间"")]
+        public string GraduationDate { get; set; }
+
+        /// <summary>
+        /// 课程专业名称
+        /// </summary>
+        [JsonPropertyName(""课程专业名称"")]
+        public string CourseName { get; set; }
+    }
+
+    /// <summary>
+    /// 工作经历
+    /// </summary>
+    public class WorkExperience
+    {
+        /// <summary>
+        /// 单位名称
+        /// </summary>
+        [JsonPropertyName(""单位名称"")]
+        public string CompanyName { get; set; }
+
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        [JsonPropertyName(""开始时间"")]
+        public string StartDate { get; set; }
+
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        [JsonPropertyName(""结束时间"")]
+        public string EndDate { get; set; }
+
+        /// <summary>
+        /// 单位所在地
+        /// </summary>
+        [JsonPropertyName(""单位所在地"")]
+        public string CompanyLocation { get; set; }
+
+        /// <summary>
+        /// 职务
+        /// </summary>
+        [JsonPropertyName(""职务"")]
+        public string Position { get; set; }
+    }
+";
+
+            #endregion
+
+            var datas = new List<VisaUploadFileTypeView>() {
+                new(){FileId = 1,FileName="澳新签证个人申请表",
+                    //KimiAITips = $"按照标题识别成json格式,其中json属性名称为中文。第一行“其他国家”文本值为string。表头及本人声明不参与识别。按照C#中的System.Text.Json可解析的格式生成。不要除JSON数据外的任何文字以及符号。该段json格式文本为压缩格式json字符串。" },
+                    KimiAITips = $"请将上传的文件内容识别为JSON格式,并按照以下指定的实体类结构进行映射。确保生成的JSON格式与实体类的属性名称和类型一致。\r\n**实体类定义**:\r\n```csharp\r\n{json1}\r\n在不影响数据完整性的前提下,该格式为压缩后的json字符串。不要除JSON数据外的任何文字以及符号。" },
+                new(){FileId = 2,FileName="出国个人申请表" },
+                new(){FileId = 3,FileName="美国签证个人申请表格" },
+                new(){FileId = 4,FileName="沙特个人信息表格" },
+                new(){FileId = 5,FileName="申根签证个人资料表" },
+                new(){FileId = 6,FileName="中文个人简历模板" },
+            };
+            return datas;
+        }
+    }
+
+
     #region 新西兰、澳大利亚签证申请资料表
     public class VisaApplication
     {
@@ -131,7 +476,7 @@ namespace OASystem.Domain.ViewModels.CRM
         /// 新西兰澳大利亚访问记录
         /// </summary>
         [JsonPropertyName("新西兰澳大利亚访问记录")]
-        public VisitHistory VisitHistory { get; set; }
+        public List<VisitHistory> VisitHistory { get; set; }
 
         /// <summary>
         /// 拒签记录
@@ -152,16 +497,11 @@ namespace OASystem.Domain.ViewModels.CRM
         public List<WorkExperience> WorkExperiences { get; set; }
 
         /// <summary>
-        /// 服兵役历史
+        /// 服兵役历史(识别成一段话)
         /// </summary>
         [JsonPropertyName("服兵役历史")]
-        public List<MilitaryService> MilitaryServices { get; set; }
+        public string MilitaryServices { get; set; }
 
-        /// <summary>
-        /// 本人声明
-        /// </summary>
-        [JsonPropertyName("本人声明")]
-        public string Declaration { get; set; }
     }
 
     /// <summary>
@@ -308,30 +648,6 @@ namespace OASystem.Domain.ViewModels.CRM
     /// 新西兰澳大利亚访问记录
     /// </summary>
     public class VisitHistory
-    {
-        /// <summary>
-        /// 第一次访问记录
-        /// </summary>
-        [JsonPropertyName("第一次")]
-        public Visit FirstVisit { get; set; }
-
-        /// <summary>
-        /// 第二次访问记录
-        /// </summary>
-        [JsonPropertyName("第二次")]
-        public Visit SecondVisit { get; set; }
-
-        /// <summary>
-        /// 第三次访问记录
-        /// </summary>
-        [JsonPropertyName("第三次")]
-        public Visit ThirdVisit { get; set; }
-    }
-
-    /// <summary>
-    /// 访问记录
-    /// </summary>
-    public class Visit
     {
         /// <summary>
         /// 抵达日期
@@ -442,36 +758,6 @@ namespace OASystem.Domain.ViewModels.CRM
         public string Position { get; set; }
     }
 
-    /// <summary>
-    /// 服兵役历史
-    /// </summary>
-    public class MilitaryService
-    {
-        /// <summary>
-        /// 军衔
-        /// </summary>
-        [JsonPropertyName("军衔")]
-        public string Rank { get; set; }
-
-        /// <summary>
-        /// 所属部队
-        /// </summary>
-        [JsonPropertyName("所属部队")]
-        public string Unit { get; set; }
-
-        /// <summary>
-        /// 军种
-        /// </summary>
-        [JsonPropertyName("军种")]
-        public string Branch { get; set; }
-
-        /// <summary>
-        /// 服役时间
-        /// </summary>
-        [JsonPropertyName("服役时间")]
-        public string ServiceDate { get; set; }
-    }
-
     #endregion
 
 

+ 192 - 0
OASystem/OASystem.Domain/ViewModels/Resource/CountryFeeCostView.cs

@@ -1,4 +1,5 @@
 using OASystem.Domain.Entities.Resource;
+using System;
 
 namespace OASystem.Domain.ViewModels.Resource
 {
@@ -20,4 +21,195 @@ namespace OASystem.Domain.ViewModels.Resource
             }
         }
     }
+
+
+    /// <summary>
+    /// 省份签证费用详情
+    /// </summary>
+    public class VisaFeeStandardDetails
+    {
+        public int Id { get; set; }
+
+        /// <summary>
+        /// 签证费用表Id(Res_VisaFeeStandard)
+        /// </summary>
+        public int ParentId { get; set; }
+
+        /// <summary>
+        /// 签证费用归属省份Id(Sys_Cities)
+        /// </summary>
+        public int ProvinceId { get; set; }
+
+        /// <summary>
+        /// 省份名称
+        /// </summary>
+        public string ProvinceName { get; set; }
+
+        /// <summary>
+        /// 送签地址
+        /// </summary>
+        public string VisaAddress { get; set; } 
+
+        /// <summary>
+        /// 是否落地签
+        /// </summary>
+        public bool IsVisaOnArrival { get; set; } = false;
+
+        /// <summary>
+        /// 是否电子签
+        /// </summary>
+        public bool IsElectronicSign { get; set; } = false;
+
+        /// <summary>
+        /// 签证时间(工作日)
+        /// </summary>
+        public string VisaTime { get; set; }
+
+        /// <summary>
+        ///  是否免签(大公务)
+        /// </summary>
+        public bool IsVisaExemptionLarge { get; set; } = false;
+
+        /// <summary>
+        /// 签证费用(大公务)
+        /// </summary>
+        public decimal LargeVisaPrice { get; set; }
+
+        /// <summary>
+        /// 代办费(大公务)
+        /// </summary>
+        public decimal LargeAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        ///  是否免签(小公务)
+        /// </summary>
+        public bool IsVisaExemptionSmall { get; set; } = false;
+
+        /// <summary>
+        /// 签证费用(小公务)
+        /// </summary>
+        public decimal SmallVisaPrice { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 代办费(小公务)
+        /// </summary>
+        public decimal SmallAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        ///  外办费用(普通)
+        /// </summary>
+        public decimal NormExtFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 外办费用(加急)
+        /// </summary>
+        public decimal UrgExtFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 签证是否加急
+        /// </summary>
+        public bool IsUrgent { get; set; } = false;
+
+        /// <summary>
+        /// 加急时间(工作日)
+        /// </summary>
+        public string UrgentTime { get; set; }
+
+        /// <summary>
+        /// 加急费用
+        /// </summary>
+        public decimal UrgentPrice { get; set; }
+
+        /// <summary>
+        /// 加急费用描述 
+        /// </summary>
+        public string UrgentPriceDesc { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        public string Remark { get; set; }
+
+        public VisaFeeStandardDetails() { }
+
+        /// <summary>
+        /// 按照指定的省份排序
+        /// </summary>
+        /// <param name="people">数据源</param>
+        /// <param name="specifiedOrder">省份排序集合</param>
+        /// <returns></returns>
+        public static List<VisaFeeStandardDetails> SortByProvinces(List<VisaFeeStandardDetails> people, List<string> specifiedOrder)
+        {
+            return people
+                .OrderBy(person => specifiedOrder.IndexOf(person.ProvinceName))
+                .ThenBy(person => person.ProvinceId) // 对未指定的省份按Id顺序排序
+                .ToList();
+        }
+    }
+
+    /// <summary>
+    /// 签证info
+    /// </summary>
+    public class VisaFeeStandardInfo
+    {
+        /// <summary>
+        /// Id
+        /// </summary>
+        public int Id { get; set; }
+
+        /// <summary>
+        /// 洲名
+        /// </summary>
+        public string Continent { get; set; }
+
+        /// <summary>
+        /// 国家名
+        /// </summary>
+        public string Country { get; set; }
+
+        /// <summary>
+        /// 签证费用类型 0 因公 1 因私
+        /// </summary>
+        public int FeeType { get; set; } = 0;
+
+    }
+
+    /// <summary>
+    /// 签证info View
+    /// </summary>
+    public class VisaFeeStandardInfoView : VisaFeeStandardInfo
+    {
+        /// <summary>
+        /// 省份签证费用集合
+        /// </summary>
+        public List<VisaFeeStandardDetails> VisaFees { get; set; }
+    }
+
+    public class VisaFeeStandardListView : VisaFeeStandardInfo
+    {
+        /// <summary>
+        /// 省份签证费用集合
+        /// </summary>
+        public List<VisaFeeStandardDetails> VisaFees { get; set; }
+        /// <summary>
+        /// 最后更新人
+        /// </summary>
+        public string LastUpdateUserName { get; set; }
+
+        /// <summary>
+        /// 最后更新时间
+        /// </summary>
+        public DateTime LastUpdateTime { get; set; }
+
+        /// <summary>
+        /// 距今更新天数
+        /// </summary>
+        public int DaysSinceUpdate
+        {
+            get
+            {
+                return (DateTime.Now - LastUpdateTime).Days;
+            }
+        }
+    }
 }

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

@@ -434,7 +434,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                         if (dto.DiId == 2590)
                         {
                             bool isAuto = false;
-                            var spPriceName = dto.PriceName.Split('-').ToArray();
+                            string[] spPriceName = dto.PriceName.Split('-').ToArray();
                             var expression = Expressionable.Create<Grp_GamesBudgetMaster>()
                                                             .And(x => x.IsDel == 0);
 
@@ -492,7 +492,6 @@ namespace OASystem.Infrastructure.Repositories.Groups
                                         {
                                             isAuto = true;
                                         }
-
                                     }
                                 }
                             }

+ 42 - 60
OASystem/OASystem.Infrastructure/Repositories/Groups/VisaFeeInfoRepository.cs

@@ -5,12 +5,6 @@ using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.Entities.Resource;
 using OASystem.Domain.ViewModels.Groups;
 using OASystem.Infrastructure.Repositories.Resource;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
 namespace OASystem.Infrastructure.Repositories.Groups
 {
     /// <summary>
@@ -40,7 +34,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// <param name="portType"></param>
         /// <param name="diId"></param>
         /// <returns></returns>
-        public async Task<Result> _Init()
+        public async Task<Result> Init()
         {
             var data = await _sqlSugar.Queryable<Res_CountryFeeCost>().Where(it => it.IsDel == 0).ToListAsync();
             _result.Code = 0;
@@ -56,10 +50,10 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// <param name="portType"></param>
         /// <param name="diId"></param>
         /// <returns></returns>
-        public async Task<Result> _List(int portType, int diId)
+        public async Task<JsonView> List(int portType, int diId)
         {
-            if (diId < 0) return _result = new Result() { Code = -1, Msg = "请传入有效的DiId参数" };
-            if (portType < 1  || portType > 3) return _result = new Result() { Code = -1, Msg = "请传入有效的portType参数" };
+            if (diId < 0) return new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "请传入有效的DiId参数" };
+            if (portType < 1  || portType > 3) return new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "请传入有效的portType参数" };
 
             string sql = string.Format($@"Select vfi.Id,vfi.IsChecked,cfc.VisaCountry AS Country,cfc.VisaPrice As VisaFee,
                                           vfi.OBType,vfi.AgencyFee,vfi.OtherFee,vfi.Remark 
@@ -72,18 +66,20 @@ namespace OASystem.Infrastructure.Repositories.Groups
             if (data.Count == 0)
             {
                 var groupInfo = await _groupRep.PostShareGroupInfo(new ShareGroupInfoDto() { PortType = 1, Id = diId });
-                List<string> countrys = new List<string>();
-                if (groupInfo.Code == 200)
+
+                if (groupInfo.Code != 200)
                 {
-                    countrys = _groupRep.GroupSplitCountry((groupInfo.Data as Web_ShareGroupInfoView)?.VisitCountry ?? "");
+                    return new JsonView() { Code = StatusCodes.Status200OK, Data = data, Msg = "团组信息不存在!" };
                 }
 
+                var countrys = _groupRep.GroupSplitCountry((groupInfo.Data as Web_ShareGroupInfoView)?.VisitCountry ?? "");
+
                 if (countrys.Any())
                 {
                     //int dataRow = 0;
                     foreach (var country in countrys)
                     {
-                        var countryInfo = _sqlSugar.Queryable<Res_CountryFeeCost>().Where(it => it.IsDel == 0 && it.VisaCountry.Equals(country)).First();
+                        var countryInfo = await _sqlSugar.Queryable<Res_CountryFeeCost>().Where(it => it.IsDel == 0 && it.VisaCountry.Equals(country)).FirstAsync();
                         if (countryInfo != null)
                         {
                             data.Add(new VisaFeeInfosView()
@@ -122,47 +118,33 @@ namespace OASystem.Infrastructure.Repositories.Groups
                         }
                     }
 
-                    if (data.Count < 10)
-                    {
-                        int defaultRow = 10 - data.Count;
-                        for (int i = 0; i < defaultRow; i++)
-                        {
-                            data.Add(new VisaFeeInfosView()
-                            {
-                                Id = 0,
-                                OBType = 1
-                            });
-                        }
-                    }
+                    AddDefaultRows(data, 10);
                 }
                 else
                 {
-                    for (int i = 0; i < 10; i++)
-                    {
-                        data.Add(new VisaFeeInfosView()
-                        {
-                            Id = 0,
-                            OBType = 1
-                        });
-                    }
+                    AddDefaultRows(data, 10);
                 }
             }
             else if (data.Count <= 10)
             {
-                int defaultRow = 10 - data.Count;
-                for (int i = 0; i < defaultRow; i++)
-                {
-                    data.Add(new VisaFeeInfosView()
-                    {
-                        Id = 0,
-                        OBType = 1
-                    });
-                }
+                AddDefaultRows(data, 10);
+            }
+
+            return new JsonView() { Code = StatusCodes.Status200OK, Data =data, Msg = "请传入有效的DiId参数" };
+        }
+
+        /// <summary>
+        /// 补齐默认行
+        /// </summary>
+        /// <param name="list"></param>
+        /// <param name="totalRows"></param>
+        private void AddDefaultRows(List<VisaFeeInfosView> list, int totalRows)
+        {
+            int defaultRow = totalRows - list.Count;
+            for (int i = 0; i < defaultRow; i++)
+            {
+                list.Add(new VisaFeeInfosView { Id = 0, OBType = 1 });
             }
-            _result.Code = 0;
-            _result.Data = data;
-            _result.Msg = "操作成功!";
-            return _result;
         }
 
         /// <summary>
@@ -170,12 +152,12 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        public async Task<Result> _Update(VisaFeeAddAndUpdateDto dto)
+        public async Task<Result> Update(VisaFeeAddAndUpdateDto dto)
         {
             if (dto.VisaFeeInfos.Count  < 1) return _result = new Result() { Code = -1, Msg = "请传入有效的签证费用集合参数" };
             if (dto.PortType < 1 || dto.PortType > 3) return _result = new Result() { Code = -1, Msg = "请传入有效的portType参数" };
 
-            List<Grp_VisaFeeInfo> visaInfos = new List<Grp_VisaFeeInfo>();
+            var visaInfos = new List<Grp_VisaFeeInfo>();
 
             BeginTran();
             //bool visaFeeUpdate = false;
@@ -215,7 +197,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                     countryVisaFeeId = info.Id;
                     if (_visaFee != info.VisaPrice) //价格不同的时候执行修改
                     {
-                        Res_CountryFeeCost _CountryFeeCost = new Res_CountryFeeCost()
+                        var _CountryFeeCost = new Res_CountryFeeCost()
                         {
                             Id = info.Id,
                             VisaPrice = _visaFee,
@@ -281,7 +263,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
             List<int> ids = visaData.Select (it => it.CountryVisaFeeId).ToList();
             var visaCountryDatas = await _sqlSugar.Queryable<Res_CountryFeeCost>().Where(it => ids.Contains(it.Id)).ToListAsync();
 
-            List<dynamic> datas = new List<dynamic>();
+            var datas = new List<dynamic>();
             string remark = "";
             decimal feeTotal = 0.00M;
 
@@ -300,14 +282,14 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 decimal _GrandBusinessAgencyFee = 0;
                 decimal _PettyBusinessAgencyFee = 0;
                 
-                string remark1 = $"签证费:{_visaFee.ToString("#0.00")}元、";
+                string remark1 = $"签证费:{_visaFee:#0.00}元、";
                 foreach (var item in kvp.ToList())
                 {
                     if (item.OBType == 1)
                     {
                         if (item.AgencyFee > 0)
                         {
-                            remark1 += $@"大公务代办费:{item.AgencyFee.ToString("#0.00")}元、";
+                            remark1 += $@"大公务代办费:{item.AgencyFee:#0.00}元、";
                             _agencyFee += item.AgencyFee;
                             _GrandBusinessAgencyFee = item.AgencyFee * priceCoeff;
                         }
@@ -324,7 +306,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 }
                 if (remark1.Length > 0) remark1 = remark1.Substring(0, remark1.Length - 1);
 
-                if (_otherFee > 0) remark1 += $@"其他费用:{_otherFee.ToString("#0.00")}元";
+                if (_otherFee > 0) remark1 += $@"其他费用:{_otherFee:#0.00}元";
 
                 visaFeeTotal += (_GrandBusinessAgencyFee + _PettyBusinessAgencyFee);
                 remark += $@"{countryData?.VisaCountry ?? ""}:签证总费用:{visaFeeTotal}元/人 其中({remark1});";
@@ -334,7 +316,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 datas.Add(new
                 {
                     Country = countryData?.VisaCountry ?? "",
-                    visaFeeTotal = visaFeeTotal,
+                    visaFeeTotal,
                     VisaFee = countryData?.VisaPrice ?? 0.00M,
                     GrandBusinessAgencyFee = _GrandBusinessAgencyFee,
                     PettyBusinessAgencyFee = _PettyBusinessAgencyFee,
@@ -344,9 +326,9 @@ namespace OASystem.Infrastructure.Repositories.Groups
 
             _result.Code = 0;
             _result.Data = new { 
-                feeTotal = feeTotal,
+                feeTotal,
                 data = datas,
-                remark = remark
+                remark
             };
 
             return _result;
@@ -382,16 +364,16 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 decimal gbAgencyFee = kvp.GrandBusinessAgencyFee;
                 decimal pbAgencyFee = kvp.PettyBusinessAgencyFee;
 
-                string remark1 = $"签证费:{visaFee.ToString("#0.00")}元、";
+                string remark1 = $"签证费:{visaFee:#0.00}元、";
                 if (gbAgencyFee > 0.00M)
                 {
-                    remark1 += $@"大公务代办费:{gbAgencyFee.ToString("#0.00")}元、";
+                    remark1 += $@"大公务代办费:{gbAgencyFee:#0.00}元、";
                     gbAgencyFee *=  priceCoeff;
                 }
 
                 if (pbAgencyFee > 0.00M)
                 {
-                    remark1 += $@"小公务代办费:{pbAgencyFee.ToString("#0.00")}元、";
+                    remark1 += $@"小公务代办费:{pbAgencyFee:#0.00}元、";
                     pbAgencyFee *= priceCoeff;
                 }
 

+ 278 - 0
OASystem/OASystem.Infrastructure/Repositories/Resource/CountryFeeRepository.cs

@@ -1,4 +1,5 @@
 using AutoMapper;
+using MathNet.Numerics.Distributions;
 using OASystem.Domain.Dtos.Resource;
 using OASystem.Domain.Entities.Resource;
 using OASystem.Domain.ViewModels.Resource;
@@ -77,5 +78,282 @@ namespace OASystem.Infrastructure.Repositories.Resource
 
             return result;
         }
+
+
+        #region New
+
+        /// <summary>
+        /// Page List Async
+        /// </summary>
+        /// <param name="pageIndex"></param>
+        /// <param name="pageSize"></param>
+        /// <param name="feeType"></param>
+        /// <param name="countryName"></param>
+        /// <returns></returns>
+        public async Task<JsonView> PageListAsync(VisaFeeStandardListDto dto)
+        {
+            int pageIndex = dto.PageIndex <= 0 ? 1 : dto.PageIndex;
+            int pageSize = dto.PageSize <= 0 ? 10 : dto.PageSize;
+            int feeType = dto.VisaFeeType < 0 ? -1 : dto.VisaFeeType; // -1:全部 0:因公 1:因私
+            string countryName = dto.CountryName?.Trim() ?? string.Empty;
+
+            var query = _sqlSugar.Queryable<Res_VisaFeeStandard>()
+                .LeftJoin<Sys_Users>((x, y) => x.LastUpdateUserId == y.Id)
+                .Where((x, y) => x.IsDel == 0 && x.FeeType == feeType)
+                .WhereIF(!string.IsNullOrEmpty(countryName), x => x.Country.Contains(countryName) || countryName.Contains(x.Country))
+                .OrderByDescending((x, y) => x.LastUpdateTime)
+                .Select((x, y) => new VisaFeeStandardListView
+                {
+                    Id = x.Id,
+                    Continent = x.Continent,
+                    Country = x.Country,
+                    FeeType = x.FeeType,
+                    LastUpdateUserName = y.CnName,
+                    LastUpdateTime = x.LastUpdateTime
+                });
+
+            RefAsync<int> total = 0;
+            var pageList = await query.ToPageListAsync(pageIndex, pageSize, total);
+
+            if (!pageList.Any())
+            {
+                return new JsonView
+                {
+                    Code = StatusCodes.Status200OK,
+                    Data = pageList,
+                    Count = total,
+                    Msg = "暂无数据!"
+                };
+            }
+
+            var ids = pageList.Select(x => x.Id).ToList();
+            var detailsList = await _sqlSugar.Queryable<Res_VisaFeeStandardDetails>()
+                .Where(x => x.IsDel == 0 && ids.Contains(x.ParentId))
+                .ToListAsync();
+
+            var mappedDetails = _mapper.Map<List<VisaFeeStandardDetails>>(detailsList);
+            var specifiedOrder = new List<string> { "四川", "重庆", "贵州", "云南" };
+
+            foreach (var item in pageList)
+            {
+                var provinceDetails = mappedDetails.Where(x => x.ParentId == item.Id).ToList();
+                if (provinceDetails.Any())
+                    provinceDetails = VisaFeeStandardDetails.SortByProvinces(provinceDetails, specifiedOrder);
+                item.VisaFees = provinceDetails;
+            }
+
+            return new JsonView
+            {
+                Code = StatusCodes.Status200OK,
+                Data = pageList,
+                Count = total,
+                Msg = "操作成功!"
+            };
+        }
+
+        /// <summary>
+        /// info Async
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task<JsonView> InfoAsync(int id)
+        {
+            var view = await Query<Res_VisaFeeStandard>(x => x.Id == id)
+                .Select(x => new VisaFeeStandardInfoView()
+                {
+                    Id = x.Id,
+                    Continent = x.Continent,
+                    Country = x.Country,
+                    FeeType = x.FeeType,
+                })
+                .FirstAsync();
+            if (view == null)
+            {
+                return new JsonView
+                {
+                    Code = StatusCodes.Status200OK,
+                    Msg = "暂无数据!",
+                    Data = view
+                };
+            }
+
+            var detailsList = await _sqlSugar.Queryable<Res_VisaFeeStandardDetails>()
+                .LeftJoin<Sys_Cities>((x, y) => x.ProvinceId == y.Id && y.Level == 1)
+                .Select((x, y) => new VisaFeeStandardDetails {
+                    Id = x.Id,
+                    ParentId = x.ParentId,
+                    ProvinceId = x.ProvinceId,
+                    ProvinceName = y.Name_EN,
+                    VisaAddress = x.VisaAddress,
+                    IsVisaOnArrival = x.IsVisaOnArrival,
+                    IsElectronicSign = x.IsElectronicSign,
+                    VisaTime = x.VisaTime,
+                    IsVisaExemptionLarge = x.IsVisaExemptionLarge,
+                    LargeVisaPrice = x.LargeVisaPrice,
+                    LargeAgencyFee = x.LargeAgencyFee,
+                    IsVisaExemptionSmall = x.IsVisaExemptionSmall,
+                    SmallVisaPrice = x.SmallVisaPrice,
+                    SmallAgencyFee = x.SmallAgencyFee,
+                    NormExtFee = x.NormExtFee,
+                    UrgExtFee = x.UrgExtFee,
+                    IsUrgent = x.IsUrgent,
+                    UrgentTime = x.UrgentTime,
+                    UrgentPrice = x.UrgentPrice,
+                    UrgentPriceDesc = x.UrgentPriceDesc,
+                    Remark = y.Remark,
+                })
+                .ToListAsync();
+
+            // 指定的省份顺序
+            var specifiedOrder = new List<string> { "四川", "重庆", "贵州", "云南" };
+            if (detailsList.Any()) 
+                detailsList = VisaFeeStandardDetails.SortByProvinces(detailsList, specifiedOrder);
+
+            view.VisaFees = detailsList;
+
+            return new JsonView
+            {
+                Code = StatusCodes.Status200OK,
+                Msg = "操作成功!",
+                Data = view
+            };
+        }
+
+        /// <summary>
+        /// Save Async
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task<JsonView> SaveAsync(VisaFeeStandardSaveDto dto)
+        {
+            var now = DateTime.Now;
+            var standardInfo = _mapper.Map<Res_VisaFeeStandard>(dto);
+            standardInfo.LastUpdateTime = now;
+            standardInfo.LastUpdateUserId = dto.CurrUserId;
+            standardInfo.CreateTime = now;
+            standardInfo.CreateUserId = dto.CurrUserId;
+
+            // 指定的省份顺序
+            var specifiedOrder = new List<string> { "四川", "重庆", "贵州", "云南" };
+            if (dto.VisaFees.Any())
+                dto.VisaFees = VisaFeeStandardDetails.SortByProvinces(dto.VisaFees, specifiedOrder);
+
+            var standardDetails = _mapper.Map<List<Res_VisaFeeStandardDetails>>(dto.VisaFees);
+            standardDetails.ForEach(x =>
+            {
+                x.CreateUserId = dto.CurrUserId;
+                x.CreateTime = now;
+            });
+
+            string msg = string.Empty;
+            _sqlSugar.BeginTran();
+            try
+            {
+                if (standardInfo.Id < 1) // 添加
+                {
+                    var insertId = await _sqlSugar.Insertable(standardInfo).ExecuteReturnIdentityAsync();
+                    if (insertId < 1)
+                    {
+                        _sqlSugar.RollbackTran();
+                        return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = "添加失败!" };
+                    }
+
+                    standardDetails.ForEach(x => x.ParentId = insertId);
+                    var detailsResult = await _sqlSugar.Insertable(standardDetails).ExecuteCommandAsync();
+                    if (detailsResult < 1)
+                    {
+                        _sqlSugar.RollbackTran();
+                        return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = "添加失败!" };
+                    }
+                    msg = "添加成功!";
+                }
+                else // 修改
+                {
+                    var updStatus = await _sqlSugar.Updateable(standardInfo)
+                        .IgnoreColumns(x => new { x.IsDel, x.CreateUserId, x.CreateTime, x.DeleteUserId, x.DeleteTime })
+                        .ExecuteCommandAsync();
+
+                    if (updStatus < 1)
+                    {
+                        _sqlSugar.RollbackTran();
+                        return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = "修改失败!" };
+                    }
+
+                    await _sqlSugar.Deleteable<Res_VisaFeeStandardDetails>()
+                        .Where(x => x.ParentId == standardInfo.Id)
+                        .ExecuteCommandAsync();
+
+                    standardDetails.ForEach(x => x.ParentId = standardInfo.Id);
+                    var detailsResult = await _sqlSugar.Insertable(standardDetails).ExecuteCommandAsync();
+                    if (detailsResult < 1)
+                    {
+                        _sqlSugar.RollbackTran();
+                        return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = "修改失败!" };
+                    }
+                    msg = "修改成功!";
+                }
+
+                _sqlSugar.CommitTran();
+                return new JsonView { Code = StatusCodes.Status200OK, Msg = msg };
+            }
+            catch(Exception ex)
+            {
+                _sqlSugar.RollbackTran();
+                msg = ex.Message;
+            }
+            return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = msg };
+        }
+
+        /// <summary>
+        /// SoftDel Async
+        /// </summary>
+        /// <param name="userId"></param>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task<JsonView> SoftDelAsync(int userId, int id)
+        {
+            _sqlSugar.BeginTran();
+            try
+            {
+                var nowString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+                // 主表软删除
+                var delStatus = await _sqlSugar.Updateable<Res_VisaFeeStandard>()
+                    .SetColumns(x => x.DeleteUserId == userId)
+                    .SetColumns(x => x.DeleteTime == nowString)
+                    .SetColumns(x => x.IsDel == 1)
+                    .Where(x => x.Id == id)
+                    .ExecuteCommandAsync();
+                if (delStatus < 1)
+                {
+                    _sqlSugar.RollbackTran();
+                    return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = "删除失败!" };
+                }
+
+                // 子表软删除
+                var detailsDelStatus = await _sqlSugar.Updateable<Res_VisaFeeStandardDetails>()
+                    .SetColumns(x => x.DeleteUserId == userId)
+                    .SetColumns(x => x.DeleteTime == nowString)
+                    .SetColumns(x => x.IsDel == 1)
+                    .Where(x => x.ParentId == id)
+                    .ExecuteCommandAsync();
+
+                if (detailsDelStatus < 1)
+                {
+                    _sqlSugar.RollbackTran();
+                    return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = "删除失败!" };
+                }
+
+                _sqlSugar.CommitTran();
+                return new JsonView { Code = StatusCodes.Status200OK, Msg = "操作成功!" };
+            }
+            catch (Exception ex)
+            {
+                _sqlSugar.RollbackTran();
+                return new JsonView { Code = StatusCodes.Status400BadRequest, Msg = ex.Message };
+            }
+        }
+
+
+        #endregion
     }
 }