LEIYI 3 ay önce
ebeveyn
işleme
9a2ae5c15b

+ 2 - 1
OASystem/OASystem.Api/Controllers/AuthController.cs

@@ -25,6 +25,7 @@ using static QRCoder.PayloadGenerator.SwissQrCode;
 using OASystem.Domain.AesEncryption;
 using XAct;
 using Microsoft.Extensions.Configuration;
+using OASystem.Domain.Attributes;
 
 namespace OASystem.API.Controllers
 {
@@ -79,6 +80,7 @@ namespace OASystem.API.Controllers
         /// <returns></returns>
         [Route("login")]
         [HttpPost]
+        //[ApiLog]
         [ProducesResponseType(typeof(LoginView), StatusCodes.Status200OK)]
         public async Task<IActionResult> LoginAsync(LoginDto dto)
         {
@@ -104,7 +106,6 @@ namespace OASystem.API.Controllers
                     if (noLoginAuth.Contains(userInfo.CnName)) return Ok(JsonView(false, "NO ACCESS!!"));
                 }
                 
-
                 //其他市场部人员 限制登录时间段
                 var currentDateTime = DateTime.Now;
                 var startTime = DateTime.Parse(_config["ApiAccessTime:StartTime"]);

+ 36 - 23
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -6,6 +6,7 @@ using DiffMatchPatch;
 using Microsoft.AspNetCore.SignalR;
 using Microsoft.EntityFrameworkCore.Query.Internal;
 using NPOI.HSSF.UserModel;
+using NPOI.SS.Formula.Functions;
 using NPOI.SS.UserModel;
 using NPOI.SS.Util;
 using NPOI.XSSF.UserModel;
@@ -422,6 +423,27 @@ namespace OASystem.API.Controllers
             return Ok(JsonView(true, $"{MsgTips.Succeed},耗时 {watch.ElapsedMilliseconds} ms", countyDatas, total));
         }
 
+        /// <summary>
+        ///  接团信息列表 Page Init
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> PostGroupPageListInit()
+        {
+            var depDatas = await GeneralMethod.GroupOpAffiliationBranchInit();
+
+            var rankDatas = await _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && x.STid == 56).Select(x => new { x.Id, x.Name }).ToListAsync();
+            rankDatas.Insert(0, new { Id=0, Name ="全部" });
+            var _view = new
+            {
+                depData = depDatas,
+                rankData = rankDatas
+            };
+            return Ok(JsonView(true, "查询成功!", _view));
+           
+        }
+
         /// <summary>
         ///  接团信息列表 Page
         /// </summary>
@@ -461,13 +483,24 @@ namespace OASystem.API.Controllers
                     sqlWhere += string.Format(@"And (ssd.Name Like '%{0}%' Or TeamName Like '%{1}%' Or ClientName Like '%{2}%' Or  ClientName Like '%{3}%' Or su.CnName  Like '%{4}%')",
                        tj, tj, tj, tj, tj);
                 }
+                if (dto.Rank > 0) sqlWhere += string.Format("And gdi.TeamLevSId = {0}", dto.Rank);
+                string sqlWhere1 = string.Empty;
+                if (!string.IsNullOrEmpty(dto.Department) && !dto.Department.Equals("全部"))
+                {
+                    sqlWhere1 = string.Format("Where Department = '{0}'", dto.Department);
+                }
 
-                string sql = string.Format(@"Select Row_Number,Id,SalesQuoteNo,TourCode,TeamTypeId, TeamType,
+
+
+
+                string sql = string.Format(@"Select Row_Number,Id,SalesQuoteNo,TourCode,TeamTypeId, TeamType,Department,
                                              	TeamLevId,TeamLev,TeamName,ClientName,ClientUnit,
                                              	VisitDate,VisitDays,VisitPNumber,JietuanOperatorId,
                                              	JietuanOperator,IsSure,CreateTime,IsBid
                                              	From (
                                              	Select row_number() over(order by gdi.CreateTime Desc) as Row_Number,
+                                                CASE WHEN gdi.JietuanOperator = 4 OR gdi.JietuanOperator = 21 THEN '管理员'
+                                                ELSE (Select DepName FROM OA2023DB.dbo.Sys_Department WHERE Id = su.DepId) END AS 'Department',
                                              	gdi.Id,SalesQuoteNo,TourCode,ssd.Id TeamTypeId, ssd.Name TeamType,
                                              	ssd1.Id TeamLevId,ssd1.Name TeamLev,TeamName,ClientName,ClientUnit,
                                              	VisitDate,VisitDays,VisitPNumber,JietuanOperator JietuanOperatorId,
@@ -477,31 +510,11 @@ namespace OASystem.API.Controllers
                                              	Left Join Sys_SetData ssd1 On gdi.TeamLevSId = ssd1.Id
                                              	Left Join Sys_Users su On gdi.JietuanOperator = su.Id
                                              	Where gdi.IsDel = 0 {0}
-                                             ) temp", sqlWhere);
+                                             ) temp{1}", sqlWhere, sqlWhere1);
 
                 RefAsync<int> total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
                 var _DelegationList = await _sqlSugar.SqlQueryable<DelegationListView>(sql).ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
 
-                #region 处理所属部门
-                /*
-                 * 1.sq 和 gyy 等显示 市场部
-                 * 2.王鸽和主管及张总还有管理员号统一国交部
-                 * 2-1.  4	管理员 ,21	张海麟
-                 */
-                List<int> userIds = _DelegationList.Select(it => it.JietuanOperatorId).ToList();
-                List<int> userIds1 = new List<int>() { 4, 21 };
-                var UserDepDatas = _sqlSugar.Queryable<Sys_Users>()
-                                            .LeftJoin<Sys_Department>((u, d) => u.DepId == d.Id)
-                                            .Where(u => u.IsDel == 0 && userIds.Contains(u.Id))
-                                            .Select((u, d) => new { UserId = u.Id, DepName = userIds1.Contains(u.Id) ? "国交部" : d.DepName })
-                                            .ToList();
-
-                foreach (var item in _DelegationList)
-                {
-                    item.Department = UserDepDatas.Find(it => item.JietuanOperatorId == it.UserId)?.DepName ?? "Unknown";
-                }
-                #endregion
-
                 var _view = new
                 {
                     PageFuncAuth = pageFunAuthView,
@@ -13009,7 +13022,7 @@ WHERE
             MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.Singleline);
 
             string[] strValueArr = new string[1];
-            foreach (Match match in matches)
+            foreach (System.Text.RegularExpressions.Match match in matches)
             {
                 var strValue = match.Groups[1].Value;
                 strValueArr = Regex.Split(strValue, @"\r\n|\n");

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

@@ -16,6 +16,7 @@ using static OASystem.API.OAMethodLib.JWTHelper;
 using System.Runtime.Intrinsics.Arm;
 using OASystem.Domain.Dtos.Statistics;
 using OASystem.Domain.AesEncryption;
+using OASystem.Domain.Entities.System;
 
 namespace OASystem.API.Controllers
 {
@@ -30,6 +31,7 @@ namespace OASystem.API.Controllers
         private readonly DepartmentRepository _sysDepRep;
         private readonly UsersRepository _userRep;
         private readonly IMapper _mapper;
+        private readonly IConfiguration _config;
         private readonly SqlSugarClient _sqlSugar;
         private readonly MessageRepository _messageRep;
         private readonly SetDataRepository _setDataRepository;
@@ -50,7 +52,7 @@ namespace OASystem.API.Controllers
             CompanyRepository syscom,
             DepartmentRepository sysDepRep,
             UsersRepository userRep,
-            IMapper mapper,
+            IMapper mapper, IConfiguration config,
             SqlSugarClient sqlSugar,
             SetDataRepository setDataRepository,
             CompanyRepository companyRepository,
@@ -79,6 +81,7 @@ namespace OASystem.API.Controllers
             _UserAuthorityRepository = userAuthorityRepository;
             _jobRep = jobRep;
             _setDataTypeRep = setDataTypeRep;
+            _config = config;
         }
         #region 消息
 
@@ -255,6 +258,34 @@ namespace OASystem.API.Controllers
 
             try
             {
+
+                #region 限制人员登录
+                var userInfo = await _sqlSugar
+                    .Queryable<Sys_Users>()
+                    .LeftJoin<Sys_Department>((u, d) => u.DepId == d.Id)
+                    .Where((u, d) => u.Id == dto.UserId)
+                    .Select((u, d) => new {
+                        DepName = d.DepName,
+                        CnName = u.CnName
+                    })
+                    .FirstAsync();
+
+                var noLoginAuth = _config.GetSection("NoLoginAuth").Get<List<string>>();
+                if (noLoginAuth.Any())
+                {
+                    if (noLoginAuth.Contains(userInfo.CnName)) return Ok(JsonView(204, "NO ACCESS!!",""));
+                }
+
+                //其他市场部人员 限制登录时间段
+                var currentDateTime = DateTime.Now;
+                var startTime = DateTime.Parse(_config["ApiAccessTime:StartTime"]);
+                var endTime = DateTime.Parse(_config["ApiAccessTime:EndTime"]);
+                if (currentDateTime < startTime && currentDateTime > endTime) return Ok(JsonView(204, "NO ACCESS!!", ""));
+                #endregion
+
+
+
+
                 int messageUnReadCount = 0;
                 int announcementUnReadCount = 0;
                 var data = await _messageRep.GetUnReadCount(dto.UserId);

+ 79 - 0
OASystem/OASystem.Api/Filters/RecordAPIOperationFilter.cs

@@ -0,0 +1,79 @@
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace OASystem.API.Filters
+{
+    public class RecordAPIOperationFilter : IActionFilter, IResultFilter
+    {
+       private string _requestParam { get; set; }
+       private string _requestMethod { get; set; }
+
+        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+        {
+            // 启用请求体缓冲
+            context.HttpContext.Request.EnableBuffering();
+
+            _requestMethod = context.HttpContext.Request.Method.ToUpper();
+
+            // 读取请求体
+            if (_requestMethod == "POST" && context.HttpContext.Request.ContentType?.Contains("application/json") == true)
+            {
+                using (var reader = new StreamReader(context.HttpContext.Request.Body))
+                {
+                    var body = await reader.ReadToEndAsync();
+                    // 重置请求体流的位置,以便后续处理
+                    context.HttpContext.Request.Body.Position = 0;
+
+                    if (!string.IsNullOrEmpty(body))
+                    {
+                        using (var jsonReader = new JsonTextReader(new StringReader(body)))
+                        {
+                            // 解析JSON内容
+                            var json = new JsonSerializer().Deserialize<Dictionary<string, object>>(jsonReader);
+                            if (json != null)
+                            {
+                                // 验证指定参数是否存在
+                                if (json.ContainsKey("specifiedKey"))
+                                {
+                                    var specifiedValue = json["specifiedKey"];
+                                    Console.WriteLine($"Specified Value: {specifiedValue}");
+                                }
+                                else
+                                {
+                                    Console.WriteLine("Specified Key does not exist in the request body.");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            // 继续执行Action
+            await next();
+        }
+
+        public void OnResultExecuting(ResultExecutingContext context)
+        {
+            // 获取返回结果
+            if (context.Result is ObjectResult objectResult)
+            {
+                Console.WriteLine("Response Result: " +objectResult.Value);
+            }
+        }
+
+        public void OnResultExecuted(ResultExecutedContext context)
+        {
+            // 结果生成后的逻辑
+        }
+
+        public void OnActionExecuting(ActionExecutingContext context)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void OnActionExecuted(ActionExecutedContext context)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
+

+ 114 - 0
OASystem/OASystem.Api/Middlewares/RecordAPIOperationMiddleware.cs

@@ -0,0 +1,114 @@
+using Aspose.Words;
+using NPOI.HSSF.Record;
+using OASystem.Domain.Attributes;
+using OASystem.Domain.Entities.Customer;
+using OASystem.Infrastructure.Repositories.CRM;
+using System.ComponentModel.DataAnnotations;
+using System.Diagnostics;
+using XAct;
+using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
+
+namespace OASystem.API.Middlewares
+{
+    /// <summary>
+    /// 指定API操作记录信息
+    /// </summary>
+    public class RecordAPIOperationMiddleware
+    {
+        private readonly RequestDelegate _next;
+        private readonly HttpClient _httpClient;
+        private readonly IConfiguration _config;
+        private readonly SqlSugarClient _sqlSugar;
+
+        public RecordAPIOperationMiddleware(RequestDelegate next, IConfiguration config, HttpClient httpClient, SqlSugarClient sqlSugar)
+        {
+            _next = next;
+            _httpClient = httpClient;
+            _config = config;
+            _sqlSugar = sqlSugar;
+        }
+
+        public async Task InvokeAsync(HttpContext context)
+        {
+            // 启用请求体流的缓冲,允许多次读取
+            context.Request.EnableBuffering();
+
+            // 读取请求体内容
+            var requestBodyText = await ReadRequestBody(context.Request);
+
+            // 检查控制器方法是否使用了自定义属性
+            var endpoint = context.GetEndpoint();
+            if (endpoint?.Metadata?.GetMetadata<ApiLogAttribute>() != null)
+            {
+                var logInfo = new Crm_TableOperationRecord();
+                logInfo.ActionName = context.Request.Path;
+                logInfo.UpdatePreData = requestBodyText;
+                // 保存原始响应体流
+                var originalResponseBody = context.Response.Body;
+
+                // 创建一个新的内存流来捕获响应体
+                using var responseMemoryStream = new MemoryStream();
+                context.Response.Body = responseMemoryStream;
+
+                // 调用下一个中间件
+                await _next(context);
+
+                // 重置响应体流的位置
+                responseMemoryStream.Position = 0;
+
+                // 读取响应体内容
+                var responseBodyText = await new StreamReader(responseMemoryStream).ReadToEndAsync();
+
+                // 将响应体内容写回原始响应体流
+                await responseMemoryStream.CopyToAsync(originalResponseBody);
+
+                logInfo.UpdateBefData = responseBodyText;
+
+               
+
+
+                // 存储到数据库
+                //_sqlSugar.ChangeDatabase(DBEnum.OA2023DB);
+                await  _sqlSugar.Insertable(logInfo).ExecuteCommandAsync();
+            }
+            else
+            {
+                // 调用下一个中间件
+                await _next(context);
+            }
+        }
+
+        private async Task<string> ReadRequestBody(HttpRequest request)
+        {
+            request.EnableBuffering();
+
+            // 读取请求体内容
+            using var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true);
+            var requestBodyText = await reader.ReadToEndAsync();
+
+            // 重置请求体流的位置
+            request.Body.Position = 0;
+
+            return requestBodyText;
+        }
+
+
+        private async Task<string> GetExternalIp()
+        {
+            var response = await _httpClient.GetAsync("https://ifconfig.me");
+            response.EnsureSuccessStatusCode();
+            return await response.Content.ReadAsStringAsync();
+        }
+
+        private async Task<string> GetIpLocation(string ip)
+        {
+            var response = await _httpClient.GetAsync($"https://ipinfo.io/{ip}/json");
+            response.EnsureSuccessStatusCode();
+            var json = await response.Content.ReadAsStringAsync();
+            var ipInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
+            return $"{ipInfo.country}, {ipInfo.city}";
+        }
+
+       
+    }
+}

+ 3 - 0
OASystem/OASystem.Api/Middlewares/TimeRestrictionMiddleware.cs

@@ -40,6 +40,9 @@ namespace OASystem.API.Middlewares
                     
                 }
 
+
+
+
                 context.Response.ContentType = "application/json";
                 context.Response.StatusCode = 201;
                 var response = context.Response;

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

@@ -47,6 +47,43 @@ namespace OASystem.API.OAMethodLib
 
         private readonly static string[] weekdays = new string[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
 
+        #region 团组操作-->团组归属部门
+
+        /// <summary>
+        /// 团组操作-->团组归属部门
+        /// </summary>
+        /// <returns></returns>
+        public static async Task<List<GroupOpAffiliationBranchView>> GroupOpAffiliationBranchInit()
+        {
+            /*
+                * 1.sq 和 gyy 等显示 市场部
+                * 2.王鸽和主管及张总还有管理员号统一国交部
+                * 2-1.  4	管理员 ,21	张海麟
+                */
+
+            //List<int> userIds = new List<int>() { 4, 21 };
+            var userDepDatas = new List<GroupOpAffiliationBranchView>();
+            //userDepDatas = _sqlSugar.Queryable<Sys_Users>()
+            //    .LeftJoin<Sys_Department>((u, d) => u.DepId == d.Id)
+            //    .Where(u => u.IsDel == 0)
+            //    .Select((u, d) => new GroupOpAffiliationBranchView { value = userIds.Contains(u.Id) ? "国交部" : d.DepName, text = userIds.Contains(u.Id) ? "国交部" : d.DepName })
+            //    .ToList();
+            userDepDatas.Insert(0, new GroupOpAffiliationBranchView() { text = "全部", value = "全部" });
+            userDepDatas.Insert(0, new GroupOpAffiliationBranchView() { text = "管理员", value = "全部" });
+            userDepDatas.Insert(0, new GroupOpAffiliationBranchView() { text = "市场部", value = "市场部" });
+            userDepDatas.Insert(0, new GroupOpAffiliationBranchView() { text = "国交部", value = "国交部" });
+
+            return userDepDatas;
+        }
+
+        public class GroupOpAffiliationBranchView
+        {
+            public string value { get; set; }
+            public string text { get; set; }
+        }
+
+        #endregion
+
         #region 员工注册默认添加基础页面
 
         /// <summary>

+ 7 - 11
OASystem/OASystem.Api/Program.cs

@@ -125,7 +125,8 @@ builder.Services.AddScoped(options =>
             ConfigId = DBEnum.OA2023DB,
             ConnectionString = _config.GetConnectionString("OA2023DB"),
             DbType = DbType.SqlServer,
-            IsAutoCloseConnection = true },
+            IsAutoCloseConnection = true
+        },
         new ConnectionConfig()
         {
             ConfigId = DBEnum.OA2014DB,
@@ -376,9 +377,6 @@ var app = builder.Build();
 
 AutofacIocManager.Instance.Container = app.UseHostFiltering().ApplicationServices.GetAutofacRoot();//AutofacIocManager
 
-
-
-
 // Configure the HTTP request pipeline.
 if (!app.Environment.IsDevelopment())
 {
@@ -387,19 +385,20 @@ if (!app.Environment.IsDevelopment())
 
 app.UseStaticFiles();
 
-
-//app.UseMiddleware<FixedPromptMiddleware>();
-app.UseMiddleware<ExceptionHandlingMiddleware>();
-
 app.UseRouting();
 
 app.UseCors("Cors");  //Cors
 
+//app.UseMiddleware<FixedPromptMiddleware>();
+app.UseMiddleware<ExceptionHandlingMiddleware>();
+
 // 定义允许API的访问时间段
 //var startTime = DateTime.Parse(_config["ApiAccessTime:StartTime"]);
 //var endTime = DateTime.Parse(_config["ApiAccessTime:EndTime"]);
 //app.UseMiddleware<TimeRestrictionMiddleware>(startTime, endTime);
 
+//指定API操作记录信息
+app.UseMiddleware<RecordAPIOperationMiddleware>();
 
 app.UseAuthentication(); // 认证
 app.UseAuthorization();  // 授权
@@ -457,9 +456,6 @@ app.MapHub<ChatHub>("/ChatHub", options =>
 #endregion
 
 
-
-
-
 app.MapControllerRoute(
     name: "default",
     pattern: "{controller=Home}/{action=Index}/{id?}");

+ 7 - 1
OASystem/OASystem.Api/appsettings.json

@@ -12,7 +12,13 @@
     "符志超",
     "杨千莹",
     "喻思霖",
-    "张倩"
+    "张倩",
+    "雷怡"
+  ],
+  //记录相关api接口
+  "RecordApiPathName": [
+    "/api/login",
+    "/api/MarketCustomerResources/NewClientOp"
   ],
   "JwtSecurityKey": "48d3f4fe770940a1068052f581536b81", //jwt密钥
   "UseSwagger": "true", //启用Swagger

+ 16 - 0
OASystem/OASystem.Domain/Attributes/ApiLogAttribute.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Attributes
+{
+    /// <summary>
+    /// 指定接口增加操作日志
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class ApiLogAttribute : Attribute
+    {
+    }
+}

+ 4 - 0
OASystem/OASystem.Domain/Dtos/Groups/GroupListDto.cs

@@ -35,6 +35,10 @@ namespace OASystem.Domain.Dtos.Groups
         /// 团组类型/团队名称/客户名称/客户单位/接团操作人
         /// </summary>
         public string? SearchCriteria { get; set; }
+
+        public string Department { get; set; }
+        public int Rank { get; set; }
+
     }
 
     /// <summary>

+ 66 - 0
OASystem/OASystem.Domain/Entities/Customer/Crm_TableOperationRecord.cs

@@ -38,5 +38,71 @@ namespace OASystem.Domain.Entities.Customer
         /// </summary>
         [SugarColumn(IsNullable = true, ColumnDataType = "int")]
         public int DataId { get; set; } = 0;
+
+        /// <summary>
+        /// 模块名称
+        /// </summary>
+        public string? ControllerName { get; set; }
+
+        /// <summary>
+        /// 方法名称
+        ///</summary>
+        public string? ActionName { get; set; }
+
+
+        /// <summary>
+        /// 执行状态
+        /// </summary>
+        public string? Status { get; set; }
+
+        /// <summary>
+        /// IP地址
+        /// </summary>
+        public string? RemoteIp { get; set; }
+
+        /// <summary>
+        /// 登录地点
+        /// </summary>
+        public string? Location { get; set; }
+
+        /// <summary>
+        /// 浏览器
+        /// </summary>
+        public string? Browser { get; set; }
+
+        /// <summary>
+        /// 操作系统
+        /// </summary>
+        public string? Os { get; set; }
+
+        /// <summary>
+        /// 操作用时
+        /// </summary>
+        public long? Elapsed { get; set; }
+
+        ///// <summary>
+        ///// 请求地址
+        ///// </summary>
+        //public string? RequestUrl { get; set; }
+
+        /// <summary>
+        /// 请求参数
+        /// </summary>
+        public string? RequestParam { get; set; }
+
+        /// <summary>
+        /// 返回结果
+        /// </summary>
+        public string? ReturnResult { get; set; }
+
+        /// <summary>
+        /// 更新前数据
+        /// </summary>
+        public string UpdatePreData { get; set; }
+
+        /// <summary>
+        /// 更新后数据
+        /// </summary>
+        public string UpdateBefData { get; set; }
     }
 }

+ 5 - 0
OASystem/OASystem.Domain/Enums/OperationEnum.cs

@@ -62,5 +62,10 @@ namespace OASystem.Domain.Enums
         /// </summary>
         [Description("批量指派")]
         BatchAssignment = 9,
+        /// <summary>
+        /// 登录
+        /// </summary>
+        [Description("登录")]
+        Login = 9,
     }
 }