瀏覽代碼

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

yuanrf 1 天之前
父節點
當前提交
cb01d53e92

+ 10 - 3
OASystem/OASystem.Api/Controllers/AuthController.cs

@@ -43,10 +43,17 @@ namespace OASystem.API.Controllers
         /// <param name="messageRep"></param>
         /// <param name="deviceRep"></param>
         /// <param name="hubContext"></param>
-        public AuthController(IConfiguration config, LoginRepository loginRep, IMapper mapper, MessageRepository message,
-            SystemMenuPermissionRepository sysMenuPermRep, IQiYeWeChatApiService qiYeWeChatApiService, MessageRepository messageRep,
+        public AuthController(
+            IConfiguration config, 
+            LoginRepository loginRep, 
+            IMapper mapper, 
+            MessageRepository message,
+            SystemMenuPermissionRepository sysMenuPermRep, 
+            IQiYeWeChatApiService qiYeWeChatApiService, 
+            MessageRepository messageRep,
             DeviceTokenRepository deviceRep,
-            IHubContext<ChatHub, IChatClient> hubContext)
+            IHubContext<ChatHub, 
+                IChatClient> hubContext)
         {
             _config = config;
             _loginRep = loginRep;

+ 91 - 4
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -26,6 +26,7 @@ using OASystem.Domain.Dtos.Groups;
 using OASystem.Domain.Entities.Customer;
 using OASystem.Domain.Entities.Financial;
 using OASystem.Domain.Entities.Groups;
+using OASystem.Domain.ViewModels.CRM;
 using OASystem.Domain.ViewModels.Financial;
 using OASystem.Domain.ViewModels.Groups;
 using OASystem.Domain.ViewModels.OCR;
@@ -39,6 +40,7 @@ using System.Data;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO.Compression;
+using System.Text.Json;
 using System.Web;
 using static OASystem.API.OAMethodLib.JWTHelper;
 using static OASystem.Infrastructure.Repositories.Groups.AirTicketResRepository;
@@ -2251,7 +2253,7 @@ FROM
                 .LeftJoin<Crm_DeleClient>((x, s, dc) => x.ClientId == dc.Id && dc.IsDel == 0)
                 .LeftJoin<Crm_CustomerCompany>((x, s, dc, cc) => dc.CrmCompanyId == cc.Id && cc.IsDel == 0)
                 .Where((x, s, dc, cc) => x.DiId == dto.GroupId && x.IsDel == 0)
-                .Select((x, s, dc, cc) => new groupClints
+                .Select((x, s, dc, cc) => new GroupClints
                 {
                     Id = x.Id,
                     Name = s.Name,
@@ -2745,18 +2747,103 @@ FROM
         /// <returns></returns>
         [HttpPost]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        public async Task<IActionResult> VisaFileUploadAndUpdate(FormFile file)
+        public async Task<IActionResult> VisaFileUploadAndUpdate(IFormFile file,int fileTypeId)
         {
             //文件验证
-            if (file.Length < 1)
+            if (file.Length < 1) return Ok(JsonView(false,"请选择文件!"));
+            
+            var visaFiles = new VisaUploadFileTypeView();
+            var filetypes = visaFiles.GetVisaUploadFileTypeViewItemInit();
+            if (!filetypes.Any(x => x.FileId == fileTypeId)) return Ok(JsonView(false, "请选择文件类型!"));
+
+            //服务器存储文件
+            var fileServerPath = $"D:/FTP/File/OA2023/Office/Word/VisaClientData/Uploads";
+            if (!Directory.Exists(fileServerPath)) Directory.CreateDirectory(fileServerPath);
+            var filePath = Path.Combine(fileServerPath, file.FileName);
+            using (var stream = new FileStream(filePath, FileMode.Create))
             {
+                await file.CopyToAsync(stream);
+            }
+            //日志记录-上传文件
+            _logger.LogInformation("【签证上传文件操作信息】签证文件存储成功!路径:{fileServerPath} 文件名称:{fileName}", fileServerPath, file.FileName);
+
+            //kimi AI 识别文档返回json结果
+            int kimiAI_API_Index = 0; //KIMI-AI-API 访问计次
+            var KiMiApi = new KiMiApiClient();
+            var files = new List<IFormFile>() { file };
+            var seedConter = await KiMiApi.UploadFilesAsync(files);
+
+            if (seedConter.Count == 0) return Ok(JsonView(false, "Kimi AI 文件上传结果为空!"));
+
+            var seedMessage = filetypes.Where(x => x.FileId == fileTypeId).FirstOrDefault()?.KimiAITips;
+            var messages = new List<SeedMessages>
+            {
+                new()  { Role = KimiRole.system, Content = "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长识别文件为Json格式的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。" },
+                new()  { Role = KimiRole.user, Content = seedMessage }
+            };
+            messages.InsertRange(1, seedConter);
 
+            string jsonString = string.Empty;
+            bool isJson = false; // 是否是json格式 不是json格式继续访问AI
+            while (!isJson)
+            {
+                kimiAI_API_Index++;
+                var kimiApiResult = await KiMiApi.SeedMessage(messages);
+                var kimiApiResult_JObject = JObject.Parse(kimiApiResult);
+                jsonString += kimiApiResult_JObject["content"].ToString();
+
+                string startStr = "```json", endStr = "```";
+
+                // 判断并清除开头部分
+                if (jsonString.StartsWith(startStr))
+                {
+                    jsonString = jsonString.Remove(0, startStr.Length);
+                }
+
+                // 判断并清除结尾部分
+                if (jsonString.EndsWith(endStr))
+                {
+                    jsonString = jsonString.Replace(endStr, "");
+                }
+
+                //验证json格式是否正确
+                try
+                {
+                    JsonDocument.Parse(jsonString);
+                    isJson = true; // 如果解析成功,则是json格式
+                }
+                catch (Exception)
+                {
+                    //messages = new List<SeedMessages>() { new() { Role = KimiRole.user, Content = "接着说" } };
+                    messages.Add(new() { Role = KimiRole.user, Content = "接着上一个话题继续完成未完成的内容。" });
+                }
             }
 
 
+            var clientInfo = new Crm_DeleClient();            //客户资料表
+            var clientFamily = new Crm_VisaCustomerFamily();  //客户家庭表
+            var clientCompany = new Crm_CustomerCompany();    //客户公司表
+            var clientCert = new Crm_CustomerCert();          //客户证件表
+            var clientSchool = new Crm_VisaCustomerSchool();  //客户学历表
+
+            //按照表格类型分别进行参数处理
+            switch (fileTypeId) {
+                //澳新签证个人申请表
+                case 1:
 
+                    _logger.LogInformation("【签证上传文件操作信息】【澳新签证个人申请表】【KIMI-AI-API访问计次】{count} 次", kimiAI_API_Index);
+                    VisaApplication resInfo = System.Text.Json.JsonSerializer.Deserialize<VisaApplication>(jsonString);
 
-            return Ok(JsonView(true));
+                    break;
+                default:
+
+                    break;
+            
+            }
+
+
+
+            return Ok(JsonView(true, jsonString));
         }
 
 

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

@@ -1,7 +1,6 @@
 using Aspose.Cells;
 using Aspose.Words;
 using EyeSoft.Extensions;
-using NPOI.SS.Formula.PTG;
 using OASystem.API.OAMethodLib;
 using OASystem.API.OAMethodLib.QiYeWeChatAPI.AppNotice;
 using OASystem.Domain.AesEncryption;
@@ -9,11 +8,9 @@ using OASystem.Domain.Dtos.Groups;
 using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.ViewModels.Groups;
 using OASystem.Infrastructure.Repositories.Groups;
-using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.Data;
 using System.Diagnostics;
-using System.Linq;
 using static OASystem.API.OAMethodLib.JWTHelper;
 
 namespace OASystem.API.Controllers
@@ -806,31 +803,47 @@ namespace OASystem.API.Controllers
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> QueryCountryFeeCost(DtoBase dto)
         {
+            var portType = dto.PortType;
+            var countryVisaFees = await _countryFeeRep
+                .QueryDto<Res_CountryFeeCost, CountryFeeCostView>()
+                .OrderByDescending(x => x.CreateTime)
+                .ToListAsync();
 
-            if (dto.PortType == 1)
-            {
-                var CountryFee = _countryFeeRep.QueryDto<Res_CountryFeeCost, CountryFeeCostView>().ToList();
-                if (CountryFee.Count == 0)
-                {
-                    return Ok(JsonView(false, "暂无数据!"));
-                }
-                CountryFee = CountryFee.OrderByDescending(s => s.CreateTime).ToList();
-                return Ok(JsonView(true, "查询成功", CountryFee));
-            }
-            else if (dto.PortType == 2)
-            {
-                var CountryFee = _countryFeeRep.QueryDto<Res_CountryFeeCost, CountryFeeCostView>().ToList();
-                if (CountryFee.Count == 0)
-                {
-                    return Ok(JsonView(false, "暂无数据!"));
-                }
-                CountryFee = CountryFee.OrderByDescending(s => s.CreateTime).ToList();
-                return Ok(JsonView(true, "查询成功", CountryFee));
-            }
-            else
-            {
+            if (!countryVisaFees.Any()) return Ok(JsonView(false, "暂无数据!"));
+
+            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>
+        /// 签证费用资料查询 Page New
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> QueryVisaCountryFeeCosts(QueryVisaCountryFeeCostsDto dto)
+        {
+            // 校验端口类型
+            if (dto.PortType != 1 && dto.PortType != 2 && dto.PortType != 3)
                 return Ok(JsonView(false, "请传入PortType参数!1:Web,2:Android,3:IOS"));
-            }
+
+            var portType = dto.PortType;
+            RefAsync<int> total = 0;
+            var query = _countryFeeRep._sqlSugar
+                .Queryable<Res_CountryFeeCost>()
+                .Where(x => x.IsDel == 0)
+                .WhereIF(dto.VisaFeeType >= 0, x => x.VisaFeeType == dto.VisaFeeType)
+                .WhereIF(!string.IsNullOrEmpty(dto.CountryName), x => x.VisaCountry.Contains(dto.CountryName))
+                .OrderByDescending(x => x.CreateTime);
+
+            var countryVisaFees = await query.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+
+            if (!countryVisaFees.Any()) return Ok(JsonView(false, "暂无数据!"));
+            var view = _mapper.Map<List<CountryFeeCostView>>(countryVisaFees);
+
+            return Ok(JsonView(true, "查询成功", view, total));
         }
 
         /// <summary>
@@ -842,29 +855,10 @@ namespace OASystem.API.Controllers
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> OperationCountryFeeCost(OperationCountryFeeCostDto dto)
         {
-            if (string.IsNullOrWhiteSpace(dto.VisaContinent))
-            {
-                return Ok(JsonView(false, "请检查州名是否填写!"));
-            }
-            if (string.IsNullOrWhiteSpace(dto.VisaCountry))
-            {
-                return Ok(JsonView(false, "请检查国家名是否填写!"));
-            }
-            if (string.IsNullOrWhiteSpace(dto.VisaTime))
-            {
-                return Ok(JsonView(false, "请检一般签证时间是否填写正确!"));
-            }
-            if (string.IsNullOrWhiteSpace(dto.UrgentTime))
-            {
-                return Ok(JsonView(false, "请检加急时间是否填写正确!"));
-            }
+            if (string.IsNullOrWhiteSpace(dto.VisaContinent) || string.IsNullOrWhiteSpace(dto.VisaCountry))
+                return Ok(JsonView(false, "请检查州名和国家名是否填写!"));
 
-            Result result = await _countryFeeRep.OperationCountryFeeCost(dto);
-            if (result.Code == 0)
-            {
-                return Ok(JsonView(true, result.Msg));
-            }
-            return Ok(JsonView(false, result.Msg));
+            return Ok(await _countryFeeRep.OperationCountryFeeCost(dto));
 
         }
 
@@ -877,10 +871,8 @@ namespace OASystem.API.Controllers
         public async Task<IActionResult> DelCountryFeeCost(DelCountryFeeCostDto dto)
         {
             var res = await _countryFeeRep.SoftDeleteByIdAsync<Res_CountryFeeCost>(dto.Id.ToString(), dto.DeleteUserId);
-            if (!res)
-            {
-                return Ok(JsonView(false, "删除失败"));
-            }
+            if (!res) return Ok(JsonView(false, "删除失败"));
+
             return Ok(JsonView(true, "删除成功!"));
 
         }
@@ -1629,14 +1621,14 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
 
                 var InvitationOfficialActivityDataList = _sqlSugar.Queryable<Res_InvitationOfficialActivityData>()
                     .Where(x => x.IsDel == 0)
-                    .Select(x => new Res_InvitationOfficialActivityData() {Id=x.Id,Country = x.Country })
+                    .Select(x => new Res_InvitationOfficialActivityData() { Id = x.Id, Country = x.Country })
                     .ToList();
 
                 foreach (var item in InvitationOfficialActivityDataList)
                 {
                     EncryptionProcessor.DecryptProperties(item);
                 }
-                
+
                 var ids = InvitationOfficialActivityDataList
                     .WhereIF(europeanCountries.Any(), x => !string.IsNullOrWhiteSpace(x.Country) && europeanCountries.Contains(x.Country))
                     .Select(x => x.Id)
@@ -2180,14 +2172,16 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
             var translatorData1 = _mapper.Map<List<TranslatorView>>(translatorData);
             foreach (var item in translatorData1) EncryptionProcessor.DecryptProperties(item);
 
-            return Ok(JsonView(true, 
-                "查询成功!", 
-                new { Delegation = groupInfos, 
-                    SetData = data1, 
-                    DataSource = data2, 
-                    currencyData = data3, 
-                    DeleFile = _DeleFile, 
-                    TranslatorData = translatorData1 
+            return Ok(JsonView(true,
+                "查询成功!",
+                new
+                {
+                    Delegation = groupInfos,
+                    SetData = data1,
+                    DataSource = data2,
+                    currencyData = data3,
+                    DeleFile = _DeleFile,
+                    TranslatorData = translatorData1
                 }));
         }
 
@@ -2818,7 +2812,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
 
 
                     builder.MoveToCell(0, i + 1, 3, 0);
-                    
+
                     //string birthDay = "";
                     string birthDayStr = string.Empty;
                     if (guestInfo.BirthDay != DateTime.MinValue)
@@ -4666,7 +4660,7 @@ WHERE
             return Ok(await _mediaSupplierRep.SoftDel(dto));
         }
 
-        
+
 
 
 
@@ -4818,9 +4812,9 @@ WHERE
         /// <returns></returns>
         [HttpGet("{id}")]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        public async Task<IActionResult> GamesBudgetMasterInfo([Required(ErrorMessage = "数据编号不能为空!")]int id)
+        public async Task<IActionResult> GamesBudgetMasterInfo([Required(ErrorMessage = "数据编号不能为空!")] int id)
         {
-            return Ok( await _gamesBudgetMasterRep.InfoAsync(id));
+            return Ok(await _gamesBudgetMasterRep.InfoAsync(id));
         }
 
         /// <summary>

+ 12 - 15
OASystem/OASystem.Api/Middlewares/ExceptionHandlingMiddleware.cs

@@ -10,19 +10,16 @@ namespace OASystem.API.Middlewares
     {
         private readonly RequestDelegate _next;  // 用来处理上下文请求
         private readonly ILogger<ExceptionHandlingMiddleware> _logger;
-        private readonly SqlSugarClient _db;
 
         /// <summary>
         /// 初始化
         /// </summary>
         /// <param name="next"></param>
         /// <param name="logger"></param>
-        /// <param name="db"></param>
-        public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger, SqlSugarClient db)
+        public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
         {
             _next = next;
             _logger = logger;
-            _db = db;
         }
 
         /// <summary>
@@ -52,17 +49,17 @@ namespace OASystem.API.Middlewares
         /// <returns></returns>
         private async Task HandleExceptionAsync(HttpContext context, Exception exception, SqlSugarClient db)
         {
-            if (db.Ado != null && db.Ado.Transaction != null)
-            {
-                try
-                {
-                    db.Ado.RollbackTran();
-                }
-                catch (Exception ex)
-                {
-                    _logger.LogError("Error rolling back transaction: {ErrorMessage}", ex.Message);
-                }
-            }
+            //if (db.Ado != null && db.Ado.Transaction != null)
+            //{
+            //    try
+            //    {
+            //        db.Ado.RollbackTran();
+            //    }
+            //    catch (Exception ex)
+            //    {
+            //        _logger.LogError("Error rolling back transaction: {ErrorMessage}", ex.Message);
+            //    }
+            //}
 
             // 检查响应是否已开始
             if (!context.Response.HasStarted)

+ 2 - 1
OASystem/OASystem.Api/Middlewares/RecordAPIOperationMiddleware.cs

@@ -79,7 +79,8 @@ namespace OASystem.API.Middlewares
                                 if (!string.IsNullOrEmpty(number))
                                 {
                                     var info = await _sqlSugar.Queryable<Sys_Users>().Where(x => x.IsDel == 0 && x.Number.Equals(number)).FirstAsync();
-                                    userId = info.Id;
+
+                                    userId = info?.Id ?? 0;
                                 }
                             }
                             else

+ 4 - 0
OASystem/OASystem.Api/OASystem.API.csproj

@@ -27,6 +27,10 @@
     <None Remove="Logs\**" />
   </ItemGroup>
 
+  <ItemGroup>
+    <None Remove="Controllers\GroupsController.cs~RF185e674.TMP" />
+  </ItemGroup>
+
   <ItemGroup>
     <PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="2.0.23" />
     <PackageReference Include="AspNetCore.HealthChecks.UI" Version="6.0.1" />

+ 9 - 1
OASystem/OASystem.Api/Program.cs

@@ -145,13 +145,19 @@ var groups = new List<Tuple<string, string>>
 #region 注入数据库
 builder.Services.AddScoped(options =>
 {
+
+    var cpuCount = Environment.ProcessorCount;
+    var poolMin = Math.Max(5, cpuCount * 2);
+    var poolMax = Math.Max(100, cpuCount * 20);
+
     return new SqlSugarClient(new List<ConnectionConfig>()
     {
         new() {
             ConfigId = DBEnum.OA2023DB,
             ConnectionString = _config.GetConnectionString("OA2023DB"),
             DbType = DbType.SqlServer,
-            IsAutoCloseConnection = true
+            IsAutoCloseConnection = true,
+            
         },
         new()
         {
@@ -198,6 +204,8 @@ builder.Services.AddScoped(options =>
 
             //获取无参数SQL对性能有影响,特别大的SQL参数多的,调试使用
             //UtilMethods.GetSqlString(DbType.SqlServer, exp.sql, exp.parameters);
+
+            
         };
         //修改SQL和参数的值
         db.Aop.OnExecutingChangeSql = (sql, pars) =>

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

@@ -239,27 +239,33 @@ namespace OASystem.Domain.AutoMappers
             CreateMap<UpCarDataDto, Res_CarData>();
             CreateMap<Res_CarData, CarDataSelectView>();
             #endregion
+
             #region 导游地接资料
             CreateMap<Res_LocalGuideData, LocalGuideDataView>();
             CreateMap<LocalGuideOperationDto, Res_LocalGuideData>();
             CreateMap<Res_LocalGuideData, Res_LocalGuideData_ListItemView>();
             #endregion
+
             #region 机场三字码资料
             CreateMap<Res_ThreeCode, ThreeCodeView>();
             CreateMap<ThreeCodeOperationDto, Res_ThreeCode>();
             #endregion
+
             #region 代理商合作资料
             CreateMap<OpAirTicketAgentDto, Res_AirTicketAgent>();
             #endregion
+
             #region 酒店资料数据
             CreateMap<Res_HotelData, HotelDataView>();
             CreateMap<Res_HotelData, QueryHotelDataSelect>();
             CreateMap<OperationHotelDto, Res_HotelData>();
             #endregion
+
             #region 签证费用资料
             CreateMap<Res_CountryFeeCost, CountryFeeCostView>();
             CreateMap<OperationCountryFeeCostDto, Res_CountryFeeCost>();
             #endregion
+
             #region 物料供应商
             CreateMap<Edit_ResItemVendorDto, Res_ItemVendor>()
                  .ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.VendorAddress))
@@ -276,6 +282,7 @@ namespace OASystem.Domain.AutoMappers
 
             CreateMap<Edit_ResItemInfoDto, Res_ItemDetailInfo>();
             #endregion
+
             #region 商邀资料
             CreateMap<OpInvitationOfficialActivityDto, Res_InvitationOfficialActivityData>();
             CreateMap<Res_InvitationOfficialActivityData, IOAInfoView>();
@@ -284,6 +291,7 @@ namespace OASystem.Domain.AutoMappers
             #region 公务出访
             CreateMap<OpOfficialActivitiesDto, Res_OfficialActivities>();
             #endregion
+
             #region 请示数据库
             CreateMap<OpAskDataDto, Res_AskData>();
             #endregion

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

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
@@ -174,11 +175,55 @@ namespace OASystem.Domain.Dtos.Resource
         /// 备注
         /// </summary>
         public string Remark { get; set; }
-       
+
+
+
+        #region 2025-06-12 新增字段
+
+        /// <summary>
+        /// 签证费用类型 0 因公 1 因私
+        /// </summary>
+        public int VisaFeeType { get; set; } = 0;
+
+        /// <summary>
+        /// 云南代办费
+        /// </summary>
+        public decimal YunNanAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 贵州代办费
+        /// </summary>
+        public decimal GuiZhouAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 重庆代办费
+        /// </summary>
+        public decimal ChongQingAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 重庆外办出入境证明费用 - 普通
+        /// </summary>
+        public decimal ChongQingNormalFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 重庆外办出入境证明费用 - 加急
+        /// </summary>
+        public decimal ChongQingUrgentFee { get; set; } = 0.00m;
+
+        #endregion
+
     }
     public class DelCountryFeeCostDto
     {
         public int Id { get; set; }
         public int DeleteUserId { get; set; }
     }
+
+    public class QueryVisaCountryFeeCostsDto:DtoBase
+    {
+        [Range(-1,1,ErrorMessage = $"请选择正确的签证费用类型,-1:全部 0:因公 1:因私 ")]
+        public int VisaFeeType { get; set; }
+
+        public string CountryName { get; set; }
+    }
 }

+ 1 - 1
OASystem/OASystem.Domain/Entities/Customer/Crm_DeleClient.cs

@@ -479,7 +479,7 @@ namespace OASystem.Domain.Entities.Customer
     }
 
 
-    public class groupClints {
+    public class GroupClints {
         public int Id { get; set; }
         public string Name { get; set; }
         /// <summary>

+ 40 - 1
OASystem/OASystem.Domain/Entities/Resource/Res_CountryFeeCost.cs

@@ -105,7 +105,7 @@ namespace OASystem.Domain.Entities.Resource
         public string UrgentPriceDesc { get; set; }
 
         /// <summary>
-        /// 签证地址
+        /// 签证地址 -> 送签地址
         /// </summary>
         [SugarColumn(IsNullable = true, ColumnDataType = "varchar(255)")]
         public string VisaAddress { get; set; }
@@ -116,5 +116,44 @@ namespace OASystem.Domain.Entities.Resource
         [SugarColumn(IsNullable = true, ColumnDataType = "varchar(30)")]
         public string LastUpdateTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
 
+        #region 2025-06-12 新增字段
+
+        /// <summary>
+        /// 签证费用类型 0 因公 1 因私
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "int")]
+        public int VisaFeeType { get; set; } = 0;
+
+        /// <summary>
+        /// 云南代办费
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal YunNanAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 贵州代办费
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal GuiZhouAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 重庆代办费
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal ChongQingAgencyFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 重庆外办出入境证明费用 - 普通
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal ChongQingNormalFee { get; set; } = 0.00m;
+
+        /// <summary>
+        /// 重庆外办出入境证明费用 - 加急
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDataType = "decimal(10,2)")]
+        public decimal ChongQingUrgentFee { get; set; } = 0.00m;
+
+        #endregion
     }
 }

+ 16 - 6
OASystem/OASystem.Domain/ViewModels/Resource/CountryFeeCostView.cs

@@ -1,13 +1,23 @@
 using OASystem.Domain.Entities.Resource;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace OASystem.Domain.ViewModels.Resource
 {
-    public class CountryFeeCostView:Res_CountryFeeCost
+    public class CountryFeeCostView : Res_CountryFeeCost
     {
+        /// <summary>
+        /// 距今更新天数
+        /// </summary>
+        public int DaysSinceUpdate
+        {
+            get
+            {
+                var now = DateTime.Now;
+                if (!string.IsNullOrWhiteSpace(LastUpdateTime) && DateTime.TryParse(LastUpdateTime, out var lastTime))
+                {
+                    return (now - lastTime).Days;
+                }
+                return (now - CreateTime).Days;
+            }
+        }
     }
 }

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

@@ -195,7 +195,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                     else if (item.OBType == 2) _pettyBusinessAgencyFee = item.AgencyFee;
                 }
 
-                var info = await _countryFeeRep._InfoByCountryName(country.Key);
+                var info = await _countryFeeRep.InfoByCountryName(country.Key);
                 if (info == null) //添加
                 {
                     int addId = _sqlSugar.Insertable(

+ 32 - 36
OASystem/OASystem.Infrastructure/Repositories/Resource/CountryFeeRepository.cs

@@ -1,13 +1,7 @@
 using AutoMapper;
-using OASystem.Domain;
 using OASystem.Domain.Dtos.Resource;
 using OASystem.Domain.Entities.Resource;
 using OASystem.Domain.ViewModels.Resource;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace OASystem.Infrastructure.Repositories.Resource
 {
@@ -19,64 +13,66 @@ namespace OASystem.Infrastructure.Repositories.Resource
             _mapper = mapper;
         }
 
-        public async Task<Res_CountryFeeCost> _InfoByCountryName(string CountryName)
+        public async Task<Res_CountryFeeCost> InfoByCountryName(string countryName)
         {
-            Res_CountryFeeCost _CountryFeeCost = new Res_CountryFeeCost();
-
-            if (string.IsNullOrEmpty(CountryName)) return _CountryFeeCost;
-
-            _CountryFeeCost = _sqlSugar.Queryable< Res_CountryFeeCost >().Where(it => it.VisaCountry.Equals(CountryName)).First();
-
-            return _CountryFeeCost;
-
+            if (string.IsNullOrEmpty(countryName)) return null;
+            return await _sqlSugar.Queryable<Res_CountryFeeCost>()
+                .FirstAsync(it => it.VisaCountry == countryName);
         }
 
 
-        public async Task<Result> OperationCountryFeeCost(OperationCountryFeeCostDto dto)
+        public async Task<JsonView> OperationCountryFeeCost(OperationCountryFeeCostDto dto)
         {
-            Result result = new Result() { Code = -2, Msg = "未知错误" };
+            var result = new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "未知错误" };
 
-            Res_CountryFeeCost _CountryFeeCost = _mapper.Map<Res_CountryFeeCost>(dto);
+            var countryFeeCost = _mapper.Map<Res_CountryFeeCost>(dto);
 
-            _CountryFeeCost.LastUpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+            countryFeeCost.LastUpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
             if (dto.Status == 1)//添加
             {
-                string selectSql = string.Format(@"select * from Res_CountryFeeCost where VisaContinent='{0}' and VisaCountry='{1}' and IsDel='{2}'"
-                                                   , dto.VisaContinent, dto.VisaCountry, 0);
-                var CountryFeeCost = await _sqlSugar.SqlQueryable<Res_CountryFeeCost>(selectSql).FirstAsync();//查询是否存在
-                if (CountryFeeCost != null)
-                {
-                    return result = new Result() { Code = -1, Msg = "该国家已存在,请勿重复添加!" };
+                var exists = await _sqlSugar.Queryable<Res_CountryFeeCost>()
+                    .AnyAsync(x => x.IsDel == 0 &&
+                                   x.VisaFeeType == dto.VisaFeeType &&
+                                   x.VisaContinent == dto.VisaContinent &&
+                                   x.VisaCountry == dto.VisaCountry);
 
+                if (exists)
+                {
+                    result.Msg = "该国家已存在,请勿重复添加!";
+                    return result;
                 }
                 else//不存在,可添加
                 {
 
-                    int id = await AddAsyncReturnId(_CountryFeeCost);
+                    int id = await AddAsyncReturnId(countryFeeCost);
                     if (id == 0)
                     {
-                        return result = new Result() { Code = -1, Msg = "添加失败!" };
-
+                        result.Msg = "添加失败!";
+                        return result;
                     }
-                    result = new Result() { Code = 0, Msg = "添加成功!", Data = new { Id = id } };
+                    result.Code = StatusCodes.Status200OK;
+                    result.Msg = "添加成功!";
                 }
             }
             else if (dto.Status == 2)//修改
             {
-                var update = await _sqlSugar.Updateable(_CountryFeeCost)
-                                            .IgnoreColumns(it => new { it.Id, it.DeleteUserId, it.DeleteTime, it.CreateUserId, it.CreateTime, it.IsDel })
-                                            .Where(it => it.Id == _CountryFeeCost.Id)
-                                            .ExecuteCommandAsync();
+                var update = await _sqlSugar
+                    .Updateable(countryFeeCost)
+                    .IgnoreColumns(it => new { it.Id, it.DeleteUserId, it.DeleteTime, it.CreateUserId, it.CreateTime, it.IsDel })
+                    .Where(it => it.Id == countryFeeCost.Id)
+                    .ExecuteCommandAsync();
                 //bool res = await UpdateAsync(a => a.Id == dto.Id, a => _CountryFeeCost);
                 if (update < 1)
                 {
-                    return result = new Result() { Code = -1, Msg = "修改失败!" };
+                    result.Msg = "修改失败!";
+                    return result;
                 }
-                result = new Result() { Code = 0, Msg = "修改成功!" };
+                result.Code = StatusCodes.Status200OK;
+                result.Msg = "修改成功!";
             }
             else
             {
-                return result = new Result() { Code = -1, Msg = "请传入Status参数,1添加 2修改!" };
+                result.Msg = "请传入Status参数,1添加 2修改!";
             }
 
             return result;