diff --git a/.cursor/mcp.json b/.cursor/mcp.json index e4549872..ecf4f224 100644 --- a/.cursor/mcp.json +++ b/.cursor/mcp.json @@ -9,13 +9,11 @@ ], "env": {} }, - "mysql": { - "type": "stdio", - "command": "uvx", + "openauthpro": { + "command": "powershell", "args": [ - "--from", - "mysql-mcp-server", - "mysql_mcp_server" + "-Command", + "npx -y @f4ww4z/mcp-mysql-server" ], "env": { "MYSQL_HOST": "localhost", diff --git a/Infrastructure/Helpers/TimeHelper.cs b/Infrastructure/Helpers/TimeHelper.cs new file mode 100644 index 00000000..2edb9463 --- /dev/null +++ b/Infrastructure/Helpers/TimeHelper.cs @@ -0,0 +1,117 @@ +using System; + +namespace Infrastructure.Helpers +{ + /// + /// 时间处理帮助类 + /// 统一处理时区问题,确保所有时间都使用正确的时区 + /// + public static class TimeHelper + { + /// + /// 获取当前中国标准时间(UTC+8) + /// + /// 当前中国标准时间 + public static DateTime Now => GetChinaStandardTime(); + + /// + /// 获取当前中国标准时间(UTC+8) + /// + /// 当前中国标准时间 + public static DateTime GetChinaStandardTime() + { + // 获取UTC时间 + var utcNow = DateTime.UtcNow; + + // 转换为中国标准时间(UTC+8) + var chinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"); + + // 如果找不到中国时区,使用手动计算(UTC+8) + if (chinaTimeZone == null) + { + return utcNow.AddHours(8); + } + + return TimeZoneInfo.ConvertTimeFromUtc(utcNow, chinaTimeZone); + } + + /// + /// 将UTC时间转换为中国标准时间 + /// + /// UTC时间 + /// 中国标准时间 + public static DateTime ConvertUtcToChinaTime(DateTime utcTime) + { + if (utcTime.Kind != DateTimeKind.Utc) + { + utcTime = DateTime.SpecifyKind(utcTime, DateTimeKind.Utc); + } + + var chinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"); + + if (chinaTimeZone == null) + { + return utcTime.AddHours(8); + } + + return TimeZoneInfo.ConvertTimeFromUtc(utcTime, chinaTimeZone); + } + + /// + /// 将中国标准时间转换为UTC时间 + /// + /// 中国标准时间 + /// UTC时间 + public static DateTime ConvertChinaTimeToUtc(DateTime chinaTime) + { + var chinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"); + + if (chinaTimeZone == null) + { + return chinaTime.AddHours(-8); + } + + return TimeZoneInfo.ConvertTimeToUtc(chinaTime, chinaTimeZone); + } + + /// + /// 获取当前时间的Unix时间戳(秒) + /// + /// Unix时间戳 + public static long GetUnixTimestamp() + { + return ((DateTimeOffset)Now).ToUnixTimeSeconds(); + } + + /// + /// 获取当前时间的Unix时间戳(毫秒) + /// + /// Unix时间戳(毫秒) + public static long GetUnixTimestampMilliseconds() + { + return ((DateTimeOffset)Now).ToUnixTimeMilliseconds(); + } + + /// + /// 将Unix时间戳转换为中国标准时间 + /// + /// Unix时间戳(秒) + /// 中国标准时间 + public static DateTime FromUnixTimestamp(long timestamp) + { + var utcTime = DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime; + return ConvertUtcToChinaTime(utcTime); + } + + /// + /// 将Unix时间戳(毫秒)转换为中国标准时间 + /// + /// Unix时间戳(毫秒) + /// 中国标准时间 + public static DateTime FromUnixTimestampMilliseconds(long timestamp) + { + var utcTime = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).DateTime; + return ConvertUtcToChinaTime(utcTime); + } + } +} diff --git a/OpenAuth.App/Files/FileApp.cs b/OpenAuth.App/Files/FileApp.cs index af273118..5904579d 100644 --- a/OpenAuth.App/Files/FileApp.cs +++ b/OpenAuth.App/Files/FileApp.cs @@ -149,7 +149,7 @@ namespace OpenAuth.App /// private void SaveFile(string fileName, byte[] fileBuffers) { - string folder = DateTime.Now.ToString("yyyyMMdd"); + string folder = TimeHelper.Now.ToString("yyyyMMdd"); //判断文件是否为空 if (string.IsNullOrEmpty(fileName)) diff --git a/OpenAuth.App/Flow/FlowRuntime.cs b/OpenAuth.App/Flow/FlowRuntime.cs index c0e5def9..1e2e3786 100644 --- a/OpenAuth.App/Flow/FlowRuntime.cs +++ b/OpenAuth.App/Flow/FlowRuntime.cs @@ -15,6 +15,7 @@ using OpenAuth.App.Interface; using OpenAuth.App.Request; using SqlSugar; using Microsoft.Extensions.Configuration; +using Infrastructure.Helpers; namespace OpenAuth.App.Flow { @@ -221,7 +222,7 @@ namespace OpenAuth.App.Flow } var content = - $"{user.Account}-{DateTime.Now:yyyy-MM-dd HH:mm}审批了【{Nodes[canCheckId].name}】" + + $"{user.Account}-{TimeHelper.Now:yyyy-MM-dd HH:mm}审批了【{Nodes[canCheckId].name}】" + $"结果:{(tag.Taged == 1 ? "同意" : "不同意")},备注:{tag.Description}"; SaveOperationHis(content); @@ -389,7 +390,7 @@ namespace OpenAuth.App.Flow sugarClient.Updateable(flowInstance).ExecuteCommand(); SaveOperationHis( - $"{user.Account}-{DateTime.Now.ToString("yyyy-MM-dd HH:mm")}驳回了【{currentNode.name}】"); + $"{user.Account}-{TimeHelper.Now.ToString("yyyy-MM-dd HH:mm")}驳回了【{currentNode.name}】"); NotifyThirdParty(client, currentNode, tag); } @@ -437,7 +438,7 @@ namespace OpenAuth.App.Flow item.Value.setInfo.UserId = tag.UserId; item.Value.setInfo.UserName = tag.UserName; item.Value.setInfo.Description = tag.Description; - item.Value.setInfo.TagedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm"); + item.Value.setInfo.TagedTime = TimeHelper.Now.ToString("yyyy-MM-dd HH:mm"); break; } } @@ -462,7 +463,7 @@ namespace OpenAuth.App.Flow InstanceId = flowInstanceId, CreateUserId = userId, CreateUserName = userName, - CreateDate = DateTime.Now, + CreateDate = TimeHelper.Now, Content = opHis }; //操作记录 @@ -744,7 +745,7 @@ namespace OpenAuth.App.Flow ApproveType = node.setInfo.NodeConfluenceType, ReturnToSignNode = false, Reason = "", - CreateDate = DateTime.Now + CreateDate = TimeHelper.Now }; sugarClient.Insertable(flowApprover).ExecuteCommand(); } diff --git a/OpenAuth.App/FlowInstance/FlowInstanceApp.cs b/OpenAuth.App/FlowInstance/FlowInstanceApp.cs index 12228fc3..c6f1fad4 100644 --- a/OpenAuth.App/FlowInstance/FlowInstanceApp.cs +++ b/OpenAuth.App/FlowInstance/FlowInstanceApp.cs @@ -2,7 +2,7 @@ * @Author: yubaolee | ahfu~ <954478625@qq.com> * @Date: 2024-12-13 16:55:17 * @Description: 工作流实例表操作 - * @LastEditTime: 2025-04-21 10:54:45 + * @LastEditTime: 2025-10-18 14:35:01 * Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved. */ @@ -199,7 +199,7 @@ namespace OpenAuth.App val = ""; break; case "DateTime": - val = DateTime.Now.ToString("yyyy-MM-dd"); + val = TimeHelper.Now.ToString("yyyy-MM-dd"); break; } } @@ -516,7 +516,7 @@ namespace OpenAuth.App } var content = - $"{user.Account}-{DateTime.Now.ToString("yyyy-MM-dd HH:mm")}审批了【{wfruntime.currentNode.name}】" + + $"{user.Account}-{TimeHelper.Now.ToString("yyyy-MM-dd HH:mm")}审批了【{wfruntime.currentNode.name}】" + $"结果:{(tag.Taged == 1 ? "同意" : "不同意")},备注:{tag.Description}"; wfruntime.SaveOperationHis(tag.UserId, tag.UserName, content); diff --git a/OpenAuth.App/FlowScheme/FlowSchemeApp.cs b/OpenAuth.App/FlowScheme/FlowSchemeApp.cs index 6b11ffc0..1ba83e12 100644 --- a/OpenAuth.App/FlowScheme/FlowSchemeApp.cs +++ b/OpenAuth.App/FlowScheme/FlowSchemeApp.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Infrastructure; +using Infrastructure.Helpers; using OpenAuth.App.Interface; using OpenAuth.App.Request; using OpenAuth.App.Response; @@ -41,7 +42,7 @@ namespace OpenAuth.App { SchemeContent = flowScheme.SchemeContent, SchemeName = flowScheme.SchemeName, - ModifyDate = DateTime.Now, + ModifyDate = TimeHelper.Now, FrmId = flowScheme.FrmId, FrmType = flowScheme.FrmType, FrmUrlTemplate = flowScheme.FrmUrlTemplate, diff --git a/OpenAuth.App/Jobs/OpenJobApp.cs b/OpenAuth.App/Jobs/OpenJobApp.cs index 177ae698..6684a9fe 100644 --- a/OpenAuth.App/Jobs/OpenJobApp.cs +++ b/OpenAuth.App/Jobs/OpenJobApp.cs @@ -11,6 +11,7 @@ using OpenAuth.App.Interface; using OpenAuth.App.Request; using OpenAuth.App.Response; using OpenAuth.Repository.Domain; +using Infrastructure.Helpers; using Quartz; using SqlSugar; @@ -62,7 +63,7 @@ namespace OpenAuth.App public void Add(AddOrUpdateOpenJobReq req) { var obj = req.MapTo(); - obj.CreateTime = DateTime.Now; + obj.CreateTime = TimeHelper.Now; var user = _auth.GetCurrentUser().User; obj.CreateUserId = user.Id; obj.CreateUserName = user.Name; @@ -81,7 +82,7 @@ namespace OpenAuth.App Cron = obj.Cron, Status = obj.Status, Remark = obj.Remark, - UpdateTime = DateTime.Now, + UpdateTime = TimeHelper.Now, UpdateUserId = user.Id, UpdateUserName = user.Name },u => u.Id == obj.Id); @@ -126,7 +127,7 @@ namespace OpenAuth.App var user = _auth.GetCurrentUser().User; job.Status = req.Status; - job.UpdateTime = DateTime.Now; + job.UpdateTime = TimeHelper.Now; job.UpdateUserId = user.Id; job.UpdateUserName = user.Name; Repository.Update(job); @@ -150,7 +151,7 @@ namespace OpenAuth.App } job.RunCount++; - job.LastRunTime = DateTime.Now; + job.LastRunTime = TimeHelper.Now; Repository.Update(job); _sysLogApp.Add(new SysLog diff --git a/OpenAuth.App/Relevance/RevelanceManagerApp.cs b/OpenAuth.App/Relevance/RevelanceManagerApp.cs index 32992ef7..a4d92b24 100644 --- a/OpenAuth.App/Relevance/RevelanceManagerApp.cs +++ b/OpenAuth.App/Relevance/RevelanceManagerApp.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Infrastructure; +using Infrastructure.Helpers; using Microsoft.Extensions.Logging; using OpenAuth.App.Interface; using OpenAuth.App.Request; @@ -44,7 +45,7 @@ namespace OpenAuth.App RelKey = key, FirstId = sameVals.Key, SecondId = value, - OperateTime = DateTime.Now + OperateTime = TimeHelper.Now }).ToArray()); UnitWork.Save(); } @@ -152,7 +153,7 @@ namespace OpenAuth.App FirstId = request.RoleId, SecondId = request.ModuleCode, ThirdId = requestProperty, - OperateTime = DateTime.Now + OperateTime = TimeHelper.Now }); } @@ -206,7 +207,7 @@ namespace OpenAuth.App RelKey = Define.USERROLE, FirstId = firstId, SecondId = request.RoleId, - OperateTime = DateTime.Now + OperateTime = TimeHelper.Now }).ToArray()); UnitWork.Save(); }); @@ -229,7 +230,7 @@ namespace OpenAuth.App RelKey = Define.USERORG, FirstId = firstId, SecondId = request.OrgId, - OperateTime = DateTime.Now + OperateTime = TimeHelper.Now }).ToArray()); UnitWork.Save(); }); @@ -252,7 +253,7 @@ namespace OpenAuth.App RelKey = Define.ROLERESOURCE, FirstId = request.RoleId, SecondId = firstId, - OperateTime = DateTime.Now + OperateTime = TimeHelper.Now }).ToArray()); UnitWork.Save(); }); diff --git a/OpenAuth.App/Resources/ResourceApp.cs b/OpenAuth.App/Resources/ResourceApp.cs index 374e1f73..cec93d69 100644 --- a/OpenAuth.App/Resources/ResourceApp.cs +++ b/OpenAuth.App/Resources/ResourceApp.cs @@ -10,6 +10,7 @@ using OpenAuth.App.Request; using OpenAuth.App.Response; using OpenAuth.Repository.Domain; using SqlSugar; +using Infrastructure.Helpers; namespace OpenAuth.App { @@ -34,7 +35,7 @@ namespace OpenAuth.App { var obj = resource.MapTo(); CaculateCascade(obj); - obj.CreateTime = DateTime.Now; + obj.CreateTime = TimeHelper.Now; var user = _auth.GetCurrentUser().User; obj.CreateUserId = user.Id; obj.CreateUserName = user.Name; @@ -56,7 +57,7 @@ namespace OpenAuth.App TypeId = obj.TypeId, TypeName = obj.TypeName, Description = obj.Description, - UpdateTime = DateTime.Now, + UpdateTime = TimeHelper.Now, UpdateUserId = user.Id, UpdateUserName = user.Name //todo:要修改的字段赋值 @@ -157,7 +158,7 @@ namespace OpenAuth.App TypeId = Define.API, TypeName = "API接口", Description = api.Summary??"", - CreateTime = DateTime.Now, + CreateTime = TimeHelper.Now, CreateUserId = user.Id, CreateUserName = user.Name }; diff --git a/OpenAuth.App/RoleManager/RoleApp.cs b/OpenAuth.App/RoleManager/RoleApp.cs index b52c0f53..58a8682d 100644 --- a/OpenAuth.App/RoleManager/RoleApp.cs +++ b/OpenAuth.App/RoleManager/RoleApp.cs @@ -10,7 +10,7 @@ using Infrastructure; using Microsoft.EntityFrameworkCore; using OpenAuth.App.Request; using OpenAuth.Repository; - +using Infrastructure.Helpers; using SqlSugar; namespace OpenAuth.App @@ -72,7 +72,7 @@ namespace OpenAuth.App { SugarClient.Ado.BeginTran(); Role role = obj; - role.CreateTime = DateTime.Now; + role.CreateTime = TimeHelper.Now; Repository.Insert(role); obj.Id = role.Id; //要把保存后的ID存入view diff --git a/OpenAuth.App/SSO/LoginParse.cs b/OpenAuth.App/SSO/LoginParse.cs index 59544dd9..45254cca 100644 --- a/OpenAuth.App/SSO/LoginParse.cs +++ b/OpenAuth.App/SSO/LoginParse.cs @@ -5,6 +5,7 @@ using System; using Infrastructure; using Infrastructure.Cache; +using Infrastructure.Helpers; using OpenAuth.Repository; using OpenAuth.Repository.Domain; using OpenAuth.Repository.Interface; @@ -76,12 +77,12 @@ namespace OpenAuth.App.SSO Name = sysUserInfo.Name, Token = Guid.NewGuid().ToString().GetHashCode().ToString("x"), AppKey = model.AppKey, - CreateTime = DateTime.Now + CreateTime = TimeHelper.Now // , IpAddress = HttpContext.Current.Request.UserHostAddress }; //创建Session - _cacheContext.Set(currentSession.Token, currentSession, DateTime.Now.AddDays(10)); + _cacheContext.Set(currentSession.Token, currentSession, TimeHelper.Now.AddDays(10)); result.Code = 200; result.Token = currentSession.Token; diff --git a/OpenAuth.App/SysMessage/SysMessageApp.cs b/OpenAuth.App/SysMessage/SysMessageApp.cs index a299137a..7faa7933 100644 --- a/OpenAuth.App/SysMessage/SysMessageApp.cs +++ b/OpenAuth.App/SysMessage/SysMessageApp.cs @@ -10,6 +10,7 @@ using OpenAuth.App.Response; using OpenAuth.Repository; using OpenAuth.Repository.Domain; using OpenAuth.Repository.Interface; +using Infrastructure.Helpers; namespace OpenAuth.App @@ -90,7 +91,7 @@ namespace OpenAuth.App FromId = Guid.Empty.ToString(), FromName = "系统管理员", Content = message, - CreateTime = DateTime.Now + CreateTime = TimeHelper.Now }); } diff --git a/OpenAuth.Repository/Domain/FlowScheme.cs b/OpenAuth.Repository/Domain/FlowScheme.cs index 742c2ed6..72c2ffee 100644 --- a/OpenAuth.Repository/Domain/FlowScheme.cs +++ b/OpenAuth.Repository/Domain/FlowScheme.cs @@ -12,6 +12,7 @@ using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; using OpenAuth.Repository.Core; +using Infrastructure.Helpers; namespace OpenAuth.Repository.Domain { @@ -36,10 +37,10 @@ namespace OpenAuth.Repository.Domain this.DeleteMark= 0; this.Disabled= 0; this.Description= string.Empty; - this.CreateDate= DateTime.Now; + this.CreateDate= TimeHelper.Now; this.CreateUserId= string.Empty; this.CreateUserName= string.Empty; - this.ModifyDate= DateTime.Now; + this.ModifyDate= TimeHelper.Now; this.ModifyUserId= string.Empty; this.ModifyUserName= string.Empty; } diff --git a/OpenAuth.Repository/Domain/OpenJob.cs b/OpenAuth.Repository/Domain/OpenJob.cs index 6843da37..0fc6f143 100644 --- a/OpenAuth.Repository/Domain/OpenJob.cs +++ b/OpenAuth.Repository/Domain/OpenJob.cs @@ -13,6 +13,7 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; using System.Text; using OpenAuth.Repository.Core; +using Infrastructure.Helpers; namespace OpenAuth.Repository.Domain { @@ -27,19 +28,19 @@ namespace OpenAuth.Repository.Domain this.JobName= string.Empty; this.RunCount= 0; this.ErrorCount= 0; - this.NextRunTime= DateTime.Now; - this.LastRunTime= DateTime.Now; - this.LastErrorTime= DateTime.Now; + this.NextRunTime= TimeHelper.Now; + this.LastRunTime= TimeHelper.Now; + this.LastErrorTime= TimeHelper.Now; this.JobType= 0; this.JobCall= string.Empty; this.JobCallParams= string.Empty; this.Cron= string.Empty; this.Status= 0; this.Remark= string.Empty; - this.CreateTime= DateTime.Now; + this.CreateTime= TimeHelper.Now; this.CreateUserId= string.Empty; this.CreateUserName= string.Empty; - this.UpdateTime= DateTime.Now; + this.UpdateTime= TimeHelper.Now; this.UpdateUserId= string.Empty; this.UpdateUserName= string.Empty; this.OrgId= string.Empty; diff --git a/newdocs/docs/notes/core/log.md b/newdocs/docs/notes/core/log.md index b5a77d5b..b1f5deaa 100644 --- a/newdocs/docs/notes/core/log.md +++ b/newdocs/docs/notes/core/log.md @@ -3,10 +3,9 @@ title: 日志操作 createTime: 2025/04/23 21:03:10 permalink: /core/log/ --- - ## 普通日志 -框架默认使用Log4Net作为记录日志的方式,可以在Program.cs中配置日志参数或调整为其他日志。日志默认按日期生成日志文件,并存放在`log\`目录下。简单用法如下: +框架默认使用Log4Net作为记录日志的方式,可以在Program.cs中配置日志参数或调整为其他日志。日志默认按日期生成日志文件,并存放在 `log\`目录下。简单用法如下: ```csharp //具体代码参考OpenAuth.App/OpenJobApp.cs,此处简化真实逻辑,方便理解 @@ -25,7 +24,7 @@ permalink: /core/log/ ## 数据库日志 -如果想使用数据库记录业务日志(如系统默认的用户操作日志等),可以使用`SysLogApp`模块功能。日志可以在站点【消息日志】->【系统日志】中查看到记录的日志信息。简单用法如下: +如果想使用数据库记录业务日志(如系统默认的用户操作日志等),可以使用 `SysLogApp`模块功能。日志可以在站点【消息日志】->【系统日志】中查看到记录的日志信息。简单用法如下: ```csharp //具体代码参考OpenAuth.App/OpenJobApp.cs,此处简化真实逻辑,方便理解 @@ -49,30 +48,9 @@ permalink: /core/log/ } ``` -## EF打印Sql日志 +## EF输出Sql到log4net(文件/控制台) -在调试数据库时,需要打印真正执行的SQL信息。最简单的方式是使用下面方法输出到控制台: - -```csharp - public partial class OpenAuthDBContext : DbContext - { - - public static readonly ILoggerFactory MyLoggerFactory - = LoggerFactory.Create(builder => { builder.AddConsole(); }); - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.EnableSensitiveDataLogging (true); //允许打印参数 - optionsBuilder.UseLoggerFactory (MyLoggerFactory); - - base.OnConfiguring (optionsBuilder); - } - } -``` - -## EF输出Sql到log4net - -框架目前直接配置`appsettings.Development.json`即可完成输出sql语句到log4net对应的日志文件中。如下: +框架目前直接配置 `appsettings.Development.json`即可完成输出sql语句到log4net对应的日志文件中。如下: ``` "Logging": { @@ -82,7 +60,7 @@ permalink: /core/log/ } ``` -正式发布环境下,如无特殊需求,建议在`appsettings.Production.json`配置中关闭该输出 +正式发布环境下,如无特殊需求,建议在 `appsettings.Production.json`配置中关闭该输出 ## 在Swagger中输出日志 @@ -90,7 +68,7 @@ permalink: /core/log/ ![2025-04-24-00-23-43](http://img.openauth.net.cn/2025-04-24-00-23-43.png) -点击`sql`列的时间,查看详细的sql执行情况 +点击 `sql`列的时间,查看详细的sql执行情况 ![2025-04-24-00-23-53](http://img.openauth.net.cn/2025-04-24-00-23-53.png) @@ -119,6 +97,5 @@ public LoginResult Login(PassportLoginRequest request) return result; } ``` + 这时调用该API后即可看到具体步骤一、步骤二、步骤三的执行时间情况了 - -