diff --git a/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj b/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj index 9f7826c0..0c6eda36 100644 --- a/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj +++ b/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj @@ -17,27 +17,27 @@ - - - - + + + + - - + + - + - - - + + + diff --git a/Admin.NET/Admin.NET.Core/Extension/HttpContextExtension.cs b/Admin.NET/Admin.NET.Core/Extension/HttpContextExtension.cs deleted file mode 100644 index 82955e2d..00000000 --- a/Admin.NET/Admin.NET.Core/Extension/HttpContextExtension.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -using System.Net; - -namespace Admin.NET.Core; - -/// -/// HttpContext拓展 -/// -[SuppressSniffer] -public static partial class HttpContextExtension -{ - /// - /// 获取客户端真实 IP 地址 - /// - /// bool - public static string GetRemoteIp(this HttpContext httpContext) - { - var ip = string.Empty; - try - { - // 从 X-Forwarded-For 头获取 IP - ip = httpContext.Request.Headers["X-Forwarded-For"]; - if (string.IsNullOrEmpty(ip)) - { - ip = httpContext.GetRemoteIpAddressToIPv4(); - } - // 验证 IP 地址有效性 - if (!IPAddress.TryParse(ip, out _)) - { - ip = null; - } - } - catch { } - return ip; - } -} \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs b/Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs index 7fef0e55..31200c32 100644 --- a/Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs +++ b/Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs @@ -167,6 +167,13 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData new SysMenu{ Id=1310000000431, Pid=1310000000301, Title="系统配置", Path="/platform/infoSetting", Name="sysInfoSetting", Component="/system/infoSetting/index", Icon="ele-Setting", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=220 }, + new SysMenu{ Id=1310000000441, Pid=1310000000301, Title="微信支付", Path="/platform/wechatpay", Name="sysWechatPay", Component="/system/weChatPay/index", Icon="ele-Coin", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=230 }, + new SysMenu{ Id=1310000000442, Pid=1310000000441, Title="微信支付下单Native", Permission="sysWechatPay:payTransactionNative", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, + new SysMenu{ Id=1310000000443, Pid=1310000000441, Title="查询退款信息", Permission="sysWechatPay:listRefund", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, + new SysMenu{ Id=1310000000444, Pid=1310000000441, Title="获取支付订单详情(本地库)", Permission="sysWechatPay:payInfo", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, + new SysMenu{ Id=1310000000445, Pid=1310000000441, Title="获取支付订单详情(微信接口)", Permission="sysWechatPay:payInfoFromWechat", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, + new SysMenu{ Id=1310000000446, Pid=1310000000441, Title="退款申请", Permission="sysWechatPay:refundDomestic", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, + new SysMenu{ Id=1310000000501, Pid=0, Title="日志管理", Path="/log", Name="log", Component="Layout", Icon="ele-DocumentCopy", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=12000 }, new SysMenu{ Id=1310000000511, Pid=1310000000501, Title="访问日志", Path="/log/vislog", Name="sysVisLog", Component="/system/log/vislog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, new SysMenu{ Id=1310000000512, Pid=1310000000511, Title="查询", Permission="sysVislog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, diff --git a/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs b/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs index 4e4cb805..4d4af392 100644 --- a/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs @@ -238,7 +238,7 @@ public class SysAuthService : IDynamicApiController, ITransient // ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']); // 更新用户登录信息 - user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIp(); + user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(true); (user.LastLoginAddress, double? longitude, double? latitude) = CommonUtil.GetIpAddress(user.LastLoginIp); user.LastLoginTime = DateTime.Now; user.LastLoginDevice = CommonUtil.GetClientDeviceInfo(_httpContextAccessor.HttpContext?.Request?.Headers?.UserAgent); diff --git a/Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs b/Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs index d850b820..8ed4dcdd 100644 --- a/Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs +++ b/Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs @@ -64,33 +64,6 @@ public class SysFileService : IDynamicApiController, ITransient return await HandleUploadFile(input.File, input.Path, fileType: input.FileType); } - /// - /// 上传文件Base64 - /// - /// - /// - /// - /// - /// - /// - private async Task UploadFileFromBase64(string strBase64, string fileName, string contentType, string? path, string? fileType) - { - byte[] fileData = Convert.FromBase64String(strBase64); - var ms = new MemoryStream(); - ms.Write(fileData); - ms.Seek(0, SeekOrigin.Begin); - if (string.IsNullOrEmpty(fileName)) - fileName = $"{YitIdHelper.NextId()}.jpg"; - if (string.IsNullOrEmpty(contentType)) - contentType = "image/jpg"; - IFormFile formFile = new FormFile(ms, 0, fileData.Length, "file", fileName) - { - Headers = new HeaderDictionary(), - ContentType = contentType - }; - return await UploadFile(new FileUploadInput { File = formFile, Path = path, FileType = fileType }); - } - /// /// 上传文件Base64 🔖 /// @@ -99,7 +72,20 @@ public class SysFileService : IDynamicApiController, ITransient [DisplayName("上传文件Base64")] public async Task UploadFileFromBase64(UploadFileFromBase64Input input) { - return await UploadFileFromBase64(input.FileDataBase64, input.FileName, input.ContentType, input.Path, input.FileType); + byte[] fileData = Convert.FromBase64String(input.FileDataBase64); + var ms = new MemoryStream(); + ms.Write(fileData); + ms.Seek(0, SeekOrigin.Begin); + if (string.IsNullOrEmpty(input.FileName)) + input.FileName = $"{YitIdHelper.NextId()}.jpg"; + if (string.IsNullOrEmpty(input.ContentType)) + input.ContentType = "image/jpg"; + IFormFile formFile = new FormFile(ms, 0, fileData.Length, "file", input.FileName) + { + Headers = new HeaderDictionary(), + ContentType = input.ContentType + }; + return await UploadFile(new FileUploadInput { File = formFile, Path = input.Path, FileType = input.FileType }); } /// @@ -335,7 +321,7 @@ public class SysFileService : IDynamicApiController, ITransient // 获取文件后缀 var suffix = Path.GetExtension(file.FileName).ToLower(); // 后缀 - if (string.IsNullOrWhiteSpace(suffix)) + if (!string.IsNullOrWhiteSpace(suffix)) { var contentTypeProvider = FS.GetFileExtensionContentTypeProvider(); suffix = contentTypeProvider.Mappings.FirstOrDefault(u => u.Value == file.ContentType).Key; diff --git a/Admin.NET/Admin.NET.Core/Service/Job/JobClusterServer.cs b/Admin.NET/Admin.NET.Core/Service/Job/JobClusterServer.cs index b9cc448b..fca54e02 100644 --- a/Admin.NET/Admin.NET.Core/Service/Job/JobClusterServer.cs +++ b/Admin.NET/Admin.NET.Core/Service/Job/JobClusterServer.cs @@ -51,7 +51,7 @@ public class JobClusterServer : IJobClusterServer try { - ICache _cache = App.GetRequiredService(); + ICache _cache = App.GetRequiredService().Cache; // 使用分布式锁 using (_cache.AcquireLock("lock:JobClusterServer:WaitingForAsync", 1000)) { diff --git a/Admin.NET/Admin.NET.Web.Core/Startup.cs b/Admin.NET/Admin.NET.Web.Core/Startup.cs index 244ce2f1..3f55b4da 100644 --- a/Admin.NET/Admin.NET.Web.Core/Startup.cs +++ b/Admin.NET/Admin.NET.Web.Core/Startup.cs @@ -168,8 +168,11 @@ public class Startup : AppStartup services.AddViewEngine(); // 即时通讯 - services.AddSignalR(SetNewtonsoftJsonSetting); //services.AddSingleton(); + services.AddSignalR(options => + { + options.KeepAliveInterval = TimeSpan.FromSeconds(5); + }).AddNewtonsoftJsonProtocol(options => SetNewtonsoftJsonSetting(options.PayloadSerializerSettings)); // 系统日志 services.AddLoggingSetup(); diff --git a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm index 2ff769de..fd3e3842 100644 --- a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm +++ b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm @@ -199,6 +199,7 @@ if(@column.EffectType == "fk" && (@column.WhetherAddUpdate == "Y" || column.Quer @:/// @:/// @:[ApiDescriptionSettings(Name = "@(@column.FkEntityName)@(@column.PropertyName)Dropdown"), HttpGet] + @:[DisplayName("获取@(@column.ColumnComment)列表")] @:public async Task @(@column.FkEntityName)@(@column.PropertyName)Dropdown() @:{ @:return await _rep.Context.Queryable<@(@column.FkEntityName)>() diff --git a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm index b9aa23cf..a80e5927 100644 --- a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm +++ b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm @@ -1,4 +1,4 @@ -@{ +@{ var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault(); string pkFieldName = null; if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName)) @@ -192,7 +192,7 @@ v-model:page-size="tableParams.pageSize" :total="tableParams.total" :page-sizes="[10, 20, 50, 100, 200, 500]" - small="" + size="small" background="" @@size-change="handleSizeChange" @@current-change="handleCurrentChange" diff --git a/Web/package.json b/Web/package.json index fbf1ffb7..fd561aa2 100644 --- a/Web/package.json +++ b/Web/package.json @@ -49,7 +49,7 @@ "print-js": "^1.6.0", "push.js": "^1.0.12", "qrcodejs2-fixes": "^0.0.2", - "qs": "^6.12.1", + "qs": "^6.12.2", "relation-graph": "^2.2.1", "screenfull": "^6.0.2", "sm-crypto-v2": "^1.9.0", @@ -68,11 +68,11 @@ "vue-signature-pad": "^3.0.2", "vue3-tree-org": "^4.2.2", "vuedraggable": "4.0.3", - "vxe-pc-ui": "^4.0.42", - "vxe-table": "^4.7.39", + "vxe-pc-ui": "^4.0.44", + "vxe-table": "^4.7.40", "vxe-table-plugin-element": "^4.0.4", "vxe-table-plugin-export-xlsx": "^4.0.4", - "xe-utils": "^3.5.27", + "xe-utils": "^3.5.28", "xlsx-js-style": "^1.2.0" }, "devDependencies": { @@ -81,8 +81,8 @@ "@types/node": "^20.14.9", "@types/nprogress": "^0.2.3", "@types/sortablejs": "^1.15.8", - "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.14.1", + "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/parser": "^7.15.0", "@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue-jsx": "^4.0.0", "@vue/compiler-sfc": "^3.4.31", @@ -94,10 +94,10 @@ "rollup-plugin-visualizer": "^5.12.0", "sass": "^1.77.6", "terser": "^5.31.1", - "typescript": "^5.5.2", + "typescript": "^5.5.3", "vite": "^5.3.2", "vite-plugin-cdn-import": "^1.0.1", - "vite-plugin-compression2": "^1.1.1", + "vite-plugin-compression2": "^1.1.2", "vite-plugin-vue-setup-extend": "^0.4.0", "vue-eslint-parser": "^9.4.3" }, diff --git a/Web/src/views/system/cache/index.vue b/Web/src/views/system/cache/index.vue index 437c68e1..a08d5f73 100644 --- a/Web/src/views/system/cache/index.vue +++ b/Web/src/views/system/cache/index.vue @@ -1,9 +1,9 @@